@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,1672 +1,1596 @@
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/base/Log",
11
- "sap/m/Text",
12
- "sap/m/Button",
13
- "sap/m/Dialog",
14
- "sap/fe/core/CommonUtils",
15
- "sap/fe/core/BusyLocker",
16
- "sap/fe/core/library",
17
- "sap/ui/model/odata/v4/ODataListBinding",
18
- "sap/fe/core/helpers/SemanticKeyHelper",
19
- "sap/fe/core/helpers/EditState",
20
- "sap/fe/core/helpers/FPMHelper",
21
- "sap/ui/core/message/Message",
22
- "sap/ui/core/MessageType",
23
- "sap/fe/core/helpers/ModelHelper"
24
- ],
25
- function(
26
- ControllerExtension,
27
- OverrideExecution,
28
- Log,
29
- Text,
30
- Button,
31
- Dialog,
32
- CommonUtils,
33
- BusyLocker,
34
- FELibrary,
35
- ODataListBinding,
36
- SemanticKeyHelper,
37
- EditState,
38
- FPMHelper,
39
- Message,
40
- MessageType,
41
- ModelHelper
42
- ) {
43
- "use strict";
44
-
45
- /**
46
- * @class A controller extension offering hooks into the edit flow of the application
47
- *
48
- * @name sap.fe.core.controllerextensions.EditFlow
49
- * @hideconstructor
50
- * @public
51
- * @since 1.90.0
52
- */
53
-
54
- var CreationMode = FELibrary.CreationMode,
55
- ProgrammingModel = FELibrary.ProgrammingModel,
56
- Constants = FELibrary.Constants,
57
- DraftStatus = FELibrary.DraftStatus,
58
- EditMode = FELibrary.EditMode;
59
-
60
- return ControllerExtension.extend("sap.fe.core.controllerextensions.EditFlow", {
61
- metadata: {
62
- methods: {
63
- editDocument: { "public": true, "final": true },
64
- updateDocument: { "public": true, "final": true },
65
- createDocument: { "public": true, "final": true },
66
- saveDocument: { "public": true, "final": true },
67
- cancelDocument: { "public": true, "final": true },
68
- deleteDocument: { "public": true, "final": true },
69
- deleteMultipleDocuments: { "public": true, "final": true },
70
- applyDocument: { "public": true, "final": true },
71
- invokeAction: { "public": true, "final": true },
72
- securedExecution: { "public": true, "final": true },
73
-
74
- onBeforeSave: { "public": true, "final": false, "overrideExecution": OverrideExecution.After },
75
- onBeforeDelete: { "public": true, "final": false, "overrideExecution": OverrideExecution.After },
76
- onBeforeCreate: { "public": true, "final": false, "overrideExecution": OverrideExecution.After },
77
- onBeforeEdit: { "public": true, "final": false, "overrideExecution": OverrideExecution.After },
78
- onBeforeDiscard: { "public": true, "final": false, "overrideExecution": OverrideExecution.After }
79
- }
80
- },
81
-
82
- //////////////////////////////////////
83
- // Public methods
84
- //////////////////////////////////////
85
-
86
- // Internal only params ---
87
- // @param {boolean} mParameters.prepareOnEdit Indicates that the 'prepare' action for draft-based documents is called
88
-
89
- // eslint-disable-next-line jsdoc/require-param
90
- /**
91
- * Creates a draft document for an existing active document.
92
- *
93
- * @memberof sap.fe.core.controllerextensions.EditFlow
94
- * @param {object} oContext Context of the active document
95
- * @param {map} [mParameters] Contains the following attributes:
96
- * @param {boolean} [mParameters.prepareOnEdit] For a service with a prepare action, this parameter decides if the action is to be executed
97
- * @returns {Promise} Promise resolves once the editable document is available
98
- * @alias sap.fe.core.controllerextensions.EditFlow#editDocument
99
- * @public
100
- * @since 1.90.0
101
- */
102
- editDocument: function(oContext, mParameters) {
103
- mParameters = mParameters || {};
104
- var that = this,
105
- bPrepareOnEdit = mParameters.prepareOnEdit || undefined,
106
- bDraftNavigation = true,
107
- transactionHelper = this._getTransactionHelper();
108
-
109
- return this.base.editFlow
110
- .onBeforeEdit({ context: oContext })
111
- .then(
112
- transactionHelper.editDocument.bind(
113
- transactionHelper,
114
- oContext,
115
- bPrepareOnEdit,
116
- that.getView(),
117
- that._getMessageHandler()
118
- )
119
- )
120
- .then(function(oNewDocumentContext) {
121
- var sProgrammingModel = that._getProgrammingModel(oContext);
122
-
123
- if (sProgrammingModel === ProgrammingModel.Sticky) {
124
- that._getInternalModel().setProperty("/sessionOn", true);
125
- }
126
- if (oNewDocumentContext) {
127
- that._setEditMode(EditMode.Editable, false);
128
- that._getMessageHandler().showMessageDialog();
129
-
130
- if (oNewDocumentContext !== oContext) {
131
- return that
132
- ._handleNewContext(oNewDocumentContext, true, undefined, bDraftNavigation, true)
133
- .then(function() {
134
- if (sProgrammingModel === ProgrammingModel.Sticky) {
135
- // The stickyOn handler must be set after the navigation has been done,
136
- // as the URL may change in the case of FCL
137
- that._handleStickyOn(oNewDocumentContext);
138
- }
139
- });
140
- }
141
- }
142
- })
143
- .catch(function(oError) {
144
- Log.error("Error while editing the document", oError);
145
- });
146
- },
147
-
148
- deleteMultipleDocuments: function(aContexts, mParameters) {
149
- if (mParameters) {
150
- mParameters.beforeDeleteCallBack = this.base.editFlow.onBeforeDelete;
151
- } else {
152
- mParameters = {
153
- beforeDeleteCallBack: this.base.editFlow.onBeforeDelete
154
- };
155
- }
156
- return this.base
157
- .getView()
158
- .getController()
159
- ._editFlow.deleteMultipleDocuments(aContexts, mParameters);
160
- },
161
-
162
- /**
163
- * Updates the draft status and displays the error messages if there are errors during an update.
164
- *
165
- * @memberof sap.fe.core.controllerextensions.EditFlow
166
- * @param {object} oContext Context of the updated field
167
- * @param {object} oPromise Promise to determine when the update operation is completed. The promise should be resolved when the update operation is completed, so the draft status can be updated.
168
- * @returns {Promise} Promise resolves once draft status has been updated
169
- * @alias sap.fe.core.controllerextensions.EditFlow#updateDocument
170
- * @public
171
- * @since 1.90.0
172
- */
173
- updateDocument: function(oContext, oPromise) {
174
- var that = this,
175
- transactionHelper = that._getTransactionHelper(),
176
- oBindingContext = that.getView().getBindingContext(),
177
- bIsDraft = that._getProgrammingModel(oContext) === ProgrammingModel.Draft;
178
-
179
- this._getMessageHandler().removeTransitionMessages();
180
- return this._syncTask(function() {
181
- if (oBindingContext) {
182
- transactionHelper.handleDocumentModifications();
183
- EditState.setEditStateDirty();
184
-
185
- if (bIsDraft) {
186
- that._setDraftStatus(DraftStatus.Saving);
187
- }
188
- }
189
- that._getMessageHandler().removeTransitionMessages();
190
-
191
- return oPromise
192
- .then(
193
- function() {
194
- if (bIsDraft && oBindingContext) {
195
- var oMetaModel = oBindingContext.getModel().getMetaModel(),
196
- sEntitySetName = oMetaModel.getMetaContext(oBindingContext.getPath()).getObject("@sapui.name"),
197
- aSemanticKeys = SemanticKeyHelper.getSemanticKeys(oMetaModel, sEntitySetName);
198
- if (aSemanticKeys && aSemanticKeys.length) {
199
- var oCurrentSemanticMapping = that.base
200
- .getAppComponent()
201
- .getRoutingService()
202
- .getLastSemanticMapping(),
203
- sCurrentSemanticPath = oCurrentSemanticMapping && oCurrentSemanticMapping.semanticPath,
204
- sChangedPath = SemanticKeyHelper.getSemanticPath(oBindingContext, true);
205
-
206
- if (sCurrentSemanticPath !== sChangedPath) {
207
- return that._handleNewContext(oBindingContext, true, undefined, true).then(function() {
208
- that._setDraftStatus(DraftStatus.Saved);
209
- });
210
- } else {
211
- that._setDraftStatus(DraftStatus.Saved);
212
- }
213
- } else {
214
- that._setDraftStatus(DraftStatus.Saved);
215
- }
216
- }
217
- },
218
- function() {
219
- if (bIsDraft && oBindingContext) {
220
- that._setDraftStatus(DraftStatus.Clear);
221
- }
222
- }
223
- )
224
- .catch(function(oError) {
225
- Log.error("Error while updating the document", oError);
226
- })
227
- .finally(function() {
228
- that._getMessageHandler().showMessages();
229
- });
230
- });
231
- },
232
-
233
- // Internal only params ---
234
- // * @param {string} mParameters.creationMode The creation mode using one of the following:
235
- // * Sync - the creation is triggered and once the document is created, the navigation is done
236
- // * Async - the creation and the navigation to the instance are done in parallel
237
- // * Deferred - the creation is done on the target page
238
- // * CreationRow - The creation is done inline async so the user is not blocked
239
- // mParameters.creationRow Instance of the creation row - (TODO: get rid but use list bindings only)
240
-
241
- // eslint-disable-next-line jsdoc/require-param
242
- /**
243
- * Creates a new document.
244
- *
245
- * @memberof sap.fe.core.controllerextensions.EditFlow
246
- * @param {sap.ui.model.odata.v4.ODataListBinding|string} vListBinding ODataListBinding object or the binding path for a temporary list binding
247
- * @param {map} mParameters Contains the following attributes:
248
- * @param {string} mParameters.creationMode The creation mode using one of the following:
249
- * NewPage - the created document is shown in a new page, depending on whether metadata 'Sync', 'Async' or 'Deferred' is used
250
- * Inline - The creation is done inline (in a table)
251
- * External - The creation is done in a different application specified via the parameter 'outbound'
252
- * @param {string} [mParameters.outbound] The navigation target where the document is created in case of creationMode 'External'
253
- * @param {boolean} [mParameters.createAtEnd] Specifies if the new entry should be created at the top or bottom of a table in case of creationMode 'Inline'
254
- * @returns {Promise} Promise resolves once the object has been created
255
- * @alias sap.fe.core.controllerextensions.EditFlow#createDocument
256
- * @public
257
- * @since 1.90.0
258
- */
259
- createDocument: function(vListBinding, mParameters) {
260
- var that = this,
261
- transactionHelper = this._getTransactionHelper(),
262
- oLockObject = this._getGlobalUIModel(),
263
- oTable,
264
- iCountTableItems = 0,
265
- oResourceBundle = that.getView().getController().oResourceBundle,
266
- bShouldBusyLock =
267
- !mParameters ||
268
- (mParameters.creationMode !== CreationMode.Inline &&
269
- mParameters.creationMode !== CreationMode.CreationRow &&
270
- mParameters.creationMode !== CreationMode.External),
271
- oExecCustomValidation = Promise.resolve([]),
272
- oAppComponent = CommonUtils.getAppComponent(this.getView());
273
- oAppComponent.getRouterProxy().removeIAppStateKey();
274
-
275
- if (mParameters.creationMode === CreationMode.External) {
276
- // Create by navigating to an external target
277
- // TODO: Call appropriate function (currently using the same as for outbound chevron nav, and without any context - 3rd param)
278
- return this._syncTask().then(function() {
279
- var oController = that.getView().getController(),
280
- sCreatePath = ModelHelper.getAbsoluteMetaPathForListBinding(that.getView(), vListBinding);
281
-
282
- oController.handlers.onChevronPressNavigateOutBound(oController, mParameters.outbound, undefined, sCreatePath);
283
- });
284
- }
285
-
286
- if (mParameters.creationMode === CreationMode.CreationRow && mParameters.creationRow) {
287
- var oCreationRowObjects = mParameters.creationRow.getBindingContext().getObject();
288
- delete oCreationRowObjects["@$ui5.context.isTransient"];
289
- oTable = mParameters.creationRow.getParent();
290
- oExecCustomValidation = transactionHelper.validateDocument(
291
- oTable.getBindingContext(),
292
- {
293
- data: oCreationRowObjects,
294
- customValidationFunction: oTable.getCreationRow().data("customValidationFunction")
295
- },
296
- that.base.getView()
297
- );
298
-
299
- // disableAddRowButtonForEmptyData is set to false in manifest converter (Table.ts) if customValidationFunction exists
300
- if (oTable.getCreationRow().data("disableAddRowButtonForEmptyData") === "true") {
301
- var oInternalModelContext = oTable.getBindingContext("internal");
302
- oInternalModelContext.setProperty("creationRowFieldValidity", {});
303
- }
304
- }
305
-
306
- if (mParameters.creationMode === CreationMode.Inline && mParameters.tableId) {
307
- oTable = this.getView().byId(mParameters.tableId);
308
- }
309
-
310
- /**
311
- * @param {sap.ui.model.odata.v4.ODataListBinding} oListBinding
312
- * @param {object} oCreationPromise
313
- */
314
- function handleSideEffects(oListBinding, oCreationPromise) {
315
- oCreationPromise
316
- .then(function(oNewContext) {
317
- // transient contexts are reliably removed once oNewContext.created() is resolved
318
- return oNewContext.created();
319
- })
320
- .then(function() {
321
- var oBindingContext = that.getView().getBindingContext();
322
- // if there are transient contexts, we must avoid requesting side effects
323
- // this is avoid a potential list refresh, there could be a side effect that refreshes the list binding
324
- // if list binding is refreshed, transient contexts might be lost
325
- if (!CommonUtils.hasTransientContext(oListBinding)) {
326
- var oAppComponent = CommonUtils.getAppComponent(that.getView());
327
- oAppComponent
328
- .getSideEffectsService()
329
- .requestSideEffectsForNavigationProperty(oListBinding.getPath(), oBindingContext);
330
- }
331
- })
332
- .catch(function(oError) {
333
- Log.error("Error while creating the document", oError);
334
- });
335
- }
336
-
337
- /**
338
- * @param {Array} aValidationMessages Error messages from custom validation function
339
- */
340
- function createCustomValidationMessages(aValidationMessages) {
341
- var sCustomValidationFunction = oTable && oTable.getCreationRow().data("customValidationFunction"),
342
- mCustomValidity = oTable && oTable.getBindingContext("internal").getProperty("creationRowCustomValidity"),
343
- oMessageManager = sap.ui.getCore().getMessageManager(),
344
- aCustomMessages = [],
345
- oFieldControl,
346
- sTarget;
347
-
348
- // Remove existing CustomValidation message
349
- oMessageManager
350
- .getMessageModel()
351
- .getData()
352
- .forEach(function(oMessage) {
353
- if (oMessage.code === sCustomValidationFunction) {
354
- oMessageManager.removeMessages(oMessage);
355
- }
356
- });
357
-
358
- aValidationMessages.forEach(function(oValidationMessage) {
359
- // Handle Bound CustomValidation message
360
- if (oValidationMessage.messageTarget) {
361
- oFieldControl = sap.ui.getCore().getControl(mCustomValidity[oValidationMessage.messageTarget].fieldId);
362
- sTarget = oFieldControl.getBindingContext().getPath() + "/" + oFieldControl.getBindingPath("value");
363
- // Add validation message if still not exists
364
- if (
365
- oMessageManager
366
- .getMessageModel()
367
- .getData()
368
- .filter(function(oMessage) {
369
- return oMessage.target === sTarget;
370
- }).length === 0
371
- ) {
372
- oMessageManager.addMessages(
373
- new Message({
374
- message: oValidationMessage.messageText,
375
- processor: that.getView().getModel(),
376
- type: MessageType.Error,
377
- code: sCustomValidationFunction,
378
- technical: false,
379
- persistent: false,
380
- target: sTarget
381
- })
382
- );
383
- }
384
- // Add controlId in order to get the focus handling of the error popover runable
385
- var aExistingValidationMessages = oMessageManager
386
- .getMessageModel()
387
- .getData()
388
- .filter(function(oMessage) {
389
- return oMessage.target === sTarget;
390
- });
391
- aExistingValidationMessages[0].addControlId(mCustomValidity[oValidationMessage.messageTarget].fieldId);
392
-
393
- // Handle Unbound CustomValidation message
394
- } else {
395
- aCustomMessages.push({
396
- code: sCustomValidationFunction,
397
- text: oValidationMessage.messageText,
398
- persistent: true,
399
- type: MessageType.Error
400
- });
401
- }
402
- });
403
-
404
- if (aCustomMessages.length > 0) {
405
- that._getMessageHandler().showMessageDialog({
406
- customMessages: aCustomMessages
407
- });
408
- }
409
- }
410
-
411
- bShouldBusyLock && BusyLocker.lock(oLockObject);
412
- return this._syncTask(oExecCustomValidation)
413
- .then(function(aValidationMessages) {
414
- if (aValidationMessages.length > 0) {
415
- createCustomValidationMessages(aValidationMessages);
416
- Log.error("Custom Validation failed");
417
- // if custom validation fails, we leave the method immediately
418
- return;
419
- }
420
-
421
- var sProgrammingModel, oListBinding, oModel;
422
-
423
- mParameters = mParameters || {};
424
-
425
- if (vListBinding && typeof vListBinding === "object") {
426
- // we already get a list binding use this one
427
- oListBinding = vListBinding;
428
- } else if (typeof vListBinding === "string") {
429
- oListBinding = new ODataListBinding(that.getView().getModel(), vListBinding);
430
- mParameters.creationMode = CreationMode.Sync;
431
- delete mParameters.createAtEnd;
432
- } else {
433
- throw new Error("Binding object or path expected");
434
- }
435
-
436
- oModel = oListBinding.getModel();
437
- iCountTableItems = oListBinding.iMaxLength || 0;
438
- var sCreationMode = mParameters.creationMode;
439
-
440
- return Promise.resolve(that._getProgrammingModel(oListBinding))
441
- .then(function(programmingModel) {
442
- sProgrammingModel = programmingModel;
443
- if (sCreationMode && sCreationMode !== CreationMode.NewPage) {
444
- // use the passed creation mode
445
- return sCreationMode;
446
- } else {
447
- var oMetaModel = oModel.getMetaModel();
448
- // NewAction is not yet supported for NavigationProperty collection
449
- if (!oListBinding.isRelative()) {
450
- var sPath = oListBinding.getPath(),
451
- // if NewAction with parameters is present, then creation is 'Deferred'
452
- // in the absence of NewAction or NewAction with parameters, creation is async
453
- sNewAction =
454
- sProgrammingModel === ProgrammingModel.Draft
455
- ? oMetaModel.getObject(sPath + "@com.sap.vocabularies.Common.v1.DraftRoot/NewAction")
456
- : oMetaModel.getObject(
457
- sPath + "@com.sap.vocabularies.Session.v1.StickySessionSupported/NewAction"
458
- );
459
- if (sNewAction) {
460
- var aParameters = oMetaModel.getObject("/" + sNewAction + "/@$ui5.overload/0/$Parameter") || [];
461
- // binding parameter (eg: _it) is not considered
462
- if (aParameters.length > 1) {
463
- return CreationMode.Deferred;
464
- }
465
- }
466
- }
467
- var sMetaPath = oMetaModel.getMetaPath(oListBinding.getHeaderContext().getPath());
468
- var aNonComputedVisibleKeyFields = CommonUtils.getNonComputedVisibleFields(
469
- oMetaModel,
470
- sMetaPath,
471
- that.getView()
472
- );
473
- if (aNonComputedVisibleKeyFields.length > 0) {
474
- return CreationMode.Deferred;
475
- }
476
- return CreationMode.Async;
477
- }
478
- })
479
- .then(function(sCreationMode) {
480
- var oCreation,
481
- mArgs,
482
- oCreationRow = mParameters.creationRow,
483
- oCreationRowContext,
484
- oValidationCheck = Promise.resolve(),
485
- oPayload,
486
- sMetaPath,
487
- oMetaModel = oModel.getMetaModel(),
488
- oRoutingListener = that._getRoutingListener();
489
-
490
- if (sCreationMode !== CreationMode.Deferred) {
491
- if (sCreationMode === CreationMode.CreationRow) {
492
- oCreationRowContext = oCreationRow.getBindingContext();
493
- sMetaPath = oMetaModel.getMetaPath(oCreationRowContext.getPath());
494
- // prefill data from creation row
495
- oPayload = oCreationRowContext.getObject();
496
- mParameters.data = {};
497
- Object.keys(oPayload).forEach(function(sPropertyPath) {
498
- var oProperty = oMetaModel.getObject(sMetaPath + "/" + sPropertyPath);
499
- // ensure navigation properties are not part of the payload, deep create not supported
500
- if (oProperty && oProperty.$kind === "NavigationProperty") {
501
- return;
502
- }
503
- mParameters.data[sPropertyPath] = oPayload[sPropertyPath];
504
- });
505
- oValidationCheck = that._checkForValidationErrors(oCreationRowContext);
506
- }
507
- if (sCreationMode === CreationMode.CreationRow || sCreationMode === CreationMode.Inline) {
508
- mParameters.keepTransientContextOnFailed = false; // currently not fully supported
509
- // busy handling shall be done locally only
510
- mParameters.busyMode = "Local";
511
-
512
- // take care on message handling, draft indicator (in case of draft)
513
- // Attach the create sent and create completed event to the object page binding so that we can react
514
- that._handleCreateEvents(oListBinding);
515
- }
516
-
517
- oCreation = oValidationCheck.then(function() {
518
- if (!mParameters.parentControl) {
519
- mParameters.parentControl = that.getView();
520
- }
521
- mParameters.beforeCreateCallBack = that.base.editFlow.onBeforeCreate;
522
- return transactionHelper.createDocument(
523
- oListBinding,
524
- mParameters,
525
- oResourceBundle,
526
- that._getMessageHandler(),
527
- false,
528
- that.getView()
529
- );
530
- });
531
- }
532
-
533
- var oNavigation;
534
- switch (sCreationMode) {
535
- case CreationMode.Deferred:
536
- oNavigation = oRoutingListener.navigateForwardToContext(oListBinding, {
537
- bDeferredContext: true,
538
- editable: true,
539
- bForceFocus: true
540
- });
541
- break;
542
- case CreationMode.Async:
543
- oNavigation = oRoutingListener.navigateForwardToContext(oListBinding, {
544
- asyncContext: oCreation,
545
- editable: true,
546
- bForceFocus: true
547
- });
548
- break;
549
- case CreationMode.Sync:
550
- mArgs = {
551
- editable: true,
552
- bForceFocus: true
553
- };
554
- if (sProgrammingModel == ProgrammingModel.Sticky || mParameters.createAction) {
555
- mArgs.transient = true;
556
- }
557
- oNavigation = oCreation.then(function(oNewDocumentContext) {
558
- if (!oNewDocumentContext) {
559
- var oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core");
560
- return oRoutingListener.navigateToMessagePage(
561
- oResourceBundle.getText("C_COMMON_SAPFE_DATA_RECEIVED_ERROR"),
562
- {
563
- title: oResourceBundle.getText("C_COMMON_SAPFE_ERROR"),
564
- description: oResourceBundle.getText("C_EDITFLOW_SAPFE_CREATION_FAILED_DESCRIPTION")
565
- }
566
- );
567
- } else {
568
- return oRoutingListener.navigateForwardToContext(oNewDocumentContext, mArgs);
569
- }
570
- });
571
- break;
572
- case CreationMode.Inline:
573
- handleSideEffects(oListBinding, oCreation);
574
- that._syncTask(oCreation);
575
- break;
576
- case CreationMode.CreationRow:
577
- // the creation row shall be cleared once the validation check was successful and
578
- // therefore the POST can be sent async to the backend
579
- oNavigation = oValidationCheck
580
- .then(function() {
581
- var oCreationRowListBinding = oCreationRowContext.getBinding(),
582
- oNewTransientContext;
583
-
584
- if (!mParameters.bSkipSideEffects) {
585
- handleSideEffects(oListBinding, oCreation);
586
- }
587
-
588
- oNewTransientContext = oCreationRowListBinding.create();
589
- oCreationRow.setBindingContext(oNewTransientContext);
590
-
591
- // this is needed to avoid console errors TO be checked with model colleagues
592
- oNewTransientContext.created().catch(function() {
593
- Log.trace("transient fast creation context deleted");
594
- });
595
- return oCreationRowContext.delete("$direct");
596
- })
597
- .catch(function(oError) {
598
- // Reset busy indicator after a validation error
599
- if (BusyLocker.isLocked(that.getView().getModel("ui"))) {
600
- BusyLocker.unlock(that.getView().getModel("ui"));
601
- }
602
- Log.error("CreationRow navigation error: ", oError);
603
- });
604
- break;
605
- default:
606
- oNavigation = Promise.reject("Unhandled creationMode " + sCreationMode);
607
- break;
608
- }
609
-
610
- if (sProgrammingModel === ProgrammingModel.Sticky) {
611
- that._getInternalModel().setProperty("/sessionOn", true);
612
- }
613
- var bIsNewPageCreation =
614
- mParameters.creationMode !== CreationMode.CreationRow &&
615
- mParameters.creationMode !== CreationMode.Inline;
616
- if (oCreation) {
617
- return Promise.all([oCreation, oNavigation])
618
- .then(function(aParams) {
619
- if (bIsNewPageCreation) {
620
- that._setEditMode(EditMode.Editable, bIsNewPageCreation);
621
- } else {
622
- that._setEditMode(EditMode.Editable);
623
- }
624
- var oNewDocumentContext = aParams[0];
625
- if (oNewDocumentContext) {
626
- EditState.setEditStateDirty();
627
-
628
- if (sProgrammingModel === ProgrammingModel.Sticky) {
629
- that._handleStickyOn(oNewDocumentContext);
630
- }
631
- }
632
- })
633
- .catch(function(oError) {
634
- if (oError && oError.navigateBackFromTransientState) {
635
- oRoutingListener.navigateBackFromTransientState();
636
- }
637
-
638
- return Promise.reject(oError);
639
- });
640
- }
641
- });
642
- })
643
- .finally(function() {
644
- if (oTable && oTable.isA("sap.ui.mdc.Table")) {
645
- var fnFocusOrScroll =
646
- mParameters.creationMode === CreationMode.Inline
647
- ? oTable.focusRow.bind(oTable)
648
- : oTable.scrollToIndex.bind(oTable);
649
- oTable.getRowBinding().attachEventOnce("change", function() {
650
- switch (mParameters.createAtEnd) {
651
- case true:
652
- if (oTable.data("tableType") === "ResponsiveTable" && oTable.getThreshold()) {
653
- fnFocusOrScroll(oTable.getThreshold(), true);
654
- } else {
655
- fnFocusOrScroll(iCountTableItems, true);
656
- }
657
- break;
658
- case false:
659
- fnFocusOrScroll(0, true);
660
- break;
661
- }
662
- });
663
- }
664
- bShouldBusyLock && BusyLocker.unlock(oLockObject);
665
- });
666
- },
667
-
668
- /**
669
- * This function can be used to intercept the 'Save' action. You can execute custom coding in this function.
670
- * The framework waits for the returned promise to be resolved before continuing the 'Save' action.
671
- * If you reject the promise, the 'Save' action is stopped and the user stays in edit mode.
672
- *
673
- * This function is meant to be individually overridden by consuming controllers, but not to be called directly.
674
- * The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
675
- * @param {map} [mParameters] Object containing the parameters passed to onBeforeSave
676
- * @param {sap.ui.model.odata.v4.Context} [mParameters.context] Page context that is going to be saved.
677
- * @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Save' action is triggered. If rejected, the 'Save' action is not triggered and the user stays in edit mode.
678
- * @memberof sap.fe.core.controllerextensions.EditFlow
679
- * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeSave
680
- * @public
681
- * @experimental As of version 1.90.0
682
- * @since 1.90.0
683
- */
684
- onBeforeSave: function(mParameters) {
685
- // to be overridden
686
- return Promise.resolve();
687
- },
688
- /**
689
- * This function can be used to intercept the 'Create' action. You can execute custom coding in this function.
690
- * The framework waits for the returned promise to be resolved before continuing the 'Create' action.
691
- * If you reject the promise, the 'Create' action is stopped.
692
- *
693
- * This function is meant to be individually overridden by consuming controllers, but not to be called directly.
694
- * The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
695
- * @param {map} [mParameters] Object containing the parameters passed to onBeforeCreate
696
- * @param {string} [mParameters.contextPath] Path pointing to the context on which Create action is triggered
697
- * @param {Array} [mParameters.createParameters] Array of values that are filled in the Action Parameter Dialog
698
- * @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Create' action is triggered. If rejected, the 'Create' action is not triggered.
699
- * @memberof sap.fe.core.controllerextensions.EditFlow
700
- * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeCreate
701
- * @public
702
- * @experimental As of version 1.98.0
703
- * @since 1.98.0
704
- */
705
- onBeforeCreate: function(mParameters) {
706
- // to be overridden
707
- return Promise.resolve();
708
- },
709
- /**
710
- * This function can be used to intercept the 'Edit' action. You can execute custom coding in this function.
711
- * The framework waits for the returned promise to be resolved before continuing the 'Edit' action.
712
- * If you reject the promise, the 'Edit' action is stopped and the user stays in display mode.
713
- *
714
- * This function is meant to be individually overridden by consuming controllers, but not to be called directly.
715
- * The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
716
- * @param {map} [mParameters] Object containing the parameters passed to onBeforeEdit
717
- * @param {sap.ui.model.odata.v4.Context} [mParameters.context] Page context that is going to be edited.
718
- * @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Edit' action is triggered. If rejected, the 'Edit' action is not triggered and the user stays in display mode.
719
- * @memberof sap.fe.core.controllerextensions.EditFlow
720
- * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeEdit
721
- * @public
722
- * @experimental As of version 1.98.0
723
- * @since 1.98.0
724
- */
725
- onBeforeEdit: function(mParameters) {
726
- // to be overridden
727
- return Promise.resolve();
728
- },
729
- /**
730
- * This function can be used to intercept the 'Discard' action. You can execute custom coding in this function.
731
- * The framework waits for the returned promise to be resolved before continuing the 'Discard' action.
732
- * If you reject the promise, the 'Discard' action is stopped and the user stays in edit mode.
733
- *
734
- * This function is meant to be individually overridden by consuming controllers, but not to be called directly.
735
- * The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
736
- * @param {map} [mParameters] Object containing the parameters passed to onBeforeDiscard
737
- * @param {sap.ui.model.odata.v4.Context} [mParameters.context] Page context that is going to be discarded.
738
- * @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Discard' action is triggered. If rejected, the 'Discard' action is not triggered and the user stays in edit mode.
739
- * @memberof sap.fe.core.controllerextensions.EditFlow
740
- * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeDiscard
741
- * @public
742
- * @experimental As of version 1.98.0
743
- * @since 1.98.0
744
- */
745
- onBeforeDiscard: function(mParameters) {
746
- // to be overridden
747
- return Promise.resolve();
748
- },
749
- /**
750
- * This function can be used to intercept the 'Delete' action. You can execute custom coding in this function.
751
- * The framework waits for the returned promise to be resolved before continuing the 'Delete' action.
752
- * If you reject the promise, the 'Delete' action is stopped.
753
- *
754
- * This function is meant to be individually overridden by consuming controllers, but not to be called directly.
755
- * The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
756
- * @param {map} [mParameters] Object containing the parameters passed to onBeforeDelete
757
- * @param {Array} [mParameters.contexts] An array of contexts that are going to be deleted
758
- * @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Delete' action is triggered. If rejected, the 'Delete' action is not triggered.
759
- * @memberof sap.fe.core.controllerextensions.EditFlow
760
- * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeDelete
761
- * @public
762
- * @experimental As of version 1.98.0
763
- * @since 1.98.0
764
- */
765
- onBeforeDelete: function(mParameters) {
766
- // to be overridden
767
- return Promise.resolve();
768
- },
769
-
770
- // Internal only params ---
771
- // @param {boolean} mParameters.bExecuteSideEffectsOnError Indicates whether SideEffects need to be ignored when user clicks on Save during an Inline creation
772
- // @param {object} mParameters.bindings List bindings of the tables in the view.
773
- // Both of the above parameters are for the same purpose. User can enter some information in the creation row(s) but does not 'Add row', instead clicks Save.
774
- // There can be more than one in the view.
775
-
776
- // eslint-disable-next-line jsdoc/require-param
777
- /**
778
- * Saves a new document after checking it.
779
- *
780
- * @memberof sap.fe.core.controllerextensions.EditFlow
781
- * @param {object} oContext Context of the editable document
782
- * @returns {Promise} Promise resolves once save is complete
783
- * @alias sap.fe.core.controllerextensions.EditFlow#saveDocument
784
- * @public
785
- * @since 1.90.0
786
- */
787
- saveDocument: function(oContext, mParameters) {
788
- mParameters = mParameters || {};
789
- var that = this,
790
- bExecuteSideEffectsOnError = mParameters.bExecuteSideEffectsOnError || undefined,
791
- bDraftNavigation = true,
792
- transactionHelper = this._getTransactionHelper(),
793
- oResourceBundle = that.getView().getController().oResourceBundle,
794
- aBindings = mParameters.bindings;
795
- // first of all wait until all key-match-requests are done
796
- return (
797
- this._syncTask()
798
- // submit any open changes if there any (although there are validation/parse errors)
799
- .then(this._submitOpenChanges.bind(this, oContext))
800
- // check if there are any validation/parse errors
801
- .then(this._checkForValidationErrors.bind(this, oContext))
802
- .then(this.base.editFlow.onBeforeSave.bind(this, { context: oContext }))
803
- // and finally if all user changes are submitted and valid save the document
804
- .then(
805
- transactionHelper.saveDocument.bind(
806
- transactionHelper,
807
- oContext,
808
- oResourceBundle,
809
- bExecuteSideEffectsOnError,
810
- aBindings,
811
- that._getMessageHandler()
812
- )
813
- )
814
- .then(function(oActiveDocumentContext) {
815
- var sProgrammingModel = that._getProgrammingModel(oContext);
816
-
817
- that._removeContextsFromPages();
818
- if (sProgrammingModel === ProgrammingModel.Sticky) {
819
- that._getInternalModel().setProperty("/sessionOn", false);
820
- that._handleStickyOff(oContext);
821
- }
822
-
823
- that._setEditMode(EditMode.Display, false);
824
- that._getMessageHandler().showMessageDialog();
825
-
826
- if (oActiveDocumentContext !== oContext) {
827
- that._handleNewContext(oActiveDocumentContext, false, undefined, bDraftNavigation, true);
828
- }
829
- })
830
- .catch(function(oError) {
831
- Log.error("Error while saving the document", oError);
832
- return Promise.reject(oError);
833
- })
834
- );
835
- },
836
-
837
- toggleDraftActive: function(oContext) {
838
- var oContextData = oContext.getObject();
839
- var that = this;
840
- var bEditable;
841
- var bIsDraft = oContext && this._getProgrammingModel(oContext) === ProgrammingModel.Draft;
842
- var oToggleContext = oContext
843
- .getModel()
844
- .bindContext(oContext.getPath() + "/SiblingEntity")
845
- .getBoundContext();
846
-
847
- //toggle between draft and active document is only available for edit drafts and active documents with draft)
848
- if (
849
- !bIsDraft ||
850
- !(
851
- (!oContextData.IsActiveEntity && oContextData.HasActiveEntity) ||
852
- (oContextData.IsActiveEntity && oContextData.HasDraftEntity)
853
- )
854
- ) {
855
- return;
856
- }
857
-
858
- if (!oContextData.IsActiveEntity && oContextData.HasActiveEntity) {
859
- //start Point: edit draft
860
- bEditable = false;
861
- } else if (oContextData.IsActiveEntity && oContextData.HasDraftEntity) {
862
- // start point active document
863
- bEditable = true;
864
- }
865
- oToggleContext
866
- .requestCanonicalPath()
867
- .then(function(sCanonicalPath) {
868
- // We use the canonical path for the navigation instead of the semantic path, as the
869
- // semantic key values may have changed between the draft and the active version (BCP 2170216142)
870
- return oToggleContext
871
- .getModel()
872
- .bindContext(sCanonicalPath)
873
- .getBoundContext();
874
- })
875
- .then(function(oToggleContext) {
876
- that._setEditMode(bEditable ? EditMode.Editable : EditMode.Display, false); //switch to edit mode only if a draft is available
877
- that._handleNewContext(oToggleContext, bEditable, true, true, true);
878
- })
879
- .catch(function(err) {
880
- return Promise.reject("Error in EditFlow.toggleDraftActive:" + err);
881
- });
882
- },
883
-
884
- // Internal only params ---
885
- // @param {sap.m.Button} mParameters.cancelButton - Currently this is passed as cancelButton internally (replaced by mParameters.control in the JSDoc below). Currently it is also mandatory.
886
- // Plan - This should not be mandatory. If not provided, we should have a default that can act as reference control for the discard popover OR we can show a dialog instead of a popover.
887
-
888
- /**
889
- * Discard the editable document.
890
- *
891
- * @memberof sap.fe.core.controllerextensions.EditFlow
892
- * @param {object} oContext Context of the editable document
893
- * @param {map} mParameters Can contain the following attributes:
894
- * @param {object} mParameters.control This is the control used to open the discard popover
895
- * @param {boolean} [mParameters.skipDiscardPopover] Optional, supresses the discard popover and allows custom handling
896
- * @returns {Promise} Promise resolves once editable document has been discarded
897
- * @alias sap.fe.core.controllerextensions.EditFlow#cancelDocument
898
- * @public
899
- * @since 1.90.0
900
- */
901
- cancelDocument: function(oContext, mParameters) {
902
- var that = this,
903
- transactionHelper = this._getTransactionHelper(),
904
- oResourceBundle = that.getView().getController().oResourceBundle;
905
- mParameters.cancelButton = mParameters.control || mParameters.cancelButton;
906
- mParameters.beforeCancelCallBack = this.base.editFlow.onBeforeDiscard;
907
- return this._syncTask()
908
- .then(
909
- transactionHelper.cancelDocument.bind(
910
- transactionHelper,
911
- oContext,
912
- mParameters,
913
- oResourceBundle,
914
- that._getMessageHandler()
915
- )
916
- )
917
- .then(function(oActiveDocumentContext) {
918
- var bDraftNavigation = true,
919
- sProgrammingModel = that._getProgrammingModel(oContext);
920
-
921
- that._removeContextsFromPages();
922
- if (sProgrammingModel === ProgrammingModel.Sticky) {
923
- that._getInternalModel().setProperty("/sessionOn", false);
924
- that._handleStickyOff(oContext);
925
- }
926
-
927
- that._setEditMode(EditMode.Display, false);
928
- that._setDraftStatus(DraftStatus.Clear);
929
-
930
- //in case of a new document, the value of hasActiveEntity is returned. navigate back.
931
- if (!oActiveDocumentContext) {
932
- EditState.setEditStateDirty();
933
- return mParameters.skipBackNavigation
934
- ? undefined
935
- : that._getRoutingListener().navigateBackFromContext(oContext);
936
- } else if (sProgrammingModel === ProgrammingModel.Draft) {
937
- // We need to load the semantic keys of the active context, as we need them
938
- // for the navigation
939
- return that._fetchSemanticKeyValues(oActiveDocumentContext).then(function() {
940
- // We force the recreation of the context, so that it's created and bound in the same microtask,
941
- // so that all properties are loaded together by autoExpandSelect, so that when switching back to Edit mode
942
- // $$inheritExpandSelect takes all loaded properties into account (BCP 2070462265)
943
- if (mParameters.skipBindingToView) {
944
- return oActiveDocumentContext;
945
- } else {
946
- return that._handleNewContext(oActiveDocumentContext, false, true, bDraftNavigation, true);
947
- }
948
- });
949
- } else {
950
- //active context is returned in case of cancel of existing document
951
- return that._handleNewContext(oActiveDocumentContext, false, undefined, bDraftNavigation, true);
952
- }
953
- })
954
- .catch(function(oError) {
955
- Log.error("Error while discarding the document", oError);
956
- });
957
- },
958
-
959
- // Internal only params ---
960
- // @param {string} mParameters.entitySetName Name of the EntitySet to which the object belongs
961
-
962
- /**
963
- * Deletes the document.
964
- *
965
- * @memberof sap.fe.core.controllerextensions.EditFlow
966
- * @param {object} oContext Context of the document
967
- * @param {map} mParameters Can contain the following attributes:
968
- * @param {string} mParameters.title Title of the object being deleted
969
- * @param {string} mParameters.description Description of the object being deleted
970
- * @returns {Promise} Promise resolves once document has been deleted
971
- * @alias sap.fe.core.controllerextensions.EditFlow#deleteDocument
972
- * @public
973
- * @since 1.90.0
974
- */
975
- deleteDocument: function(oContext, mParameters) {
976
- var that = this;
977
- var oAppComponent = CommonUtils.getAppComponent(that.getView());
978
- if (!mParameters) {
979
- mParameters = {
980
- bFindActiveContexts: false
981
- };
982
- } else {
983
- mParameters.bFindActiveContexts = false;
984
- }
985
- mParameters.beforeDeleteCallBack = this.base.editFlow.onBeforeDelete;
986
- return this._deleteDocumentTransaction(oContext, mParameters)
987
- .then(function() {
988
- // Single objet deletion is triggered from an OP header button (not from a list)
989
- // --> Mark UI dirty and navigate back to dismiss the OP
990
- EditState.setEditStateDirty();
991
-
992
- that._getRoutingListener().navigateBackFromContext(oContext);
993
- // After delete is successfull, we need to dettch the setBackNavigation Methods
994
- if (oAppComponent) {
995
- oAppComponent.getShellServices().setBackNavigation();
996
- }
997
- })
998
- .catch(function(oError) {
999
- Log.error("Error while deleting the document", oError);
1000
- });
1001
- },
1002
-
1003
- /**
1004
- * Submit the current set of changes and navigate back.
1005
- *
1006
- * @memberof sap.fe.core.controllerextensions.EditFlow
1007
- * @param {object} oContext Context of the document
1008
- * @returns {Promise} Promise resolves once the changes have been saved
1009
- * @alias sap.fe.core.controllerextensions.EditFlow#applyDocument
1010
- * @public
1011
- * @since 1.90.0
1012
- */
1013
- applyDocument: function(oContext) {
1014
- var that = this,
1015
- oLockObject = this._getGlobalUIModel();
1016
- BusyLocker.lock(oLockObject);
1017
- return (
1018
- this._submitOpenChanges(oContext)
1019
- // check if there are any validation/parse errors
1020
- .then(this._checkForValidationErrors.bind(this, oContext))
1021
- .then(function() {
1022
- that._getMessageHandler().showMessageDialog();
1023
- that._getRoutingListener().navigateBackFromContext(oContext);
1024
- return true;
1025
- })
1026
- .finally(function() {
1027
- if (BusyLocker.isLocked(oLockObject)) {
1028
- BusyLocker.unlock(oLockObject);
1029
- }
1030
- })
1031
- );
1032
- },
1033
-
1034
- // Internal only params ---
1035
- // @param {boolean} [mParameters.bStaticAction] Boolean value for static action, undefined for other actions
1036
- // @param {boolean} [mParameters.isNavigable] Boolean value indicating whether navigation is required after the action has been executed
1037
- // Currently the parameter isNavigable is used internally and should be changed to requiresNavigation as it is a more apt name for this param
1038
-
1039
- /**
1040
- * Invokes an action (bound or unbound) and tracks the changes so that other pages can be refreshed and show the updated data upon navigation.
1041
- *
1042
- * @memberof sap.fe.core.controllerextensions.EditFlow
1043
- * @param {string} sActionName The name of the action to be called
1044
- * @param {map} [mParameters] Contains the following attributes:
1045
- * @param {sap.ui.model.odata.v4.Context} [mParameters.contexts] For a bound action, a context or an array with contexts for which the action is to be called must be provided
1046
- * @param {sap.ui.model.odata.v4.ODataModel} [mParameters.model] For an unbound action, an instance of an OData V4 model must be provided
1047
- * @param {boolean} [mParameters.requiresNavigation] Boolean value indicating whether navigation is required after the action has been executed. Navigation takes place to the context returned by the action
1048
- * @param {string} [mParameters.label] A human-readable label for the action. This is needed in case the action has a parameter and a parameter dialog is shown to the user. The label will be used for the title of the dialog and for the confirmation button
1049
- * @param {string} [mParameters.invocationGrouping] Mode how actions are to be called: 'ChangeSet' to put all action calls into one changeset, 'Isolated' to put them into separate changesets
1050
- * @returns {Promise}
1051
- * @alias sap.fe.core.controllerextensions.EditFlow#invokeAction
1052
- * @public
1053
- * @since 1.90.0
1054
- * @final
1055
- **/
1056
- invokeAction: function(sActionName, mParameters) {
1057
- var that = this,
1058
- oControl,
1059
- transactionHelper = this._getTransactionHelper(),
1060
- oCurrentControl,
1061
- oBindingContext,
1062
- aParts,
1063
- sOverloadEntityType,
1064
- oCurrentActionCallBacks,
1065
- oView = this.getView();
1066
-
1067
- mParameters = mParameters || {};
1068
-
1069
- // Due to a mistake the invokeAction in the extensionAPI had a different API than this one.
1070
- // The one from the extensionAPI doesn't exist anymore as we expose the full edit flow now but
1071
- // due to compatibility reasons we still need to support the old signature
1072
- if (
1073
- (mParameters.isA && mParameters.isA("sap.ui.model.odata.v4.Context")) ||
1074
- Array.isArray(mParameters) ||
1075
- arguments.length === 3
1076
- ) {
1077
- var contexts = mParameters;
1078
- mParameters = arguments[2] || {};
1079
- if (contexts) {
1080
- mParameters.contexts = contexts;
1081
- } else {
1082
- mParameters.model = this.getView().getModel();
1083
- }
1084
- }
1085
-
1086
- mParameters.isNavigable = mParameters.requiresNavigation || mParameters.isNavigable;
1087
-
1088
- if (!mParameters.parentControl) {
1089
- mParameters.parentControl = this.getView();
1090
- }
1091
-
1092
- if (mParameters.controlId) {
1093
- oControl = this.getView().byId(mParameters.controlId);
1094
- if (oControl) {
1095
- // TODO: currently this selected contexts update is done within the operation, should be moved out
1096
- mParameters.internalModelContext = oControl.getBindingContext("internal");
1097
- }
1098
- } else {
1099
- mParameters.internalModelContext = oView.getBindingContext("internal");
1100
- }
1101
-
1102
- if (sActionName && sActionName.indexOf("(") > -1) {
1103
- // get entity type of action overload and remove it from the action path
1104
- // Example sActionName = "<ActionName>(Collection(<OverloadEntityType>))"
1105
- // sActionName = aParts[0] --> <ActionName>
1106
- // sOverloadEntityType = aParts[2] --> <OverloadEntityType>
1107
- aParts = sActionName.split("(");
1108
- sActionName = aParts[0];
1109
- sOverloadEntityType = aParts[aParts.length - 1].replaceAll(")", "");
1110
- }
1111
-
1112
- if (mParameters.bStaticAction) {
1113
- if (oControl.isTableBound()) {
1114
- mParameters.contexts = oControl.getRowBinding().getHeaderContext();
1115
- } else {
1116
- var sBindingPath = oControl.data("rowsBindingInfo").path,
1117
- oListBinding = new ODataListBinding(that.getView().getModel(), sBindingPath);
1118
- mParameters.contexts = oListBinding.getHeaderContext();
1119
- }
1120
-
1121
- if (sOverloadEntityType) {
1122
- var sTableContextEntityType = mParameters.contexts
1123
- .getModel()
1124
- .getMetaModel()
1125
- .getMetaContext(mParameters.contexts.getPath())
1126
- .getObject("$Type");
1127
- if (sOverloadEntityType !== sTableContextEntityType) {
1128
- // search for context in control tree hierarchy
1129
- oCurrentControl = oControl;
1130
- while (oCurrentControl) {
1131
- oBindingContext = oCurrentControl.getBindingContext();
1132
- if (
1133
- oBindingContext &&
1134
- oBindingContext
1135
- .getModel()
1136
- .getMetaModel()
1137
- .getMetaContext(oBindingContext.getPath())
1138
- .getObject("$Type") === sOverloadEntityType
1139
- ) {
1140
- mParameters.contexts = oBindingContext;
1141
- break;
1142
- } else {
1143
- // check parent
1144
- oCurrentControl = oCurrentControl.getParent();
1145
- }
1146
- }
1147
- if (!mParameters.contexts) {
1148
- return Promise.reject("Context not found for entity type " + sOverloadEntityType);
1149
- }
1150
- }
1151
- }
1152
-
1153
- if (mParameters.enableAutoScroll) {
1154
- oCurrentActionCallBacks = this._createActionPromise(sActionName, oControl.sId);
1155
- }
1156
- }
1157
-
1158
- if (mParameters.isNavigable) {
1159
- mParameters.bGetBoundContext = false;
1160
- } else {
1161
- mParameters.bGetBoundContext = true;
1162
- }
1163
- // Need to know that the action is called from ObjectPage for changeSet Isolated workaround
1164
- mParameters.bObjectPage = oView.getViewData().converterType === "ObjectPage";
1165
- return this._syncTask()
1166
- .then(
1167
- transactionHelper.callAction.bind(
1168
- transactionHelper,
1169
- sActionName,
1170
- mParameters,
1171
- that.getView(),
1172
- that._getMessageHandler()
1173
- )
1174
- )
1175
- .then(function(oResponse) {
1176
- // if the returned context for the bound action is different than the context on which action was called,
1177
- // refresh the corresponding list binding
1178
- if (mParameters.contexts) {
1179
- return that
1180
- ._refreshListIfRequired(that._getActionResponseDataAndKeys(sActionName, oResponse), mParameters.contexts[0])
1181
- .then(function() {
1182
- return oResponse;
1183
- });
1184
- }
1185
- })
1186
- .then(function(oResponse) {
1187
- if (oCurrentActionCallBacks) {
1188
- oCurrentActionCallBacks.fResolver(oResponse);
1189
- }
1190
- /*
1191
- We set the (upper) pages to dirty after an execution of an action
1192
- TODO: get rid of this workaround
1193
- This workaround is only needed as long as the model does not support the synchronization.
1194
- Once this is supported we don't need to set the pages to dirty anymore as the context itself
1195
- is already refreshed (it's just not reflected in the object page)
1196
- we explicitly don't call this method from the list report but only call it from the object page
1197
- as if it is called in the list report it's not needed - as we anyway will remove this logic
1198
- we can live with this
1199
- we need a context to set the upper pages to dirty - if there are more than one we use the
1200
- first one as they are anyway siblings
1201
- */
1202
- if (mParameters.contexts) {
1203
- EditState.setEditStateDirty();
1204
- that._getInternalModel().setProperty("/sCustomAction", sActionName);
1205
- }
1206
- if (mParameters.isNavigable) {
1207
- var vContext = oResponse;
1208
- if (Array.isArray(vContext) && vContext.length === 1) {
1209
- vContext = vContext[0];
1210
- }
1211
- if (vContext && !Array.isArray(vContext)) {
1212
- var oMetaModel = oView.getModel().getMetaModel();
1213
- var sContextMetaPath = oMetaModel.getMetaPath(vContext.getPath());
1214
- var oActionContext = Array.isArray(mParameters.contexts) ? mParameters.contexts[0] : mParameters.contexts;
1215
- var sActionContextMetaPath = oActionContext && oMetaModel.getMetaPath(oActionContext.getPath());
1216
- if (sContextMetaPath != undefined && sContextMetaPath === sActionContextMetaPath) {
1217
- if (oActionContext.getPath() !== vContext.getPath()) {
1218
- that._getRoutingListener().navigateForwardToContext(vContext, {
1219
- noHistoryEntry: false
1220
- });
1221
- } else {
1222
- Log.info("Navigation to the same context is not allowed");
1223
- }
1224
- }
1225
- }
1226
- }
1227
- })
1228
- .catch(function(err) {
1229
- if (oCurrentActionCallBacks) {
1230
- oCurrentActionCallBacks.fRejector();
1231
- }
1232
- if (err == Constants.CancelActionDialog) {
1233
- return Promise.reject("Dialog cancelled.");
1234
- } else {
1235
- return Promise.reject("Error in EditFlow.invokeAction:" + err);
1236
- }
1237
- });
1238
- },
1239
-
1240
- /**
1241
- * Secured execution of the given function. Ensures that the function is only executed when certain conditions are fulfilled.
1242
- *
1243
- * @memberof sap.fe.core.controllerextensions.EditFlow
1244
- * @param {Function} fnFunction The function to be executed. Should return a promise that is settled after completion of the execution. If nothing is returned, immediate completion is assumed.
1245
- * @param {map} [mParameters] Definitions of the preconditions to be checked before execution
1246
- * @param {object} [mParameters.busy] Defines the busy indicator
1247
- * @param {boolean} [mParameters.busy.set=true] Triggers a busy indicator when the function is executed.
1248
- * @param {boolean} [mParameters.busy.check=true] Executes function only if application isn't busy.
1249
- * @param {boolean} [mParameters.updatesDocument] This operation updates the current document without using the bound model and context. As a result, the draft status is updated if a draft document exists, and the user has to confirm the cancellation of the editing process.
1250
- * @returns {Promise} A promise that is rejected if the execution is prohibited and resolved by the promise returned by the fnFunction.
1251
- * @alias sap.fe.core.controllerextensions.EditFlow#securedExecution
1252
- * @public
1253
- * @experimental As of version 1.90.0
1254
- * @since 1.90.0
1255
- */
1256
- securedExecution: function(fnFunction, mParameters) {
1257
- var bBusySet = mParameters && mParameters.busy && mParameters.busy.set !== undefined ? mParameters.busy.set : true,
1258
- bBusyCheck = mParameters && mParameters.busy && mParameters.busy.check !== undefined ? mParameters.busy.check : true,
1259
- bUpdatesDocument = (mParameters && mParameters.updatesDocument) || false,
1260
- oLockObject = this._getGlobalUIModel(),
1261
- oContext = this.base.getView().getBindingContext(),
1262
- bIsDraft = oContext && this._getProgrammingModel(oContext) === ProgrammingModel.Draft,
1263
- that = this;
1264
-
1265
- if (bBusyCheck && BusyLocker.isLocked(oLockObject)) {
1266
- return Promise.reject("Application already busy therefore execution rejected");
1267
- }
1268
-
1269
- // we have to set busy and draft indicator immediately also the function might be executed later in queue
1270
- if (bBusySet) {
1271
- BusyLocker.lock(oLockObject);
1272
- }
1273
- if (bUpdatesDocument && bIsDraft) {
1274
- this._setDraftStatus(DraftStatus.Saving);
1275
- }
1276
-
1277
- this._getMessageHandler().removeTransitionMessages();
1278
-
1279
- return this._syncTask(fnFunction)
1280
- .then(function() {
1281
- if (bUpdatesDocument) {
1282
- that._getTransactionHelper().handleDocumentModifications();
1283
- EditState.setEditStateDirty();
1284
- if (bIsDraft) {
1285
- that._setDraftStatus(DraftStatus.Saved);
1286
- }
1287
- }
1288
- })
1289
- .catch(function(oError) {
1290
- if (bUpdatesDocument && bIsDraft) {
1291
- that._setDraftStatus(DraftStatus.Clear);
1292
- }
1293
- return Promise.reject(oError);
1294
- })
1295
- .finally(function() {
1296
- if (bBusySet) {
1297
- BusyLocker.unlock(oLockObject);
1298
- }
1299
- return that._getMessageHandler().showMessageDialog();
1300
- });
1301
- },
1302
-
1303
- /**
1304
- * Handles the patchSent event: register document modification.
1305
- *
1306
- * @param oEvent
1307
- */
1308
- handlePatchSent: function(oEvent) {
1309
- var that = this;
1310
- this.mPatchPromises = this.mPatchPromises ? this.mPatchPromises : {};
1311
- // do this for every unique object (eg: every table) so that each associated promise is fulfilled at the end
1312
- var oPatchPromise = new Promise(function(resolve, reject) {
1313
- that.mPatchPromises[oEvent.getSource()] = {
1314
- resolvePatchPromise: resolve,
1315
- rejectPatchPromise: reject
1316
- };
1317
- });
1318
- this.updateDocument(oEvent.getSource(), oPatchPromise);
1319
- },
1320
-
1321
- /**
1322
- * Handles the patchCompleted event: resolves or rejects document modification.
1323
- *
1324
- * @param oEvent
1325
- */
1326
- handlePatchCompleted: function(oEvent) {
1327
- var bSuccess = oEvent.getParameter("success");
1328
- if (bSuccess) {
1329
- this.mPatchPromises[oEvent.getSource()].resolvePatchPromise();
1330
- } else {
1331
- this.mPatchPromises[oEvent.getSource()].rejectPatchPromise();
1332
- }
1333
- delete this.mPatchPromises[oEvent.getSource()];
1334
- },
1335
-
1336
- //////////////////////////////////////
1337
- // Private methods
1338
- //////////////////////////////////////
1339
-
1340
- /*
1341
- TO BE CHECKED / DISCUSSED
1342
- _createMultipleDocuments and deleteMultiDocument - couldn't we combine them with create and delete document?
1343
- _createActionPromise and deleteCurrentActionPromise -> next step
1344
-
1345
- */
1346
-
1347
- _setEditMode: function(sEditMode, bCreationMode) {
1348
- this.base
1349
- .getView()
1350
- .getController()
1351
- ._editFlow.setEditMode(sEditMode, bCreationMode);
1352
- },
1353
-
1354
- _setDraftStatus: function(sDraftState) {
1355
- this.base
1356
- .getView()
1357
- .getController()
1358
- ._editFlow.setDraftStatus(sDraftState);
1359
- },
1360
-
1361
- _getRoutingListener: function() {
1362
- return this.base
1363
- .getView()
1364
- .getController()
1365
- ._editFlow.getRoutingListener();
1366
- },
1367
-
1368
- _getGlobalUIModel: function() {
1369
- return this.base
1370
- .getView()
1371
- .getController()
1372
- ._editFlow.getGlobalUIModel();
1373
- },
1374
-
1375
- _syncTask: function(vTask) {
1376
- return this.base
1377
- .getView()
1378
- .getController()
1379
- ._editFlow.syncTask(vTask);
1380
- },
1381
-
1382
- _getProgrammingModel: function(oContext) {
1383
- return this.base
1384
- .getView()
1385
- .getController()
1386
- ._editFlow.getProgrammingModel(oContext);
1387
- },
1388
-
1389
- _deleteDocumentTransaction: function(oContext, mParameters) {
1390
- return this.base
1391
- .getView()
1392
- .getController()
1393
- ._editFlow.deleteDocumentTransaction(oContext, mParameters);
1394
- },
1395
-
1396
- _handleCreateEvents: function(oBinding) {
1397
- this.base
1398
- .getView()
1399
- .getController()
1400
- ._editFlow.handleCreateEvents(oBinding);
1401
- },
1402
-
1403
- _getTransactionHelper: function() {
1404
- return this.base
1405
- .getView()
1406
- .getController()
1407
- ._editFlow.getTransactionHelper();
1408
- },
1409
-
1410
- _getInternalModel: function() {
1411
- return this.base
1412
- .getView()
1413
- .getController()
1414
- ._editFlow.getInternalModel();
1415
- },
1416
-
1417
- /**
1418
- * Creates a new promise to wait for an action to be executed
1419
- *
1420
- * @function
1421
- * @name _createActionPromise
1422
- * @memberof sap.fe.core.controllerextensions.EditFlow
1423
- *
1424
- * @returns {Function} The resolver function which can be used to externally resolve the promise
1425
- */
1426
-
1427
- _createActionPromise: function(sActionName, sControlId) {
1428
- return this.base
1429
- .getView()
1430
- .getController()
1431
- ._editFlow.createActionPromise(sActionName, sControlId);
1432
- },
1433
-
1434
- _getCurrentActionPromise: function() {
1435
- return this.base
1436
- .getView()
1437
- .getController()
1438
- ._editFlow.getCurrentActionPromise();
1439
- },
1440
-
1441
- _deleteCurrentActionPromise: function() {
1442
- return this.base
1443
- .getView()
1444
- .getController()
1445
- ._editFlow.deleteCurrentActionPromise();
1446
- },
1447
-
1448
- _getMessageHandler: function() {
1449
- return this.base
1450
- .getView()
1451
- .getController()
1452
- ._editFlow.getMessageHandler();
1453
- },
1454
-
1455
- /**
1456
- * @function
1457
- * @name _getActionResponseDataAndKeys
1458
- * @memberof sap.fe.core.controllerextensions.EditFlow
1459
- * @param {string} sActionName The name of the action that is executed
1460
- * @param {object} oResponse The bound action's response data or response context
1461
- * @returns {object} Object with data and names of the key fields of the response
1462
- */
1463
- _getActionResponseDataAndKeys: function(sActionName, oResponse) {
1464
- return this.base
1465
- .getView()
1466
- .getController()
1467
- ._editFlow.getActionResponseDataAndKeys(sActionName, oResponse);
1468
- },
1469
-
1470
- _submitOpenChanges: function(oContext) {
1471
- var oModel = oContext.getModel(),
1472
- oLockObject = this._getGlobalUIModel();
1473
- //Currently we are using only 1 updateGroupId, hence submitting the batch directly here
1474
- return oModel
1475
- .submitBatch("$auto")
1476
- .then(function() {
1477
- if (oModel.hasPendingChanges("$auto")) {
1478
- // the submit was not successful
1479
- return Promise.reject("submit of open changes failed");
1480
- }
1481
- })
1482
- .finally(function() {
1483
- if (BusyLocker.isLocked(oLockObject)) {
1484
- BusyLocker.unlock(oLockObject);
1485
- }
1486
- });
1487
- },
1488
-
1489
- _handleStickyOn: function(oContext) {
1490
- return this.base
1491
- .getView()
1492
- .getController()
1493
- ._editFlow.handleStickyOn(oContext);
1494
- },
1495
-
1496
- _handleStickyOff: function() {
1497
- return this.base
1498
- .getView()
1499
- .getController()
1500
- ._editFlow.handleStickyOff();
1501
- },
1502
-
1503
- _onBackNavigationInSession: function() {
1504
- return this.base
1505
- .getView()
1506
- .getController()
1507
- ._editFlow.onBackNavigationInSession();
1508
- },
1509
-
1510
- _discardStickySession: function(oContext) {
1511
- return this.base
1512
- .getView()
1513
- .getController()
1514
- ._editFlow.discardStickySession(oContext);
1515
- },
1516
-
1517
- _handleNewContext: function(oContext, bEditable, bRecreateContext, bDraftNavigation, bForceFocus) {
1518
- EditState.setEditStateDirty();
1519
-
1520
- return this._getRoutingListener().navigateToContext(oContext, {
1521
- checkNoHashChange: true,
1522
- editable: bEditable,
1523
- bPersistOPScroll: true,
1524
- bRecreateContext: bRecreateContext,
1525
- bDraftNavigation: bDraftNavigation,
1526
- showPlaceholder: false,
1527
- bForceFocus: bForceFocus
1528
- });
1529
- },
1530
-
1531
- /**
1532
- * Checks if there are validation (parse) errors for controls bound to a given context
1533
- *
1534
- * @function
1535
- * @name _checkForValidationErrors
1536
- * @memberof sap.fe.core.controllerextensions.EditFlow
1537
- * @param {sap.ui.model.odata.v4.Context} Context that should be checked
1538
- * @returns {Promise} Promise resolves if there are no validation errors, and rejects if there are validation errors
1539
- */
1540
-
1541
- _checkForValidationErrors: function(oContext) {
1542
- var that = this;
1543
- return this._syncTask().then(function() {
1544
- var sViewId = that.base.getView().getId();
1545
- var aMessages = sap.ui
1546
- .getCore()
1547
- .getMessageManager()
1548
- .getMessageModel()
1549
- .getData(),
1550
- oControl,
1551
- oMessage;
1552
-
1553
- if (!aMessages.length) {
1554
- return Promise.resolve("No validation errors found");
1555
- }
1556
-
1557
- for (var i = 0; i < aMessages.length; i++) {
1558
- oMessage = aMessages[i];
1559
- if (oMessage.validation) {
1560
- oControl = sap.ui.getCore().byId(oMessage.getControlId());
1561
- while (oControl) {
1562
- if (oControl.getId() === sViewId) {
1563
- return Promise.reject("validation errors exist");
1564
- }
1565
- oControl = oControl.getParent();
1566
- }
1567
- }
1568
- }
1569
- });
1570
- },
1571
-
1572
- /**
1573
- * @function
1574
- * @name _refreshListIfRequired
1575
- * @memberof sap.fe.core.controllerextensions.EditFlow
1576
- * @param {object} oResponse The response of the bound action and the names of the key fields
1577
- * @param {sap.ui.model.odata.v4.Context} oContext The bound context on which the action was executed
1578
- * @returns {Promise} Always resolves to param oResponse
1579
- */
1580
- _refreshListIfRequired: function(oResponse, oContext) {
1581
- if (!oContext || !oResponse || !oResponse.oData) {
1582
- return Promise.resolve();
1583
- }
1584
- var oBinding = oContext.getBinding();
1585
- // refresh only lists
1586
- if (oBinding && oBinding.isA("sap.ui.model.odata.v4.ODataListBinding")) {
1587
- var that = this,
1588
- oContextData = oResponse.oData,
1589
- aKeys = oResponse.keys,
1590
- oCurrentData = oContext.getObject(),
1591
- bReturnedContextIsSame = true;
1592
- // ensure context is in the response
1593
- if (Object.keys(oContextData).length) {
1594
- // check if context in response is different than the bound context
1595
- bReturnedContextIsSame = aKeys.every(function(sKey) {
1596
- return oCurrentData[sKey] === oContextData[sKey];
1597
- });
1598
- if (!bReturnedContextIsSame) {
1599
- return new Promise(function(resolve, reject) {
1600
- if (oBinding.isRoot()) {
1601
- oBinding.attachEventOnce("dataReceived", function() {
1602
- resolve();
1603
- });
1604
- oBinding.refresh();
1605
- } else {
1606
- var oAppComponent = CommonUtils.getAppComponent(that.getView());
1607
- oAppComponent
1608
- .getSideEffectsService()
1609
- .requestSideEffects([{ $NavigationPropertyPath: oBinding.getPath() }], oBinding.getContext())
1610
- .then(
1611
- function() {
1612
- resolve();
1613
- },
1614
- function() {
1615
- Log.error("Error while refreshing the table");
1616
- resolve();
1617
- }
1618
- )
1619
- .catch(function(e) {
1620
- Log.error("Error while refreshing the table", e);
1621
- });
1622
- }
1623
- });
1624
- }
1625
- }
1626
- }
1627
- // resolve with oResponse to not disturb the promise chain afterwards
1628
- return Promise.resolve();
1629
- },
1630
-
1631
- _fetchSemanticKeyValues: function(oContext) {
1632
- var oMetaModel = oContext.getModel().getMetaModel(),
1633
- sEntitySetName = oMetaModel.getMetaContext(oContext.getPath()).getObject("@sapui.name"),
1634
- aSemanticKeys = SemanticKeyHelper.getSemanticKeys(oMetaModel, sEntitySetName);
1635
-
1636
- if (aSemanticKeys && aSemanticKeys.length) {
1637
- var aRequestPromises = aSemanticKeys.map(function(oKey) {
1638
- return oContext.requestObject(oKey.$PropertyPath);
1639
- });
1640
-
1641
- return Promise.all(aRequestPromises);
1642
- } else {
1643
- return Promise.resolve();
1644
- }
1645
- },
1646
-
1647
- // Ugly Workaround to overcome mdc field issue, we remove the binding context before
1648
- // switching to display mode to avoid the field reads additional values for non existing
1649
- // drafts or sticky sessions in the backend
1650
- _removeContextsFromPages: function() {
1651
- var aPages = [];
1652
- var oAppComponent = CommonUtils.getAppComponent(this.getView());
1653
- if (oAppComponent._isFclEnabled()) {
1654
- aPages = aPages.concat(oAppComponent.getRootContainer().getMidColumnPages() || []);
1655
- aPages = aPages.concat(oAppComponent.getRootContainer().getEndColumnPages() || []);
1656
- } else {
1657
- aPages = oAppComponent.getRootContainer().getPages() || [];
1658
- }
1659
-
1660
- aPages.forEach(function(oPage) {
1661
- if (oPage.isA("sap.ui.core.ComponentContainer")) {
1662
- oPage = oPage.getComponentInstance(); // The binding context is set at the component level, not the component container
1663
- }
1664
-
1665
- if (oPage.getBindingContext()) {
1666
- oPage.setBindingContext(null);
1667
- }
1668
- });
1669
- }
1670
- });
1671
- }
1672
- );
5
+ sap.ui.define(["sap/ui/core/mvc/ControllerExtension", "sap/ui/core/mvc/OverrideExecution", "sap/base/Log", "sap/fe/core/CommonUtils", "sap/fe/core/BusyLocker", "sap/fe/core/library", "sap/ui/model/odata/v4/ODataListBinding", "sap/fe/core/helpers/SemanticKeyHelper", "sap/fe/core/helpers/EditState", "sap/ui/core/message/Message", "sap/ui/core/library", "sap/fe/core/helpers/ModelHelper", "sap/fe/core/helpers/ClassSupport", "sap/fe/core/controllerextensions/ControllerExtensionMetadata", "sap/fe/core/actions/collaboration/ActivitySync", "sap/fe/core/actions/collaboration/CollaborationCommon"], function (ControllerExtension, OverrideExecution, Log, CommonUtils, BusyLocker, FELibrary, ODataListBinding, SemanticKeyHelper, EditState, Message, coreLibrary, ModelHelper, ClassSupport, ControllerExtensionMetadata, ActivitySync, CollaborationCommon) {
6
+ "use strict";
7
+
8
+ var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _class, _class2;
9
+
10
+ var Activity = CollaborationCommon.Activity;
11
+ var send = ActivitySync.send;
12
+ var UI5Class = ClassSupport.UI5Class;
13
+ var Public = ClassSupport.Public;
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
+ var CreationMode = FELibrary.CreationMode,
24
+ ProgrammingModel = FELibrary.ProgrammingModel,
25
+ Constants = FELibrary.Constants,
26
+ DraftStatus = FELibrary.DraftStatus,
27
+ EditMode = FELibrary.EditMode,
28
+ MessageType = coreLibrary.MessageType;
29
+ /**
30
+ * A controller extension offering hooks into the edit flow of the application
31
+ *
32
+ * @hideconstructor
33
+ * @public
34
+ * @since 1.90.0
35
+ */
36
+
37
+ var EditFlow = (_dec = UI5Class("sap.fe.core.controllerextensions.EditFlow", ControllerExtensionMetadata), _dec2 = Extensible(OverrideExecution.After), _dec3 = Extensible(OverrideExecution.After), _dec4 = Extensible(OverrideExecution.After), _dec5 = Extensible(OverrideExecution.After), _dec6 = Extensible(OverrideExecution.After), _dec(_class = (_class2 = /*#__PURE__*/function (_ControllerExtension) {
38
+ _inherits(EditFlow, _ControllerExtension);
39
+
40
+ function EditFlow() {
41
+ return _ControllerExtension.apply(this, arguments) || this;
42
+ }
43
+
44
+ var _proto = EditFlow.prototype;
45
+
46
+ //////////////////////////////////////
47
+ // Public methods
48
+ //////////////////////////////////////
49
+
50
+ /**
51
+ * Creates a draft document for an existing active document.
52
+ *
53
+ * @memberof sap.fe.core.controllerextensions.EditFlow
54
+ * @param {object} oContext Context of the active document
55
+ * @returns {Promise} Promise resolves once the editable document is available
56
+ * @alias sap.fe.core.controllerextensions.EditFlow#editDocument
57
+ * @public
58
+ * @since 1.90.0
59
+ */
60
+ _proto.editDocument = function editDocument(oContext) {
61
+ var _this = this;
62
+
63
+ var bDraftNavigation = true;
64
+
65
+ var transactionHelper = this._getTransactionHelper();
66
+
67
+ return this.base.editFlow.onBeforeEdit({
68
+ context: oContext
69
+ }).then(transactionHelper.editDocument.bind(transactionHelper, oContext, this.getView(), this._getMessageHandler())).then(function (oNewDocumentContext) {
70
+ var sProgrammingModel = _this._getProgrammingModel(oContext);
71
+
72
+ if (sProgrammingModel === ProgrammingModel.Sticky) {
73
+ _this._getInternalModel().setProperty("/sessionOn", true);
74
+ }
75
+
76
+ if (oNewDocumentContext) {
77
+ _this._setEditMode(EditMode.Editable, false);
78
+
79
+ _this._getMessageHandler().showMessageDialog();
80
+
81
+ if (oNewDocumentContext !== oContext) {
82
+ return _this._handleNewContext(oNewDocumentContext, true, false, bDraftNavigation, true).then(function () {
83
+ if (sProgrammingModel === ProgrammingModel.Sticky) {
84
+ // The stickyOn handler must be set after the navigation has been done,
85
+ // as the URL may change in the case of FCL
86
+ _this._handleStickyOn(oNewDocumentContext);
87
+ }
88
+ });
89
+ }
90
+ }
91
+ }).catch(function (oError) {
92
+ Log.error("Error while editing the document", oError);
93
+ });
94
+ };
95
+
96
+ _proto.deleteMultipleDocuments = function deleteMultipleDocuments(aContexts, mParameters) {
97
+ if (mParameters) {
98
+ mParameters.beforeDeleteCallBack = this.base.editFlow.onBeforeDelete;
99
+ } else {
100
+ mParameters = {
101
+ beforeDeleteCallBack: this.base.editFlow.onBeforeDelete
102
+ };
103
+ }
104
+
105
+ return this.base.getView().getController()._editFlow.deleteMultipleDocuments(aContexts, mParameters);
106
+ }
107
+ /**
108
+ * Updates the draft status and displays the error messages if there are errors during an update.
109
+ *
110
+ * @memberof sap.fe.core.controllerextensions.EditFlow
111
+ * @param {object} oContext Context of the updated field
112
+ * @param {object} oPromise Promise to determine when the update operation is completed. The promise should be resolved when the update operation is completed, so the draft status can be updated.
113
+ * @returns {Promise} Promise resolves once draft status has been updated
114
+ * @alias sap.fe.core.controllerextensions.EditFlow#updateDocument
115
+ * @public
116
+ * @since 1.90.0
117
+ */
118
+ ;
119
+
120
+ _proto.updateDocument = function updateDocument(oContext, oPromise) {
121
+ var _this2 = this;
122
+
123
+ var transactionHelper = this._getTransactionHelper(),
124
+ oBindingContext = this.getView().getBindingContext(),
125
+ bIsDraft = this._getProgrammingModel(oContext) === ProgrammingModel.Draft;
126
+
127
+ this._getMessageHandler().removeTransitionMessages();
128
+
129
+ return this._syncTask(function () {
130
+ if (oBindingContext) {
131
+ transactionHelper.handleDocumentModifications();
132
+ EditState.setEditStateDirty();
133
+
134
+ if (bIsDraft) {
135
+ _this2._setDraftStatus(DraftStatus.Saving);
136
+ }
137
+ }
138
+
139
+ _this2._getMessageHandler().removeTransitionMessages();
140
+
141
+ return oPromise.then(function () {
142
+ if (bIsDraft && oBindingContext) {
143
+ var oMetaModel = oBindingContext.getModel().getMetaModel(),
144
+ sEntitySetName = oMetaModel.getMetaContext(oBindingContext.getPath()).getObject("@sapui.name"),
145
+ aSemanticKeys = SemanticKeyHelper.getSemanticKeys(oMetaModel, sEntitySetName);
146
+
147
+ if (aSemanticKeys && aSemanticKeys.length) {
148
+ var oCurrentSemanticMapping = _this2.base.getAppComponent().getRoutingService().getLastSemanticMapping(),
149
+ sCurrentSemanticPath = oCurrentSemanticMapping && oCurrentSemanticMapping.semanticPath,
150
+ sChangedPath = SemanticKeyHelper.getSemanticPath(oBindingContext, true);
151
+
152
+ if (sCurrentSemanticPath !== sChangedPath) {
153
+ return _this2._handleNewContext(oBindingContext, true, false, true).then(function () {
154
+ _this2._setDraftStatus(DraftStatus.Saved);
155
+ });
156
+ } else {
157
+ _this2._setDraftStatus(DraftStatus.Saved);
158
+ }
159
+ } else {
160
+ _this2._setDraftStatus(DraftStatus.Saved);
161
+ }
162
+ }
163
+ }, function () {
164
+ if (bIsDraft && oBindingContext) {
165
+ _this2._setDraftStatus(DraftStatus.Clear);
166
+ }
167
+ }).catch(function (oError) {
168
+ Log.error("Error while updating the document", oError);
169
+ }).finally(function () {
170
+ _this2._getMessageHandler().showMessages();
171
+ });
172
+ });
173
+ } // Internal only params ---
174
+ // * @param {string} mParameters.creationMode The creation mode using one of the following:
175
+ // * Sync - the creation is triggered and once the document is created, the navigation is done
176
+ // * Async - the creation and the navigation to the instance are done in parallel
177
+ // * Deferred - the creation is done on the target page
178
+ // * CreationRow - The creation is done inline async so the user is not blocked
179
+ // mParameters.creationRow Instance of the creation row - (TODO: get rid but use list bindings only)
180
+ // eslint-disable-next-line jsdoc/require-param
181
+
182
+ /**
183
+ * Creates a new document.
184
+ *
185
+ * @memberof sap.fe.core.controllerextensions.EditFlow
186
+ * @param {sap.ui.model.odata.v4.ODataListBinding|string} vListBinding ODataListBinding object or the binding path for a temporary list binding
187
+ * @param {map} mInParameters Contains the following attributes:
188
+ * @param {string} mInParameters.creationMode The creation mode using one of the following:
189
+ * NewPage - the created document is shown in a new page, depending on whether metadata 'Sync', 'Async' or 'Deferred' is used
190
+ * Inline - The creation is done inline (in a table)
191
+ * External - The creation is done in a different application specified via the parameter 'outbound'
192
+ * @param {string} mInParameters.outbound The navigation target where the document is created in case of creationMode 'External'
193
+ * @param {boolean} mInParameters.createAtEnd Specifies if the new entry should be created at the top or bottom of a table in case of creationMode 'Inline'
194
+ * @returns {Promise} Promise resolves once the object has been created
195
+ * @alias sap.fe.core.controllerextensions.EditFlow#createDocument
196
+ * @public
197
+ * @since 1.90.0
198
+ */
199
+ ;
200
+
201
+ _proto.createDocument = function createDocument(vListBinding, mInParameters) {
202
+ var _this3 = this;
203
+
204
+ var transactionHelper = this._getTransactionHelper(),
205
+ oLockObject = this._getGlobalUIModel();
206
+
207
+ var oTable;
208
+ var iCountTableItems = 0;
209
+ var mParameters = mInParameters;
210
+ var oResourceBundle = this.getView().getController().oResourceBundle;
211
+ var bShouldBusyLock = !mParameters || mParameters.creationMode !== CreationMode.Inline && mParameters.creationMode !== CreationMode.CreationRow && mParameters.creationMode !== CreationMode.External;
212
+ var oExecCustomValidation = Promise.resolve([]);
213
+ var oAppComponent = CommonUtils.getAppComponent(this.getView());
214
+ oAppComponent.getRouterProxy().removeIAppStateKey();
215
+
216
+ if (mParameters.creationMode === CreationMode.External) {
217
+ // Create by navigating to an external target
218
+ // TODO: Call appropriate function (currently using the same as for outbound chevron nav, and without any context - 3rd param)
219
+ return this._syncTask().then(function () {
220
+ var oController = _this3.getView().getController(),
221
+ sCreatePath = ModelHelper.getAbsoluteMetaPathForListBinding(_this3.getView(), vListBinding);
222
+
223
+ oController.handlers.onChevronPressNavigateOutBound(oController, mParameters.outbound, undefined, sCreatePath);
224
+ });
225
+ }
226
+
227
+ if (mParameters.creationMode === CreationMode.CreationRow && mParameters.creationRow) {
228
+ var oCreationRowObjects = mParameters.creationRow.getBindingContext().getObject();
229
+ delete oCreationRowObjects["@$ui5.context.isTransient"];
230
+ oTable = mParameters.creationRow.getParent();
231
+ oExecCustomValidation = transactionHelper.validateDocument(oTable.getBindingContext(), {
232
+ data: oCreationRowObjects,
233
+ customValidationFunction: oTable.getCreationRow().data("customValidationFunction")
234
+ }, this.base.getView()); // disableAddRowButtonForEmptyData is set to false in manifest converter (Table.ts) if customValidationFunction exists
235
+
236
+ if (oTable.getCreationRow().data("disableAddRowButtonForEmptyData") === "true") {
237
+ var oInternalModelContext = oTable.getBindingContext("internal");
238
+ oInternalModelContext.setProperty("creationRowFieldValidity", {});
239
+ }
240
+ }
241
+
242
+ if (mParameters.creationMode === CreationMode.Inline && mParameters.tableId) {
243
+ oTable = this.getView().byId(mParameters.tableId);
244
+ }
245
+ /**
246
+ * @param {sap.ui.model.odata.v4.ODataListBinding} oListBinding
247
+ * @param {object} oCreationPromise
248
+ */
249
+
250
+
251
+ var handleSideEffects = function (oListBinding, oCreationPromise) {
252
+ oCreationPromise.then(function (oNewContext) {
253
+ // transient contexts are reliably removed once oNewContext.created() is resolved
254
+ return oNewContext.created();
255
+ }).then(function () {
256
+ var oBindingContext = _this3.getView().getBindingContext(); // if there are transient contexts, we must avoid requesting side effects
257
+ // this is avoid a potential list refresh, there could be a side effect that refreshes the list binding
258
+ // if list binding is refreshed, transient contexts might be lost
259
+
260
+
261
+ if (!CommonUtils.hasTransientContext(oListBinding)) {
262
+ var _oAppComponent = CommonUtils.getAppComponent(_this3.getView());
263
+
264
+ _oAppComponent.getSideEffectsService().requestSideEffectsForNavigationProperty(oListBinding.getPath(), oBindingContext);
265
+ }
266
+ }).catch(function (oError) {
267
+ Log.error("Error while creating the document", oError);
268
+ });
269
+ };
270
+ /**
271
+ * @param {Array} aValidationMessages Error messages from custom validation function
272
+ */
273
+
274
+
275
+ var createCustomValidationMessages = function (aValidationMessages) {
276
+ var _oTable$getBindingCon;
277
+
278
+ var sCustomValidationFunction = oTable && oTable.getCreationRow().data("customValidationFunction");
279
+ var mCustomValidity = oTable && ((_oTable$getBindingCon = oTable.getBindingContext("internal")) === null || _oTable$getBindingCon === void 0 ? void 0 : _oTable$getBindingCon.getProperty("creationRowCustomValidity"));
280
+ var oMessageManager = sap.ui.getCore().getMessageManager();
281
+ var aCustomMessages = [];
282
+ var oFieldControl;
283
+ var sTarget; // Remove existing CustomValidation message
284
+
285
+ oMessageManager.getMessageModel().getData().forEach(function (oMessage) {
286
+ if (oMessage.code === sCustomValidationFunction) {
287
+ oMessageManager.removeMessages(oMessage);
288
+ }
289
+ });
290
+ aValidationMessages.forEach(function (oValidationMessage) {
291
+ // Handle Bound CustomValidation message
292
+ if (oValidationMessage.messageTarget) {
293
+ var _oFieldControl$getBin;
294
+
295
+ oFieldControl = sap.ui.getCore().getControl(mCustomValidity[oValidationMessage.messageTarget].fieldId);
296
+ sTarget = ((_oFieldControl$getBin = oFieldControl.getBindingContext()) === null || _oFieldControl$getBin === void 0 ? void 0 : _oFieldControl$getBin.getPath()) + "/" + oFieldControl.getBindingPath("value"); // Add validation message if still not exists
297
+
298
+ if (oMessageManager.getMessageModel().getData().filter(function (oMessage) {
299
+ return oMessage.target === sTarget;
300
+ }).length === 0) {
301
+ oMessageManager.addMessages(new Message({
302
+ message: oValidationMessage.messageText,
303
+ processor: _this3.getView().getModel(),
304
+ type: MessageType.Error,
305
+ code: sCustomValidationFunction,
306
+ technical: false,
307
+ persistent: false,
308
+ target: sTarget
309
+ }));
310
+ } // Add controlId in order to get the focus handling of the error popover runable
311
+
312
+
313
+ var aExistingValidationMessages = oMessageManager.getMessageModel().getData().filter(function (oMessage) {
314
+ return oMessage.target === sTarget;
315
+ });
316
+ aExistingValidationMessages[0].addControlId(mCustomValidity[oValidationMessage.messageTarget].fieldId); // Handle Unbound CustomValidation message
317
+ } else {
318
+ aCustomMessages.push({
319
+ code: sCustomValidationFunction,
320
+ text: oValidationMessage.messageText,
321
+ persistent: true,
322
+ type: MessageType.Error
323
+ });
324
+ }
325
+ });
326
+
327
+ if (aCustomMessages.length > 0) {
328
+ _this3._getMessageHandler().showMessageDialog({
329
+ customMessages: aCustomMessages
330
+ });
331
+ }
332
+ };
333
+
334
+ bShouldBusyLock && BusyLocker.lock(oLockObject);
335
+ return this._syncTask(oExecCustomValidation).then(function (aValidationMessages) {
336
+ if (aValidationMessages.length > 0) {
337
+ createCustomValidationMessages(aValidationMessages);
338
+ Log.error("Custom Validation failed"); // if custom validation fails, we leave the method immediately
339
+
340
+ return;
341
+ }
342
+
343
+ var sProgrammingModel;
344
+ var oListBinding;
345
+ mParameters = mParameters || {};
346
+
347
+ if (vListBinding && typeof vListBinding === "object") {
348
+ // we already get a list binding use this one
349
+ oListBinding = vListBinding;
350
+ } else if (typeof vListBinding === "string") {
351
+ oListBinding = new ODataListBinding(_this3.getView().getModel(), vListBinding);
352
+ mParameters.creationMode = CreationMode.Sync;
353
+ delete mParameters.createAtEnd;
354
+ } else {
355
+ throw new Error("Binding object or path expected");
356
+ }
357
+
358
+ var oModel = oListBinding.getModel();
359
+ iCountTableItems = oListBinding.iMaxLength || 0;
360
+ var sCreationMode = mParameters.creationMode;
361
+ return Promise.resolve(_this3._getProgrammingModel(oListBinding)).then(function (programmingModel) {
362
+ sProgrammingModel = programmingModel;
363
+
364
+ if (sCreationMode && sCreationMode !== CreationMode.NewPage) {
365
+ // use the passed creation mode
366
+ return sCreationMode;
367
+ } else {
368
+ var oMetaModel = oModel.getMetaModel(); // NewAction is not yet supported for NavigationProperty collection
369
+
370
+ if (!oListBinding.isRelative()) {
371
+ var sPath = oListBinding.getPath(),
372
+ // if NewAction with parameters is present, then creation is 'Deferred'
373
+ // in the absence of NewAction or NewAction with parameters, creation is async
374
+ sNewAction = sProgrammingModel === ProgrammingModel.Draft ? oMetaModel.getObject(sPath + "@com.sap.vocabularies.Common.v1.DraftRoot/NewAction") : oMetaModel.getObject(sPath + "@com.sap.vocabularies.Session.v1.StickySessionSupported/NewAction");
375
+
376
+ if (sNewAction) {
377
+ var aParameters = oMetaModel.getObject("/" + sNewAction + "/@$ui5.overload/0/$Parameter") || []; // binding parameter (eg: _it) is not considered
378
+
379
+ if (aParameters.length > 1) {
380
+ return CreationMode.Deferred;
381
+ }
382
+ }
383
+ }
384
+
385
+ var sMetaPath = oMetaModel.getMetaPath(oListBinding.getHeaderContext().getPath());
386
+ var aNonComputedVisibleKeyFields = CommonUtils.getNonComputedVisibleFields(oMetaModel, sMetaPath, _this3.getView());
387
+
388
+ if (aNonComputedVisibleKeyFields.length > 0) {
389
+ return CreationMode.Deferred;
390
+ }
391
+
392
+ return CreationMode.Async;
393
+ }
394
+ }).then(function (sCreationMode) {
395
+ var oCreation;
396
+ var mArgs;
397
+ var oCreationRow = mParameters.creationRow;
398
+ var oCreationRowContext;
399
+ var oValidationCheck = Promise.resolve();
400
+ var oPayload;
401
+ var sMetaPath;
402
+ var oMetaModel = oModel.getMetaModel();
403
+
404
+ var oRoutingListener = _this3._getRoutingListener();
405
+
406
+ if (sCreationMode !== CreationMode.Deferred) {
407
+ if (sCreationMode === CreationMode.CreationRow) {
408
+ oCreationRowContext = oCreationRow.getBindingContext();
409
+ sMetaPath = oMetaModel.getMetaPath(oCreationRowContext.getPath()); // prefill data from creation row
410
+
411
+ oPayload = oCreationRowContext.getObject();
412
+ mParameters.data = {};
413
+ Object.keys(oPayload).forEach(function (sPropertyPath) {
414
+ var oProperty = oMetaModel.getObject(sMetaPath + "/" + sPropertyPath); // ensure navigation properties are not part of the payload, deep create not supported
415
+
416
+ if (oProperty && oProperty.$kind === "NavigationProperty") {
417
+ return;
418
+ }
419
+
420
+ mParameters.data[sPropertyPath] = oPayload[sPropertyPath];
421
+ });
422
+ oValidationCheck = _this3._checkForValidationErrors();
423
+ }
424
+
425
+ if (sCreationMode === CreationMode.CreationRow || sCreationMode === CreationMode.Inline) {
426
+ mParameters.keepTransientContextOnFailed = false; // currently not fully supported
427
+ // busy handling shall be done locally only
428
+
429
+ mParameters.busyMode = "Local"; // take care on message handling, draft indicator (in case of draft)
430
+ // Attach the create sent and create completed event to the object page binding so that we can react
431
+
432
+ _this3._handleCreateEvents(oListBinding);
433
+ }
434
+
435
+ oCreation = oValidationCheck.then(function () {
436
+ if (!mParameters.parentControl) {
437
+ mParameters.parentControl = _this3.getView();
438
+ }
439
+
440
+ mParameters.beforeCreateCallBack = _this3.base.editFlow.onBeforeCreate;
441
+ return transactionHelper.createDocument(oListBinding, mParameters, oResourceBundle, _this3._getMessageHandler(), false, _this3.getView());
442
+ });
443
+ }
444
+
445
+ var oNavigation;
446
+
447
+ switch (sCreationMode) {
448
+ case CreationMode.Deferred:
449
+ oNavigation = oRoutingListener.navigateForwardToContext(oListBinding, {
450
+ bDeferredContext: true,
451
+ editable: true,
452
+ bForceFocus: true
453
+ });
454
+ break;
455
+
456
+ case CreationMode.Async:
457
+ oNavigation = oRoutingListener.navigateForwardToContext(oListBinding, {
458
+ asyncContext: oCreation,
459
+ editable: true,
460
+ bForceFocus: true
461
+ });
462
+ break;
463
+
464
+ case CreationMode.Sync:
465
+ mArgs = {
466
+ editable: true,
467
+ bForceFocus: true
468
+ };
469
+
470
+ if (sProgrammingModel == ProgrammingModel.Sticky || mParameters.createAction) {
471
+ mArgs.transient = true;
472
+ }
473
+
474
+ oNavigation = oCreation.then(function (oNewDocumentContext) {
475
+ if (!oNewDocumentContext) {
476
+ var _oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core");
477
+
478
+ return oRoutingListener.navigateToMessagePage(_oResourceBundle.getText("C_COMMON_SAPFE_DATA_RECEIVED_ERROR"), {
479
+ title: _oResourceBundle.getText("C_COMMON_SAPFE_ERROR"),
480
+ description: _oResourceBundle.getText("C_EDITFLOW_SAPFE_CREATION_FAILED_DESCRIPTION")
481
+ });
482
+ } else {
483
+ return oRoutingListener.navigateForwardToContext(oNewDocumentContext, mArgs);
484
+ }
485
+ });
486
+ break;
487
+
488
+ case CreationMode.Inline:
489
+ handleSideEffects(oListBinding, oCreation);
490
+
491
+ _this3._syncTask(oCreation);
492
+
493
+ break;
494
+
495
+ case CreationMode.CreationRow:
496
+ // the creation row shall be cleared once the validation check was successful and
497
+ // therefore the POST can be sent async to the backend
498
+ oNavigation = oValidationCheck.then(function () {
499
+ var oCreationRowListBinding = oCreationRowContext.getBinding();
500
+
501
+ if (!mParameters.bSkipSideEffects) {
502
+ handleSideEffects(oListBinding, oCreation);
503
+ }
504
+
505
+ var oNewTransientContext = oCreationRowListBinding.create();
506
+ oCreationRow.setBindingContext(oNewTransientContext); // this is needed to avoid console errors TO be checked with model colleagues
507
+
508
+ oNewTransientContext.created().catch(function () {
509
+ Log.trace("transient fast creation context deleted");
510
+ });
511
+ return oCreationRowContext.delete("$direct");
512
+ }).catch(function (oError) {
513
+ // Reset busy indicator after a validation error
514
+ if (BusyLocker.isLocked(_this3.getView().getModel("ui"))) {
515
+ BusyLocker.unlock(_this3.getView().getModel("ui"));
516
+ }
517
+
518
+ Log.error("CreationRow navigation error: ", oError);
519
+ });
520
+ break;
521
+
522
+ default:
523
+ oNavigation = Promise.reject("Unhandled creationMode " + sCreationMode);
524
+ break;
525
+ }
526
+
527
+ if (sProgrammingModel === ProgrammingModel.Sticky) {
528
+ _this3._getInternalModel().setProperty("/sessionOn", true);
529
+ }
530
+
531
+ var bIsNewPageCreation = mParameters.creationMode !== CreationMode.CreationRow && mParameters.creationMode !== CreationMode.Inline;
532
+
533
+ if (oCreation) {
534
+ return Promise.all([oCreation, oNavigation]).then(function (aParams) {
535
+ if (bIsNewPageCreation) {
536
+ _this3._setEditMode(EditMode.Editable, bIsNewPageCreation);
537
+ } else {
538
+ _this3._setEditMode(EditMode.Editable);
539
+ }
540
+
541
+ var oNewDocumentContext = aParams[0];
542
+
543
+ if (oNewDocumentContext) {
544
+ EditState.setEditStateDirty();
545
+ send(_this3.getView(), Activity.Create, oNewDocumentContext);
546
+
547
+ if (sProgrammingModel === ProgrammingModel.Sticky) {
548
+ _this3._handleStickyOn(oNewDocumentContext);
549
+ }
550
+ }
551
+ }).catch(function (oError) {
552
+ if (oError && (oError.navigateBackFromTransientState || oError == Constants.CancelActionDialog)) {
553
+ oRoutingListener.navigateBackFromTransientState();
554
+ }
555
+
556
+ return Promise.reject(oError);
557
+ });
558
+ }
559
+ });
560
+ }).finally(function () {
561
+ if (oTable && oTable.isA("sap.ui.mdc.Table")) {
562
+ var fnFocusOrScroll = mParameters.creationMode === CreationMode.Inline ? oTable.focusRow.bind(oTable) : oTable.scrollToIndex.bind(oTable);
563
+ oTable.getRowBinding().attachEventOnce("change", function () {
564
+ switch (mParameters.createAtEnd) {
565
+ case true:
566
+ if (oTable.data("tableType") === "ResponsiveTable" && oTable.getThreshold()) {
567
+ fnFocusOrScroll(oTable.getThreshold(), true);
568
+ } else {
569
+ fnFocusOrScroll(iCountTableItems, true);
570
+ }
571
+
572
+ break;
573
+
574
+ case false:
575
+ fnFocusOrScroll(0, true);
576
+ break;
577
+ }
578
+ });
579
+ }
580
+
581
+ bShouldBusyLock && BusyLocker.unlock(oLockObject);
582
+ });
583
+ }
584
+ /**
585
+ * This function can be used to intercept the 'Save' action. You can execute custom coding in this function.
586
+ * The framework waits for the returned promise to be resolved before continuing the 'Save' action.
587
+ * If you reject the promise, the 'Save' action is stopped and the user stays in edit mode.
588
+ *
589
+ * This function is meant to be individually overridden by consuming controllers, but not to be called directly.
590
+ * The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
591
+ * @param {object} mParameters Object containing the parameters passed to onBeforeSave
592
+ * @param {sap.ui.model.odata.v4.Context} mParameters.context Page context that is going to be saved.
593
+ * @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Save' action is triggered. If rejected, the 'Save' action is not triggered and the user stays in edit mode.
594
+ * @memberof sap.fe.core.controllerextensions.EditFlow
595
+ * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeSave
596
+ * @public
597
+ * @experimental As of version 1.90.0
598
+ * @since 1.90.0
599
+ */
600
+ ;
601
+
602
+ _proto. // eslint-disable-next-line @typescript-eslint/no-unused-vars
603
+ onBeforeSave = function onBeforeSave(mParameters) {
604
+ // to be overridden
605
+ return Promise.resolve();
606
+ }
607
+ /**
608
+ * This function can be used to intercept the 'Create' action. You can execute custom coding in this function.
609
+ * The framework waits for the returned promise to be resolved before continuing the 'Create' action.
610
+ * If you reject the promise, the 'Create' action is stopped.
611
+ *
612
+ * This function is meant to be individually overridden by consuming controllers, but not to be called directly.
613
+ * The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
614
+ * @param {map} mParameters Object containing the parameters passed to onBeforeCreate
615
+ * @param {string} mParameters.contextPath Path pointing to the context on which Create action is triggered
616
+ * @param {Array} mParameters.createParameters Array of values that are filled in the Action Parameter Dialog
617
+ * @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Create' action is triggered. If rejected, the 'Create' action is not triggered.
618
+ * @memberof sap.fe.core.controllerextensions.EditFlow
619
+ * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeCreate
620
+ * @public
621
+ * @experimental As of version 1.98.0
622
+ * @since 1.98.0
623
+ */
624
+ ;
625
+
626
+ _proto. // eslint-disable-next-line @typescript-eslint/no-unused-vars
627
+ onBeforeCreate = function onBeforeCreate(mParameters) {
628
+ // to be overridden
629
+ return Promise.resolve();
630
+ }
631
+ /**
632
+ * This function can be used to intercept the 'Edit' action. You can execute custom coding in this function.
633
+ * The framework waits for the returned promise to be resolved before continuing the 'Edit' action.
634
+ * If you reject the promise, the 'Edit' action is stopped and the user stays in display mode.
635
+ *
636
+ * This function is meant to be individually overridden by consuming controllers, but not to be called directly.
637
+ * The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
638
+ * @param {object} mParameters Object containing the parameters passed to onBeforeEdit
639
+ * @param {sap.ui.model.odata.v4.Context} mParameters.context Page context that is going to be edited.
640
+ * @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Edit' action is triggered. If rejected, the 'Edit' action is not triggered and the user stays in display mode.
641
+ * @memberof sap.fe.core.controllerextensions.EditFlow
642
+ * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeEdit
643
+ * @public
644
+ * @experimental As of version 1.98.0
645
+ * @since 1.98.0
646
+ */
647
+ ;
648
+
649
+ _proto. // eslint-disable-next-line @typescript-eslint/no-unused-vars
650
+ onBeforeEdit = function onBeforeEdit(mParameters) {
651
+ // to be overridden
652
+ return Promise.resolve();
653
+ }
654
+ /**
655
+ * This function can be used to intercept the 'Discard' action. You can execute custom coding in this function.
656
+ * The framework waits for the returned promise to be resolved before continuing the 'Discard' action.
657
+ * If you reject the promise, the 'Discard' action is stopped and the user stays in edit mode.
658
+ *
659
+ * This function is meant to be individually overridden by consuming controllers, but not to be called directly.
660
+ * The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
661
+ * @param {object} mParameters Object containing the parameters passed to onBeforeDiscard
662
+ * @param {sap.ui.model.odata.v4.Context} mParameters.context Page context that is going to be discarded.
663
+ * @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Discard' action is triggered. If rejected, the 'Discard' action is not triggered and the user stays in edit mode.
664
+ * @memberof sap.fe.core.controllerextensions.EditFlow
665
+ * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeDiscard
666
+ * @public
667
+ * @experimental As of version 1.98.0
668
+ * @since 1.98.0
669
+ */
670
+ ;
671
+
672
+ _proto. // eslint-disable-next-line @typescript-eslint/no-unused-vars
673
+ onBeforeDiscard = function onBeforeDiscard(mParameters) {
674
+ // to be overridden
675
+ return Promise.resolve();
676
+ }
677
+ /**
678
+ * This function can be used to intercept the 'Delete' action. You can execute custom coding in this function.
679
+ * The framework waits for the returned promise to be resolved before continuing the 'Delete' action.
680
+ * If you reject the promise, the 'Delete' action is stopped.
681
+ *
682
+ * This function is meant to be individually overridden by consuming controllers, but not to be called directly.
683
+ * The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
684
+ * @param {object} mParameters Object containing the parameters passed to onBeforeDelete
685
+ * @param {Array} mParameters.contexts An array of contexts that are going to be deleted
686
+ * @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Delete' action is triggered. If rejected, the 'Delete' action is not triggered.
687
+ * @memberof sap.fe.core.controllerextensions.EditFlow
688
+ * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeDelete
689
+ * @public
690
+ * @experimental As of version 1.98.0
691
+ * @since 1.98.0
692
+ */
693
+ ;
694
+
695
+ _proto. // eslint-disable-next-line @typescript-eslint/no-unused-vars
696
+ onBeforeDelete = function onBeforeDelete(mParameters) {
697
+ // to be overridden
698
+ return Promise.resolve();
699
+ } // Internal only params ---
700
+ // @param {boolean} mParameters.bExecuteSideEffectsOnError Indicates whether SideEffects need to be ignored when user clicks on Save during an Inline creation
701
+ // @param {object} mParameters.bindings List bindings of the tables in the view.
702
+ // Both of the above parameters are for the same purpose. User can enter some information in the creation row(s) but does not 'Add row', instead clicks Save.
703
+ // There can be more than one in the view.
704
+ // eslint-disable-next-line jsdoc/require-param
705
+
706
+ /**
707
+ * Saves a new document after checking it.
708
+ *
709
+ * @memberof sap.fe.core.controllerextensions.EditFlow
710
+ * @param {object} oContext Context of the editable document
711
+ * @returns {Promise} Promise resolves once save is complete
712
+ * @alias sap.fe.core.controllerextensions.EditFlow#saveDocument
713
+ * @public
714
+ * @since 1.90.0
715
+ */
716
+ ;
717
+
718
+ _proto.saveDocument = function saveDocument(oContext, mParameters) {
719
+ var _this4 = this;
720
+
721
+ mParameters = mParameters || {};
722
+ var bExecuteSideEffectsOnError = mParameters.bExecuteSideEffectsOnError || undefined;
723
+ var bDraftNavigation = true;
724
+
725
+ var transactionHelper = this._getTransactionHelper();
726
+
727
+ var oResourceBundle = this.getView().getController().oResourceBundle;
728
+ var aBindings = mParameters.bindings; // first of all wait until all key-match-requests are done
729
+
730
+ return this._syncTask() // submit any open changes if there any (although there are validation/parse errors)
731
+ .then(this._submitOpenChanges.bind(this, oContext)) // check if there are any validation/parse errors
732
+ .then(this._checkForValidationErrors.bind(this, oContext)).then(this.base.editFlow.onBeforeSave.bind(this, {
733
+ context: oContext
734
+ })) // and finally if all user changes are submitted and valid save the document
735
+ .then(transactionHelper.saveDocument.bind(transactionHelper, oContext, oResourceBundle, bExecuteSideEffectsOnError, aBindings, this._getMessageHandler())).then(function (oActiveDocumentContext) {
736
+ var sProgrammingModel = _this4._getProgrammingModel(oContext);
737
+
738
+ _this4._removeContextsFromPages();
739
+
740
+ if (sProgrammingModel === ProgrammingModel.Sticky) {
741
+ _this4._getInternalModel().setProperty("/sessionOn", false);
742
+
743
+ _this4._handleStickyOff();
744
+ }
745
+
746
+ send(_this4.getView(), Activity.Activate, oActiveDocumentContext);
747
+
748
+ _this4._setEditMode(EditMode.Display, false);
749
+
750
+ _this4._getMessageHandler().showMessageDialog();
751
+
752
+ if (oActiveDocumentContext !== oContext) {
753
+ _this4._handleNewContext(oActiveDocumentContext, false, false, bDraftNavigation, true);
754
+ }
755
+ }).catch(function (oError) {
756
+ Log.error("Error while saving the document", oError);
757
+ return Promise.reject(oError);
758
+ });
759
+ };
760
+
761
+ _proto.toggleDraftActive = function toggleDraftActive(oContext) {
762
+ var _this5 = this;
763
+
764
+ var oContextData = oContext.getObject();
765
+ var bEditable;
766
+ var bIsDraft = oContext && this._getProgrammingModel(oContext) === ProgrammingModel.Draft;
767
+ var oToggleContext = oContext.getModel().bindContext(oContext.getPath() + "/SiblingEntity").getBoundContext(); //toggle between draft and active document is only available for edit drafts and active documents with draft)
768
+
769
+ if (!bIsDraft || !(!oContextData.IsActiveEntity && oContextData.HasActiveEntity || oContextData.IsActiveEntity && oContextData.HasDraftEntity)) {
770
+ return;
771
+ }
772
+
773
+ if (!oContextData.IsActiveEntity && oContextData.HasActiveEntity) {
774
+ //start Point: edit draft
775
+ bEditable = false;
776
+ } else if (oContextData.IsActiveEntity && oContextData.HasDraftEntity) {
777
+ // start point active document
778
+ bEditable = true;
779
+ }
780
+
781
+ oToggleContext.requestCanonicalPath().then(function (sCanonicalPath) {
782
+ // We use the canonical path for the navigation instead of the semantic path, as the
783
+ // semantic key values may have changed between the draft and the active version (BCP 2170216142)
784
+ return oToggleContext.getModel().bindContext(sCanonicalPath).getBoundContext();
785
+ }).then(function (oToggleContext) {
786
+ _this5._setEditMode(bEditable ? EditMode.Editable : EditMode.Display, false); //switch to edit mode only if a draft is available
787
+
788
+
789
+ _this5._handleNewContext(oToggleContext, bEditable, true, true, true);
790
+ }).catch(function (err) {
791
+ return Promise.reject("Error in EditFlow.toggleDraftActive:" + err);
792
+ });
793
+ } // Internal only params ---
794
+ // @param {sap.m.Button} mParameters.cancelButton - Currently this is passed as cancelButton internally (replaced by mParameters.control in the JSDoc below). Currently it is also mandatory.
795
+ // Plan - This should not be mandatory. If not provided, we should have a default that can act as reference control for the discard popover OR we can show a dialog instead of a popover.
796
+
797
+ /**
798
+ * Discard the editable document.
799
+ *
800
+ * @memberof sap.fe.core.controllerextensions.EditFlow
801
+ * @param {object} oContext Context of the editable document
802
+ * @param {map} mParameters Can contain the following attributes:
803
+ * @param {object} mParameters.control This is the control used to open the discard popover
804
+ * @param {boolean} mParameters.skipDiscardPopover Optional, supresses the discard popover and allows custom handling
805
+ * @returns {Promise} Promise resolves once editable document has been discarded
806
+ * @alias sap.fe.core.controllerextensions.EditFlow#cancelDocument
807
+ * @public
808
+ * @since 1.90.0
809
+ */
810
+ ;
811
+
812
+ _proto.cancelDocument = function cancelDocument(oContext, mParameters) {
813
+ var _this6 = this;
814
+
815
+ var transactionHelper = this._getTransactionHelper(),
816
+ oResourceBundle = this.getView().getController().oResourceBundle;
817
+
818
+ var mInParameters = mParameters;
819
+ mInParameters.cancelButton = mParameters.control || mInParameters.cancelButton;
820
+ mInParameters.beforeCancelCallBack = this.base.editFlow.onBeforeDiscard;
821
+ return this._syncTask().then(transactionHelper.cancelDocument.bind(transactionHelper, oContext, mParameters, oResourceBundle, this._getMessageHandler())).then(function (oActiveDocumentContext) {
822
+ var bDraftNavigation = true,
823
+ sProgrammingModel = _this6._getProgrammingModel(oContext);
824
+
825
+ _this6._removeContextsFromPages();
826
+
827
+ if (sProgrammingModel === ProgrammingModel.Sticky) {
828
+ _this6._getInternalModel().setProperty("/sessionOn", false);
829
+
830
+ _this6._handleStickyOff();
831
+ }
832
+
833
+ send(_this6.getView(), Activity.Discard, oActiveDocumentContext);
834
+
835
+ _this6._setEditMode(EditMode.Display, false);
836
+
837
+ _this6._setDraftStatus(DraftStatus.Clear); //in case of a new document, the value of hasActiveEntity is returned. navigate back.
838
+
839
+
840
+ if (!oActiveDocumentContext) {
841
+ EditState.setEditStateDirty();
842
+ return mInParameters.skipBackNavigation ? undefined : _this6._getRoutingListener().navigateBackFromContext(oContext);
843
+ } else if (sProgrammingModel === ProgrammingModel.Draft) {
844
+ // We need to load the semantic keys of the active context, as we need them
845
+ // for the navigation
846
+ return _this6._fetchSemanticKeyValues(oActiveDocumentContext).then(function () {
847
+ // We force the recreation of the context, so that it's created and bound in the same microtask,
848
+ // so that all properties are loaded together by autoExpandSelect, so that when switching back to Edit mode
849
+ // $$inheritExpandSelect takes all loaded properties into account (BCP 2070462265)
850
+ if (mInParameters.skipBindingToView) {
851
+ return oActiveDocumentContext;
852
+ } else {
853
+ return _this6._handleNewContext(oActiveDocumentContext, false, true, bDraftNavigation, true);
854
+ }
855
+ });
856
+ } else {
857
+ //active context is returned in case of cancel of existing document
858
+ return _this6._handleNewContext(oActiveDocumentContext, false, false, bDraftNavigation, true);
859
+ }
860
+ }).catch(function (oError) {
861
+ Log.error("Error while discarding the document", oError);
862
+ });
863
+ } // Internal only params ---
864
+ // @param {string} mParameters.entitySetName Name of the EntitySet to which the object belongs
865
+
866
+ /**
867
+ * Deletes the document.
868
+ *
869
+ * @memberof sap.fe.core.controllerextensions.EditFlow
870
+ * @param {object} oContext Context of the document
871
+ * @param {object} mInParameters Can contain the following attributes:
872
+ * @param {string} mInParameters.title Title of the object being deleted
873
+ * @param {string} mInParameters.description Description of the object being deleted
874
+ * @returns {Promise} Promise resolves once document has been deleted
875
+ * @alias sap.fe.core.controllerextensions.EditFlow#deleteDocument
876
+ * @public
877
+ * @since 1.90.0
878
+ */
879
+ ;
880
+
881
+ _proto.deleteDocument = function deleteDocument(oContext, mInParameters) {
882
+ var _this7 = this;
883
+
884
+ var oAppComponent = CommonUtils.getAppComponent(this.getView());
885
+ var sPath = oContext.getPath();
886
+ var mParameters = mInParameters;
887
+
888
+ if (!mParameters) {
889
+ mParameters = {
890
+ bFindActiveContexts: false
891
+ };
892
+ } else {
893
+ mParameters.bFindActiveContexts = false;
894
+ }
895
+
896
+ mParameters.beforeDeleteCallBack = this.base.editFlow.onBeforeDelete;
897
+ return this._deleteDocumentTransaction(oContext, mParameters).then(function () {
898
+ // Single objet deletion is triggered from an OP header button (not from a list)
899
+ // --> Mark UI dirty and navigate back to dismiss the OP
900
+ EditState.setEditStateDirty();
901
+ send(_this7.getView(), Activity.Delete, sPath);
902
+
903
+ _this7._getRoutingListener().navigateBackFromContext(oContext); // After delete is successfull, we need to dettch the setBackNavigation Methods
904
+
905
+
906
+ if (oAppComponent) {
907
+ oAppComponent.getShellServices().setBackNavigation();
908
+ }
909
+ }).catch(function (oError) {
910
+ Log.error("Error while deleting the document", oError);
911
+ });
912
+ }
913
+ /**
914
+ * Submit the current set of changes and navigate back.
915
+ *
916
+ * @memberof sap.fe.core.controllerextensions.EditFlow
917
+ * @param {object} oContext Context of the document
918
+ * @returns {Promise} Promise resolves once the changes have been saved
919
+ * @alias sap.fe.core.controllerextensions.EditFlow#applyDocument
920
+ * @public
921
+ * @since 1.90.0
922
+ */
923
+ ;
924
+
925
+ _proto.applyDocument = function applyDocument(oContext) {
926
+ var _this8 = this;
927
+
928
+ var oLockObject = this._getGlobalUIModel();
929
+
930
+ BusyLocker.lock(oLockObject);
931
+ return this._submitOpenChanges(oContext) // check if there are any validation/parse errors
932
+ .then(this._checkForValidationErrors.bind(this, oContext)).then(function () {
933
+ _this8._getMessageHandler().showMessageDialog();
934
+
935
+ _this8._getRoutingListener().navigateBackFromContext(oContext);
936
+
937
+ return true;
938
+ }).finally(function () {
939
+ if (BusyLocker.isLocked(oLockObject)) {
940
+ BusyLocker.unlock(oLockObject);
941
+ }
942
+ });
943
+ } // Internal only params ---
944
+ // @param {boolean} [mParameters.bStaticAction] Boolean value for static action, undefined for other actions
945
+ // @param {boolean} [mParameters.isNavigable] Boolean value indicating whether navigation is required after the action has been executed
946
+ // Currently the parameter isNavigable is used internally and should be changed to requiresNavigation as it is a more apt name for this param
947
+
948
+ /**
949
+ * Invokes an action (bound or unbound) and tracks the changes so that other pages can be refreshed and show the updated data upon navigation.
950
+ *
951
+ * @memberof sap.fe.core.controllerextensions.EditFlow
952
+ * @param {string} sActionName The name of the action to be called
953
+ * @param {object} mInParameters Contains the following attributes:
954
+ * @param {sap.ui.model.odata.v4.Context} mInParameters.contexts For a bound action, a context or an array with contexts for which the action is to be called must be provided
955
+ * @param {sap.ui.model.odata.v4.ODataModel} mInParameters.model For an unbound action, an instance of an OData V4 model must be provided
956
+ * @param {boolean} mInParameters.requiresNavigation Boolean value indicating whether navigation is required after the action has been executed. Navigation takes place to the context returned by the action
957
+ * @param {string} mInParameters.label A human-readable label for the action. This is needed in case the action has a parameter and a parameter dialog is shown to the user. The label will be used for the title of the dialog and for the confirmation button
958
+ * @param {string} mInParameters.invocationGrouping Mode how actions are to be called: 'ChangeSet' to put all action calls into one changeset, 'Isolated' to put them into separate changesets
959
+ * @param {object} mExtraParams PRIVATE
960
+ * @returns {Promise}
961
+ * @alias sap.fe.core.controllerextensions.EditFlow#invokeAction
962
+ * @public
963
+ * @since 1.90.0
964
+ * @final
965
+ **/
966
+ ;
967
+
968
+ _proto.invokeAction = function invokeAction(sActionName, mInParameters, mExtraParams) {
969
+ var _this9 = this;
970
+
971
+ var oControl;
972
+
973
+ var transactionHelper = this._getTransactionHelper();
974
+
975
+ var oCurrentControl;
976
+ var oBindingContext;
977
+ var aParts;
978
+ var sOverloadEntityType;
979
+ var oCurrentActionCallBacks;
980
+ var oView = this.getView();
981
+ var mParameters = mInParameters || {}; // Due to a mistake the invokeAction in the extensionAPI had a different API than this one.
982
+ // The one from the extensionAPI doesn't exist anymore as we expose the full edit flow now but
983
+ // due to compatibility reasons we still need to support the old signature
984
+
985
+ if (mParameters.isA && mParameters.isA("sap.ui.model.odata.v4.Context") || Array.isArray(mParameters) || arguments.length === 3) {
986
+ var contexts = mParameters;
987
+ mParameters = mExtraParams || {};
988
+
989
+ if (contexts) {
990
+ mParameters.contexts = contexts;
991
+ } else {
992
+ mParameters.model = this.getView().getModel();
993
+ }
994
+ }
995
+
996
+ mParameters.isNavigable = mParameters.requiresNavigation || mParameters.isNavigable;
997
+
998
+ if (!mParameters.parentControl) {
999
+ mParameters.parentControl = this.getView();
1000
+ }
1001
+
1002
+ if (mParameters.controlId) {
1003
+ oControl = this.getView().byId(mParameters.controlId);
1004
+
1005
+ if (oControl) {
1006
+ // TODO: currently this selected contexts update is done within the operation, should be moved out
1007
+ mParameters.internalModelContext = oControl.getBindingContext("internal");
1008
+ }
1009
+ } else {
1010
+ mParameters.internalModelContext = oView.getBindingContext("internal");
1011
+ }
1012
+
1013
+ if (sActionName && sActionName.indexOf("(") > -1) {
1014
+ // get entity type of action overload and remove it from the action path
1015
+ // Example sActionName = "<ActionName>(Collection(<OverloadEntityType>))"
1016
+ // sActionName = aParts[0] --> <ActionName>
1017
+ // sOverloadEntityType = aParts[2] --> <OverloadEntityType>
1018
+ aParts = sActionName.split("(");
1019
+ sActionName = aParts[0];
1020
+ sOverloadEntityType = aParts[aParts.length - 1].replaceAll(")", "");
1021
+ }
1022
+
1023
+ if (mParameters.bStaticAction) {
1024
+ if (oControl.isTableBound()) {
1025
+ mParameters.contexts = oControl.getRowBinding().getHeaderContext();
1026
+ } else {
1027
+ var sBindingPath = oControl.data("rowsBindingInfo").path,
1028
+ oListBinding = new ODataListBinding(this.getView().getModel(), sBindingPath);
1029
+ mParameters.contexts = oListBinding.getHeaderContext();
1030
+ }
1031
+
1032
+ if (sOverloadEntityType) {
1033
+ var sTableContextEntityType = mParameters.contexts.getModel().getMetaModel().getMetaContext(mParameters.contexts.getPath()).getObject("$Type");
1034
+
1035
+ if (sOverloadEntityType !== sTableContextEntityType) {
1036
+ // search for context in control tree hierarchy
1037
+ oCurrentControl = oControl;
1038
+
1039
+ while (oCurrentControl) {
1040
+ oBindingContext = oCurrentControl.getBindingContext();
1041
+
1042
+ if (oBindingContext && oBindingContext.getModel().getMetaModel().getMetaContext(oBindingContext.getPath()).getObject("$Type") === sOverloadEntityType) {
1043
+ mParameters.contexts = oBindingContext;
1044
+ break;
1045
+ } else {
1046
+ // check parent
1047
+ oCurrentControl = oCurrentControl.getParent();
1048
+ }
1049
+ } // context was not found in UI hierarchy going straight upwards - try to find it in SubSections
1050
+
1051
+
1052
+ if (!oCurrentControl) {
1053
+ var oActionOverloadContext = this._getActionOverloadContextFromSubSections(oControl, sOverloadEntityType);
1054
+
1055
+ if (oActionOverloadContext !== undefined) {
1056
+ mParameters.contexts = oActionOverloadContext;
1057
+ }
1058
+ }
1059
+
1060
+ if (!mParameters.contexts) {
1061
+ return Promise.reject("Context not found for entity type " + sOverloadEntityType);
1062
+ }
1063
+ }
1064
+ }
1065
+
1066
+ if (mParameters.enableAutoScroll) {
1067
+ oCurrentActionCallBacks = this._createActionPromise(sActionName, oControl.sId);
1068
+ }
1069
+ }
1070
+
1071
+ if (mParameters.isNavigable) {
1072
+ mParameters.bGetBoundContext = false;
1073
+ } else {
1074
+ mParameters.bGetBoundContext = true;
1075
+ } // Need to know that the action is called from ObjectPage for changeSet Isolated workaround
1076
+
1077
+
1078
+ mParameters.bObjectPage = oView.getViewData().converterType === "ObjectPage";
1079
+ return this._syncTask().then(transactionHelper.callAction.bind(transactionHelper, sActionName, mParameters, this.getView(), this._getMessageHandler())).then(function (oResponse) {
1080
+ // if the returned context for the bound action is different than the context on which action was called,
1081
+ // refresh the corresponding list binding
1082
+ if (mParameters.contexts) {
1083
+ return _this9._refreshListIfRequired(_this9._getActionResponseDataAndKeys(sActionName, oResponse), mParameters.contexts[0]).then(function () {
1084
+ return oResponse;
1085
+ });
1086
+ }
1087
+ }).then(function (oResponse) {
1088
+ send(_this9.getView(), Activity.Action, mParameters.contexts);
1089
+
1090
+ if (oCurrentActionCallBacks) {
1091
+ oCurrentActionCallBacks.fResolver(oResponse);
1092
+ }
1093
+ /*
1094
+ We set the (upper) pages to dirty after an execution of an action
1095
+ TODO: get rid of this workaround
1096
+ This workaround is only needed as long as the model does not support the synchronization.
1097
+ Once this is supported we don't need to set the pages to dirty anymore as the context itself
1098
+ is already refreshed (it's just not reflected in the object page)
1099
+ we explicitly don't call this method from the list report but only call it from the object page
1100
+ as if it is called in the list report it's not needed - as we anyway will remove this logic
1101
+ we can live with this
1102
+ we need a context to set the upper pages to dirty - if there are more than one we use the
1103
+ first one as they are anyway siblings
1104
+ */
1105
+
1106
+
1107
+ if (mParameters.contexts) {
1108
+ EditState.setEditStateDirty();
1109
+
1110
+ _this9._getInternalModel().setProperty("/sCustomAction", sActionName);
1111
+ }
1112
+
1113
+ if (mParameters.isNavigable) {
1114
+ var vContext = oResponse;
1115
+
1116
+ if (Array.isArray(vContext) && vContext.length === 1) {
1117
+ vContext = vContext[0];
1118
+ }
1119
+
1120
+ if (vContext && !Array.isArray(vContext)) {
1121
+ var oMetaModel = oView.getModel().getMetaModel();
1122
+ var sContextMetaPath = oMetaModel.getMetaPath(vContext.getPath());
1123
+ var oActionContext = Array.isArray(mParameters.contexts) ? mParameters.contexts[0] : mParameters.contexts;
1124
+ var sActionContextMetaPath = oActionContext && oMetaModel.getMetaPath(oActionContext.getPath());
1125
+
1126
+ if (sContextMetaPath != undefined && sContextMetaPath === sActionContextMetaPath) {
1127
+ if (oActionContext.getPath() !== vContext.getPath()) {
1128
+ _this9._getRoutingListener().navigateForwardToContext(vContext, {
1129
+ noHistoryEntry: false
1130
+ });
1131
+ } else {
1132
+ Log.info("Navigation to the same context is not allowed");
1133
+ }
1134
+ }
1135
+ }
1136
+ }
1137
+ }).catch(function (err) {
1138
+ if (oCurrentActionCallBacks) {
1139
+ oCurrentActionCallBacks.fRejector();
1140
+ }
1141
+
1142
+ if (err == Constants.CancelActionDialog) {
1143
+ return Promise.reject("Dialog cancelled.");
1144
+ } else {
1145
+ return Promise.reject("Error in EditFlow.invokeAction:" + err);
1146
+ }
1147
+ });
1148
+ }
1149
+ /**
1150
+ * Secured execution of the given function. Ensures that the function is only executed when certain conditions are fulfilled.
1151
+ *
1152
+ * @memberof sap.fe.core.controllerextensions.EditFlow
1153
+ * @param {Function} fnFunction The function to be executed. Should return a promise that is settled after completion of the execution. If nothing is returned, immediate completion is assumed.
1154
+ * @param {object} mParameters Definitions of the preconditions to be checked before execution
1155
+ * @param {object} mParameters.busy Defines the busy indicator
1156
+ * @param {boolean} mParameters.busy.set Triggers a busy indicator when the function is executed.
1157
+ * @param {boolean} mParameters.busy.check Executes function only if application isn't busy.
1158
+ * @param {boolean} mParameters.updatesDocument This operation updates the current document without using the bound model and context. As a result, the draft status is updated if a draft document exists, and the user has to confirm the cancellation of the editing process.
1159
+ * @returns {Promise} A promise that is rejected if the execution is prohibited and resolved by the promise returned by the fnFunction.
1160
+ * @alias sap.fe.core.controllerextensions.EditFlow#securedExecution
1161
+ * @public
1162
+ * @experimental As of version 1.90.0
1163
+ * @since 1.90.0
1164
+ */
1165
+ ;
1166
+
1167
+ _proto.securedExecution = function securedExecution(fnFunction, mParameters) {
1168
+ var _this10 = this;
1169
+
1170
+ var bBusySet = mParameters && mParameters.busy && mParameters.busy.set !== undefined ? mParameters.busy.set : true,
1171
+ bBusyCheck = mParameters && mParameters.busy && mParameters.busy.check !== undefined ? mParameters.busy.check : true,
1172
+ bUpdatesDocument = mParameters && mParameters.updatesDocument || false,
1173
+ oLockObject = this._getGlobalUIModel(),
1174
+ oContext = this.base.getView().getBindingContext(),
1175
+ bIsDraft = oContext && this._getProgrammingModel(oContext) === ProgrammingModel.Draft;
1176
+
1177
+ if (bBusyCheck && BusyLocker.isLocked(oLockObject)) {
1178
+ return Promise.reject("Application already busy therefore execution rejected");
1179
+ } // we have to set busy and draft indicator immediately also the function might be executed later in queue
1180
+
1181
+
1182
+ if (bBusySet) {
1183
+ BusyLocker.lock(oLockObject);
1184
+ }
1185
+
1186
+ if (bUpdatesDocument && bIsDraft) {
1187
+ this._setDraftStatus(DraftStatus.Saving);
1188
+ }
1189
+
1190
+ this._getMessageHandler().removeTransitionMessages();
1191
+
1192
+ return this._syncTask(fnFunction).then(function () {
1193
+ if (bUpdatesDocument) {
1194
+ _this10._getTransactionHelper().handleDocumentModifications();
1195
+
1196
+ EditState.setEditStateDirty();
1197
+
1198
+ if (bIsDraft) {
1199
+ _this10._setDraftStatus(DraftStatus.Saved);
1200
+ }
1201
+ }
1202
+ }).catch(function (oError) {
1203
+ if (bUpdatesDocument && bIsDraft) {
1204
+ _this10._setDraftStatus(DraftStatus.Clear);
1205
+ }
1206
+
1207
+ return Promise.reject(oError);
1208
+ }).finally(function () {
1209
+ if (bBusySet) {
1210
+ BusyLocker.unlock(oLockObject);
1211
+ }
1212
+
1213
+ return _this10._getMessageHandler().showMessageDialog();
1214
+ });
1215
+ }
1216
+ /**
1217
+ * Handles the patchSent event: register document modification.
1218
+ *
1219
+ * @param oEvent
1220
+ */
1221
+ ;
1222
+
1223
+ _proto.handlePatchSent = function handlePatchSent(oEvent) {
1224
+ var _this11 = this;
1225
+
1226
+ this.mPatchPromises = this.mPatchPromises ? this.mPatchPromises : {}; // do this for every unique object (eg: every table) so that each associated promise is fulfilled at the end
1227
+
1228
+ var oPatchPromise = new Promise(function (resolve, reject) {
1229
+ _this11.mPatchPromises[oEvent.getSource()] = {
1230
+ resolvePatchPromise: resolve,
1231
+ rejectPatchPromise: reject
1232
+ };
1233
+ });
1234
+ this.updateDocument(oEvent.getSource(), oPatchPromise);
1235
+ }
1236
+ /**
1237
+ * Handles the patchCompleted event: resolves or rejects document modification.
1238
+ *
1239
+ * @param oEvent
1240
+ */
1241
+ ;
1242
+
1243
+ _proto.handlePatchCompleted = function handlePatchCompleted(oEvent) {
1244
+ var bSuccess = oEvent.getParameter("success");
1245
+
1246
+ if (bSuccess) {
1247
+ this.mPatchPromises[oEvent.getSource()].resolvePatchPromise();
1248
+ } else {
1249
+ this.mPatchPromises[oEvent.getSource()].rejectPatchPromise();
1250
+ }
1251
+
1252
+ delete this.mPatchPromises[oEvent.getSource()];
1253
+ } //////////////////////////////////////
1254
+ // Private methods
1255
+ //////////////////////////////////////
1256
+
1257
+ /*
1258
+ TO BE CHECKED / DISCUSSED
1259
+ _createMultipleDocuments and deleteMultiDocument - couldn't we combine them with create and delete document?
1260
+ _createActionPromise and deleteCurrentActionPromise -> next step
1261
+ */
1262
+ ;
1263
+
1264
+ _proto._setEditMode = function _setEditMode(sEditMode, bCreationMode) {
1265
+ this.base.getView().getController()._editFlow.setEditMode(sEditMode, bCreationMode);
1266
+ };
1267
+
1268
+ _proto._setDraftStatus = function _setDraftStatus(sDraftState) {
1269
+ this.base.getView().getController()._editFlow.setDraftStatus(sDraftState);
1270
+ };
1271
+
1272
+ _proto._getRoutingListener = function _getRoutingListener() {
1273
+ return this.base.getView().getController()._editFlow.getRoutingListener();
1274
+ };
1275
+
1276
+ _proto._getGlobalUIModel = function _getGlobalUIModel() {
1277
+ return this.base.getView().getController()._editFlow.getGlobalUIModel();
1278
+ };
1279
+
1280
+ _proto._syncTask = function _syncTask(vTask) {
1281
+ return this.base.getView().getController()._editFlow.syncTask(vTask);
1282
+ };
1283
+
1284
+ _proto._getProgrammingModel = function _getProgrammingModel(oContext) {
1285
+ return this.base.getView().getController()._editFlow.getProgrammingModel(oContext);
1286
+ };
1287
+
1288
+ _proto._deleteDocumentTransaction = function _deleteDocumentTransaction(oContext, mParameters) {
1289
+ return this.base.getView().getController()._editFlow.deleteDocumentTransaction(oContext, mParameters);
1290
+ };
1291
+
1292
+ _proto._handleCreateEvents = function _handleCreateEvents(oBinding) {
1293
+ this.base.getView().getController()._editFlow.handleCreateEvents(oBinding);
1294
+ };
1295
+
1296
+ _proto._getTransactionHelper = function _getTransactionHelper() {
1297
+ return this.base.getView().getController()._editFlow.getTransactionHelper();
1298
+ };
1299
+
1300
+ _proto._getInternalModel = function _getInternalModel() {
1301
+ return this.base.getView().getController()._editFlow.getInternalModel();
1302
+ }
1303
+ /**
1304
+ * Creates a new promise to wait for an action to be executed
1305
+ *
1306
+ * @function
1307
+ * @name _createActionPromise
1308
+ * @memberof sap.fe.core.controllerextensions.EditFlow
1309
+ *
1310
+ * @returns {Function} The resolver function which can be used to externally resolve the promise
1311
+ */
1312
+ ;
1313
+
1314
+ _proto._createActionPromise = function _createActionPromise(sActionName, sControlId) {
1315
+ return this.base.getView().getController()._editFlow.createActionPromise(sActionName, sControlId);
1316
+ };
1317
+
1318
+ _proto._getCurrentActionPromise = function _getCurrentActionPromise() {
1319
+ return this.base.getView().getController()._editFlow.getCurrentActionPromise();
1320
+ };
1321
+
1322
+ _proto._deleteCurrentActionPromise = function _deleteCurrentActionPromise() {
1323
+ return this.base.getView().getController()._editFlow.deleteCurrentActionPromise();
1324
+ };
1325
+
1326
+ _proto._getMessageHandler = function _getMessageHandler() {
1327
+ return this.base.getView().getController()._editFlow.getMessageHandler();
1328
+ }
1329
+ /**
1330
+ * @function
1331
+ * @name _getActionResponseDataAndKeys
1332
+ * @memberof sap.fe.core.controllerextensions.EditFlow
1333
+ * @param {string} sActionName The name of the action that is executed
1334
+ * @param {object} oResponse The bound action's response data or response context
1335
+ * @returns {object} Object with data and names of the key fields of the response
1336
+ */
1337
+ ;
1338
+
1339
+ _proto._getActionResponseDataAndKeys = function _getActionResponseDataAndKeys(sActionName, oResponse) {
1340
+ return this.base.getView().getController()._editFlow.getActionResponseDataAndKeys(sActionName, oResponse);
1341
+ };
1342
+
1343
+ _proto._submitOpenChanges = function _submitOpenChanges(oContext) {
1344
+ var oModel = oContext.getModel(),
1345
+ oLockObject = this._getGlobalUIModel(); //Currently we are using only 1 updateGroupId, hence submitting the batch directly here
1346
+
1347
+
1348
+ return oModel.submitBatch("$auto").then(function () {
1349
+ if (oModel.hasPendingChanges("$auto")) {
1350
+ // the submit was not successful
1351
+ return Promise.reject("submit of open changes failed");
1352
+ }
1353
+ }).finally(function () {
1354
+ if (BusyLocker.isLocked(oLockObject)) {
1355
+ BusyLocker.unlock(oLockObject);
1356
+ }
1357
+ });
1358
+ };
1359
+
1360
+ _proto._handleStickyOn = function _handleStickyOn(oContext) {
1361
+ return this.base.getView().getController()._editFlow.handleStickyOn(oContext);
1362
+ };
1363
+
1364
+ _proto._handleStickyOff = function _handleStickyOff() {
1365
+ return this.base.getView().getController()._editFlow.handleStickyOff();
1366
+ };
1367
+
1368
+ _proto._onBackNavigationInSession = function _onBackNavigationInSession() {
1369
+ return this.base.getView().getController()._editFlow.onBackNavigationInSession();
1370
+ };
1371
+
1372
+ _proto._discardStickySession = function _discardStickySession(oContext) {
1373
+ return this.base.getView().getController()._editFlow.discardStickySession(oContext);
1374
+ };
1375
+
1376
+ _proto._handleNewContext = function _handleNewContext(oContext, bEditable, bRecreateContext, bDraftNavigation, bForceFocus) {
1377
+ EditState.setEditStateDirty();
1378
+ return this._getRoutingListener().navigateToContext(oContext, {
1379
+ checkNoHashChange: true,
1380
+ editable: bEditable,
1381
+ bPersistOPScroll: true,
1382
+ bRecreateContext: bRecreateContext,
1383
+ bDraftNavigation: bDraftNavigation,
1384
+ showPlaceholder: false,
1385
+ bForceFocus: bForceFocus
1386
+ });
1387
+ }
1388
+ /**
1389
+ * Checks if there are validation (parse) errors for controls bound to a given context
1390
+ *
1391
+ * @function
1392
+ * @name _checkForValidationErrors
1393
+ * @memberof sap.fe.core.controllerextensions.EditFlow
1394
+ * @returns {Promise} Promise resolves if there are no validation errors, and rejects if there are validation errors
1395
+ */
1396
+ ;
1397
+
1398
+ _proto._checkForValidationErrors = function _checkForValidationErrors() {
1399
+ var _this12 = this;
1400
+
1401
+ return this._syncTask().then(function () {
1402
+ var sViewId = _this12.base.getView().getId();
1403
+
1404
+ var aMessages = sap.ui.getCore().getMessageManager().getMessageModel().getData();
1405
+ var oControl;
1406
+ var oMessage;
1407
+
1408
+ if (!aMessages.length) {
1409
+ return Promise.resolve("No validation errors found");
1410
+ }
1411
+
1412
+ for (var i = 0; i < aMessages.length; i++) {
1413
+ oMessage = aMessages[i];
1414
+
1415
+ if (oMessage.validation) {
1416
+ oControl = sap.ui.getCore().byId(oMessage.getControlId());
1417
+
1418
+ while (oControl) {
1419
+ if (oControl.getId() === sViewId) {
1420
+ return Promise.reject("validation errors exist");
1421
+ }
1422
+
1423
+ oControl = oControl.getParent();
1424
+ }
1425
+ }
1426
+ }
1427
+ });
1428
+ }
1429
+ /**
1430
+ * @function
1431
+ * @name _refreshListIfRequired
1432
+ * @memberof sap.fe.core.controllerextensions.EditFlow
1433
+ * @param {object} oResponse The response of the bound action and the names of the key fields
1434
+ * @param {sap.ui.model.odata.v4.Context} oContext The bound context on which the action was executed
1435
+ * @returns {Promise} Always resolves to param oResponse
1436
+ */
1437
+ ;
1438
+
1439
+ _proto._refreshListIfRequired = function _refreshListIfRequired(oResponse, oContext) {
1440
+ var _this13 = this;
1441
+
1442
+ if (!oContext || !oResponse || !oResponse.oData) {
1443
+ return Promise.resolve();
1444
+ }
1445
+
1446
+ var oBinding = oContext.getBinding(); // refresh only lists
1447
+
1448
+ if (oBinding && oBinding.isA("sap.ui.model.odata.v4.ODataListBinding")) {
1449
+ var oContextData = oResponse.oData;
1450
+ var aKeys = oResponse.keys;
1451
+ var oCurrentData = oContext.getObject();
1452
+ var bReturnedContextIsSame = true; // ensure context is in the response
1453
+
1454
+ if (Object.keys(oContextData).length) {
1455
+ // check if context in response is different than the bound context
1456
+ bReturnedContextIsSame = aKeys.every(function (sKey) {
1457
+ return oCurrentData[sKey] === oContextData[sKey];
1458
+ });
1459
+
1460
+ if (!bReturnedContextIsSame) {
1461
+ return new Promise(function (resolve) {
1462
+ if (oBinding.isRoot()) {
1463
+ oBinding.attachEventOnce("dataReceived", function () {
1464
+ resolve();
1465
+ });
1466
+ oBinding.refresh();
1467
+ } else {
1468
+ var oAppComponent = CommonUtils.getAppComponent(_this13.getView());
1469
+ oAppComponent.getSideEffectsService().requestSideEffects([{
1470
+ $NavigationPropertyPath: oBinding.getPath()
1471
+ }], oBinding.getContext()).then(function () {
1472
+ resolve();
1473
+ }, function () {
1474
+ Log.error("Error while refreshing the table");
1475
+ resolve();
1476
+ }).catch(function (e) {
1477
+ Log.error("Error while refreshing the table", e);
1478
+ });
1479
+ }
1480
+ });
1481
+ }
1482
+ }
1483
+ } // resolve with oResponse to not disturb the promise chain afterwards
1484
+
1485
+
1486
+ return Promise.resolve();
1487
+ };
1488
+
1489
+ _proto._fetchSemanticKeyValues = function _fetchSemanticKeyValues(oContext) {
1490
+ var oMetaModel = oContext.getModel().getMetaModel(),
1491
+ sEntitySetName = oMetaModel.getMetaContext(oContext.getPath()).getObject("@sapui.name"),
1492
+ aSemanticKeys = SemanticKeyHelper.getSemanticKeys(oMetaModel, sEntitySetName);
1493
+
1494
+ if (aSemanticKeys && aSemanticKeys.length) {
1495
+ var aRequestPromises = aSemanticKeys.map(function (oKey) {
1496
+ return oContext.requestObject(oKey.$PropertyPath);
1497
+ });
1498
+ return Promise.all(aRequestPromises);
1499
+ } else {
1500
+ return Promise.resolve();
1501
+ }
1502
+ } // Ugly Workaround to overcome mdc field issue, we remove the binding context before
1503
+ // switching to display mode to avoid the field reads additional values for non existing
1504
+ // drafts or sticky sessions in the backend
1505
+ ;
1506
+
1507
+ _proto._removeContextsFromPages = function _removeContextsFromPages() {
1508
+ var aPages = [];
1509
+ var oAppComponent = CommonUtils.getAppComponent(this.getView());
1510
+
1511
+ if (oAppComponent._isFclEnabled()) {
1512
+ var oFCL = oAppComponent.getRootContainer();
1513
+ aPages = aPages.concat(oFCL.getMidColumnPages() || []);
1514
+ aPages = aPages.concat(oFCL.getEndColumnPages() || []);
1515
+ } else {
1516
+ var oNavContainer = oAppComponent.getRootContainer();
1517
+ aPages = oNavContainer.getPages() || [];
1518
+ }
1519
+
1520
+ aPages.forEach(function (oPage) {
1521
+ if (oPage.isA("sap.ui.core.ComponentContainer")) {
1522
+ oPage = oPage.getComponentInstance(); // The binding context is set at the component level, not the component container
1523
+ }
1524
+
1525
+ if (oPage.getBindingContext()) {
1526
+ oPage.setBindingContext(null);
1527
+ }
1528
+ });
1529
+ };
1530
+
1531
+ _proto._getActionOverloadContextFromSubSections = function _getActionOverloadContextFromSubSections(oControl, sOverloadEntityType) {
1532
+ var oCurrentControl;
1533
+
1534
+ function _checkActions(aActions) {
1535
+ var oActionBindingContext;
1536
+
1537
+ try {
1538
+ aActions.forEach(function (oAction) {
1539
+ oActionBindingContext = oAction.getBindingContext();
1540
+
1541
+ if (oActionBindingContext.getModel().getMetaModel().getMetaContext(oActionBindingContext.getPath()).getObject("$Type") === sOverloadEntityType) {
1542
+ throw "context found - stop actions loop";
1543
+ }
1544
+ });
1545
+ return undefined;
1546
+ } catch (e) {
1547
+ return oActionBindingContext;
1548
+ }
1549
+ }
1550
+
1551
+ function _checkSubSections(aSubSections) {
1552
+ var oActionBindingContext;
1553
+
1554
+ try {
1555
+ aSubSections.forEach(function (oSubSection) {
1556
+ if (oActionBindingContext) {
1557
+ throw "context found - stop SubSections loop";
1558
+ }
1559
+
1560
+ var aActions = oSubSection.getAggregation("actions");
1561
+ oActionBindingContext = _checkActions(aActions);
1562
+ });
1563
+ return oActionBindingContext ? oActionBindingContext : undefined;
1564
+ } catch (e) {
1565
+ return oActionBindingContext;
1566
+ }
1567
+ }
1568
+
1569
+ try {
1570
+ if (oControl === undefined) {
1571
+ throw new Error("input parameter oControl undefined when trying to determine the action overload context");
1572
+ }
1573
+
1574
+ oCurrentControl = oControl;
1575
+
1576
+ while (!oCurrentControl.isA("sap.uxap.ObjectPageSection")) {
1577
+ oCurrentControl = oCurrentControl.getParent();
1578
+ }
1579
+
1580
+ if (!oCurrentControl) {
1581
+ throw new Error("ObjectPageSection not found in UI hierarchy");
1582
+ } else {
1583
+ var aSubSections = oCurrentControl.getAggregation("subSections");
1584
+ return _checkSubSections(aSubSections);
1585
+ }
1586
+ } catch (error) {
1587
+ Log.info(error);
1588
+ return undefined;
1589
+ }
1590
+ };
1591
+
1592
+ return EditFlow;
1593
+ }(ControllerExtension), (_applyDecoratedDescriptor(_class2.prototype, "editDocument", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "editDocument"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "deleteMultipleDocuments", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "deleteMultipleDocuments"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "updateDocument", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "updateDocument"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "createDocument", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "createDocument"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "onBeforeSave", [Public, _dec2], Object.getOwnPropertyDescriptor(_class2.prototype, "onBeforeSave"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "onBeforeCreate", [Public, _dec3], Object.getOwnPropertyDescriptor(_class2.prototype, "onBeforeCreate"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "onBeforeEdit", [Public, _dec4], Object.getOwnPropertyDescriptor(_class2.prototype, "onBeforeEdit"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "onBeforeDiscard", [Public, _dec5], Object.getOwnPropertyDescriptor(_class2.prototype, "onBeforeDiscard"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "onBeforeDelete", [Public, _dec6], Object.getOwnPropertyDescriptor(_class2.prototype, "onBeforeDelete"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "saveDocument", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "saveDocument"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "toggleDraftActive", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "toggleDraftActive"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "cancelDocument", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "cancelDocument"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "deleteDocument", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "deleteDocument"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "applyDocument", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "applyDocument"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "invokeAction", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "invokeAction"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "securedExecution", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "securedExecution"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "handlePatchSent", [Public], Object.getOwnPropertyDescriptor(_class2.prototype, "handlePatchSent"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "handlePatchCompleted", [Public], Object.getOwnPropertyDescriptor(_class2.prototype, "handlePatchCompleted"), _class2.prototype)), _class2)) || _class);
1594
+ return EditFlow;
1595
+ }, false);
1596
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkVkaXRGbG93LnRzIl0sIm5hbWVzIjpbIkNyZWF0aW9uTW9kZSIsIkZFTGlicmFyeSIsIlByb2dyYW1taW5nTW9kZWwiLCJDb25zdGFudHMiLCJEcmFmdFN0YXR1cyIsIkVkaXRNb2RlIiwiTWVzc2FnZVR5cGUiLCJjb3JlTGlicmFyeSIsIkVkaXRGbG93IiwiVUk1Q2xhc3MiLCJDb250cm9sbGVyRXh0ZW5zaW9uTWV0YWRhdGEiLCJFeHRlbnNpYmxlIiwiT3ZlcnJpZGVFeGVjdXRpb24iLCJBZnRlciIsImVkaXREb2N1bWVudCIsIm9Db250ZXh0IiwiYkRyYWZ0TmF2aWdhdGlvbiIsInRyYW5zYWN0aW9uSGVscGVyIiwiX2dldFRyYW5zYWN0aW9uSGVscGVyIiwiYmFzZSIsImVkaXRGbG93Iiwib25CZWZvcmVFZGl0IiwiY29udGV4dCIsInRoZW4iLCJiaW5kIiwiZ2V0VmlldyIsIl9nZXRNZXNzYWdlSGFuZGxlciIsIm9OZXdEb2N1bWVudENvbnRleHQiLCJzUHJvZ3JhbW1pbmdNb2RlbCIsIl9nZXRQcm9ncmFtbWluZ01vZGVsIiwiU3RpY2t5IiwiX2dldEludGVybmFsTW9kZWwiLCJzZXRQcm9wZXJ0eSIsIl9zZXRFZGl0TW9kZSIsIkVkaXRhYmxlIiwic2hvd01lc3NhZ2VEaWFsb2ciLCJfaGFuZGxlTmV3Q29udGV4dCIsIl9oYW5kbGVTdGlja3lPbiIsImNhdGNoIiwib0Vycm9yIiwiTG9nIiwiZXJyb3IiLCJkZWxldGVNdWx0aXBsZURvY3VtZW50cyIsImFDb250ZXh0cyIsIm1QYXJhbWV0ZXJzIiwiYmVmb3JlRGVsZXRlQ2FsbEJhY2siLCJvbkJlZm9yZURlbGV0ZSIsImdldENvbnRyb2xsZXIiLCJfZWRpdEZsb3ciLCJ1cGRhdGVEb2N1bWVudCIsIm9Qcm9taXNlIiwib0JpbmRpbmdDb250ZXh0IiwiZ2V0QmluZGluZ0NvbnRleHQiLCJiSXNEcmFmdCIsIkRyYWZ0IiwicmVtb3ZlVHJhbnNpdGlvbk1lc3NhZ2VzIiwiX3N5bmNUYXNrIiwiaGFuZGxlRG9jdW1lbnRNb2RpZmljYXRpb25zIiwiRWRpdFN0YXRlIiwic2V0RWRpdFN0YXRlRGlydHkiLCJfc2V0RHJhZnRTdGF0dXMiLCJTYXZpbmciLCJvTWV0YU1vZGVsIiwiZ2V0TW9kZWwiLCJnZXRNZXRhTW9kZWwiLCJzRW50aXR5U2V0TmFtZSIsImdldE1ldGFDb250ZXh0IiwiZ2V0UGF0aCIsImdldE9iamVjdCIsImFTZW1hbnRpY0tleXMiLCJTZW1hbnRpY0tleUhlbHBlciIsImdldFNlbWFudGljS2V5cyIsImxlbmd0aCIsIm9DdXJyZW50U2VtYW50aWNNYXBwaW5nIiwiZ2V0QXBwQ29tcG9uZW50IiwiZ2V0Um91dGluZ1NlcnZpY2UiLCJnZXRMYXN0U2VtYW50aWNNYXBwaW5nIiwic0N1cnJlbnRTZW1hbnRpY1BhdGgiLCJzZW1hbnRpY1BhdGgiLCJzQ2hhbmdlZFBhdGgiLCJnZXRTZW1hbnRpY1BhdGgiLCJTYXZlZCIsIkNsZWFyIiwiZmluYWxseSIsInNob3dNZXNzYWdlcyIsImNyZWF0ZURvY3VtZW50Iiwidkxpc3RCaW5kaW5nIiwibUluUGFyYW1ldGVycyIsIm9Mb2NrT2JqZWN0IiwiX2dldEdsb2JhbFVJTW9kZWwiLCJvVGFibGUiLCJpQ291bnRUYWJsZUl0ZW1zIiwib1Jlc291cmNlQnVuZGxlIiwiYlNob3VsZEJ1c3lMb2NrIiwiY3JlYXRpb25Nb2RlIiwiSW5saW5lIiwiQ3JlYXRpb25Sb3ciLCJFeHRlcm5hbCIsIm9FeGVjQ3VzdG9tVmFsaWRhdGlvbiIsIlByb21pc2UiLCJyZXNvbHZlIiwib0FwcENvbXBvbmVudCIsIkNvbW1vblV0aWxzIiwiZ2V0Um91dGVyUHJveHkiLCJyZW1vdmVJQXBwU3RhdGVLZXkiLCJvQ29udHJvbGxlciIsInNDcmVhdGVQYXRoIiwiTW9kZWxIZWxwZXIiLCJnZXRBYnNvbHV0ZU1ldGFQYXRoRm9yTGlzdEJpbmRpbmciLCJoYW5kbGVycyIsIm9uQ2hldnJvblByZXNzTmF2aWdhdGVPdXRCb3VuZCIsIm91dGJvdW5kIiwidW5kZWZpbmVkIiwiY3JlYXRpb25Sb3ciLCJvQ3JlYXRpb25Sb3dPYmplY3RzIiwiZ2V0UGFyZW50IiwidmFsaWRhdGVEb2N1bWVudCIsImRhdGEiLCJjdXN0b21WYWxpZGF0aW9uRnVuY3Rpb24iLCJnZXRDcmVhdGlvblJvdyIsIm9JbnRlcm5hbE1vZGVsQ29udGV4dCIsInRhYmxlSWQiLCJieUlkIiwiaGFuZGxlU2lkZUVmZmVjdHMiLCJvTGlzdEJpbmRpbmciLCJvQ3JlYXRpb25Qcm9taXNlIiwib05ld0NvbnRleHQiLCJjcmVhdGVkIiwiaGFzVHJhbnNpZW50Q29udGV4dCIsImdldFNpZGVFZmZlY3RzU2VydmljZSIsInJlcXVlc3RTaWRlRWZmZWN0c0Zvck5hdmlnYXRpb25Qcm9wZXJ0eSIsImNyZWF0ZUN1c3RvbVZhbGlkYXRpb25NZXNzYWdlcyIsImFWYWxpZGF0aW9uTWVzc2FnZXMiLCJzQ3VzdG9tVmFsaWRhdGlvbkZ1bmN0aW9uIiwibUN1c3RvbVZhbGlkaXR5IiwiZ2V0UHJvcGVydHkiLCJvTWVzc2FnZU1hbmFnZXIiLCJzYXAiLCJ1aSIsImdldENvcmUiLCJnZXRNZXNzYWdlTWFuYWdlciIsImFDdXN0b21NZXNzYWdlcyIsIm9GaWVsZENvbnRyb2wiLCJzVGFyZ2V0IiwiZ2V0TWVzc2FnZU1vZGVsIiwiZ2V0RGF0YSIsImZvckVhY2giLCJvTWVzc2FnZSIsImNvZGUiLCJyZW1vdmVNZXNzYWdlcyIsIm9WYWxpZGF0aW9uTWVzc2FnZSIsIm1lc3NhZ2VUYXJnZXQiLCJnZXRDb250cm9sIiwiZmllbGRJZCIsImdldEJpbmRpbmdQYXRoIiwiZmlsdGVyIiwidGFyZ2V0IiwiYWRkTWVzc2FnZXMiLCJNZXNzYWdlIiwibWVzc2FnZSIsIm1lc3NhZ2VUZXh0IiwicHJvY2Vzc29yIiwidHlwZSIsIkVycm9yIiwidGVjaG5pY2FsIiwicGVyc2lzdGVudCIsImFFeGlzdGluZ1ZhbGlkYXRpb25NZXNzYWdlcyIsImFkZENvbnRyb2xJZCIsInB1c2giLCJ0ZXh0IiwiY3VzdG9tTWVzc2FnZXMiLCJCdXN5TG9ja2VyIiwibG9jayIsIk9EYXRhTGlzdEJpbmRpbmciLCJTeW5jIiwiY3JlYXRlQXRFbmQiLCJvTW9kZWwiLCJpTWF4TGVuZ3RoIiwic0NyZWF0aW9uTW9kZSIsInByb2dyYW1taW5nTW9kZWwiLCJOZXdQYWdlIiwiaXNSZWxhdGl2ZSIsInNQYXRoIiwic05ld0FjdGlvbiIsImFQYXJhbWV0ZXJzIiwiRGVmZXJyZWQiLCJzTWV0YVBhdGgiLCJnZXRNZXRhUGF0aCIsImdldEhlYWRlckNvbnRleHQiLCJhTm9uQ29tcHV0ZWRWaXNpYmxlS2V5RmllbGRzIiwiZ2V0Tm9uQ29tcHV0ZWRWaXNpYmxlRmllbGRzIiwiQXN5bmMiLCJvQ3JlYXRpb24iLCJtQXJncyIsIm9DcmVhdGlvblJvdyIsIm9DcmVhdGlvblJvd0NvbnRleHQiLCJvVmFsaWRhdGlvbkNoZWNrIiwib1BheWxvYWQiLCJvUm91dGluZ0xpc3RlbmVyIiwiX2dldFJvdXRpbmdMaXN0ZW5lciIsIk9iamVjdCIsImtleXMiLCJzUHJvcGVydHlQYXRoIiwib1Byb3BlcnR5IiwiJGtpbmQiLCJfY2hlY2tGb3JWYWxpZGF0aW9uRXJyb3JzIiwia2VlcFRyYW5zaWVudENvbnRleHRPbkZhaWxlZCIsImJ1c3lNb2RlIiwiX2hhbmRsZUNyZWF0ZUV2ZW50cyIsInBhcmVudENvbnRyb2wiLCJiZWZvcmVDcmVhdGVDYWxsQmFjayIsIm9uQmVmb3JlQ3JlYXRlIiwib05hdmlnYXRpb24iLCJuYXZpZ2F0ZUZvcndhcmRUb0NvbnRleHQiLCJiRGVmZXJyZWRDb250ZXh0IiwiZWRpdGFibGUiLCJiRm9yY2VGb2N1cyIsImFzeW5jQ29udGV4dCIsImNyZWF0ZUFjdGlvbiIsInRyYW5zaWVudCIsImdldExpYnJhcnlSZXNvdXJjZUJ1bmRsZSIsIm5hdmlnYXRlVG9NZXNzYWdlUGFnZSIsImdldFRleHQiLCJ0aXRsZSIsImRlc2NyaXB0aW9uIiwib0NyZWF0aW9uUm93TGlzdEJpbmRpbmciLCJnZXRCaW5kaW5nIiwiYlNraXBTaWRlRWZmZWN0cyIsIm9OZXdUcmFuc2llbnRDb250ZXh0IiwiY3JlYXRlIiwic2V0QmluZGluZ0NvbnRleHQiLCJ0cmFjZSIsImRlbGV0ZSIsImlzTG9ja2VkIiwidW5sb2NrIiwicmVqZWN0IiwiYklzTmV3UGFnZUNyZWF0aW9uIiwiYWxsIiwiYVBhcmFtcyIsInNlbmQiLCJBY3Rpdml0eSIsIkNyZWF0ZSIsIm5hdmlnYXRlQmFja0Zyb21UcmFuc2llbnRTdGF0ZSIsIkNhbmNlbEFjdGlvbkRpYWxvZyIsImlzQSIsImZuRm9jdXNPclNjcm9sbCIsImZvY3VzUm93Iiwic2Nyb2xsVG9JbmRleCIsImdldFJvd0JpbmRpbmciLCJhdHRhY2hFdmVudE9uY2UiLCJnZXRUaHJlc2hvbGQiLCJvbkJlZm9yZVNhdmUiLCJvbkJlZm9yZURpc2NhcmQiLCJzYXZlRG9jdW1lbnQiLCJiRXhlY3V0ZVNpZGVFZmZlY3RzT25FcnJvciIsImFCaW5kaW5ncyIsImJpbmRpbmdzIiwiX3N1Ym1pdE9wZW5DaGFuZ2VzIiwib0FjdGl2ZURvY3VtZW50Q29udGV4dCIsIl9yZW1vdmVDb250ZXh0c0Zyb21QYWdlcyIsIl9oYW5kbGVTdGlja3lPZmYiLCJBY3RpdmF0ZSIsIkRpc3BsYXkiLCJ0b2dnbGVEcmFmdEFjdGl2ZSIsIm9Db250ZXh0RGF0YSIsImJFZGl0YWJsZSIsIm9Ub2dnbGVDb250ZXh0IiwiYmluZENvbnRleHQiLCJnZXRCb3VuZENvbnRleHQiLCJJc0FjdGl2ZUVudGl0eSIsIkhhc0FjdGl2ZUVudGl0eSIsIkhhc0RyYWZ0RW50aXR5IiwicmVxdWVzdENhbm9uaWNhbFBhdGgiLCJzQ2Fub25pY2FsUGF0aCIsImVyciIsImNhbmNlbERvY3VtZW50IiwiY2FuY2VsQnV0dG9uIiwiY29udHJvbCIsImJlZm9yZUNhbmNlbENhbGxCYWNrIiwiRGlzY2FyZCIsInNraXBCYWNrTmF2aWdhdGlvbiIsIm5hdmlnYXRlQmFja0Zyb21Db250ZXh0IiwiX2ZldGNoU2VtYW50aWNLZXlWYWx1ZXMiLCJza2lwQmluZGluZ1RvVmlldyIsImRlbGV0ZURvY3VtZW50IiwiYkZpbmRBY3RpdmVDb250ZXh0cyIsIl9kZWxldGVEb2N1bWVudFRyYW5zYWN0aW9uIiwiRGVsZXRlIiwiZ2V0U2hlbGxTZXJ2aWNlcyIsInNldEJhY2tOYXZpZ2F0aW9uIiwiYXBwbHlEb2N1bWVudCIsImludm9rZUFjdGlvbiIsInNBY3Rpb25OYW1lIiwibUV4dHJhUGFyYW1zIiwib0NvbnRyb2wiLCJvQ3VycmVudENvbnRyb2wiLCJhUGFydHMiLCJzT3ZlcmxvYWRFbnRpdHlUeXBlIiwib0N1cnJlbnRBY3Rpb25DYWxsQmFja3MiLCJvVmlldyIsIkFycmF5IiwiaXNBcnJheSIsImFyZ3VtZW50cyIsImNvbnRleHRzIiwibW9kZWwiLCJpc05hdmlnYWJsZSIsInJlcXVpcmVzTmF2aWdhdGlvbiIsImNvbnRyb2xJZCIsImludGVybmFsTW9kZWxDb250ZXh0IiwiaW5kZXhPZiIsInNwbGl0IiwicmVwbGFjZUFsbCIsImJTdGF0aWNBY3Rpb24iLCJpc1RhYmxlQm91bmQiLCJzQmluZGluZ1BhdGgiLCJwYXRoIiwic1RhYmxlQ29udGV4dEVudGl0eVR5cGUiLCJvQWN0aW9uT3ZlcmxvYWRDb250ZXh0IiwiX2dldEFjdGlvbk92ZXJsb2FkQ29udGV4dEZyb21TdWJTZWN0aW9ucyIsImVuYWJsZUF1dG9TY3JvbGwiLCJfY3JlYXRlQWN0aW9uUHJvbWlzZSIsInNJZCIsImJHZXRCb3VuZENvbnRleHQiLCJiT2JqZWN0UGFnZSIsImdldFZpZXdEYXRhIiwiY29udmVydGVyVHlwZSIsImNhbGxBY3Rpb24iLCJvUmVzcG9uc2UiLCJfcmVmcmVzaExpc3RJZlJlcXVpcmVkIiwiX2dldEFjdGlvblJlc3BvbnNlRGF0YUFuZEtleXMiLCJBY3Rpb24iLCJmUmVzb2x2ZXIiLCJ2Q29udGV4dCIsInNDb250ZXh0TWV0YVBhdGgiLCJvQWN0aW9uQ29udGV4dCIsInNBY3Rpb25Db250ZXh0TWV0YVBhdGgiLCJub0hpc3RvcnlFbnRyeSIsImluZm8iLCJmUmVqZWN0b3IiLCJzZWN1cmVkRXhlY3V0aW9uIiwiZm5GdW5jdGlvbiIsImJCdXN5U2V0IiwiYnVzeSIsInNldCIsImJCdXN5Q2hlY2siLCJjaGVjayIsImJVcGRhdGVzRG9jdW1lbnQiLCJ1cGRhdGVzRG9jdW1lbnQiLCJoYW5kbGVQYXRjaFNlbnQiLCJvRXZlbnQiLCJtUGF0Y2hQcm9taXNlcyIsIm9QYXRjaFByb21pc2UiLCJnZXRTb3VyY2UiLCJyZXNvbHZlUGF0Y2hQcm9taXNlIiwicmVqZWN0UGF0Y2hQcm9taXNlIiwiaGFuZGxlUGF0Y2hDb21wbGV0ZWQiLCJiU3VjY2VzcyIsImdldFBhcmFtZXRlciIsInNFZGl0TW9kZSIsImJDcmVhdGlvbk1vZGUiLCJzZXRFZGl0TW9kZSIsInNEcmFmdFN0YXRlIiwic2V0RHJhZnRTdGF0dXMiLCJnZXRSb3V0aW5nTGlzdGVuZXIiLCJnZXRHbG9iYWxVSU1vZGVsIiwidlRhc2siLCJzeW5jVGFzayIsImdldFByb2dyYW1taW5nTW9kZWwiLCJkZWxldGVEb2N1bWVudFRyYW5zYWN0aW9uIiwib0JpbmRpbmciLCJoYW5kbGVDcmVhdGVFdmVudHMiLCJnZXRUcmFuc2FjdGlvbkhlbHBlciIsImdldEludGVybmFsTW9kZWwiLCJzQ29udHJvbElkIiwiY3JlYXRlQWN0aW9uUHJvbWlzZSIsIl9nZXRDdXJyZW50QWN0aW9uUHJvbWlzZSIsImdldEN1cnJlbnRBY3Rpb25Qcm9taXNlIiwiX2RlbGV0ZUN1cnJlbnRBY3Rpb25Qcm9taXNlIiwiZGVsZXRlQ3VycmVudEFjdGlvblByb21pc2UiLCJnZXRNZXNzYWdlSGFuZGxlciIsImdldEFjdGlvblJlc3BvbnNlRGF0YUFuZEtleXMiLCJzdWJtaXRCYXRjaCIsImhhc1BlbmRpbmdDaGFuZ2VzIiwiaGFuZGxlU3RpY2t5T24iLCJoYW5kbGVTdGlja3lPZmYiLCJfb25CYWNrTmF2aWdhdGlvbkluU2Vzc2lvbiIsIm9uQmFja05hdmlnYXRpb25JblNlc3Npb24iLCJfZGlzY2FyZFN0aWNreVNlc3Npb24iLCJkaXNjYXJkU3RpY2t5U2Vzc2lvbiIsImJSZWNyZWF0ZUNvbnRleHQiLCJuYXZpZ2F0ZVRvQ29udGV4dCIsImNoZWNrTm9IYXNoQ2hhbmdlIiwiYlBlcnNpc3RPUFNjcm9sbCIsInNob3dQbGFjZWhvbGRlciIsInNWaWV3SWQiLCJnZXRJZCIsImFNZXNzYWdlcyIsImkiLCJ2YWxpZGF0aW9uIiwiZ2V0Q29udHJvbElkIiwib0RhdGEiLCJhS2V5cyIsIm9DdXJyZW50RGF0YSIsImJSZXR1cm5lZENvbnRleHRJc1NhbWUiLCJldmVyeSIsInNLZXkiLCJpc1Jvb3QiLCJyZWZyZXNoIiwicmVxdWVzdFNpZGVFZmZlY3RzIiwiJE5hdmlnYXRpb25Qcm9wZXJ0eVBhdGgiLCJnZXRDb250ZXh0IiwiZSIsImFSZXF1ZXN0UHJvbWlzZXMiLCJtYXAiLCJvS2V5IiwicmVxdWVzdE9iamVjdCIsIiRQcm9wZXJ0eVBhdGgiLCJhUGFnZXMiLCJfaXNGY2xFbmFibGVkIiwib0ZDTCIsImdldFJvb3RDb250YWluZXIiLCJjb25jYXQiLCJnZXRNaWRDb2x1bW5QYWdlcyIsImdldEVuZENvbHVtblBhZ2VzIiwib05hdkNvbnRhaW5lciIsImdldFBhZ2VzIiwib1BhZ2UiLCJnZXRDb21wb25lbnRJbnN0YW5jZSIsIl9jaGVja0FjdGlvbnMiLCJhQWN0aW9ucyIsIm9BY3Rpb25CaW5kaW5nQ29udGV4dCIsIm9BY3Rpb24iLCJfY2hlY2tTdWJTZWN0aW9ucyIsImFTdWJTZWN0aW9ucyIsIm9TdWJTZWN0aW9uIiwiZ2V0QWdncmVnYXRpb24iLCJDb250cm9sbGVyRXh0ZW5zaW9uIiwiUHVibGljIiwiRmluYWwiXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF3QkEsTUFBTUEsWUFBWSxHQUFHQyxTQUFTLENBQUNELFlBQS9CO0FBQUEsTUFDQ0UsZ0JBQWdCLEdBQUdELFNBQVMsQ0FBQ0MsZ0JBRDlCO0FBQUEsTUFFQ0MsU0FBUyxHQUFHRixTQUFTLENBQUNFLFNBRnZCO0FBQUEsTUFHQ0MsV0FBVyxHQUFHSCxTQUFTLENBQUNHLFdBSHpCO0FBQUEsTUFJQ0MsUUFBUSxHQUFHSixTQUFTLENB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QUdELFFBQWxCOztBQUNBLGVBQU8sQ0FBQ0MsZUFBZSxDQUFDbkQsR0FBaEIsQ0FBb0IsNEJBQXBCLENBQVIsRUFBMkQ7QUFDMURtRCxVQUFBQSxlQUFlLEdBQUdBLGVBQWUsQ0FBQ3BMLFNBQWhCLEVBQWxCO0FBQ0E7O0FBRUQsWUFBSSxDQUFDb0wsZUFBTCxFQUFzQjtBQUNyQixnQkFBTSxJQUFJcEksS0FBSixDQUFVLDZDQUFWLENBQU47QUFDQSxTQUZELE1BRU87QUFDTixjQUFNOFEsWUFBWSxHQUFHMUksZUFBZSxDQUFDNEksY0FBaEIsQ0FBK0IsYUFBL0IsQ0FBckI7QUFDQSxpQkFBT0gsaUJBQWlCLENBQUNDLFlBQUQsQ0FBeEI7QUFDQTtBQUNELE9BaEJELENBZ0JFLE9BQU94WSxLQUFQLEVBQWM7QUFDZkQsUUFBQUEsR0FBRyxDQUFDeVMsSUFBSixDQUFTeFMsS0FBVDtBQUNBLGVBQU91RSxTQUFQO0FBQ0E7QUFDRCxLOzs7SUE1bERxQm9VLG1CLGtFQXNCckJDLE0sRUFDQUMsSyxvS0FpQ0FELE0sRUFDQUMsSyxzS0F1QkFELE0sRUFDQUMsSyw2SkFxRkFELE0sRUFDQUMsSywySkE4YUFELE0sa0tBd0JBQSxNLGtLQXVCQUEsTSxtS0F1QkFBLE0scUtBdUJBQSxNLGtLQXlCQUEsTSxFQUNBQyxLLDhKQW1EQUQsTSxFQUNBQyxLLGdLQWdFQUQsTSxFQUNBQyxLLDZKQXFFQUQsTSxFQUNBQyxLLDRKQTBDQUQsTSxFQUNBQyxLLDBKQTRDQUQsTSxFQUNBQyxLLDZKQWlOQUQsTSxFQUNBQyxLLGdLQTZEQUQsTSxvS0FrQkFBLE07U0ErVmE3YSxRIiwic291cmNlUm9vdCI6Ii4iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ29udHJvbGxlckV4dGVuc2lvbiBmcm9tIFwic2FwL3VpL2NvcmUvbXZjL0NvbnRyb2xsZXJFeHRlbnNpb25cIjtcbmltcG9ydCBPdmVycmlkZUV4ZWN1dGlvbiBmcm9tIFwic2FwL3VpL2NvcmUvbXZjL092ZXJyaWRlRXhlY3V0aW9uXCI7XG5pbXBvcnQgTG9nIGZyb20gXCJzYXAvYmFzZS9Mb2dcIjtcbmltcG9ydCBDb21tb25VdGlscyBmcm9tIFwic2FwL2ZlL2NvcmUvQ29tbW9uVXRpbHNcIjtcbmltcG9ydCBCdXN5TG9ja2VyIGZyb20gXCJzYXAvZmUvY29yZS9CdXN5TG9ja2VyXCI7XG5pbXBvcnQgRkVMaWJyYXJ5IGZyb20gXCJzYXAvZmUvY29yZS9saWJyYXJ5XCI7XG5pbXBvcnQgT0RhdGFMaXN0QmluZGluZyBmcm9tIFwic2FwL3VpL21vZGVsL29kYXRhL3Y0L09EYXRhTGlzdEJpbmRpbmdcIjtcbmltcG9ydCBTZW1hbnRpY0tleUhlbHBlciBmcm9tIFwic2FwL2ZlL2NvcmUvaGVscGVycy9TZW1hbnRpY0tleUhlbHBlclwiO1xuaW1wb3J0IEVkaXRTdGF0ZSBmcm9tIFwic2FwL2ZlL2NvcmUvaGVscGVycy9FZGl0U3RhdGVcIjtcbmltcG9ydCBNZXNzYWdlIGZyb20gXCJzYXAvdWkvY29yZS9tZXNzYWdlL01lc3NhZ2VcIjtcbmltcG9ydCBjb3JlTGlicmFyeSBmcm9tIFwic2FwL3VpL2NvcmUvbGlicmFyeVwiO1xuaW1wb3J0IE1vZGVsSGVscGVyLCB7IEludGVybmFsTW9kZWxDb250ZXh0IH0gZnJvbSBcInNhcC9mZS9jb3JlL2hlbHBlcnMvTW9kZWxIZWxwZXJcIjtcbmltcG9ydCB7IEV4dGVuc2libGUsIEZpbmFsLCBQdWJsaWMsIFVJNUNsYXNzIH0gZnJvbSBcInNhcC9mZS9jb3JlL2hlbHBlcnMvQ2xhc3NTdXBwb3J0XCI7XG5pbXBvcnQgQ29udHJvbGxlckV4dGVuc2lvbk1ldGFkYXRhIGZyb20gXCJzYXAvZmUvY29yZS9jb250cm9sbGVyZXh0ZW5zaW9ucy9Db250cm9sbGVyRXh0ZW5zaW9uTWV0YWRhdGFcIjtcbmltcG9ydCBQYWdlQ29udHJvbGxlciBmcm9tIFwic2FwL2ZlL2NvcmUvUGFnZUNvbnRyb2xsZXJcIjtcbmltcG9ydCBPRGF0YU1ldGFNb2RlbCBmcm9tIFwic2FwL3VpL21vZGVsL29kYXRhL3Y0L09EYXRhTWV0YU1vZGVsXCI7XG5pbXBvcnQgVGFibGUgZnJvbSBcInNhcC91aS9tZGMvVGFibGVcIjtcbmltcG9ydCBDb250ZXh0IGZyb20gXCJzYXAvdWkvbW9kZWwvb2RhdGEvdjQvQ29udGV4dFwiO1xuaW1wb3J0IFJlc291cmNlQnVuZGxlIGZyb20gXCJzYXAvYmFzZS9pMThuL1Jlc291cmNlQnVuZGxlXCI7XG5pbXBvcnQgQ29udHJvbCBmcm9tIFwic2FwL3VpL2NvcmUvQ29udHJvbFwiO1xuaW1wb3J0IHsgc2VuZCB9IGZyb20gXCJzYXAvZmUvY29yZS9hY3Rpb25zL2NvbGxhYm9yYXRpb24vQWN0aXZpdHlTeW5jXCI7XG5pbXBvcnQgeyBBY3Rpdml0eSB9IGZyb20gXCJzYXAvZmUvY29yZS9hY3Rpb25zL2NvbGxhYm9yYXRpb24vQ29sbGFib3JhdGlvbkNvbW1vblwiO1xuaW1wb3J0IE9EYXRhTW9kZWwgZnJvbSBcInNhcC91aS9tb2RlbC9vZGF0YS92NC9PRGF0YU1vZGVsXCI7XG5pbXBvcnQgRmxleGlibGVDb2x1bW5MYXlvdXQgZnJvbSBcInNhcC9mL0ZsZXhpYmxlQ29sdW1uTGF5b3V0XCI7XG5pbXBvcnQgTmF2Q29udGFpbmVyIGZyb20gXCJzYXAvbS9OYXZDb250YWluZXJcIjtcblxuY29uc3QgQ3JlYXRpb25Nb2RlID0gRkVMaWJyYXJ5LkNyZWF0aW9uTW9kZSxcblx0UHJvZ3JhbW1pbmdNb2RlbCA9IEZFTGlicmFyeS5Qcm9ncmFtbWluZ01vZGVsLFxuXHRDb25zdGFudHMgPSBGRUxpYnJhcnkuQ29uc3RhbnRzLFxuXHREcmFmdFN0YXR1cyA9IEZFTGlicmFyeS5EcmFmdFN0YXR1cyxcblx0RWRpdE1vZGUgPSBGRUxpYnJhcnkuRWRpdE1vZGUsXG5cdE1lc3NhZ2VUeXBlID0gY29yZUxpYnJhcnkuTWVzc2FnZVR5cGU7XG4vKipcbiAqIEEgY29udHJvbGxlciBleHRlbnNpb24gb2ZmZXJpbmcgaG9va3MgaW50byB0aGUgZWRpdCBmbG93IG9mIHRoZSBhcHBsaWNhdGlvblxuICpcbiAqIEBoaWRlY29uc3RydWN0b3JcbiAqIEBwdWJsaWNcbiAqIEBzaW5jZSAxLjkwLjBcbiAqL1xuQFVJNUNsYXNzKFwic2FwLmZlLmNvcmUuY29udHJvbGxlcmV4dGVuc2lvbnMuRWRpdEZsb3dcIiwgQ29udHJvbGxlckV4dGVuc2lvbk1ldGFkYXRhKVxuY2xhc3MgRWRpdEZsb3cgZXh0ZW5kcyBDb250cm9sbGVyRXh0ZW5zaW9uIHtcblx0cHJpdmF0ZSBiYXNlITogUGFnZUNvbnRyb2xsZXI7XG5cblx0Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0Ly8gUHVibGljIG1ldGhvZHNcblx0Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuXHRwcml2YXRlIGZuRGlydHlTdGF0ZVByb3ZpZGVyPzogRnVuY3Rpb247XG5cdHByaXZhdGUgZm5IYW5kbGVTZXNzaW9uVGltZW91dD86IEZ1bmN0aW9uO1xuXHRwcml2YXRlIG1QYXRjaFByb21pc2VzPzogYW55O1xuXHRwcml2YXRlIF9mblN0aWNreURpc2NhcmRBZnRlck5hdmlnYXRpb24/OiBGdW5jdGlvbjtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIGRyYWZ0IGRvY3VtZW50IGZvciBhbiBleGlzdGluZyBhY3RpdmUgZG9jdW1lbnQuXG5cdCAqXG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5jb250cm9sbGVyZXh0ZW5zaW9ucy5FZGl0Rmxvd1xuXHQgKiBAcGFyYW0ge29iamVjdH0gb0NvbnRleHQgQ29udGV4dCBvZiB0aGUgYWN0aXZlIGRvY3VtZW50XG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHJlc29sdmVzIG9uY2UgdGhlIGVkaXRhYmxlIGRvY3VtZW50IGlzIGF2YWlsYWJsZVxuXHQgKiBAYWxpYXMgc2FwLmZlLmNvcmUuY29udHJvbGxlcmV4dGVuc2lvbnMuRWRpdEZsb3cjZWRpdERvY3VtZW50XG5cdCAqIEBwdWJsaWNcblx0ICogQHNpbmNlIDEuOTAuMFxuXHQgKi9cblx0QFB1YmxpY1xuXHRARmluYWxcblx0ZWRpdERvY3VtZW50KG9Db250ZXh0OiBDb250ZXh0KTogUHJvbWlzZTxhbnk+IHtcblx0XHRjb25zdCBiRHJhZnROYXZpZ2F0aW9uID0gdHJ1ZTtcblx0XHRjb25zdCB0cmFuc2FjdGlvbkhlbHBlciA9IHRoaXMuX2dldFRyYW5zYWN0aW9uSGVscGVyKCk7XG5cblx0XHRyZXR1cm4gdGhpcy5iYXNlLmVkaXRGbG93XG5cdFx0XHQub25CZWZvcmVFZGl0KHsgY29udGV4dDogb0NvbnRleHQgfSlcblx0XHRcdC50aGVuKHRyYW5zYWN0aW9uSGVscGVyLmVkaXREb2N1bWVudC5iaW5kKHRyYW5zYWN0aW9uSGVscGVyLCBvQ29udGV4dCwgdGhpcy5nZXRWaWV3KCksIHRoaXMuX2dldE1lc3NhZ2VIYW5kbGVyKCkpKVxuXHRcdFx0LnRoZW4oKG9OZXdEb2N1bWVudENvbnRleHQ6IGFueSkgPT4ge1xuXHRcdFx0XHRjb25zdCBzUHJvZ3JhbW1pbmdNb2RlbCA9IHRoaXMuX2dldFByb2dyYW1taW5nTW9kZWwob0NvbnRleHQpO1xuXG5cdFx0XHRcdGlmIChzUHJvZ3JhbW1pbmdNb2RlbCA9PT0gUHJvZ3JhbW1pbmdNb2RlbC5TdGlja3kpIHtcblx0XHRcdFx0XHR0aGlzLl9nZXRJbnRlcm5hbE1vZGVsKCkuc2V0UHJvcGVydHkoXCIvc2Vzc2lvbk9uXCIsIHRydWUpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChvTmV3RG9jdW1lbnRDb250ZXh0KSB7XG5cdFx0XHRcdFx0dGhpcy5fc2V0RWRpdE1vZGUoRWRpdE1vZGUuRWRpdGFibGUsIGZhbHNlKTtcblx0XHRcdFx0XHR0aGlzLl9nZXRNZXNzYWdlSGFuZGxlcigpLnNob3dNZXNzYWdlRGlhbG9nKCk7XG5cblx0XHRcdFx0XHRpZiAob05ld0RvY3VtZW50Q29udGV4dCAhPT0gb0NvbnRleHQpIHtcblx0XHRcdFx0XHRcdHJldHVybiB0aGlzLl9oYW5kbGVOZXdDb250ZXh0KG9OZXdEb2N1bWVudENvbnRleHQsIHRydWUsIGZhbHNlLCBiRHJhZnROYXZpZ2F0aW9uLCB0cnVlKS50aGVuKCgpID0+IHtcblx0XHRcdFx0XHRcdFx0aWYgKHNQcm9ncmFtbWluZ01vZGVsID09PSBQcm9ncmFtbWluZ01vZGVsLlN0aWNreSkge1xuXHRcdFx0XHRcdFx0XHRcdC8vIFRoZSBzdGlja3lPbiBoYW5kbGVyIG11c3QgYmUgc2V0IGFmdGVyIHRoZSBuYXZpZ2F0aW9uIGhhcyBiZWVuIGRvbmUsXG5cdFx0XHRcdFx0XHRcdFx0Ly8gYXMgdGhlIFVSTCBtYXkgY2hhbmdlIGluIHRoZSBjYXNlIG9mIEZDTFxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuX2hhbmRsZVN0aWNreU9uKG9OZXdEb2N1bWVudENvbnRleHQpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cdFx0XHQuY2F0Y2goZnVuY3Rpb24ob0Vycm9yOiBhbnkpIHtcblx0XHRcdFx0TG9nLmVycm9yKFwiRXJyb3Igd2hpbGUgZWRpdGluZyB0aGUgZG9jdW1lbnRcIiwgb0Vycm9yKTtcblx0XHRcdH0pO1xuXHR9XG5cdEBQdWJsaWNcblx0QEZpbmFsXG5cdGRlbGV0ZU11bHRpcGxlRG9jdW1lbnRzKGFDb250ZXh0czogYW55LCBtUGFyYW1ldGVyczogYW55KSB7XG5cdFx0aWYgKG1QYXJhbWV0ZXJzKSB7XG5cdFx0XHRtUGFyYW1ldGVycy5iZWZvcmVEZWxldGVDYWxsQmFjayA9IHRoaXMuYmFzZS5lZGl0Rmxvdy5vbkJlZm9yZURlbGV0ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bVBhcmFtZXRlcnMgPSB7XG5cdFx0XHRcdGJlZm9yZURlbGV0ZUNhbGxCYWNrOiB0aGlzLmJhc2UuZWRpdEZsb3cub25CZWZvcmVEZWxldGVcblx0XHRcdH07XG5cdFx0fVxuXHRcdHJldHVybiAodGhpcy5iYXNlLmdldFZpZXcoKS5nZXRDb250cm9sbGVyKCkgYXMgUGFnZUNvbnRyb2xsZXIpLl9lZGl0Rmxvdy5kZWxldGVNdWx0aXBsZURvY3VtZW50cyhhQ29udGV4dHMsIG1QYXJhbWV0ZXJzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBVcGRhdGVzIHRoZSBkcmFmdCBzdGF0dXMgYW5kIGRpc3BsYXlzIHRoZSBlcnJvciBtZXNzYWdlcyBpZiB0aGVyZSBhcmUgZXJyb3JzIGR1cmluZyBhbiB1cGRhdGUuXG5cdCAqXG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5jb250cm9sbGVyZXh0ZW5zaW9ucy5FZGl0Rmxvd1xuXHQgKiBAcGFyYW0ge29iamVjdH0gb0NvbnRleHQgQ29udGV4dCBvZiB0aGUgdXBkYXRlZCBmaWVsZFxuXHQgKiBAcGFyYW0ge29iamVjdH0gb1Byb21pc2UgUHJvbWlzZSB0byBkZXRlcm1pbmUgd2hlbiB0aGUgdXBkYXRlIG9wZXJhdGlvbiBpcyBjb21wbGV0ZWQuIFRoZSBwcm9taXNlIHNob3VsZCBiZSByZXNvbHZlZCB3aGVuIHRoZSB1cGRhdGUgb3BlcmF0aW9uIGlzIGNvbXBsZXRlZCwgc28gdGhlIGRyYWZ0IHN0YXR1cyBjYW4gYmUgdXBkYXRlZC5cblx0ICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgcmVzb2x2ZXMgb25jZSBkcmFmdCBzdGF0dXMgaGFzIGJlZW4gdXBkYXRlZFxuXHQgKiBAYWxpYXMgc2FwLmZlLmNvcmUuY29udHJvbGxlcmV4dGVuc2lvbnMuRWRpdEZsb3cjdXBkYXRlRG9jdW1lbnRcblx0ICogQHB1YmxpY1xuXHQgKiBAc2luY2UgMS45MC4wXG5cdCAqL1xuXHRAUHVibGljXG5cdEBGaW5hbFxuXHR1cGRhdGVEb2N1bWVudChvQ29udGV4dDogb2JqZWN0LCBvUHJvbWlzZTogUHJvbWlzZTxhbnk+KTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Y29uc3QgdHJhbnNhY3Rpb25IZWxwZXIgPSB0aGlzLl9nZXRUcmFuc2FjdGlvbkhlbHBlcigpLFxuXHRcdFx0b0JpbmRpbmdDb250ZXh0ID0gdGhpcy5nZXRWaWV3KCkuZ2V0QmluZGluZ0NvbnRleHQoKSxcblx0XHRcdGJJc0RyYWZ0ID0gdGhpcy5fZ2V0UHJvZ3JhbW1pbmdNb2RlbChvQ29udGV4dCkgPT09IFByb2dyYW1taW5nTW9kZWwuRHJhZnQ7XG5cblx0XHR0aGlzLl9nZXRNZXNzYWdlSGFuZGxlcigpLnJlbW92ZVRyYW5zaXRpb25NZXNzYWdlcygpO1xuXHRcdHJldHVybiB0aGlzLl9zeW5jVGFzaygoKSA9PiB7XG5cdFx0XHRpZiAob0JpbmRpbmdDb250ZXh0KSB7XG5cdFx0XHRcdHRyYW5zYWN0aW9uSGVscGVyLmhhbmRsZURvY3VtZW50TW9kaWZpY2F0aW9ucygpO1xuXHRcdFx0XHRFZGl0U3RhdGUuc2V0RWRpdFN0YXRlRGlydHkoKTtcblxuXHRcdFx0XHRpZiAoYklzRHJhZnQpIHtcblx0XHRcdFx0XHR0aGlzLl9zZXREcmFmdFN0YXR1cyhEcmFmdFN0YXR1cy5TYXZpbmcpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHR0aGlzLl9nZXRNZXNzYWdlSGFuZGxlcigpLnJlbW92ZVRyYW5zaXRpb25NZXNzYWdlcygpO1xuXG5cdFx0XHRyZXR1cm4gb1Byb21pc2Vcblx0XHRcdFx0LnRoZW4oXG5cdFx0XHRcdFx0KCkgPT4ge1xuXHRcdFx0XHRcdFx0aWYgKGJJc0RyYWZ0ICYmIG9CaW5kaW5nQ29udGV4dCkge1xuXHRcdFx0XHRcdFx0XHRjb25zdCBvTWV0YU1vZGVsID0gb0JpbmRpbmdDb250ZXh0LmdldE1vZGVsKCkuZ2V0TWV0YU1vZGVsKCkgYXMgT0RhdGFNZXRhTW9kZWwsXG5cdFx0XHRcdFx0XHRcdFx0c0VudGl0eVNldE5hbWUgPSAob01ldGFNb2RlbCBhcyBhbnkpLmdldE1ldGFDb250ZXh0KG9CaW5kaW5nQ29udGV4dC5nZXRQYXRoKCkpLmdldE9iamVjdChcIkBzYXB1aS5uYW1lXCIpLFxuXHRcdFx0XHRcdFx0XHRcdGFTZW1hbnRpY0tleXMgPSBTZW1hbnRpY0tleUhlbHBlci5nZXRTZW1hbnRpY0tleXMob01ldGFNb2RlbCwgc0VudGl0eVNldE5hbWUpO1xuXHRcdFx0XHRcdFx0XHRpZiAoYVNlbWFudGljS2V5cyAmJiBhU2VtYW50aWNLZXlzLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IG9DdXJyZW50U2VtYW50aWNNYXBwaW5nID0gKHRoaXMuYmFzZS5nZXRBcHBDb21wb25lbnQoKSBhcyBhbnkpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5nZXRSb3V0aW5nU2VydmljZSgpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5nZXRMYXN0U2VtYW50aWNNYXBwaW5nKCksXG5cdFx0XHRcdFx0XHRcdFx0XHRzQ3VycmVudFNlbWFudGljUGF0aCA9IG9DdXJyZW50U2VtYW50aWNNYXBwaW5nICYmIG9DdXJyZW50U2VtYW50aWNNYXBwaW5nLnNlbWFudGljUGF0aCxcblx0XHRcdFx0XHRcdFx0XHRcdHNDaGFuZ2VkUGF0aCA9IFNlbWFudGljS2V5SGVscGVyLmdldFNlbWFudGljUGF0aChvQmluZGluZ0NvbnRleHQsIHRydWUpO1xuXG5cdFx0XHRcdFx0XHRcdFx0aWYgKHNDdXJyZW50U2VtYW50aWNQYXRoICE9PSBzQ2hhbmdlZFBhdGgpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiB0aGlzLl9oYW5kbGVOZXdDb250ZXh0KG9CaW5kaW5nQ29udGV4dCwgdHJ1ZSwgZmFsc2UsIHRydWUpLnRoZW4oKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0aGlzLl9zZXREcmFmdFN0YXR1cyhEcmFmdFN0YXR1cy5TYXZlZCk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5fc2V0RHJhZnRTdGF0dXMoRHJhZnRTdGF0dXMuU2F2ZWQpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLl9zZXREcmFmdFN0YXR1cyhEcmFmdFN0YXR1cy5TYXZlZCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdCgpID0+IHtcblx0XHRcdFx0XHRcdGlmIChiSXNEcmFmdCAmJiBvQmluZGluZ0NvbnRleHQpIHtcblx0XHRcdFx0XHRcdFx0dGhpcy5fc2V0RHJhZnRTdGF0dXMoRHJhZnRTdGF0dXMuQ2xlYXIpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0KVxuXHRcdFx0XHQuY2F0Y2goZnVuY3Rpb24ob0Vycm9yOiBhbnkpIHtcblx0XHRcdFx0XHRMb2cuZXJyb3IoXCJFcnJvciB3aGlsZSB1cGRhdGluZyB0aGUgZG9jdW1lbnRcIiwgb0Vycm9yKTtcblx0XHRcdFx0fSlcblx0XHRcdFx0LmZpbmFsbHkoKCkgPT4ge1xuXHRcdFx0XHRcdHRoaXMuX2dldE1lc3NhZ2VIYW5kbGVyKCkuc2hvd01lc3NhZ2VzKCk7XG5cdFx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9XG5cblx0Ly8gSW50ZXJuYWwgb25seSBwYXJhbXMgLS0tXG5cdC8vICogQHBhcmFtIHtzdHJpbmd9IG1QYXJhbWV0ZXJzLmNyZWF0aW9uTW9kZSBUaGUgY3JlYXRpb24gbW9kZSB1c2luZyBvbmUgb2YgdGhlIGZvbGxvd2luZzpcblx0Ly8gKiAgICAgICAgICAgICAgICAgICAgU3luYyAtIHRoZSBjcmVhdGlvbiBpcyB0cmlnZ2VyZWQgYW5kIG9uY2UgdGhlIGRvY3VtZW50IGlzIGNyZWF0ZWQsIHRoZSBuYXZpZ2F0aW9uIGlzIGRvbmVcblx0Ly8gKiAgICAgICAgICAgICAgICAgICAgQXN5bmMgLSB0aGUgY3JlYXRpb24gYW5kIHRoZSBuYXZpZ2F0aW9uIHRvIHRoZSBpbnN0YW5jZSBhcmUgZG9uZSBpbiBwYXJhbGxlbFxuXHQvLyAqICAgICAgICAgICAgICAgICAgICBEZWZlcnJlZCAtIHRoZSBjcmVhdGlvbiBpcyBkb25lIG9uIHRoZSB0YXJnZXQgcGFnZVxuXHQvLyAqICAgICAgICAgICAgICAgICAgICBDcmVhdGlvblJvdyAtIFRoZSBjcmVhdGlvbiBpcyBkb25lIGlubGluZSBhc3luYyBzbyB0aGUgdXNlciBpcyBub3QgYmxvY2tlZFxuXHQvLyBtUGFyYW1ldGVycy5jcmVhdGlvblJvdyBJbnN0YW5jZSBvZiB0aGUgY3JlYXRpb24gcm93IC0gKFRPRE86IGdldCByaWQgYnV0IHVzZSBsaXN0IGJpbmRpbmdzIG9ubHkpXG5cblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtcGFyYW1cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgZG9jdW1lbnQuXG5cdCAqXG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5jb250cm9sbGVyZXh0ZW5zaW9ucy5FZGl0Rmxvd1xuXHQgKiBAcGFyYW0ge3NhcC51aS5tb2RlbC5vZGF0YS52NC5PRGF0YUxpc3RCaW5kaW5nfHN0cmluZ30gdkxpc3RCaW5kaW5nICBPRGF0YUxpc3RCaW5kaW5nIG9iamVjdCBvciB0aGUgYmluZGluZyBwYXRoIGZvciBhIHRlbXBvcmFyeSBsaXN0IGJpbmRpbmdcblx0ICogQHBhcmFtIHttYXB9IG1JblBhcmFtZXRlcnMgQ29udGFpbnMgdGhlIGZvbGxvd2luZyBhdHRyaWJ1dGVzOlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbUluUGFyYW1ldGVycy5jcmVhdGlvbk1vZGUgVGhlIGNyZWF0aW9uIG1vZGUgdXNpbmcgb25lIG9mIHRoZSBmb2xsb3dpbmc6XG5cdCAqICAgICAgICAgICAgICAgICAgICBOZXdQYWdlIC0gdGhlIGNyZWF0ZWQgZG9jdW1lbnQgaXMgc2hvd24gaW4gYSBuZXcgcGFnZSwgZGVwZW5kaW5nIG9uIHdoZXRoZXIgbWV0YWRhdGEgJ1N5bmMnLCAnQXN5bmMnIG9yICdEZWZlcnJlZCcgaXMgdXNlZFxuXHQgKiAgICAgICAgICAgICAgICAgICAgSW5saW5lIC0gVGhlIGNyZWF0aW9uIGlzIGRvbmUgaW5saW5lIChpbiBhIHRhYmxlKVxuXHQgKiAgICAgICAgICAgICAgICAgICAgRXh0ZXJuYWwgLSBUaGUgY3JlYXRpb24gaXMgZG9uZSBpbiBhIGRpZmZlcmVudCBhcHBsaWNhdGlvbiBzcGVjaWZpZWQgdmlhIHRoZSBwYXJhbWV0ZXIgJ291dGJvdW5kJ1xuXHQgKiBAcGFyYW0ge3N0cmluZ30gbUluUGFyYW1ldGVycy5vdXRib3VuZCBUaGUgbmF2aWdhdGlvbiB0YXJnZXQgd2hlcmUgdGhlIGRvY3VtZW50IGlzIGNyZWF0ZWQgaW4gY2FzZSBvZiBjcmVhdGlvbk1vZGUgJ0V4dGVybmFsJ1xuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IG1JblBhcmFtZXRlcnMuY3JlYXRlQXRFbmQgU3BlY2lmaWVzIGlmIHRoZSBuZXcgZW50cnkgc2hvdWxkIGJlIGNyZWF0ZWQgYXQgdGhlIHRvcCBvciBib3R0b20gb2YgYSB0YWJsZSBpbiBjYXNlIG9mIGNyZWF0aW9uTW9kZSAnSW5saW5lJ1xuXHQgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSByZXNvbHZlcyBvbmNlIHRoZSBvYmplY3QgaGFzIGJlZW4gY3JlYXRlZFxuXHQgKiBAYWxpYXMgc2FwLmZlLmNvcmUuY29udHJvbGxlcmV4dGVuc2lvbnMuRWRpdEZsb3cjY3JlYXRlRG9jdW1lbnRcblx0ICogQHB1YmxpY1xuXHQgKiBAc2luY2UgMS45MC4wXG5cdCAqL1xuXHRAUHVibGljXG5cdEBGaW5hbFxuXHRjcmVhdGVEb2N1bWVudChcblx0XHR2TGlzdEJpbmRpbmc6IE9EYXRhTGlzdEJpbmRpbmcgfCBzdHJpbmcsXG5cdFx0bUluUGFyYW1ldGVyczoge1xuXHRcdFx0Y3JlYXRpb25Nb2RlOiBzdHJpbmc7XG5cdFx0XHRvdXRib3VuZD86IHN0cmluZztcblx0XHRcdGNyZWF0ZUF0RW5kPzogYm9vbGVhbjtcblx0XHR9XG5cdCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IHRyYW5zYWN0aW9uSGVscGVyID0gdGhpcy5fZ2V0VHJhbnNhY3Rpb25IZWxwZXIoKSxcblx0XHRcdG9Mb2NrT2JqZWN0ID0gdGhpcy5fZ2V0R2xvYmFsVUlNb2RlbCgpO1xuXHRcdGxldCBvVGFibGU6IFRhYmxlO1xuXHRcdGxldCBpQ291bnRUYWJsZUl0ZW1zID0gMDtcblx0XHRsZXQgbVBhcmFtZXRlcnM6IGFueSA9IG1JblBhcmFtZXRlcnM7XG5cdFx0Y29uc3Qgb1Jlc291cmNlQnVuZGxlID0gKHRoaXMuZ2V0VmlldygpLmdldENvbnRyb2xsZXIoKSBhcyBhbnkpLm9SZXNvdXJjZUJ1bmRsZTtcblx0XHRjb25zdCBiU2hvdWxkQnVzeUxvY2sgPVxuXHRcdFx0IW1QYXJhbWV0ZXJzIHx8XG5cdFx0XHQobVBhcmFtZXRlcnMuY3JlYXRpb25Nb2RlICE9PSBDcmVhdGlvbk1vZGUuSW5saW5lICYmXG5cdFx0XHRcdG1QYXJhbWV0ZXJzLmNyZWF0aW9uTW9kZSAhPT0gQ3JlYXRpb25Nb2RlLkNyZWF0aW9uUm93ICYmXG5cdFx0XHRcdG1QYXJhbWV0ZXJzLmNyZWF0aW9uTW9kZSAhPT0gQ3JlYXRpb25Nb2RlLkV4dGVybmFsKTtcblx0XHRsZXQgb0V4ZWNDdXN0b21WYWxpZGF0aW9uID0gUHJvbWlzZS5yZXNvbHZlKFtdKTtcblx0XHRjb25zdCBvQXBwQ29tcG9uZW50ID0gQ29tbW9uVXRpbHMuZ2V0QXBwQ29tcG9uZW50KHRoaXMuZ2V0VmlldygpKTtcblx0XHRvQXBwQ29tcG9uZW50LmdldFJvdXRlclByb3h5KCkucmVtb3ZlSUFwcFN0YXRlS2V5KCk7XG5cblx0XHRpZiAobVBhcmFtZXRlcnMuY3JlYXRpb25Nb2RlID09PSBDcmVhdGlvbk1vZGUuRXh0ZXJuYWwpIHtcblx0XHRcdC8vIENyZWF0ZSBieSBuYXZpZ2F0aW5nIHRvIGFuIGV4dGVybmFsIHRhcmdldFxuXHRcdFx0Ly8gVE9ETzogQ2FsbCBhcHByb3ByaWF0ZSBmdW5jdGlvbiAoY3VycmVudGx5IHVzaW5nIHRoZSBzYW1lIGFzIGZvciBvdXRib3VuZCBjaGV2cm9uIG5hdiwgYW5kIHdpdGhvdXQgYW55IGNvbnRleHQgLSAzcmQgcGFyYW0pXG5cdFx0XHRyZXR1cm4gdGhpcy5fc3luY1Rhc2soKS50aGVuKCgpID0+IHtcblx0XHRcdFx0Y29uc3Qgb0NvbnRyb2xsZXIgPSB0aGlzLmdldFZpZXcoKS5nZXRDb250cm9sbGVyKCksXG5cdFx0XHRcdFx0c0NyZWF0ZVBhdGggPSBNb2RlbEhlbHBlci5nZXRBYnNvbHV0ZU1ldGFQYXRoRm9yTGlzdEJpbmRpbmcodGhpcy5nZXRWaWV3KCksIHZMaXN0QmluZGluZyk7XG5cblx0XHRcdFx0KG9Db250cm9sbGVyIGFzIGFueSkuaGFuZGxlcnMub25DaGV2cm9uUHJlc3NOYXZpZ2F0ZU91dEJvdW5kKG9Db250cm9sbGVyLCBtUGFyYW1ldGVycy5vdXRib3VuZCwgdW5kZWZpbmVkLCBzQ3JlYXRlUGF0aCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRpZiAobVBhcmFtZXRlcnMuY3JlYXRpb25Nb2RlID09PSBDcmVhdGlvbk1vZGUuQ3JlYXRpb25Sb3cgJiYgbVBhcmFtZXRlcnMuY3JlYXRpb25Sb3cpIHtcblx0XHRcdGNvbnN0IG9DcmVhdGlvblJvd09iamVjdHMgPSBtUGFyYW1ldGVycy5jcmVhdGlvblJvdy5nZXRCaW5kaW5nQ29udGV4dCgpLmdldE9iamVjdCgpO1xuXHRcdFx0ZGVsZXRlIG9DcmVhdGlvblJvd09iamVjdHNbXCJAJHVpNS5jb250ZXh0LmlzVHJhbnNpZW50XCJdO1xuXHRcdFx0b1RhYmxlID0gbVBhcmFtZXRlcnMuY3JlYXRpb25Sb3cuZ2V0UGFyZW50KCk7XG5cdFx0XHRvRXhlY0N1c3RvbVZhbGlkYXRpb24gPSB0cmFuc2FjdGlvbkhlbHBlci52YWxpZGF0ZURvY3VtZW50KFxuXHRcdFx0XHRvVGFibGUuZ2V0QmluZGluZ0NvbnRleHQoKSxcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGRhdGE6IG9DcmVhdGlvblJvd09iamVjdHMsXG5cdFx0XHRcdFx0Y3VzdG9tVmFsaWRhdGlvbkZ1bmN0aW9uOiAob1RhYmxlLmdldENyZWF0aW9uUm93KCkgYXMgYW55KS5kYXRhKFwiY3VzdG9tVmFsaWRhdGlvbkZ1bmN0aW9uXCIpXG5cdFx0XHRcdH0sXG5cdFx0XHRcdHRoaXMuYmFzZS5nZXRWaWV3KClcblx0XHRcdCk7XG5cblx0XHRcdC8vIGRpc2FibGVBZGRSb3dCdXR0b25Gb3JFbXB0eURhdGEgaXMgc2V0IHRvIGZhbHNlIGluIG1hbmlmZXN0IGNvbnZlcnRlciAoVGFibGUudHMpIGlmIGN1c3RvbVZhbGlkYXRpb25GdW5jdGlvbiBleGlzdHNcblx0XHRcdGlmICgob1RhYmxlLmdldENyZWF0aW9uUm93KCkgYXMgYW55KS5kYXRhKFwiZGlzYWJsZUFkZFJvd0J1dHRvbkZvckVtcHR5RGF0YVwiKSA9PT0gXCJ0cnVlXCIpIHtcblx0XHRcdFx0Y29uc3Qgb0ludGVybmFsTW9kZWxDb250ZXh0ID0gb1RhYmxlLmdldEJpbmRpbmdDb250ZXh0KFwiaW50ZXJuYWxcIikgYXMgSW50ZXJuYWxNb2RlbENvbnRleHQ7XG5cdFx0XHRcdG9JbnRlcm5hbE1vZGVsQ29udGV4dC5zZXRQcm9wZXJ0eShcImNyZWF0aW9uUm93RmllbGRWYWxpZGl0eVwiLCB7fSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKG1QYXJhbWV0ZXJzLmNyZWF0aW9uTW9kZSA9PT0gQ3JlYXRpb25Nb2RlLklubGluZSAmJiBtUGFyYW1ldGVycy50YWJsZUlkKSB7XG5cdFx0XHRvVGFibGUgPSB0aGlzLmdldFZpZXcoKS5ieUlkKG1QYXJhbWV0ZXJzLnRhYmxlSWQpIGFzIFRhYmxlO1xuXHRcdH1cblxuXHRcdC8qKlxuXHRcdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0Lk9EYXRhTGlzdEJpbmRpbmd9IG9MaXN0QmluZGluZ1xuXHRcdCAqIEBwYXJhbSB7b2JqZWN0fSBvQ3JlYXRpb25Qcm9taXNlXG5cdFx0ICovXG5cdFx0Y29uc3QgaGFuZGxlU2lkZUVmZmVjdHMgPSAob0xpc3RCaW5kaW5nOiBhbnksIG9DcmVhdGlvblByb21pc2U6IFByb21pc2U8Q29udGV4dD4pID0+IHtcblx0XHRcdG9DcmVhdGlvblByb21pc2Vcblx0XHRcdFx0LnRoZW4oZnVuY3Rpb24ob05ld0NvbnRleHQ6IGFueSkge1xuXHRcdFx0XHRcdC8vIHRyYW5zaWVudCBjb250ZXh0cyBhcmUgcmVsaWFibHkgcmVtb3ZlZCBvbmNlIG9OZXdDb250ZXh0LmNyZWF0ZWQoKSBpcyByZXNvbHZlZFxuXHRcdFx0XHRcdHJldHVybiBvTmV3Q29udGV4dC5jcmVhdGVkKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0XHRjb25zdCBvQmluZGluZ0NvbnRleHQgPSB0aGlzLmdldFZpZXcoKS5nZXRCaW5kaW5nQ29udGV4dCgpIGFzIENvbnRleHQ7XG5cdFx0XHRcdFx0Ly8gaWYgdGhlcmUgYXJlIHRyYW5zaWVudCBjb250ZXh0cywgd2UgbXVzdCBhdm9pZCByZXF1ZXN0aW5nIHNpZGUgZWZmZWN0c1xuXHRcdFx0XHRcdC8vIHRoaXMgaXMgYXZvaWQgYSBwb3RlbnRpYWwgbGlzdCByZWZyZXNoLCB0aGVyZSBjb3VsZCBiZSBhIHNpZGUgZWZmZWN0IHRoYXQgcmVmcmVzaGVzIHRoZSBsaXN0IGJpbmRpbmdcblx0XHRcdFx0XHQvLyBpZiBsaXN0IGJpbmRpbmcgaXMgcmVmcmVzaGVkLCB0cmFuc2llbnQgY29udGV4dHMgbWlnaHQgYmUgbG9zdFxuXHRcdFx0XHRcdGlmICghQ29tbW9uVXRpbHMuaGFzVHJhbnNpZW50Q29udGV4dChvTGlzdEJpbmRpbmcpKSB7XG5cdFx0XHRcdFx0XHRjb25zdCBvQXBwQ29tcG9uZW50ID0gQ29tbW9uVXRpbHMuZ2V0QXBwQ29tcG9uZW50KHRoaXMuZ2V0VmlldygpKTtcblx0XHRcdFx0XHRcdG9BcHBDb21wb25lbnRcblx0XHRcdFx0XHRcdFx0LmdldFNpZGVFZmZlY3RzU2VydmljZSgpXG5cdFx0XHRcdFx0XHRcdC5yZXF1ZXN0U2lkZUVmZmVjdHNGb3JOYXZpZ2F0aW9uUHJvcGVydHkob0xpc3RCaW5kaW5nLmdldFBhdGgoKSwgb0JpbmRpbmdDb250ZXh0KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5jYXRjaChmdW5jdGlvbihvRXJyb3I6IGFueSkge1xuXHRcdFx0XHRcdExvZy5lcnJvcihcIkVycm9yIHdoaWxlIGNyZWF0aW5nIHRoZSBkb2N1bWVudFwiLCBvRXJyb3IpO1xuXHRcdFx0XHR9KTtcblx0XHR9O1xuXG5cdFx0LyoqXG5cdFx0ICogQHBhcmFtIHtBcnJheX0gYVZhbGlkYXRpb25NZXNzYWdlcyBFcnJvciBtZXNzYWdlcyBmcm9tIGN1c3RvbSB2YWxpZGF0aW9uIGZ1bmN0aW9uXG5cdFx0ICovXG5cdFx0Y29uc3QgY3JlYXRlQ3VzdG9tVmFsaWRhdGlvbk1lc3NhZ2VzID0gKGFWYWxpZGF0aW9uTWVzc2FnZXM6IGFueVtdKSA9PiB7XG5cdFx0XHRjb25zdCBzQ3VzdG9tVmFsaWRhdGlvbkZ1bmN0aW9uID0gb1RhYmxlICYmIChvVGFibGUuZ2V0Q3JlYXRpb25Sb3coKSBhcyBhbnkpLmRhdGEoXCJjdXN0b21WYWxpZGF0aW9uRnVuY3Rpb25cIik7XG5cdFx0XHRjb25zdCBtQ3VzdG9tVmFsaWRpdHkgPSBvVGFibGUgJiYgb1RhYmxlLmdldEJpbmRpbmdDb250ZXh0KFwiaW50ZXJuYWxcIik/LmdldFByb3BlcnR5KFwiY3JlYXRpb25Sb3dDdXN0b21WYWxpZGl0eVwiKTtcblx0XHRcdGNvbnN0IG9NZXNzYWdlTWFuYWdlciA9IHNhcC51aS5nZXRDb3JlKCkuZ2V0TWVzc2FnZU1hbmFnZXIoKTtcblx0XHRcdGNvbnN0IGFDdXN0b21NZXNzYWdlczogYW55W10gPSBbXTtcblx0XHRcdGxldCBvRmllbGRDb250cm9sO1xuXHRcdFx0bGV0IHNUYXJnZXQ6IHN0cmluZztcblxuXHRcdFx0Ly8gUmVtb3ZlIGV4aXN0aW5nIEN1c3RvbVZhbGlkYXRpb24gbWVzc2FnZVxuXHRcdFx0b01lc3NhZ2VNYW5hZ2VyXG5cdFx0XHRcdC5nZXRNZXNzYWdlTW9kZWwoKVxuXHRcdFx0XHQuZ2V0RGF0YSgpXG5cdFx0XHRcdC5mb3JFYWNoKGZ1bmN0aW9uKG9NZXNzYWdlOiBhbnkpIHtcblx0XHRcdFx0XHRpZiAob01lc3NhZ2UuY29kZSA9PT0gc0N1c3RvbVZhbGlkYXRpb25GdW5jdGlvbikge1xuXHRcdFx0XHRcdFx0b01lc3NhZ2VNYW5hZ2VyLnJlbW92ZU1lc3NhZ2VzKG9NZXNzYWdlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXG5cdFx0XHRhVmFsaWRhdGlvbk1lc3NhZ2VzLmZvckVhY2goKG9WYWxpZGF0aW9uTWVzc2FnZTogYW55KSA9PiB7XG5cdFx0XHRcdC8vIEhhbmRsZSBCb3VuZCBDdXN0b21WYWxpZGF0aW9uIG1lc3NhZ2Vcblx0XHRcdFx0aWYgKG9WYWxpZGF0aW9uTWVzc2FnZS5tZXNzYWdlVGFyZ2V0KSB7XG5cdFx0XHRcdFx0b0ZpZWxkQ29udHJvbCA9IHNhcC51aS5nZXRDb3JlKCkuZ2V0Q29udHJvbChtQ3VzdG9tVmFsaWRpdHlbb1ZhbGlkYXRpb25NZXNzYWdlLm1lc3NhZ2VUYXJnZXRdLmZpZWxkSWQpIGFzIENvbnRyb2w7XG5cdFx0XHRcdFx0c1RhcmdldCA9IG9GaWVsZENvbnRyb2wuZ2V0QmluZGluZ0NvbnRleHQoKT8uZ2V0UGF0aCgpICsgXCIvXCIgKyBvRmllbGRDb250cm9sLmdldEJpbmRpbmdQYXRoKFwidmFsdWVcIik7XG5cdFx0XHRcdFx0Ly8gQWRkIHZhbGlkYXRpb24gbWVzc2FnZSBpZiBzdGlsbCBub3QgZXhpc3RzXG5cdFx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdFx0b01lc3NhZ2VNYW5hZ2VyXG5cdFx0XHRcdFx0XHRcdC5nZXRNZXNzYWdlTW9kZWwoKVxuXHRcdFx0XHRcdFx0XHQuZ2V0RGF0YSgpXG5cdFx0XHRcdFx0XHRcdC5maWx0ZXIoZnVuY3Rpb24ob01lc3NhZ2U6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiBvTWVzc2FnZS50YXJnZXQgPT09IHNUYXJnZXQ7XG5cdFx0XHRcdFx0XHRcdH0pLmxlbmd0aCA9PT0gMFxuXHRcdFx0XHRcdCkge1xuXHRcdFx0XHRcdFx0b01lc3NhZ2VNYW5hZ2VyLmFkZE1lc3NhZ2VzKFxuXHRcdFx0XHRcdFx0XHRuZXcgTWVzc2FnZSh7XG5cdFx0XHRcdFx0XHRcdFx0bWVzc2FnZTogb1ZhbGlkYXRpb25NZXNzYWdlLm1lc3NhZ2VUZXh0LFxuXHRcdFx0XHRcdFx0XHRcdHByb2Nlc3NvcjogdGhpcy5nZXRWaWV3KCkuZ2V0TW9kZWwoKSxcblx0XHRcdFx0XHRcdFx0XHR0eXBlOiBNZXNzYWdlVHlwZS5FcnJvcixcblx0XHRcdFx0XHRcdFx0XHRjb2RlOiBzQ3VzdG9tVmFsaWRhdGlvbkZ1bmN0aW9uLFxuXHRcdFx0XHRcdFx0XHRcdHRlY2huaWNhbDogZmFsc2UsXG5cdFx0XHRcdFx0XHRcdFx0cGVyc2lzdGVudDogZmFsc2UsXG5cdFx0XHRcdFx0XHRcdFx0dGFyZ2V0OiBzVGFyZ2V0XG5cdFx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHQvLyBBZGQgY29udHJvbElkIGluIG9yZGVyIHRvIGdldCB0aGUgZm9jdXMgaGFuZGxpbmcgb2YgdGhlIGVycm9yIHBvcG92ZXIgcnVuYWJsZVxuXHRcdFx0XHRcdGNvbnN0IGFFeGlzdGluZ1ZhbGlkYXRpb25NZXNzYWdlcyA9IG9NZXNzYWdlTWFuYWdlclxuXHRcdFx0XHRcdFx0LmdldE1lc3NhZ2VNb2RlbCgpXG5cdFx0XHRcdFx0XHQuZ2V0RGF0YSgpXG5cdFx0XHRcdFx0XHQuZmlsdGVyKGZ1bmN0aW9uKG9NZXNzYWdlOiBhbnkpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIG9NZXNzYWdlLnRhcmdldCA9PT0gc1RhcmdldDtcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdGFFeGlzdGluZ1ZhbGlkYXRpb25NZXNzYWdlc1swXS5hZGRDb250cm9sSWQobUN1c3RvbVZhbGlkaXR5W29WYWxpZGF0aW9uTWVzc2FnZS5tZXNzYWdlVGFyZ2V0XS5maWVsZElkKTtcblxuXHRcdFx0XHRcdC8vIEhhbmRsZSBVbmJvdW5kIEN1c3RvbVZhbGlkYXRpb24gbWVzc2FnZVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGFDdXN0b21NZXNzYWdlcy5wdXNoKHtcblx0XHRcdFx0XHRcdGNvZGU6IHNDdXN0b21WYWxpZGF0aW9uRnVuY3Rpb24sXG5cdFx0XHRcdFx0XHR0ZXh0OiBvVmFsaWRhdGlvbk1lc3NhZ2UubWVzc2FnZVRleHQsXG5cdFx0XHRcdFx0XHRwZXJzaXN0ZW50OiB0cnVlLFxuXHRcdFx0XHRcdFx0dHlwZTogTWVzc2FnZVR5cGUuRXJyb3Jcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdGlmIChhQ3VzdG9tTWVzc2FnZXMubGVuZ3RoID4gMCkge1xuXHRcdFx0XHR0aGlzLl9nZXRNZXNzYWdlSGFuZGxlcigpLnNob3dNZXNzYWdlRGlhbG9nKHtcblx0XHRcdFx0XHRjdXN0b21NZXNzYWdlczogYUN1c3RvbU1lc3NhZ2VzXG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHRiU2hvdWxkQnVzeUxvY2sgJiYgQnVzeUxvY2tlci5sb2NrKG9Mb2NrT2JqZWN0KTtcblx0XHRyZXR1cm4gdGhpcy5fc3luY1Rhc2sob0V4ZWNDdXN0b21WYWxpZGF0aW9uKVxuXHRcdFx0LnRoZW4oKGFWYWxpZGF0aW9uTWVzc2FnZXM6IGFueSkgPT4ge1xuXHRcdFx0XHRpZiAoYVZhbGlkYXRpb25NZXNzYWdlcy5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdFx0Y3JlYXRlQ3VzdG9tVmFsaWRhdGlvbk1lc3NhZ2VzKGFWYWxpZGF0aW9uTWVzc2FnZXMpO1xuXHRcdFx0XHRcdExvZy5lcnJvcihcIkN1c3RvbSBWYWxpZGF0aW9uIGZhaWxlZFwiKTtcblx0XHRcdFx0XHQvLyBpZiBjdXN0b20gdmFsaWRhdGlvbiBmYWlscywgd2UgbGVhdmUgdGhlIG1ldGhvZCBpbW1lZGlhdGVseVxuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGxldCBzUHJvZ3JhbW1pbmdNb2RlbDogc3RyaW5nO1xuXHRcdFx0XHRsZXQgb0xpc3RCaW5kaW5nOiBhbnk7XG5cblx0XHRcdFx0bVBhcmFtZXRlcnMgPSBtUGFyYW1ldGVycyB8fCB7fTtcblxuXHRcdFx0XHRpZiAodkxpc3RCaW5kaW5nICYmIHR5cGVvZiB2TGlzdEJpbmRpbmcgPT09IFwib2JqZWN0XCIpIHtcblx0XHRcdFx0XHQvLyB3ZSBhbHJlYWR5IGdldCBhIGxpc3QgYmluZGluZyB1c2UgdGhpcyBvbmVcblx0XHRcdFx0XHRvTGlzdEJpbmRpbmcgPSB2TGlzdEJpbmRpbmc7XG5cdFx0XHRcdH0gZWxzZSBpZiAodHlwZW9mIHZMaXN0QmluZGluZyA9PT0gXCJzdHJpbmdcIikge1xuXHRcdFx0XHRcdG9MaXN0QmluZGluZyA9IG5ldyAoT0RhdGFMaXN0QmluZGluZyBhcyBhbnkpKHRoaXMuZ2V0VmlldygpLmdldE1vZGVsKCksIHZMaXN0QmluZGluZyk7XG5cdFx0XHRcdFx0bVBhcmFtZXRlcnMuY3JlYXRpb25Nb2RlID0gQ3JlYXRpb25Nb2RlLlN5bmM7XG5cdFx0XHRcdFx0ZGVsZXRlIG1QYXJhbWV0ZXJzLmNyZWF0ZUF0RW5kO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRocm93IG5ldyBFcnJvcihcIkJpbmRpbmcgb2JqZWN0IG9yIHBhdGggZXhwZWN0ZWRcIik7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRjb25zdCBvTW9kZWwgPSBvTGlzdEJpbmRpbmcuZ2V0TW9kZWwoKTtcblx0XHRcdFx0aUNvdW50VGFibGVJdGVtcyA9IG9MaXN0QmluZGluZy5pTWF4TGVuZ3RoIHx8IDA7XG5cdFx0XHRcdGNvbnN0IHNDcmVhdGlvbk1vZGUgPSBtUGFyYW1ldGVycy5jcmVhdGlvbk1vZGU7XG5cblx0XHRcdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLl9nZXRQcm9ncmFtbWluZ01vZGVsKG9MaXN0QmluZGluZykpXG5cdFx0XHRcdFx0LnRoZW4oKHByb2dyYW1taW5nTW9kZWw6IGFueSkgPT4ge1xuXHRcdFx0XHRcdFx0c1Byb2dyYW1taW5nTW9kZWwgPSBwcm9ncmFtbWluZ01vZGVsO1xuXHRcdFx0XHRcdFx0aWYgKHNDcmVhdGlvbk1vZGUgJiYgc0NyZWF0aW9uTW9kZSAhPT0gQ3JlYXRpb25Nb2RlLk5ld1BhZ2UpIHtcblx0XHRcdFx0XHRcdFx0Ly8gdXNlIHRoZSBwYXNzZWQgY3JlYXRpb24gbW9kZVxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gc0NyZWF0aW9uTW9kZTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IG9NZXRhTW9kZWwgPSBvTW9kZWwuZ2V0TWV0YU1vZGVsKCk7XG5cdFx0XHRcdFx0XHRcdC8vIE5ld0FjdGlvbiBpcyBub3QgeWV0IHN1cHBvcnRlZCBmb3IgTmF2aWdhdGlvblByb3BlcnR5IGNvbGxlY3Rpb25cblx0XHRcdFx0XHRcdFx0aWYgKCFvTGlzdEJpbmRpbmcuaXNSZWxhdGl2ZSgpKSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29uc3Qgc1BhdGggPSBvTGlzdEJpbmRpbmcuZ2V0UGF0aCgpLFxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gaWYgTmV3QWN0aW9uIHdpdGggcGFyYW1ldGVycyBpcyBwcmVzZW50LCB0aGVuIGNyZWF0aW9uIGlzICdEZWZlcnJlZCdcblx0XHRcdFx0XHRcdFx0XHRcdC8vIGluIHRoZSBhYnNlbmNlIG9mIE5ld0FjdGlvbiBvciBOZXdBY3Rpb24gd2l0aCBwYXJhbWV0ZXJzLCBjcmVhdGlvbiBpcyBhc3luY1xuXHRcdFx0XHRcdFx0XHRcdFx0c05ld0FjdGlvbiA9XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHNQcm9ncmFtbWluZ01vZGVsID09PSBQcm9ncmFtbWluZ01vZGVsLkRyYWZ0XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0PyBvTWV0YU1vZGVsLmdldE9iamVjdChzUGF0aCArIFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5EcmFmdFJvb3QvTmV3QWN0aW9uXCIpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0OiBvTWV0YU1vZGVsLmdldE9iamVjdChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0c1BhdGggKyBcIkBjb20uc2FwLnZvY2FidWxhcmllcy5TZXNzaW9uLnYxLlN0aWNreVNlc3Npb25TdXBwb3J0ZWQvTmV3QWN0aW9uXCJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICk7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKHNOZXdBY3Rpb24pIHtcblx0XHRcdFx0XHRcdFx0XHRcdGNvbnN0IGFQYXJhbWV0ZXJzID0gb01ldGFNb2RlbC5nZXRPYmplY3QoXCIvXCIgKyBzTmV3QWN0aW9uICsgXCIvQCR1aTUub3ZlcmxvYWQvMC8kUGFyYW1ldGVyXCIpIHx8IFtdO1xuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gYmluZGluZyBwYXJhbWV0ZXIgKGVnOiBfaXQpIGlzIG5vdCBjb25zaWRlcmVkXG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoYVBhcmFtZXRlcnMubGVuZ3RoID4gMSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gQ3JlYXRpb25Nb2RlLkRlZmVycmVkO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRjb25zdCBzTWV0YVBhdGggPSBvTWV0YU1vZGVsLmdldE1ldGFQYXRoKG9MaXN0QmluZGluZy5nZXRIZWFkZXJDb250ZXh0KCkuZ2V0UGF0aCgpKTtcblx0XHRcdFx0XHRcdFx0Y29uc3QgYU5vbkNvbXB1dGVkVmlzaWJsZUtleUZpZWxkcyA9IENvbW1vblV0aWxzLmdldE5vbkNvbXB1dGVkVmlzaWJsZUZpZWxkcyhcblx0XHRcdFx0XHRcdFx0XHRvTWV0YU1vZGVsLFxuXHRcdFx0XHRcdFx0XHRcdHNNZXRhUGF0aCxcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmdldFZpZXcoKVxuXHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHRpZiAoYU5vbkNvbXB1dGVkVmlzaWJsZUtleUZpZWxkcy5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIENyZWF0aW9uTW9kZS5EZWZlcnJlZDtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gQ3JlYXRpb25Nb2RlLkFzeW5jO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0LnRoZW4oKHNDcmVhdGlvbk1vZGU6IGFueSkgPT4ge1xuXHRcdFx0XHRcdFx0bGV0IG9DcmVhdGlvbjogYW55O1xuXHRcdFx0XHRcdFx0bGV0IG1BcmdzOiBhbnk7XG5cdFx0XHRcdFx0XHRjb25zdCBvQ3JlYXRpb25Sb3cgPSBtUGFyYW1ldGVycy5jcmVhdGlvblJvdztcblx0XHRcdFx0XHRcdGxldCBvQ3JlYXRpb25Sb3dDb250ZXh0OiBhbnk7XG5cdFx0XHRcdFx0XHRsZXQgb1ZhbGlkYXRpb25DaGVjayA9IFByb21pc2UucmVzb2x2ZSgpO1xuXHRcdFx0XHRcdFx0bGV0IG9QYXlsb2FkOiBhbnk7XG5cdFx0XHRcdFx0XHRsZXQgc01ldGFQYXRoOiBzdHJpbmc7XG5cdFx0XHRcdFx0XHRjb25zdCBvTWV0YU1vZGVsID0gb01vZGVsLmdldE1ldGFNb2RlbCgpO1xuXHRcdFx0XHRcdFx0Y29uc3Qgb1JvdXRpbmdMaXN0ZW5lciA9IHRoaXMuX2dldFJvdXRpbmdMaXN0ZW5lcigpO1xuXG5cdFx0XHRcdFx0XHRpZiAoc0NyZWF0aW9uTW9kZSAhPT0gQ3JlYXRpb25Nb2RlLkRlZmVycmVkKSB7XG5cdFx0XHRcdFx0XHRcdGlmIChzQ3JlYXRpb25Nb2RlID09PSBDcmVhdGlvbk1vZGUuQ3JlYXRpb25Sb3cpIHtcblx0XHRcdFx0XHRcdFx0XHRvQ3JlYXRpb25Sb3dDb250ZXh0ID0gb0NyZWF0aW9uUm93LmdldEJpbmRpbmdDb250ZXh0KCk7XG5cdFx0XHRcdFx0XHRcdFx0c01ldGFQYXRoID0gb01ldGFNb2RlbC5nZXRNZXRhUGF0aChvQ3JlYXRpb25Sb3dDb250ZXh0LmdldFBhdGgoKSk7XG5cdFx0XHRcdFx0XHRcdFx0Ly8gcHJlZmlsbCBkYXRhIGZyb20gY3JlYXRpb24gcm93XG5cdFx0XHRcdFx0XHRcdFx0b1BheWxvYWQgPSBvQ3JlYXRpb25Sb3dDb250ZXh0LmdldE9iamVjdCgpO1xuXHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmRhdGEgPSB7fTtcblx0XHRcdFx0XHRcdFx0XHRPYmplY3Qua2V5cyhvUGF5bG9hZCkuZm9yRWFjaChmdW5jdGlvbihzUHJvcGVydHlQYXRoOiBzdHJpbmcpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGNvbnN0IG9Qcm9wZXJ0eSA9IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNNZXRhUGF0aCArIFwiL1wiICsgc1Byb3BlcnR5UGF0aCk7XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBlbnN1cmUgbmF2aWdhdGlvbiBwcm9wZXJ0aWVzIGFyZSBub3QgcGFydCBvZiB0aGUgcGF5bG9hZCwgZGVlcCBjcmVhdGUgbm90IHN1cHBvcnRlZFxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKG9Qcm9wZXJ0eSAmJiBvUHJvcGVydHkuJGtpbmQgPT09IFwiTmF2aWdhdGlvblByb3BlcnR5XCIpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMuZGF0YVtzUHJvcGVydHlQYXRoXSA9IG9QYXlsb2FkW3NQcm9wZXJ0eVBhdGhdO1xuXHRcdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0XHRcdG9WYWxpZGF0aW9uQ2hlY2sgPSB0aGlzLl9jaGVja0ZvclZhbGlkYXRpb25FcnJvcnMoLypvQ3JlYXRpb25Sb3dDb250ZXh0Ki8pO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGlmIChzQ3JlYXRpb25Nb2RlID09PSBDcmVhdGlvbk1vZGUuQ3JlYXRpb25Sb3cgfHwgc0NyZWF0aW9uTW9kZSA9PT0gQ3JlYXRpb25Nb2RlLklubGluZSkge1xuXHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmtlZXBUcmFuc2llbnRDb250ZXh0T25GYWlsZWQgPSBmYWxzZTsgLy8gY3VycmVudGx5IG5vdCBmdWxseSBzdXBwb3J0ZWRcblx0XHRcdFx0XHRcdFx0XHQvLyBidXN5IGhhbmRsaW5nIHNoYWxsIGJlIGRvbmUgbG9jYWxseSBvbmx5XG5cdFx0XHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMuYnVzeU1vZGUgPSBcIkxvY2FsXCI7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyB0YWtlIGNhcmUgb24gbWVzc2FnZSBoYW5kbGluZywgZHJhZnQgaW5kaWNhdG9yIChpbiBjYXNlIG9mIGRyYWZ0KVxuXHRcdFx0XHRcdFx0XHRcdC8vIEF0dGFjaCB0aGUgY3JlYXRlIHNlbnQgYW5kIGNyZWF0ZSBjb21wbGV0ZWQgZXZlbnQgdG8gdGhlIG9iamVjdCBwYWdlIGJpbmRpbmcgc28gdGhhdCB3ZSBjYW4gcmVhY3Rcblx0XHRcdFx0XHRcdFx0XHR0aGlzLl9oYW5kbGVDcmVhdGVFdmVudHMob0xpc3RCaW5kaW5nKTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdG9DcmVhdGlvbiA9IG9WYWxpZGF0aW9uQ2hlY2sudGhlbigoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCFtUGFyYW1ldGVycy5wYXJlbnRDb250cm9sKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5wYXJlbnRDb250cm9sID0gdGhpcy5nZXRWaWV3KCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmJlZm9yZUNyZWF0ZUNhbGxCYWNrID0gdGhpcy5iYXNlLmVkaXRGbG93Lm9uQmVmb3JlQ3JlYXRlO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiB0cmFuc2FjdGlvbkhlbHBlci5jcmVhdGVEb2N1bWVudChcblx0XHRcdFx0XHRcdFx0XHRcdG9MaXN0QmluZGluZyxcblx0XHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLFxuXHRcdFx0XHRcdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlLFxuXHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5fZ2V0TWVzc2FnZUhhbmRsZXIoKSxcblx0XHRcdFx0XHRcdFx0XHRcdGZhbHNlLFxuXHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5nZXRWaWV3KClcblx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0bGV0IG9OYXZpZ2F0aW9uO1xuXHRcdFx0XHRcdFx0c3dpdGNoIChzQ3JlYXRpb25Nb2RlKSB7XG5cdFx0XHRcdFx0XHRcdGNhc2UgQ3JlYXRpb25Nb2RlLkRlZmVycmVkOlxuXHRcdFx0XHRcdFx0XHRcdG9OYXZpZ2F0aW9uID0gb1JvdXRpbmdMaXN0ZW5lci5uYXZpZ2F0ZUZvcndhcmRUb0NvbnRleHQob0xpc3RCaW5kaW5nLCB7XG5cdFx0XHRcdFx0XHRcdFx0XHRiRGVmZXJyZWRDb250ZXh0OiB0cnVlLFxuXHRcdFx0XHRcdFx0XHRcdFx0ZWRpdGFibGU6IHRydWUsXG5cdFx0XHRcdFx0XHRcdFx0XHRiRm9yY2VGb2N1czogdHJ1ZVxuXHRcdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRjYXNlIENyZWF0aW9uTW9kZS5Bc3luYzpcblx0XHRcdFx0XHRcdFx0XHRvTmF2aWdhdGlvbiA9IG9Sb3V0aW5nTGlzdGVuZXIubmF2aWdhdGVGb3J3YXJkVG9Db250ZXh0KG9MaXN0QmluZGluZywge1xuXHRcdFx0XHRcdFx0XHRcdFx0YXN5bmNDb250ZXh0OiBvQ3JlYXRpb24sXG5cdFx0XHRcdFx0XHRcdFx0XHRlZGl0YWJsZTogdHJ1ZSxcblx0XHRcdFx0XHRcdFx0XHRcdGJGb3JjZUZvY3VzOiB0cnVlXG5cdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdGNhc2UgQ3JlYXRpb25Nb2RlLlN5bmM6XG5cdFx0XHRcdFx0XHRcdFx0bUFyZ3MgPSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRlZGl0YWJsZTogdHJ1ZSxcblx0XHRcdFx0XHRcdFx0XHRcdGJGb3JjZUZvY3VzOiB0cnVlXG5cdFx0XHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRcdFx0XHRpZiAoc1Byb2dyYW1taW5nTW9kZWwgPT0gUHJvZ3JhbW1pbmdNb2RlbC5TdGlja3kgfHwgbVBhcmFtZXRlcnMuY3JlYXRlQWN0aW9uKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRtQXJncy50cmFuc2llbnQgPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRvTmF2aWdhdGlvbiA9IG9DcmVhdGlvbi50aGVuKGZ1bmN0aW9uKG9OZXdEb2N1bWVudENvbnRleHQ6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCFvTmV3RG9jdW1lbnRDb250ZXh0KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGNvbnN0IG9SZXNvdXJjZUJ1bmRsZSA9IHNhcC51aS5nZXRDb3JlKCkuZ2V0TGlicmFyeVJlc291cmNlQnVuZGxlKFwic2FwLmZlLmNvcmVcIikgYXMgUmVzb3VyY2VCdW5kbGU7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBvUm91dGluZ0xpc3RlbmVyLm5hdmlnYXRlVG9NZXNzYWdlUGFnZShcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGUuZ2V0VGV4dChcIkNfQ09NTU9OX1NBUEZFX0RBVEFfUkVDRUlWRURfRVJST1JcIiksXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGl0bGU6IG9SZXNvdXJjZUJ1bmRsZS5nZXRUZXh0KFwiQ19DT01NT05fU0FQRkVfRVJST1JcIiksXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRkZXNjcmlwdGlvbjogb1Jlc291cmNlQnVuZGxlLmdldFRleHQoXCJDX0VESVRGTE9XX1NBUEZFX0NSRUFUSU9OX0ZBSUxFRF9ERVNDUklQVElPTlwiKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBvUm91dGluZ0xpc3RlbmVyLm5hdmlnYXRlRm9yd2FyZFRvQ29udGV4dChvTmV3RG9jdW1lbnRDb250ZXh0LCBtQXJncyk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdGNhc2UgQ3JlYXRpb25Nb2RlLklubGluZTpcblx0XHRcdFx0XHRcdFx0XHRoYW5kbGVTaWRlRWZmZWN0cyhvTGlzdEJpbmRpbmcsIG9DcmVhdGlvbik7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5fc3luY1Rhc2sob0NyZWF0aW9uKTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0Y2FzZSBDcmVhdGlvbk1vZGUuQ3JlYXRpb25Sb3c6XG5cdFx0XHRcdFx0XHRcdFx0Ly8gdGhlIGNyZWF0aW9uIHJvdyBzaGFsbCBiZSBjbGVhcmVkIG9uY2UgdGhlIHZhbGlkYXRpb24gY2hlY2sgd2FzIHN1Y2Nlc3NmdWwgYW5kXG5cdFx0XHRcdFx0XHRcdFx0Ly8gdGhlcmVmb3JlIHRoZSBQT1NUIGNhbiBiZSBzZW50IGFzeW5jIHRvIHRoZSBiYWNrZW5kXG5cdFx0XHRcdFx0XHRcdFx0b05hdmlnYXRpb24gPSBvVmFsaWRhdGlvbkNoZWNrXG5cdFx0XHRcdFx0XHRcdFx0XHQudGhlbihmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0Y29uc3Qgb0NyZWF0aW9uUm93TGlzdEJpbmRpbmcgPSBvQ3JlYXRpb25Sb3dDb250ZXh0LmdldEJpbmRpbmcoKTtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIW1QYXJhbWV0ZXJzLmJTa2lwU2lkZUVmZmVjdHMpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRoYW5kbGVTaWRlRWZmZWN0cyhvTGlzdEJpbmRpbmcsIG9DcmVhdGlvbik7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRjb25zdCBvTmV3VHJhbnNpZW50Q29udGV4dCA9IG9DcmVhdGlvblJvd0xpc3RCaW5kaW5nLmNyZWF0ZSgpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRvQ3JlYXRpb25Sb3cuc2V0QmluZGluZ0NvbnRleHQob05ld1RyYW5zaWVudENvbnRleHQpO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIHRoaXMgaXMgbmVlZGVkIHRvIGF2b2lkIGNvbnNvbGUgZXJyb3JzIFRPIGJlIGNoZWNrZWQgd2l0aCBtb2RlbCBjb2xsZWFndWVzXG5cdFx0XHRcdFx0XHRcdFx0XHRcdG9OZXdUcmFuc2llbnRDb250ZXh0LmNyZWF0ZWQoKS5jYXRjaChmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRMb2cudHJhY2UoXCJ0cmFuc2llbnQgZmFzdCBjcmVhdGlvbiBjb250ZXh0IGRlbGV0ZWRcIik7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gb0NyZWF0aW9uUm93Q29udGV4dC5kZWxldGUoXCIkZGlyZWN0XCIpO1xuXHRcdFx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdFx0XHRcdC5jYXRjaCgob0Vycm9yOiBhbnkpID0+IHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gUmVzZXQgYnVzeSBpbmRpY2F0b3IgYWZ0ZXIgYSB2YWxpZGF0aW9uIGVycm9yXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmIChCdXN5TG9ja2VyLmlzTG9ja2VkKHRoaXMuZ2V0VmlldygpLmdldE1vZGVsKFwidWlcIikpKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0QnVzeUxvY2tlci51bmxvY2sodGhpcy5nZXRWaWV3KCkuZ2V0TW9kZWwoXCJ1aVwiKSk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0TG9nLmVycm9yKFwiQ3JlYXRpb25Sb3cgbmF2aWdhdGlvbiBlcnJvcjogXCIsIG9FcnJvcik7XG5cdFx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRcdFx0XHRvTmF2aWdhdGlvbiA9IFByb21pc2UucmVqZWN0KFwiVW5oYW5kbGVkIGNyZWF0aW9uTW9kZSBcIiArIHNDcmVhdGlvbk1vZGUpO1xuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRpZiAoc1Byb2dyYW1taW5nTW9kZWwgPT09IFByb2dyYW1taW5nTW9kZWwuU3RpY2t5KSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMuX2dldEludGVybmFsTW9kZWwoKS5zZXRQcm9wZXJ0eShcIi9zZXNzaW9uT25cIiwgdHJ1ZSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRjb25zdCBiSXNOZXdQYWdlQ3JlYXRpb24gPVxuXHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5jcmVhdGlvbk1vZGUgIT09IENyZWF0aW9uTW9kZS5DcmVhdGlvblJvdyAmJiBtUGFyYW1ldGVycy5jcmVhdGlvbk1vZGUgIT09IENyZWF0aW9uTW9kZS5JbmxpbmU7XG5cdFx0XHRcdFx0XHRpZiAob0NyZWF0aW9uKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBQcm9taXNlLmFsbChbb0NyZWF0aW9uLCBvTmF2aWdhdGlvbl0pXG5cdFx0XHRcdFx0XHRcdFx0LnRoZW4oKGFQYXJhbXM6IFthbnksIGFueV0pID0+IHtcblx0XHRcdFx0XHRcdFx0XHRcdGlmIChiSXNOZXdQYWdlQ3JlYXRpb24pIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5fc2V0RWRpdE1vZGUoRWRpdE1vZGUuRWRpdGFibGUsIGJJc05ld1BhZ2VDcmVhdGlvbik7XG5cdFx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0aGlzLl9zZXRFZGl0TW9kZShFZGl0TW9kZS5FZGl0YWJsZSk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRjb25zdCBvTmV3RG9jdW1lbnRDb250ZXh0ID0gYVBhcmFtc1swXTtcblx0XHRcdFx0XHRcdFx0XHRcdGlmIChvTmV3RG9jdW1lbnRDb250ZXh0KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdEVkaXRTdGF0ZS5zZXRFZGl0U3RhdGVEaXJ0eSgpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRzZW5kKHRoaXMuZ2V0VmlldygpLCBBY3Rpdml0eS5DcmVhdGUsIG9OZXdEb2N1bWVudENvbnRleHQpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoc1Byb2dyYW1taW5nTW9kZWwgPT09IFByb2dyYW1taW5nTW9kZWwuU3RpY2t5KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5faGFuZGxlU3RpY2t5T24ob05ld0RvY3VtZW50Q29udGV4dCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0XHRcdC5jYXRjaChmdW5jdGlvbihvRXJyb3I6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKG9FcnJvciAmJiAob0Vycm9yLm5hdmlnYXRlQmFja0Zyb21UcmFuc2llbnRTdGF0ZSB8fCBvRXJyb3IgPT0gQ29uc3RhbnRzLkNhbmNlbEFjdGlvbkRpYWxvZykpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0b1JvdXRpbmdMaXN0ZW5lci5uYXZpZ2F0ZUJhY2tGcm9tVHJhbnNpZW50U3RhdGUoKTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIFByb21pc2UucmVqZWN0KG9FcnJvcik7XG5cdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHR9KVxuXHRcdFx0LmZpbmFsbHkoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmIChvVGFibGUgJiYgb1RhYmxlLmlzQShcInNhcC51aS5tZGMuVGFibGVcIikpIHtcblx0XHRcdFx0XHRjb25zdCBmbkZvY3VzT3JTY3JvbGwgPVxuXHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMuY3JlYXRpb25Nb2RlID09PSBDcmVhdGlvbk1vZGUuSW5saW5lID8gb1RhYmxlLmZvY3VzUm93LmJpbmQob1RhYmxlKSA6IG9UYWJsZS5zY3JvbGxUb0luZGV4LmJpbmQob1RhYmxlKTtcblx0XHRcdFx0XHRvVGFibGUuZ2V0Um93QmluZGluZygpLmF0dGFjaEV2ZW50T25jZShcImNoYW5nZVwiLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdHN3aXRjaCAobVBhcmFtZXRlcnMuY3JlYXRlQXRFbmQpIHtcblx0XHRcdFx0XHRcdFx0Y2FzZSB0cnVlOlxuXHRcdFx0XHRcdFx0XHRcdGlmIChvVGFibGUuZGF0YShcInRhYmxlVHlwZVwiKSA9PT0gXCJSZXNwb25zaXZlVGFibGVcIiAmJiBvVGFibGUuZ2V0VGhyZXNob2xkKCkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGZuRm9jdXNPclNjcm9sbChvVGFibGUuZ2V0VGhyZXNob2xkKCksIHRydWUpO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRmbkZvY3VzT3JTY3JvbGwoaUNvdW50VGFibGVJdGVtcywgdHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRjYXNlIGZhbHNlOlxuXHRcdFx0XHRcdFx0XHRcdGZuRm9jdXNPclNjcm9sbCgwLCB0cnVlKTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRiU2hvdWxkQnVzeUxvY2sgJiYgQnVzeUxvY2tlci51bmxvY2sob0xvY2tPYmplY3QpO1xuXHRcdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBpbnRlcmNlcHQgdGhlICdTYXZlJyBhY3Rpb24uIFlvdSBjYW4gZXhlY3V0ZSBjdXN0b20gY29kaW5nIGluIHRoaXMgZnVuY3Rpb24uXG5cdCAqIFRoZSBmcmFtZXdvcmsgd2FpdHMgZm9yIHRoZSByZXR1cm5lZCBwcm9taXNlIHRvIGJlIHJlc29sdmVkIGJlZm9yZSBjb250aW51aW5nIHRoZSAnU2F2ZScgYWN0aW9uLlxuXHQgKiBJZiB5b3UgcmVqZWN0IHRoZSBwcm9taXNlLCB0aGUgJ1NhdmUnIGFjdGlvbiBpcyBzdG9wcGVkIGFuZCB0aGUgdXNlciBzdGF5cyBpbiBlZGl0IG1vZGUuXG5cdCAqXG5cdCAqIFRoaXMgZnVuY3Rpb24gaXMgbWVhbnQgdG8gYmUgaW5kaXZpZHVhbGx5IG92ZXJyaWRkZW4gYnkgY29uc3VtaW5nIGNvbnRyb2xsZXJzLCBidXQgbm90IHRvIGJlIGNhbGxlZCBkaXJlY3RseS5cblx0ICogVGhlIG92ZXJyaWRlIGV4ZWN1dGlvbiBpczoge0BsaW5rIHNhcC51aS5jb3JlLm12Yy5PdmVycmlkZUV4ZWN1dGlvbi5BZnRlcn0uXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBtUGFyYW1ldGVycyBPYmplY3QgY29udGFpbmluZyB0aGUgcGFyYW1ldGVycyBwYXNzZWQgdG8gb25CZWZvcmVTYXZlXG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHR9IG1QYXJhbWV0ZXJzLmNvbnRleHQgUGFnZSBjb250ZXh0IHRoYXQgaXMgZ29pbmcgdG8gYmUgc2F2ZWQuXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBBIHByb21pc2UgdG8gYmUgcmV0dXJuZWQgYnkgdGhlIG92ZXJyaWRkZW4gbWV0aG9kLiBJZiByZXNvbHZlZCwgdGhlICdTYXZlJyBhY3Rpb24gaXMgdHJpZ2dlcmVkLiBJZiByZWplY3RlZCwgdGhlICdTYXZlJyBhY3Rpb24gaXMgbm90IHRyaWdnZXJlZCBhbmQgdGhlIHVzZXIgc3RheXMgaW4gZWRpdCBtb2RlLlxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuY29udHJvbGxlcmV4dGVuc2lvbnMuRWRpdEZsb3dcblx0ICogQGFsaWFzIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkVkaXRGbG93I29uQmVmb3JlU2F2ZVxuXHQgKiBAcHVibGljXG5cdCAqIEBleHBlcmltZW50YWwgQXMgb2YgdmVyc2lvbiAxLjkwLjBcblx0ICogQHNpbmNlIDEuOTAuMFxuXHQgKi9cblx0QFB1YmxpY1xuXHRARXh0ZW5zaWJsZShPdmVycmlkZUV4ZWN1dGlvbi5BZnRlcilcblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuXHRvbkJlZm9yZVNhdmUobVBhcmFtZXRlcnM/OiB7IGNvbnRleHQ/OiBDb250ZXh0IH0pOiBQcm9taXNlPHZvaWQ+IHtcblx0XHQvLyB0byBiZSBvdmVycmlkZGVuXG5cdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXHR9XG5cdC8qKlxuXHQgKiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGludGVyY2VwdCB0aGUgJ0NyZWF0ZScgYWN0aW9uLiBZb3UgY2FuIGV4ZWN1dGUgY3VzdG9tIGNvZGluZyBpbiB0aGlzIGZ1bmN0aW9uLlxuXHQgKiBUaGUgZnJhbWV3b3JrIHdhaXRzIGZvciB0aGUgcmV0dXJuZWQgcHJvbWlzZSB0byBiZSByZXNvbHZlZCBiZWZvcmUgY29udGludWluZyB0aGUgJ0NyZWF0ZScgYWN0aW9uLlxuXHQgKiBJZiB5b3UgcmVqZWN0IHRoZSBwcm9taXNlLCB0aGUgJ0NyZWF0ZScgYWN0aW9uIGlzIHN0b3BwZWQuXG5cdCAqXG5cdCAqIFRoaXMgZnVuY3Rpb24gaXMgbWVhbnQgdG8gYmUgaW5kaXZpZHVhbGx5IG92ZXJyaWRkZW4gYnkgY29uc3VtaW5nIGNvbnRyb2xsZXJzLCBidXQgbm90IHRvIGJlIGNhbGxlZCBkaXJlY3RseS5cblx0ICogVGhlIG92ZXJyaWRlIGV4ZWN1dGlvbiBpczoge0BsaW5rIHNhcC51aS5jb3JlLm12Yy5PdmVycmlkZUV4ZWN1dGlvbi5BZnRlcn0uXG5cdCAqIEBwYXJhbSB7bWFwfSBtUGFyYW1ldGVycyBPYmplY3QgY29udGFpbmluZyB0aGUgcGFyYW1ldGVycyBwYXNzZWQgdG8gb25CZWZvcmVDcmVhdGVcblx0ICogQHBhcmFtIHtzdHJpbmd9IG1QYXJhbWV0ZXJzLmNvbnRleHRQYXRoIFBhdGggcG9pbnRpbmcgdG8gdGhlIGNvbnRleHQgb24gd2hpY2ggQ3JlYXRlIGFjdGlvbiBpcyB0cmlnZ2VyZWRcblx0ICogQHBhcmFtIHtBcnJheX0gbVBhcmFtZXRlcnMuY3JlYXRlUGFyYW1ldGVycyBBcnJheSBvZiB2YWx1ZXMgdGhhdCBhcmUgZmlsbGVkIGluIHRoZSBBY3Rpb24gUGFyYW1ldGVyIERpYWxvZ1xuXHQgKiBAcmV0dXJucyB7UHJvbWlzZX0gQSBwcm9taXNlIHRvIGJlIHJldHVybmVkIGJ5IHRoZSBvdmVycmlkZGVuIG1ldGhvZC4gSWYgcmVzb2x2ZWQsIHRoZSAnQ3JlYXRlJyBhY3Rpb24gaXMgdHJpZ2dlcmVkLiBJZiByZWplY3RlZCwgdGhlICdDcmVhdGUnIGFjdGlvbiBpcyBub3QgdHJpZ2dlcmVkLlxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuY29udHJvbGxlcmV4dGVuc2lvbnMuRWRpdEZsb3dcblx0ICogQGFsaWFzIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkVkaXRGbG93I29uQmVmb3JlQ3JlYXRlXG5cdCAqIEBwdWJsaWNcblx0ICogQGV4cGVyaW1lbnRhbCBBcyBvZiB2ZXJzaW9uIDEuOTguMFxuXHQgKiBAc2luY2UgMS45OC4wXG5cdCAqL1xuXHRAUHVibGljXG5cdEBFeHRlbnNpYmxlKE92ZXJyaWRlRXhlY3V0aW9uLkFmdGVyKVxuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG5cdG9uQmVmb3JlQ3JlYXRlKG1QYXJhbWV0ZXJzPzogeyBjb250ZXh0UGF0aD86IHN0cmluZzsgY3JlYXRlUGFyYW1ldGVycz86IGFueVtdIH0pOiBQcm9taXNlPHZvaWQ+IHtcblx0XHQvLyB0byBiZSBvdmVycmlkZGVuXG5cdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXHR9XG5cdC8qKlxuXHQgKiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGludGVyY2VwdCB0aGUgJ0VkaXQnIGFjdGlvbi4gWW91IGNhbiBleGVjdXRlIGN1c3RvbSBjb2RpbmcgaW4gdGhpcyBmdW5jdGlvbi5cblx0ICogVGhlIGZyYW1ld29yayB3YWl0cyBmb3IgdGhlIHJldHVybmVkIHByb21pc2UgdG8gYmUgcmVzb2x2ZWQgYmVmb3JlIGNvbnRpbnVpbmcgdGhlICdFZGl0JyBhY3Rpb24uXG5cdCAqIElmIHlvdSByZWplY3QgdGhlIHByb21pc2UsIHRoZSAnRWRpdCcgYWN0aW9uIGlzIHN0b3BwZWQgYW5kIHRoZSB1c2VyIHN0YXlzIGluIGRpc3BsYXkgbW9kZS5cblx0ICpcblx0ICogVGhpcyBmdW5jdGlvbiBpcyBtZWFudCB0byBiZSBpbmRpdmlkdWFsbHkgb3ZlcnJpZGRlbiBieSBjb25zdW1pbmcgY29udHJvbGxlcnMsIGJ1dCBub3QgdG8gYmUgY2FsbGVkIGRpcmVjdGx5LlxuXHQgKiBUaGUgb3ZlcnJpZGUgZXhlY3V0aW9uIGlzOiB7QGxpbmsgc2FwLnVpLmNvcmUubXZjLk92ZXJyaWRlRXhlY3V0aW9uLkFmdGVyfS5cblx0ICogQHBhcmFtIHtvYmplY3R9IG1QYXJhbWV0ZXJzIE9iamVjdCBjb250YWluaW5nIHRoZSBwYXJhbWV0ZXJzIHBhc3NlZCB0byBvbkJlZm9yZUVkaXRcblx0ICogQHBhcmFtIHtzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dH0gbVBhcmFtZXRlcnMuY29udGV4dCBQYWdlIGNvbnRleHQgdGhhdCBpcyBnb2luZyB0byBiZSBlZGl0ZWQuXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBBIHByb21pc2UgdG8gYmUgcmV0dXJuZWQgYnkgdGhlIG92ZXJyaWRkZW4gbWV0aG9kLiBJZiByZXNvbHZlZCwgdGhlICdFZGl0JyBhY3Rpb24gaXMgdHJpZ2dlcmVkLiBJZiByZWplY3RlZCwgdGhlICdFZGl0JyBhY3Rpb24gaXMgbm90IHRyaWdnZXJlZCBhbmQgdGhlIHVzZXIgc3RheXMgaW4gZGlzcGxheSBtb2RlLlxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuY29udHJvbGxlcmV4dGVuc2lvbnMuRWRpdEZsb3dcblx0ICogQGFsaWFzIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkVkaXRGbG93I29uQmVmb3JlRWRpdFxuXHQgKiBAcHVibGljXG5cdCAqIEBleHBlcmltZW50YWwgQXMgb2YgdmVyc2lvbiAxLjk4LjBcblx0ICogQHNpbmNlIDEuOTguMFxuXHQgKi9cblx0QFB1YmxpY1xuXHRARXh0ZW5zaWJsZShPdmVycmlkZUV4ZWN1dGlvbi5BZnRlcilcblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuXHRvbkJlZm9yZUVkaXQobVBhcmFtZXRlcnM/OiB7IGNvbnRleHQ/OiBDb250ZXh0IH0pOiBQcm9taXNlPHZvaWQ+IHtcblx0XHQvLyB0byBiZSBvdmVycmlkZGVuXG5cdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXHR9XG5cdC8qKlxuXHQgKiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGludGVyY2VwdCB0aGUgJ0Rpc2NhcmQnIGFjdGlvbi4gWW91IGNhbiBleGVjdXRlIGN1c3RvbSBjb2RpbmcgaW4gdGhpcyBmdW5jdGlvbi5cblx0ICogVGhlIGZyYW1ld29yayB3YWl0cyBmb3IgdGhlIHJldHVybmVkIHByb21pc2UgdG8gYmUgcmVzb2x2ZWQgYmVmb3JlIGNvbnRpbnVpbmcgdGhlICdEaXNjYXJkJyBhY3Rpb24uXG5cdCAqIElmIHlvdSByZWplY3QgdGhlIHByb21pc2UsIHRoZSAnRGlzY2FyZCcgYWN0aW9uIGlzIHN0b3BwZWQgYW5kIHRoZSB1c2VyIHN0YXlzIGluIGVkaXQgbW9kZS5cblx0ICpcblx0ICogVGhpcyBmdW5jdGlvbiBpcyBtZWFudCB0byBiZSBpbmRpdmlkdWFsbHkgb3ZlcnJpZGRlbiBieSBjb25zdW1pbmcgY29udHJvbGxlcnMsIGJ1dCBub3QgdG8gYmUgY2FsbGVkIGRpcmVjdGx5LlxuXHQgKiBUaGUgb3ZlcnJpZGUgZXhlY3V0aW9uIGlzOiB7QGxpbmsgc2FwLnVpLmNvcmUubXZjLk92ZXJyaWRlRXhlY3V0aW9uLkFmdGVyfS5cblx0ICogQHBhcmFtIHtvYmplY3R9IG1QYXJhbWV0ZXJzIE9iamVjdCBjb250YWluaW5nIHRoZSBwYXJhbWV0ZXJzIHBhc3NlZCB0byBvbkJlZm9yZURpc2NhcmRcblx0ICogQHBhcmFtIHtzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dH0gbVBhcmFtZXRlcnMuY29udGV4dCBQYWdlIGNvbnRleHQgdGhhdCBpcyBnb2luZyB0byBiZSBkaXNjYXJkZWQuXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBBIHByb21pc2UgdG8gYmUgcmV0dXJuZWQgYnkgdGhlIG92ZXJyaWRkZW4gbWV0aG9kLiBJZiByZXNvbHZlZCwgdGhlICdEaXNjYXJkJyBhY3Rpb24gaXMgdHJpZ2dlcmVkLiBJZiByZWplY3RlZCwgdGhlICdEaXNjYXJkJyBhY3Rpb24gaXMgbm90IHRyaWdnZXJlZCBhbmQgdGhlIHVzZXIgc3RheXMgaW4gZWRpdCBtb2RlLlxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuY29udHJvbGxlcmV4dGVuc2lvbnMuRWRpdEZsb3dcblx0ICogQGFsaWFzIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkVkaXRGbG93I29uQmVmb3JlRGlzY2FyZFxuXHQgKiBAcHVibGljXG5cdCAqIEBleHBlcmltZW50YWwgQXMgb2YgdmVyc2lvbiAxLjk4LjBcblx0ICogQHNpbmNlIDEuOTguMFxuXHQgKi9cblx0QFB1YmxpY1xuXHRARXh0ZW5zaWJsZShPdmVycmlkZUV4ZWN1dGlvbi5BZnRlcilcblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuXHRvbkJlZm9yZURpc2NhcmQobVBhcmFtZXRlcnM/OiB7IGNvbnRleHQ/OiBDb250ZXh0IH0pOiBQcm9taXNlPHZvaWQ+IHtcblx0XHQvLyB0byBiZSBvdmVycmlkZGVuXG5cdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXHR9XG5cdC8qKlxuXHQgKiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGludGVyY2VwdCB0aGUgJ0RlbGV0ZScgYWN0aW9uLiBZb3UgY2FuIGV4ZWN1dGUgY3VzdG9tIGNvZGluZyBpbiB0aGlzIGZ1bmN0aW9uLlxuXHQgKiBUaGUgZnJhbWV3b3JrIHdhaXRzIGZvciB0aGUgcmV0dXJuZWQgcHJvbWlzZSB0byBiZSByZXNvbHZlZCBiZWZvcmUgY29udGludWluZyB0aGUgJ0RlbGV0ZScgYWN0aW9uLlxuXHQgKiBJZiB5b3UgcmVqZWN0IHRoZSBwcm9taXNlLCB0aGUgJ0RlbGV0ZScgYWN0aW9uIGlzIHN0b3BwZWQuXG5cdCAqXG5cdCAqIFRoaXMgZnVuY3Rpb24gaXMgbWVhbnQgdG8gYmUgaW5kaXZpZHVhbGx5IG92ZXJyaWRkZW4gYnkgY29uc3VtaW5nIGNvbnRyb2xsZXJzLCBidXQgbm90IHRvIGJlIGNhbGxlZCBkaXJlY3RseS5cblx0ICogVGhlIG92ZXJyaWRlIGV4ZWN1dGlvbiBpczoge0BsaW5rIHNhcC51aS5jb3JlLm12Yy5PdmVycmlkZUV4ZWN1dGlvbi5BZnRlcn0uXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBtUGFyYW1ldGVycyBPYmplY3QgY29udGFpbmluZyB0aGUgcGFyYW1ldGVycyBwYXNzZWQgdG8gb25CZWZvcmVEZWxldGVcblx0ICogQHBhcmFtIHtBcnJheX0gbVBhcmFtZXRlcnMuY29udGV4dHMgQW4gYXJyYXkgb2YgY29udGV4dHMgdGhhdCBhcmUgZ29pbmcgdG8gYmUgZGVsZXRlZFxuXHQgKiBAcmV0dXJucyB7UHJvbWlzZX0gQSBwcm9taXNlIHRvIGJlIHJldHVybmVkIGJ5IHRoZSBvdmVycmlkZGVuIG1ldGhvZC4gSWYgcmVzb2x2ZWQsIHRoZSAnRGVsZXRlJyBhY3Rpb24gaXMgdHJpZ2dlcmVkLiBJZiByZWplY3RlZCwgdGhlICdEZWxldGUnIGFjdGlvbiBpcyBub3QgdHJpZ2dlcmVkLlxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuY29udHJvbGxlcmV4dGVuc2lvbnMuRWRpdEZsb3dcblx0ICogQGFsaWFzIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkVkaXRGbG93I29uQmVmb3JlRGVsZXRlXG5cdCAqIEBwdWJsaWNcblx0ICogQGV4cGVyaW1lbnRhbCBBcyBvZiB2ZXJzaW9uIDEuOTguMFxuXHQgKiBAc2luY2UgMS45OC4wXG5cdCAqL1xuXHRAUHVibGljXG5cdEBFeHRlbnNpYmxlKE92ZXJyaWRlRXhlY3V0aW9uLkFmdGVyKVxuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG5cdG9uQmVmb3JlRGVsZXRlKG1QYXJhbWV0ZXJzPzogeyBjb250ZXh0cz86IENvbnRleHRbXSB9KTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Ly8gdG8gYmUgb3ZlcnJpZGRlblxuXHRcdHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcblx0fVxuXG5cdC8vIEludGVybmFsIG9ubHkgcGFyYW1zIC0tLVxuXHQvLyBAcGFyYW0ge2Jvb2xlYW59IG1QYXJhbWV0ZXJzLmJFeGVjdXRlU2lkZUVmZmVjdHNPbkVycm9yIEluZGljYXRlcyB3aGV0aGVyIFNpZGVFZmZlY3RzIG5lZWQgdG8gYmUgaWdub3JlZCB3aGVuIHVzZXIgY2xpY2tzIG9uIFNhdmUgZHVyaW5nIGFuIElubGluZSBjcmVhdGlvblxuXHQvLyBAcGFyYW0ge29iamVjdH0gbVBhcmFtZXRlcnMuYmluZGluZ3MgTGlzdCBiaW5kaW5ncyBvZiB0aGUgdGFibGVzIGluIHRoZSB2aWV3LlxuXHQvLyBCb3RoIG9mIHRoZSBhYm92ZSBwYXJhbWV0ZXJzIGFyZSBmb3IgdGhlIHNhbWUgcHVycG9zZS4gVXNlciBjYW4gZW50ZXIgc29tZSBpbmZvcm1hdGlvbiBpbiB0aGUgY3JlYXRpb24gcm93KHMpIGJ1dCBkb2VzIG5vdCAnQWRkIHJvdycsIGluc3RlYWQgY2xpY2tzIFNhdmUuXG5cdC8vIFRoZXJlIGNhbiBiZSBtb3JlIHRoYW4gb25lIGluIHRoZSB2aWV3LlxuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLXBhcmFtXG5cdC8qKlxuXHQgKiBTYXZlcyBhIG5ldyBkb2N1bWVudCBhZnRlciBjaGVja2luZyBpdC5cblx0ICpcblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkVkaXRGbG93XG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvQ29udGV4dCAgQ29udGV4dCBvZiB0aGUgZWRpdGFibGUgZG9jdW1lbnRcblx0ICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgcmVzb2x2ZXMgb25jZSBzYXZlIGlzIGNvbXBsZXRlXG5cdCAqIEBhbGlhcyBzYXAuZmUuY29yZS5jb250cm9sbGVyZXh0ZW5zaW9ucy5FZGl0RmxvdyNzYXZlRG9jdW1lbnRcblx0ICogQHB1YmxpY1xuXHQgKiBAc2luY2UgMS45MC4wXG5cdCAqL1xuXHRAUHVibGljXG5cdEBGaW5hbFxuXHRzYXZlRG9jdW1lbnQob0NvbnRleHQ6IENvbnRleHQsIG1QYXJhbWV0ZXJzOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRtUGFyYW1ldGVycyA9IG1QYXJhbWV0ZXJzIHx8IHt9O1xuXHRcdGNvbnN0IGJFeGVjdXRlU2lkZUVmZmVjdHNPbkVycm9yID0gbVBhcmFtZXRlcnMuYkV4ZWN1dGVTaWRlRWZmZWN0c09uRXJyb3IgfHwgdW5kZWZpbmVkO1xuXHRcdGNvbnN0IGJEcmFmdE5hdmlnYXRpb24gPSB0cnVlO1xuXHRcdGNvbnN0IHRyYW5zYWN0aW9uSGVscGVyID0gdGhpcy5fZ2V0VHJhbnNhY3Rpb25IZWxwZXIoKTtcblx0XHRjb25zdCBvUmVzb3VyY2VCdW5kbGUgPSAodGhpcy5nZXRWaWV3KCkuZ2V0Q29udHJvbGxlcigpIGFzIGFueSkub1Jlc291cmNlQnVuZGxlO1xuXHRcdGNvbnN0IGFCaW5kaW5ncyA9IG1QYXJhbWV0ZXJzLmJpbmRpbmdzO1xuXHRcdC8vIGZpcnN0IG9mIGFsbCB3YWl0IHVudGlsIGFsbCBrZXktbWF0Y2gtcmVxdWVzdHMgYXJlIGRvbmVcblx0XHRyZXR1cm4gKFxuXHRcdFx0dGhpcy5fc3luY1Rhc2soKVxuXHRcdFx0XHQvLyBzdWJtaXQgYW55IG9wZW4gY2hhbmdlcyBpZiB0aGVyZSBhbnkgKGFsdGhvdWdoIHRoZXJlIGFyZSB2YWxpZGF0aW9uL3BhcnNlIGVycm9ycylcblx0XHRcdFx0LnRoZW4odGhpcy5fc3VibWl0T3BlbkNoYW5nZXMuYmluZCh0aGlzLCBvQ29udGV4dCkpXG5cdFx0XHRcdC8vIGNoZWNrIGlmIHRoZXJlIGFyZSBhbnkgdmFsaWRhdGlvbi9wYXJzZSBlcnJvcnNcblx0XHRcdFx0LnRoZW4odGhpcy5fY2hlY2tGb3JWYWxpZGF0aW9uRXJyb3JzLmJpbmQodGhpcywgb0NvbnRleHQpKVxuXHRcdFx0XHQudGhlbih0aGlzLmJhc2UuZWRpdEZsb3cub25CZWZvcmVTYXZlLmJpbmQodGhpcywgeyBjb250ZXh0OiBvQ29udGV4dCB9KSlcblx0XHRcdFx0Ly8gYW5kIGZpbmFsbHkgaWYgYWxsIHVzZXIgY2hhbmdlcyBhcmUgc3VibWl0dGVkIGFuZCB2YWxpZCBzYXZlIHRoZSBkb2N1bWVudFxuXHRcdFx0XHQudGhlbihcblx0XHRcdFx0XHR0cmFuc2FjdGlvbkhlbHBlci5zYXZlRG9jdW1lbnQuYmluZChcblx0XHRcdFx0XHRcdHRyYW5zYWN0aW9uSGVscGVyLFxuXHRcdFx0XHRcdFx0b0NvbnRleHQsXG5cdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGUsXG5cdFx0XHRcdFx0XHRiRXhlY3V0ZVNpZGVFZmZlY3RzT25FcnJvcixcblx0XHRcdFx0XHRcdGFCaW5kaW5ncyxcblx0XHRcdFx0XHRcdHRoaXMuX2dldE1lc3NhZ2VIYW5kbGVyKClcblx0XHRcdFx0XHQpXG5cdFx0XHRcdClcblx0XHRcdFx0LnRoZW4oKG9BY3RpdmVEb2N1bWVudENvbnRleHQ6IGFueSkgPT4ge1xuXHRcdFx0XHRcdGNvbnN0IHNQcm9ncmFtbWluZ01vZGVsID0gdGhpcy5fZ2V0UHJvZ3JhbW1pbmdNb2RlbChvQ29udGV4dCk7XG5cblx0XHRcdFx0XHR0aGlzLl9yZW1vdmVDb250ZXh0c0Zyb21QYWdlcygpO1xuXHRcdFx0XHRcdGlmIChzUHJvZ3JhbW1pbmdNb2RlbCA9PT0gUHJvZ3JhbW1pbmdNb2RlbC5TdGlja3kpIHtcblx0XHRcdFx0XHRcdHRoaXMuX2dldEludGVybmFsTW9kZWwoKS5zZXRQcm9wZXJ0eShcIi9zZXNzaW9uT25cIiwgZmFsc2UpO1xuXHRcdFx0XHRcdFx0dGhpcy5faGFuZGxlU3RpY2t5T2ZmKC8qb0NvbnRleHQqLyk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0c2VuZCh0aGlzLmdldFZpZXcoKSwgQWN0aXZpdHkuQWN0aXZhdGUsIG9BY3RpdmVEb2N1bWVudENvbnRleHQpO1xuXG5cdFx0XHRcdFx0dGhpcy5fc2V0RWRpdE1vZGUoRWRpdE1vZGUuRGlzcGxheSwgZmFsc2UpO1xuXHRcdFx0XHRcdHRoaXMuX2dldE1lc3NhZ2VIYW5kbGVyKCkuc2hvd01lc3NhZ2VEaWFsb2coKTtcblxuXHRcdFx0XHRcdGlmIChvQWN0aXZlRG9jdW1lbnRDb250ZXh0ICE9PSBvQ29udGV4dCkge1xuXHRcdFx0XHRcdFx0dGhpcy5faGFuZGxlTmV3Q29udGV4dChvQWN0aXZlRG9jdW1lbnRDb250ZXh0LCBmYWxzZSwgZmFsc2UsIGJEcmFmdE5hdmlnYXRpb24sIHRydWUpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSlcblx0XHRcdFx0LmNhdGNoKGZ1bmN0aW9uKG9FcnJvcjogYW55KSB7XG5cdFx0XHRcdFx0TG9nLmVycm9yKFwiRXJyb3Igd2hpbGUgc2F2aW5nIHRoZSBkb2N1bWVudFwiLCBvRXJyb3IpO1xuXHRcdFx0XHRcdHJldHVybiBQcm9taXNlLnJlamVjdChvRXJyb3IpO1xuXHRcdFx0XHR9KVxuXHRcdCk7XG5cdH1cblx0QFB1YmxpY1xuXHRARmluYWxcblx0dG9nZ2xlRHJhZnRBY3RpdmUob0NvbnRleHQ6IGFueSkge1xuXHRcdGNvbnN0IG9Db250ZXh0RGF0YSA9IG9Db250ZXh0LmdldE9iamVjdCgpO1xuXHRcdGxldCBiRWRpdGFibGU6IGJvb2xlYW47XG5cdFx0Y29uc3QgYklzRHJhZnQgPSBvQ29udGV4dCAmJiB0aGlzLl9nZXRQcm9ncmFtbWluZ01vZGVsKG9Db250ZXh0KSA9PT0gUHJvZ3JhbW1pbmdNb2RlbC5EcmFmdDtcblx0XHRjb25zdCBvVG9nZ2xlQ29udGV4dCA9IG9Db250ZXh0XG5cdFx0XHQuZ2V0TW9kZWwoKVxuXHRcdFx0LmJpbmRDb250ZXh0KG9Db250ZXh0LmdldFBhdGgoKSArIFwiL1NpYmxpbmdFbnRpdHlcIilcblx0XHRcdC5nZXRCb3VuZENvbnRleHQoKTtcblxuXHRcdC8vdG9nZ2xlIGJldHdlZW4gZHJhZnQgYW5kIGFjdGl2ZSBkb2N1bWVudCBpcyBvbmx5IGF2YWlsYWJsZSBmb3IgZWRpdCBkcmFmdHMgYW5kIGFjdGl2ZSBkb2N1bWVudHMgd2l0aCBkcmFmdClcblx0XHRpZiAoXG5cdFx0XHQhYklzRHJhZnQgfHxcblx0XHRcdCEoXG5cdFx0XHRcdCghb0NvbnRleHREYXRhLklzQWN0aXZlRW50aXR5ICYmIG9Db250ZXh0RGF0YS5IYXNBY3RpdmVFbnRpdHkpIHx8XG5cdFx0XHRcdChvQ29udGV4dERhdGEuSXNBY3RpdmVFbnRpdHkgJiYgb0NvbnRleHREYXRhLkhhc0RyYWZ0RW50aXR5KVxuXHRcdFx0KVxuXHRcdCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICghb0NvbnRleHREYXRhLklzQWN0aXZlRW50aXR5ICYmIG9Db250ZXh0RGF0YS5IYXNBY3RpdmVFbnRpdHkpIHtcblx0XHRcdC8vc3RhcnQgUG9pbnQ6IGVkaXQgZHJhZnRcblx0XHRcdGJFZGl0YWJsZSA9IGZhbHNlO1xuXHRcdH0gZWxzZSBpZiAob0NvbnRleHREYXRhLklzQWN0aXZlRW50aXR5ICYmIG9Db250ZXh0RGF0YS5IYXNEcmFmdEVudGl0eSkge1xuXHRcdFx0Ly8gc3RhcnQgcG9pbnQgYWN0aXZlIGRvY3VtZW50XG5cdFx0XHRiRWRpdGFibGUgPSB0cnVlO1xuXHRcdH1cblx0XHRvVG9nZ2xlQ29udGV4dFxuXHRcdFx0LnJlcXVlc3RDYW5vbmljYWxQYXRoKClcblx0XHRcdC50aGVuKGZ1bmN0aW9uKHNDYW5vbmljYWxQYXRoOiBhbnkpIHtcblx0XHRcdFx0Ly8gV2UgdXNlIHRoZSBjYW5vbmljYWwgcGF0aCBmb3IgdGhlIG5hdmlnYXRpb24gaW5zdGVhZCBvZiB0aGUgc2VtYW50aWMgcGF0aCwgYXMgdGhlXG5cdFx0XHRcdC8vIHNlbWFudGljIGtleSB2YWx1ZXMgbWF5IGhhdmUgY2hhbmdlZCBiZXR3ZWVuIHRoZSBkcmFmdCBhbmQgdGhlIGFjdGl2ZSB2ZXJzaW9uIChCQ1AgMjE3MDIxNjE0Milcblx0XHRcdFx0cmV0dXJuIG9Ub2dnbGVDb250ZXh0XG5cdFx0XHRcdFx0LmdldE1vZGVsKClcblx0XHRcdFx0XHQuYmluZENvbnRleHQoc0Nhbm9uaWNhbFBhdGgpXG5cdFx0XHRcdFx0LmdldEJvdW5kQ29udGV4dCgpO1xuXHRcdFx0fSlcblx0XHRcdC50aGVuKChvVG9nZ2xlQ29udGV4dDogYW55KSA9PiB7XG5cdFx0XHRcdHRoaXMuX3NldEVkaXRNb2RlKGJFZGl0YWJsZSA/IEVkaXRNb2RlLkVkaXRhYmxlIDogRWRpdE1vZGUuRGlzcGxheSwgZmFsc2UpOyAvL3N3aXRjaCB0byBlZGl0IG1vZGUgb25seSBpZiBhIGRyYWZ0IGlzIGF2YWlsYWJsZVxuXHRcdFx0XHR0aGlzLl9oYW5kbGVOZXdDb250ZXh0KG9Ub2dnbGVDb250ZXh0LCBiRWRpdGFibGUsIHRydWUsIHRydWUsIHRydWUpO1xuXHRcdFx0fSlcblx0XHRcdC5jYXRjaChmdW5jdGlvbihlcnI6IGFueSkge1xuXHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJFcnJvciBpbiBFZGl0Rmxvdy50b2dnbGVEcmFmdEFjdGl2ZTpcIiArIGVycik7XG5cdFx0XHR9KTtcblx0fVxuXG5cdC8vIEludGVybmFsIG9ubHkgcGFyYW1zIC0tLVxuXHQvLyBAcGFyYW0ge3NhcC5tLkJ1dHRvbn0gbVBhcmFtZXRlcnMuY2FuY2VsQnV0dG9uIC0gQ3VycmVudGx5IHRoaXMgaXMgcGFzc2VkIGFzIGNhbmNlbEJ1dHRvbiBpbnRlcm5hbGx5IChyZXBsYWNlZCBieSBtUGFyYW1ldGVycy5jb250cm9sIGluIHRoZSBKU0RvYyBiZWxvdykuIEN1cnJlbnRseSBpdCBpcyBhbHNvIG1hbmRhdG9yeS5cblx0Ly8gUGxhbiAtIFRoaXMgc2hvdWxkIG5vdCBiZSBtYW5kYXRvcnkuIElmIG5vdCBwcm92aWRlZCwgd2Ugc2hvdWxkIGhhdmUgYSBkZWZhdWx0IHRoYXQgY2FuIGFjdCBhcyByZWZlcmVuY2UgY29udHJvbCBmb3IgdGhlIGRpc2NhcmQgcG9wb3ZlciBPUiB3ZSBjYW4gc2hvdyBhIGRpYWxvZyBpbnN0ZWFkIG9mIGEgcG9wb3Zlci5cblxuXHQvKipcblx0ICogRGlzY2FyZCB0aGUgZWRpdGFibGUgZG9jdW1lbnQuXG5cdCAqXG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5jb250cm9sbGVyZXh0ZW5zaW9ucy5FZGl0Rmxvd1xuXHQgKiBAcGFyYW0ge29iamVjdH0gb0NvbnRleHQgIENvbnRleHQgb2YgdGhlIGVkaXRhYmxlIGRvY3VtZW50XG5cdCAqIEBwYXJhbSB7bWFwfSBtUGFyYW1ldGVycyBDYW4gY29udGFpbiB0aGUgZm9sbG93aW5nIGF0dHJpYnV0ZXM6XG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBtUGFyYW1ldGVycy5jb250cm9sIFRoaXMgaXMgdGhlIGNvbnRyb2wgdXNlZCB0byBvcGVuIHRoZSBkaXNjYXJkIHBvcG92ZXJcblx0ICogQHBhcmFtIHtib29sZWFufSBtUGFyYW1ldGVycy5za2lwRGlzY2FyZFBvcG92ZXIgT3B0aW9uYWwsIHN1cHJlc3NlcyB0aGUgZGlzY2FyZCBwb3BvdmVyIGFuZCBhbGxvd3MgY3VzdG9tIGhhbmRsaW5nXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHJlc29sdmVzIG9uY2UgZWRpdGFibGUgZG9jdW1lbnQgaGFzIGJlZW4gZGlzY2FyZGVkXG5cdCAqIEBhbGlhcyBzYXAuZmUuY29yZS5jb250cm9sbGVyZXh0ZW5zaW9ucy5FZGl0RmxvdyNjYW5jZWxEb2N1bWVudFxuXHQgKiBAcHVibGljXG5cdCAqIEBzaW5jZSAxLjkwLjBcblx0ICovXG5cdEBQdWJsaWNcblx0QEZpbmFsXG5cdGNhbmNlbERvY3VtZW50KG9Db250ZXh0OiBvYmplY3QsIG1QYXJhbWV0ZXJzOiB7IGNvbnRyb2w6IG9iamVjdDsgc2tpcERpc2NhcmRQb3BvdmVyPzogYm9vbGVhbiB9KTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Y29uc3QgdHJhbnNhY3Rpb25IZWxwZXIgPSB0aGlzLl9nZXRUcmFuc2FjdGlvbkhlbHBlcigpLFxuXHRcdFx0b1Jlc291cmNlQnVuZGxlID0gKHRoaXMuZ2V0VmlldygpLmdldENvbnRyb2xsZXIoKSBhcyBhbnkpLm9SZXNvdXJjZUJ1bmRsZTtcblx0XHRjb25zdCBtSW5QYXJhbWV0ZXJzOiBhbnkgPSBtUGFyYW1ldGVycztcblx0XHRtSW5QYXJhbWV0ZXJzLmNhbmNlbEJ1dHRvbiA9IG1QYXJhbWV0ZXJzLmNvbnRyb2wgfHwgbUluUGFyYW1ldGVycy5jYW5jZWxCdXR0b247XG5cdFx0bUluUGFyYW1ldGVycy5iZWZvcmVDYW5jZWxDYWxsQmFjayA9IHRoaXMuYmFzZS5lZGl0Rmxvdy5vbkJlZm9yZURpc2NhcmQ7XG5cdFx0cmV0dXJuIHRoaXMuX3N5bmNUYXNrKClcblx0XHRcdC50aGVuKFxuXHRcdFx0XHR0cmFuc2FjdGlvbkhlbHBlci5jYW5jZWxEb2N1bWVudC5iaW5kKHRyYW5zYWN0aW9uSGVscGVyLCBvQ29udGV4dCwgbVBhcmFtZXRlcnMsIG9SZXNvdXJjZUJ1bmRsZSwgdGhpcy5fZ2V0TWVzc2FnZUhhbmRsZXIoKSlcblx0XHRcdClcblx0XHRcdC50aGVuKChvQWN0aXZlRG9jdW1lbnRDb250ZXh0OiBhbnkpID0+IHtcblx0XHRcdFx0Y29uc3QgYkRyYWZ0TmF2aWdhdGlvbiA9IHRydWUsXG5cdFx0XHRcdFx0c1Byb2dyYW1taW5nTW9kZWwgPSB0aGlzLl9nZXRQcm9ncmFtbWluZ01vZGVsKG9Db250ZXh0KTtcblxuXHRcdFx0XHR0aGlzLl9yZW1vdmVDb250ZXh0c0Zyb21QYWdlcygpO1xuXHRcdFx0XHRpZiAoc1Byb2dyYW1taW5nTW9kZWwgPT09IFByb2dyYW1taW5nTW9kZWwuU3RpY2t5KSB7XG5cdFx0XHRcdFx0dGhpcy5fZ2V0SW50ZXJuYWxNb2RlbCgpLnNldFByb3BlcnR5KFwiL3Nlc3Npb25PblwiLCBmYWxzZSk7XG5cdFx0XHRcdFx0dGhpcy5faGFuZGxlU3RpY2t5T2ZmKC8qb0NvbnRleHQqLyk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRzZW5kKHRoaXMuZ2V0VmlldygpLCBBY3Rpdml0eS5EaXNjYXJkLCBvQWN0aXZlRG9jdW1lbnRDb250ZXh0KTtcblxuXHRcdFx0XHR0aGlzLl9zZXRFZGl0TW9kZShFZGl0TW9kZS5EaXNwbGF5LCBmYWxzZSk7XG5cdFx0XHRcdHRoaXMuX3NldERyYWZ0U3RhdHVzKERyYWZ0U3RhdHVzLkNsZWFyKTtcblxuXHRcdFx0XHQvL2luIGNhc2Ugb2YgYSBuZXcgZG9jdW1lbnQsIHRoZSB2YWx1ZSBvZiBoYXNBY3RpdmVFbnRpdHkgaXMgcmV0dXJuZWQuIG5hdmlnYXRlIGJhY2suXG5cdFx0XHRcdGlmICghb0FjdGl2ZURvY3VtZW50Q29udGV4dCkge1xuXHRcdFx0XHRcdEVkaXRTdGF0ZS5zZXRFZGl0U3RhdGVEaXJ0eSgpO1xuXHRcdFx0XHRcdHJldHVybiBtSW5QYXJhbWV0ZXJzLnNraXBCYWNrTmF2aWdhdGlvbiA/IHVuZGVmaW5lZCA6IHRoaXMuX2dldFJvdXRpbmdMaXN0ZW5lcigpLm5hdmlnYXRlQmFja0Zyb21Db250ZXh0KG9Db250ZXh0KTtcblx0XHRcdFx0fSBlbHNlIGlmIChzUHJvZ3JhbW1pbmdNb2RlbCA9PT0gUHJvZ3JhbW1pbmdNb2RlbC5EcmFmdCkge1xuXHRcdFx0XHRcdC8vIFdlIG5lZWQgdG8gbG9hZCB0aGUgc2VtYW50aWMga2V5cyBvZiB0aGUgYWN0aXZlIGNvbnRleHQsIGFzIHdlIG5lZWQgdGhlbVxuXHRcdFx0XHRcdC8vIGZvciB0aGUgbmF2aWdhdGlvblxuXHRcdFx0XHRcdHJldHVybiB0aGlzLl9mZXRjaFNlbWFudGljS2V5VmFsdWVzKG9BY3RpdmVEb2N1bWVudENvbnRleHQpLnRoZW4oKCkgPT4ge1xuXHRcdFx0XHRcdFx0Ly8gV2UgZm9yY2UgdGhlIHJlY3JlYXRpb24gb2YgdGhlIGNvbnRleHQsIHNvIHRoYXQgaXQncyBjcmVhdGVkIGFuZCBib3VuZCBpbiB0aGUgc2FtZSBtaWNyb3Rhc2ssXG5cdFx0XHRcdFx0XHQvLyBzbyB0aGF0IGFsbCBwcm9wZXJ0aWVzIGFyZSBsb2FkZWQgdG9nZXRoZXIgYnkgYXV0b0V4cGFuZFNlbGVjdCwgc28gdGhhdCB3aGVuIHN3aXRjaGluZyBiYWNrIHRvIEVkaXQgbW9kZVxuXHRcdFx0XHRcdFx0Ly8gJCRpbmhlcml0RXhwYW5kU2VsZWN0IHRha2VzIGFsbCBsb2FkZWQgcHJvcGVydGllcyBpbnRvIGFjY291bnQgKEJDUCAyMDcwNDYyMjY1KVxuXHRcdFx0XHRcdFx0aWYgKG1JblBhcmFtZXRlcnMuc2tpcEJpbmRpbmdUb1ZpZXcpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIG9BY3RpdmVEb2N1bWVudENvbnRleHQ7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdGhpcy5faGFuZGxlTmV3Q29udGV4dChvQWN0aXZlRG9jdW1lbnRDb250ZXh0LCBmYWxzZSwgdHJ1ZSwgYkRyYWZ0TmF2aWdhdGlvbiwgdHJ1ZSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly9hY3RpdmUgY29udGV4dCBpcyByZXR1cm5lZCBpbiBjYXNlIG9mIGNhbmNlbCBvZiBleGlzdGluZyBkb2N1bWVudFxuXHRcdFx0XHRcdHJldHVybiB0aGlzLl9oYW5kbGVOZXdDb250ZXh0KG9BY3RpdmVEb2N1bWVudENvbnRleHQsIGZhbHNlLCBmYWxzZSwgYkRyYWZ0TmF2aWdhdGlvbiwgdHJ1ZSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cdFx0XHQuY2F0Y2goZnVuY3Rpb24ob0Vycm9yOiBhbnkpIHtcblx0XHRcdFx0TG9nLmVycm9yKFwiRXJyb3Igd2hpbGUgZGlzY2FyZGluZyB0aGUgZG9jdW1lbnRcIiwgb0Vycm9yKTtcblx0XHRcdH0pO1xuXHR9XG5cblx0Ly8gSW50ZXJuYWwgb25seSBwYXJhbXMgLS0tXG5cdC8vIEBwYXJhbSB7c3RyaW5nfSBtUGFyYW1ldGVycy5lbnRpdHlTZXROYW1lIE5hbWUgb2YgdGhlIEVudGl0eVNldCB0byB3aGljaCB0aGUgb2JqZWN0IGJlbG9uZ3NcblxuXHQvKipcblx0ICogRGVsZXRlcyB0aGUgZG9jdW1lbnQuXG5cdCAqXG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5jb250cm9sbGVyZXh0ZW5zaW9ucy5FZGl0Rmxvd1xuXHQgKiBAcGFyYW0ge29iamVjdH0gb0NvbnRleHQgIENvbnRleHQgb2YgdGhlIGRvY3VtZW50XG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBtSW5QYXJhbWV0ZXJzIENhbiBjb250YWluIHRoZSBmb2xsb3dpbmcgYXR0cmlidXRlczpcblx0ICogQHBhcmFtIHtzdHJpbmd9IG1JblBhcmFtZXRlcnMudGl0bGUgVGl0bGUgb2YgdGhlIG9iamVjdCBiZWluZyBkZWxldGVkXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBtSW5QYXJhbWV0ZXJzLmRlc2NyaXB0aW9uIERlc2NyaXB0aW9uIG9mIHRoZSBvYmplY3QgYmVpbmcgZGVsZXRlZFxuXHQgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSByZXNvbHZlcyBvbmNlIGRvY3VtZW50IGhhcyBiZWVuIGRlbGV0ZWRcblx0ICogQGFsaWFzIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkVkaXRGbG93I2RlbGV0ZURvY3VtZW50XG5cdCAqIEBwdWJsaWNcblx0ICogQHNpbmNlIDEuOTAuMFxuXHQgKi9cblx0QFB1YmxpY1xuXHRARmluYWxcblx0ZGVsZXRlRG9jdW1lbnQob0NvbnRleHQ6IENvbnRleHQsIG1JblBhcmFtZXRlcnM6IHsgdGl0bGU6IHN0cmluZzsgZGVzY3JpcHRpb246IHN0cmluZyB9KTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Y29uc3Qgb0FwcENvbXBvbmVudCA9IENvbW1vblV0aWxzLmdldEFwcENvbXBvbmVudCh0aGlzLmdldFZpZXcoKSk7XG5cdFx0Y29uc3Qgc1BhdGggPSBvQ29udGV4dC5nZXRQYXRoKCk7XG5cdFx0bGV0IG1QYXJhbWV0ZXJzOiBhbnkgPSBtSW5QYXJhbWV0ZXJzO1xuXHRcdGlmICghbVBhcmFtZXRlcnMpIHtcblx0XHRcdG1QYXJhbWV0ZXJzID0ge1xuXHRcdFx0XHRiRmluZEFjdGl2ZUNvbnRleHRzOiBmYWxzZVxuXHRcdFx0fTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bVBhcmFtZXRlcnMuYkZpbmRBY3RpdmVDb250ZXh0cyA9IGZhbHNlO1xuXHRcdH1cblx0XHRtUGFyYW1ldGVycy5iZWZvcmVEZWxldGVDYWxsQmFjayA9IHRoaXMuYmFzZS5lZGl0Rmxvdy5vbkJlZm9yZURlbGV0ZTtcblx0XHRyZXR1cm4gdGhpcy5fZGVsZXRlRG9jdW1lbnRUcmFuc2FjdGlvbihvQ29udGV4dCwgbVBhcmFtZXRlcnMpXG5cdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdC8vIFNpbmdsZSBvYmpldCBkZWxldGlvbiBpcyB0cmlnZ2VyZWQgZnJvbSBhbiBPUCBoZWFkZXIgYnV0dG9uIChub3QgZnJvbSBhIGxpc3QpXG5cdFx0XHRcdC8vIC0tPiBNYXJrIFVJIGRpcnR5IGFuZCBuYXZpZ2F0ZSBiYWNrIHRvIGRpc21pc3MgdGhlIE9QXG5cdFx0XHRcdEVkaXRTdGF0ZS5zZXRFZGl0U3RhdGVEaXJ0eSgpO1xuXG5cdFx0XHRcdHNlbmQodGhpcy5nZXRWaWV3KCksIEFjdGl2aXR5LkRlbGV0ZSwgc1BhdGgpO1xuXG5cdFx0XHRcdHRoaXMuX2dldFJvdXRpbmdMaXN0ZW5lcigpLm5hdmlnYXRlQmFja0Zyb21Db250ZXh0KG9Db250ZXh0KTtcblx0XHRcdFx0Ly8gQWZ0ZXIgZGVsZXRlIGlzIHN1Y2Nlc3NmdWxsLCB3ZSBuZWVkIHRvIGRldHRjaCB0aGUgc2V0QmFja05hdmlnYXRpb24gTWV0aG9kc1xuXHRcdFx0XHRpZiAob0FwcENvbXBvbmVudCkge1xuXHRcdFx0XHRcdG9BcHBDb21wb25lbnQuZ2V0U2hlbGxTZXJ2aWNlcygpLnNldEJhY2tOYXZpZ2F0aW9uKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cdFx0XHQuY2F0Y2goZnVuY3Rpb24ob0Vycm9yOiBhbnkpIHtcblx0XHRcdFx0TG9nLmVycm9yKFwiRXJyb3Igd2hpbGUgZGVsZXRpbmcgdGhlIGRvY3VtZW50XCIsIG9FcnJvcik7XG5cdFx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTdWJtaXQgdGhlIGN1cnJlbnQgc2V0IG9mIGNoYW5nZXMgYW5kIG5hdmlnYXRlIGJhY2suXG5cdCAqXG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5jb250cm9sbGVyZXh0ZW5zaW9ucy5FZGl0Rmxvd1xuXHQgKiBAcGFyYW0ge29iamVjdH0gb0NvbnRleHQgIENvbnRleHQgb2YgdGhlIGRvY3VtZW50XG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHJlc29sdmVzIG9uY2UgdGhlIGNoYW5nZXMgaGF2ZSBiZWVuIHNhdmVkXG5cdCAqIEBhbGlhcyBzYXAuZmUuY29yZS5jb250cm9sbGVyZXh0ZW5zaW9ucy5FZGl0RmxvdyNhcHBseURvY3VtZW50XG5cdCAqIEBwdWJsaWNcblx0ICogQHNpbmNlIDEuOTAuMFxuXHQgKi9cblx0QFB1YmxpY1xuXHRARmluYWxcblx0YXBwbHlEb2N1bWVudChvQ29udGV4dDogb2JqZWN0KTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Y29uc3Qgb0xvY2tPYmplY3QgPSB0aGlzLl9nZXRHbG9iYWxVSU1vZGVsKCk7XG5cdFx0QnVzeUxvY2tlci5sb2NrKG9Mb2NrT2JqZWN0KTtcblx0XHRyZXR1cm4gKFxuXHRcdFx0dGhpcy5fc3VibWl0T3BlbkNoYW5nZXMob0NvbnRleHQpXG5cdFx0XHRcdC8vIGNoZWNrIGlmIHRoZXJlIGFyZSBhbnkgdmFsaWRhdGlvbi9wYXJzZSBlcnJvcnNcblx0XHRcdFx0LnRoZW4odGhpcy5fY2hlY2tGb3JWYWxpZGF0aW9uRXJyb3JzLmJpbmQodGhpcywgb0NvbnRleHQpKVxuXHRcdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5fZ2V0TWVzc2FnZUhhbmRsZXIoKS5zaG93TWVzc2FnZURpYWxvZygpO1xuXHRcdFx0XHRcdHRoaXMuX2dldFJvdXRpbmdMaXN0ZW5lcigpLm5hdmlnYXRlQmFja0Zyb21Db250ZXh0KG9Db250ZXh0KTtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fSlcblx0XHRcdFx0LmZpbmFsbHkoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0aWYgKEJ1c3lMb2NrZXIuaXNMb2NrZWQob0xvY2tPYmplY3QpKSB7XG5cdFx0XHRcdFx0XHRCdXN5TG9ja2VyLnVubG9jayhvTG9ja09iamVjdCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KVxuXHRcdCk7XG5cdH1cblxuXHQvLyBJbnRlcm5hbCBvbmx5IHBhcmFtcyAtLS1cblx0Ly8gQHBhcmFtIHtib29sZWFufSBbbVBhcmFtZXRlcnMuYlN0YXRpY0FjdGlvbl0gQm9vbGVhbiB2YWx1ZSBmb3Igc3RhdGljIGFjdGlvbiwgdW5kZWZpbmVkIGZvciBvdGhlciBhY3Rpb25zXG5cdC8vIEBwYXJhbSB7Ym9vbGVhbn0gW21QYXJhbWV0ZXJzLmlzTmF2aWdhYmxlXSBCb29sZWFuIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciBuYXZpZ2F0aW9uIGlzIHJlcXVpcmVkIGFmdGVyIHRoZSBhY3Rpb24gaGFzIGJlZW4gZXhlY3V0ZWRcblx0Ly8gQ3VycmVudGx5IHRoZSBwYXJhbWV0ZXIgaXNOYXZpZ2FibGUgaXMgdXNlZCBpbnRlcm5hbGx5IGFuZCBzaG91bGQgYmUgY2hhbmdlZCB0byByZXF1aXJlc05hdmlnYXRpb24gYXMgaXQgaXMgYSBtb3JlIGFwdCBuYW1lIGZvciB0aGlzIHBhcmFtXG5cblx0LyoqXG5cdCAqIEludm9rZXMgYW4gYWN0aW9uIChib3VuZCBvciB1bmJvdW5kKSBhbmQgdHJhY2tzIHRoZSBjaGFuZ2VzIHNvIHRoYXQgb3RoZXIgcGFnZXMgY2FuIGJlIHJlZnJlc2hlZCBhbmQgc2hvdyB0aGUgdXBkYXRlZCBkYXRhIHVwb24gbmF2aWdhdGlvbi5cblx0ICpcblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkVkaXRGbG93XG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzQWN0aW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgYWN0aW9uIHRvIGJlIGNhbGxlZFxuXHQgKiBAcGFyYW0ge29iamVjdH0gbUluUGFyYW1ldGVycyBDb250YWlucyB0aGUgZm9sbG93aW5nIGF0dHJpYnV0ZXM6XG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHR9IG1JblBhcmFtZXRlcnMuY29udGV4dHMgRm9yIGEgYm91bmQgYWN0aW9uLCBhIGNvbnRleHQgb3IgYW4gYXJyYXkgd2l0aCBjb250ZXh0cyBmb3Igd2hpY2ggdGhlIGFjdGlvbiBpcyB0byBiZSBjYWxsZWQgbXVzdCBiZSBwcm92aWRlZFxuXHQgKiBAcGFyYW0ge3NhcC51aS5tb2RlbC5vZGF0YS52NC5PRGF0YU1vZGVsfSBtSW5QYXJhbWV0ZXJzLm1vZGVsIEZvciBhbiB1bmJvdW5kIGFjdGlvbiwgYW4gaW5zdGFuY2Ugb2YgYW4gT0RhdGEgVjQgbW9kZWwgbXVzdCBiZSBwcm92aWRlZFxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IG1JblBhcmFtZXRlcnMucmVxdWlyZXNOYXZpZ2F0aW9uIEJvb2xlYW4gdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIG5hdmlnYXRpb24gaXMgcmVxdWlyZWQgYWZ0ZXIgdGhlIGFjdGlvbiBoYXMgYmVlbiBleGVjdXRlZC4gTmF2aWdhdGlvbiB0YWtlcyBwbGFjZSB0byB0aGUgY29udGV4dCByZXR1cm5lZCBieSB0aGUgYWN0aW9uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBtSW5QYXJhbWV0ZXJzLmxhYmVsIEEgaHVtYW4tcmVhZGFibGUgbGFiZWwgZm9yIHRoZSBhY3Rpb24uIFRoaXMgaXMgbmVlZGVkIGluIGNhc2UgdGhlIGFjdGlvbiBoYXMgYSBwYXJhbWV0ZXIgYW5kIGEgcGFyYW1ldGVyIGRpYWxvZyBpcyBzaG93biB0byB0aGUgdXNlci4gVGhlIGxhYmVsIHdpbGwgYmUgdXNlZCBmb3IgdGhlIHRpdGxlIG9mIHRoZSBkaWFsb2cgYW5kIGZvciB0aGUgY29uZmlybWF0aW9uIGJ1dHRvblxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbUluUGFyYW1ldGVycy5pbnZvY2F0aW9uR3JvdXBpbmcgTW9kZSBob3cgYWN0aW9ucyBhcmUgdG8gYmUgY2FsbGVkOiAnQ2hhbmdlU2V0JyB0byBwdXQgYWxsIGFjdGlvbiBjYWxscyBpbnRvIG9uZSBjaGFuZ2VzZXQsICdJc29sYXRlZCcgdG8gcHV0IHRoZW0gaW50byBzZXBhcmF0ZSBjaGFuZ2VzZXRzXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBtRXh0cmFQYXJhbXMgUFJJVkFURVxuXHQgKiBAcmV0dXJucyB7UHJvbWlzZX1cblx0ICogQGFsaWFzIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkVkaXRGbG93I2ludm9rZUFjdGlvblxuXHQgKiBAcHVibGljXG5cdCAqIEBzaW5jZSAxLjkwLjBcblx0ICogQGZpbmFsXG5cdCAqKi9cblx0QFB1YmxpY1xuXHRARmluYWxcblx0aW52b2tlQWN0aW9uKFxuXHRcdHNBY3Rpb25OYW1lOiBzdHJpbmcsXG5cdFx0bUluUGFyYW1ldGVycz86IHtcblx0XHRcdGNvbnRleHRzPzogQ29udGV4dCB8IENvbnRleHRbXTtcblx0XHRcdG1vZGVsPzogT0RhdGFNb2RlbDtcblx0XHRcdHJlcXVpcmVzTmF2aWdhdGlvbj86IGJvb2xlYW47XG5cdFx0XHRsYWJlbD86IHN0cmluZztcblx0XHRcdGludm9jYXRpb25Hcm91cGluZz86IHN0cmluZztcblx0XHR9LFxuXHRcdG1FeHRyYVBhcmFtcz86IGFueVxuXHQpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRsZXQgb0NvbnRyb2w6IGFueTtcblx0XHRjb25zdCB0cmFuc2FjdGlvbkhlbHBlciA9IHRoaXMuX2dldFRyYW5zYWN0aW9uSGVscGVyKCk7XG5cdFx0bGV0IG9DdXJyZW50Q29udHJvbDtcblx0XHRsZXQgb0JpbmRpbmdDb250ZXh0O1xuXHRcdGxldCBhUGFydHM7XG5cdFx0bGV0IHNPdmVybG9hZEVudGl0eVR5cGU7XG5cdFx0bGV0IG9DdXJyZW50QWN0aW9uQ2FsbEJhY2tzOiBhbnk7XG5cdFx0Y29uc3Qgb1ZpZXcgPSB0aGlzLmdldFZpZXcoKTtcblxuXHRcdGxldCBtUGFyYW1ldGVyczogYW55ID0gbUluUGFyYW1ldGVycyB8fCB7fTtcblxuXHRcdC8vIER1ZSB0byBhIG1pc3Rha2UgdGhlIGludm9rZUFjdGlvbiBpbiB0aGUgZXh0ZW5zaW9uQVBJIGhhZCBhIGRpZmZlcmVudCBBUEkgdGhhbiB0aGlzIG9uZS5cblx0XHQvLyBUaGUgb25lIGZyb20gdGhlIGV4dGVuc2lvbkFQSSBkb2Vzbid0IGV4aXN0IGFueW1vcmUgYXMgd2UgZXhwb3NlIHRoZSBmdWxsIGVkaXQgZmxvdyBub3cgYnV0XG5cdFx0Ly8gZHVlIHRvIGNvbXBhdGliaWxpdHkgcmVhc29ucyB3ZSBzdGlsbCBuZWVkIHRvIHN1cHBvcnQgdGhlIG9sZCBzaWduYXR1cmVcblx0XHRpZiAoKG1QYXJhbWV0ZXJzLmlzQSAmJiBtUGFyYW1ldGVycy5pc0EoXCJzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dFwiKSkgfHwgQXJyYXkuaXNBcnJheShtUGFyYW1ldGVycykgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMykge1xuXHRcdFx0Y29uc3QgY29udGV4dHMgPSBtUGFyYW1ldGVycztcblx0XHRcdG1QYXJhbWV0ZXJzID0gbUV4dHJhUGFyYW1zIHx8IHt9O1xuXHRcdFx0aWYgKGNvbnRleHRzKSB7XG5cdFx0XHRcdG1QYXJhbWV0ZXJzLmNvbnRleHRzID0gY29udGV4dHM7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRtUGFyYW1ldGVycy5tb2RlbCA9IHRoaXMuZ2V0VmlldygpLmdldE1vZGVsKCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0bVBhcmFtZXRlcnMuaXNOYXZpZ2FibGUgPSBtUGFyYW1ldGVycy5yZXF1aXJlc05hdmlnYXRpb24gfHwgbVBhcmFtZXRlcnMuaXNOYXZpZ2FibGU7XG5cblx0XHRpZiAoIW1QYXJhbWV0ZXJzLnBhcmVudENvbnRyb2wpIHtcblx0XHRcdG1QYXJhbWV0ZXJzLnBhcmVudENvbnRyb2wgPSB0aGlzLmdldFZpZXcoKTtcblx0XHR9XG5cblx0XHRpZiAobVBhcmFtZXRlcnMuY29udHJvbElkKSB7XG5cdFx0XHRvQ29udHJvbCA9IHRoaXMuZ2V0VmlldygpLmJ5SWQobVBhcmFtZXRlcnMuY29udHJvbElkKTtcblx0XHRcdGlmIChvQ29udHJvbCkge1xuXHRcdFx0XHQvLyBUT0RPOiBjdXJyZW50bHkgdGhpcyBzZWxlY3RlZCBjb250ZXh0cyB1cGRhdGUgaXMgZG9uZSB3aXRoaW4gdGhlIG9wZXJhdGlvbiwgc2hvdWxkIGJlIG1vdmVkIG91dFxuXHRcdFx0XHRtUGFyYW1ldGVycy5pbnRlcm5hbE1vZGVsQ29udGV4dCA9IG9Db250cm9sLmdldEJpbmRpbmdDb250ZXh0KFwiaW50ZXJuYWxcIik7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdG1QYXJhbWV0ZXJzLmludGVybmFsTW9kZWxDb250ZXh0ID0gb1ZpZXcuZ2V0QmluZGluZ0NvbnRleHQoXCJpbnRlcm5hbFwiKTtcblx0XHR9XG5cblx0XHRpZiAoc0FjdGlvbk5hbWUgJiYgc0FjdGlvbk5hbWUuaW5kZXhPZihcIihcIikgPiAtMSkge1xuXHRcdFx0Ly8gZ2V0IGVudGl0eSB0eXBlIG9mIGFjdGlvbiBvdmVybG9hZCBhbmQgcmVtb3ZlIGl0IGZyb20gdGhlIGFjdGlvbiBwYXRoXG5cdFx0XHQvLyBFeGFtcGxlIHNBY3Rpb25OYW1lID0gXCI8QWN0aW9uTmFtZT4oQ29sbGVjdGlvbig8T3ZlcmxvYWRFbnRpdHlUeXBlPikpXCJcblx0XHRcdC8vIHNBY3Rpb25OYW1lID0gYVBhcnRzWzBdIC0tPiA8QWN0aW9uTmFtZT5cblx0XHRcdC8vIHNPdmVybG9hZEVudGl0eVR5cGUgPSBhUGFydHNbMl0gLS0+IDxPdmVybG9hZEVudGl0eVR5cGU+XG5cdFx0XHRhUGFydHMgPSBzQWN0aW9uTmFtZS5zcGxpdChcIihcIik7XG5cdFx0XHRzQWN0aW9uTmFtZSA9IGFQYXJ0c1swXTtcblx0XHRcdHNPdmVybG9hZEVudGl0eVR5cGUgPSAoYVBhcnRzW2FQYXJ0cy5sZW5ndGggLSAxXSBhcyBhbnkpLnJlcGxhY2VBbGwoXCIpXCIsIFwiXCIpO1xuXHRcdH1cblxuXHRcdGlmIChtUGFyYW1ldGVycy5iU3RhdGljQWN0aW9uKSB7XG5cdFx0XHRpZiAob0NvbnRyb2wuaXNUYWJsZUJvdW5kKCkpIHtcblx0XHRcdFx0bVBhcmFtZXRlcnMuY29udGV4dHMgPSBvQ29udHJvbC5nZXRSb3dCaW5kaW5nKCkuZ2V0SGVhZGVyQ29udGV4dCgpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29uc3Qgc0JpbmRpbmdQYXRoID0gb0NvbnRyb2wuZGF0YShcInJvd3NCaW5kaW5nSW5mb1wiKS5wYXRoLFxuXHRcdFx0XHRcdG9MaXN0QmluZGluZyA9IG5ldyAoT0RhdGFMaXN0QmluZGluZyBhcyBhbnkpKHRoaXMuZ2V0VmlldygpLmdldE1vZGVsKCksIHNCaW5kaW5nUGF0aCk7XG5cdFx0XHRcdG1QYXJhbWV0ZXJzLmNvbnRleHRzID0gb0xpc3RCaW5kaW5nLmdldEhlYWRlckNvbnRleHQoKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHNPdmVybG9hZEVudGl0eVR5cGUpIHtcblx0XHRcdFx0Y29uc3Qgc1RhYmxlQ29udGV4dEVudGl0eVR5cGUgPSBtUGFyYW1ldGVycy5jb250ZXh0c1xuXHRcdFx0XHRcdC5nZXRNb2RlbCgpXG5cdFx0XHRcdFx0LmdldE1ldGFNb2RlbCgpXG5cdFx0XHRcdFx0LmdldE1ldGFDb250ZXh0KG1QYXJhbWV0ZXJzLmNvbnRleHRzLmdldFBhdGgoKSlcblx0XHRcdFx0XHQuZ2V0T2JqZWN0KFwiJFR5cGVcIik7XG5cdFx0XHRcdGlmIChzT3ZlcmxvYWRFbnRpdHlUeXBlICE9PSBzVGFibGVDb250ZXh0RW50aXR5VHlwZSkge1xuXHRcdFx0XHRcdC8vIHNlYXJjaCBmb3IgY29udGV4dCBpbiBjb250cm9sIHRyZWUgaGllcmFyY2h5XG5cdFx0XHRcdFx0b0N1cnJlbnRDb250cm9sID0gb0NvbnRyb2w7XG5cdFx0XHRcdFx0d2hpbGUgKG9DdXJyZW50Q29udHJvbCkge1xuXHRcdFx0XHRcdFx0b0JpbmRpbmdDb250ZXh0ID0gb0N1cnJlbnRDb250cm9sLmdldEJpbmRpbmdDb250ZXh0KCk7XG5cdFx0XHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0XHRcdG9CaW5kaW5nQ29udGV4dCAmJlxuXHRcdFx0XHRcdFx0XHRvQmluZGluZ0NvbnRleHRcblx0XHRcdFx0XHRcdFx0XHQuZ2V0TW9kZWwoKVxuXHRcdFx0XHRcdFx0XHRcdC5nZXRNZXRhTW9kZWwoKVxuXHRcdFx0XHRcdFx0XHRcdC5nZXRNZXRhQ29udGV4dChvQmluZGluZ0NvbnRleHQuZ2V0UGF0aCgpKVxuXHRcdFx0XHRcdFx0XHRcdC5nZXRPYmplY3QoXCIkVHlwZVwiKSA9PT0gc092ZXJsb2FkRW50aXR5VHlwZVxuXHRcdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmNvbnRleHRzID0gb0JpbmRpbmdDb250ZXh0O1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdC8vIGNoZWNrIHBhcmVudFxuXHRcdFx0XHRcdFx0XHRvQ3VycmVudENvbnRyb2wgPSBvQ3VycmVudENvbnRyb2wuZ2V0UGFyZW50KCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdC8vIGNvbnRleHQgd2FzIG5vdCBmb3VuZCBpbiBVSSBoaWVyYXJjaHkgZ29pbmcgc3RyYWlnaHQgdXB3YXJkcyAtIHRyeSB0byBmaW5kIGl0IGluIFN1YlNlY3Rpb25zXG5cdFx0XHRcdFx0aWYgKCFvQ3VycmVudENvbnRyb2wpIHtcblx0XHRcdFx0XHRcdGNvbnN0IG9BY3Rpb25PdmVybG9hZENvbnRleHQgPSB0aGlzLl9nZXRBY3Rpb25PdmVybG9hZENvbnRleHRGcm9tU3ViU2VjdGlvbnMob0NvbnRyb2wsIHNPdmVybG9hZEVudGl0eVR5cGUpO1xuXHRcdFx0XHRcdFx0aWYgKG9BY3Rpb25PdmVybG9hZENvbnRleHQgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5jb250ZXh0cyA9IG9BY3Rpb25PdmVybG9hZENvbnRleHQ7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0aWYgKCFtUGFyYW1ldGVycy5jb250ZXh0cykge1xuXHRcdFx0XHRcdFx0cmV0dXJuIFByb21pc2UucmVqZWN0KFwiQ29udGV4dCBub3QgZm91bmQgZm9yIGVudGl0eSB0eXBlIFwiICsgc092ZXJsb2FkRW50aXR5VHlwZSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmIChtUGFyYW1ldGVycy5lbmFibGVBdXRvU2Nyb2xsKSB7XG5cdFx0XHRcdG9DdXJyZW50QWN0aW9uQ2FsbEJhY2tzID0gdGhpcy5fY3JlYXRlQWN0aW9uUHJvbWlzZShzQWN0aW9uTmFtZSwgb0NvbnRyb2wuc0lkKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAobVBhcmFtZXRlcnMuaXNOYXZpZ2FibGUpIHtcblx0XHRcdG1QYXJhbWV0ZXJzLmJHZXRCb3VuZENvbnRleHQgPSBmYWxzZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bVBhcmFtZXRlcnMuYkdldEJvdW5kQ29udGV4dCA9IHRydWU7XG5cdFx0fVxuXHRcdC8vIE5lZWQgdG8ga25vdyB0aGF0IHRoZSBhY3Rpb24gaXMgY2FsbGVkIGZyb20gT2JqZWN0UGFnZSBmb3IgY2hhbmdlU2V0IElzb2xhdGVkIHdvcmthcm91bmRcblx0XHRtUGFyYW1ldGVycy5iT2JqZWN0UGFnZSA9IChvVmlldy5nZXRWaWV3RGF0YSgpIGFzIGFueSkuY29udmVydGVyVHlwZSA9PT0gXCJPYmplY3RQYWdlXCI7XG5cdFx0cmV0dXJuIHRoaXMuX3N5bmNUYXNrKClcblx0XHRcdC50aGVuKHRyYW5zYWN0aW9uSGVscGVyLmNhbGxBY3Rpb24uYmluZCh0cmFuc2FjdGlvbkhlbHBlciwgc0FjdGlvbk5hbWUsIG1QYXJhbWV0ZXJzLCB0aGlzLmdldFZpZXcoKSwgdGhpcy5fZ2V0TWVzc2FnZUhhbmRsZXIoKSkpXG5cdFx0XHQudGhlbigob1Jlc3BvbnNlOiBhbnkpID0+IHtcblx0XHRcdFx0Ly8gaWYgdGhlIHJldHVybmVkIGNvbnRleHQgZm9yIHRoZSBib3VuZCBhY3Rpb24gaXMgZGlmZmVyZW50IHRoYW4gdGhlIGNvbnRleHQgb24gd2hpY2ggYWN0aW9uIHdhcyBjYWxsZWQsXG5cdFx0XHRcdC8vIHJlZnJlc2ggdGhlIGNvcnJlc3BvbmRpbmcgbGlzdCBiaW5kaW5nXG5cdFx0XHRcdGlmIChtUGFyYW1ldGVycy5jb250ZXh0cykge1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLl9yZWZyZXNoTGlzdElmUmVxdWlyZWQoXG5cdFx0XHRcdFx0XHR0aGlzLl9nZXRBY3Rpb25SZXNwb25zZURhdGFBbmRLZXlzKHNBY3Rpb25OYW1lLCBvUmVzcG9uc2UpLFxuXHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMuY29udGV4dHNbMF1cblx0XHRcdFx0XHQpLnRoZW4oZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gb1Jlc3BvbnNlO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdFx0LnRoZW4oKG9SZXNwb25zZTogYW55KSA9PiB7XG5cdFx0XHRcdHNlbmQodGhpcy5nZXRWaWV3KCksIEFjdGl2aXR5LkFjdGlvbiwgbVBhcmFtZXRlcnMuY29udGV4dHMpO1xuXG5cdFx0XHRcdGlmIChvQ3VycmVudEFjdGlvbkNhbGxCYWNrcykge1xuXHRcdFx0XHRcdG9DdXJyZW50QWN0aW9uQ2FsbEJhY2tzLmZSZXNvbHZlcihvUmVzcG9uc2UpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8qXG5cdFx0XHRcdFx0IFdlIHNldCB0aGUgKHVwcGVyKSBwYWdlcyB0byBkaXJ0eSBhZnRlciBhbiBleGVjdXRpb24gb2YgYW4gYWN0aW9uXG5cdFx0XHRcdFx0IFRPRE86IGdldCByaWQgb2YgdGhpcyB3b3JrYXJvdW5kXG5cdFx0XHRcdFx0IFRoaXMgd29ya2Fyb3VuZCBpcyBvbmx5IG5lZWRlZCBhcyBsb25nIGFzIHRoZSBtb2RlbCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBzeW5jaHJvbml6YXRpb24uXG5cdFx0XHRcdFx0IE9uY2UgdGhpcyBpcyBzdXBwb3J0ZWQgd2UgZG9uJ3QgbmVlZCB0byBzZXQgdGhlIHBhZ2VzIHRvIGRpcnR5IGFueW1vcmUgYXMgdGhlIGNvbnRleHQgaXRzZWxmXG5cdFx0XHRcdFx0IGlzIGFscmVhZHkgcmVmcmVzaGVkIChpdCdzIGp1c3Qgbm90IHJlZmxlY3RlZCBpbiB0aGUgb2JqZWN0IHBhZ2UpXG5cdFx0XHRcdFx0IHdlIGV4cGxpY2l0bHkgZG9uJ3QgY2FsbCB0aGlzIG1ldGhvZCBmcm9tIHRoZSBsaXN0IHJlcG9ydCBidXQgb25seSBjYWxsIGl0IGZyb20gdGhlIG9iamVjdCBwYWdlXG5cdFx0XHRcdFx0IGFzIGlmIGl0IGlzIGNhbGxlZCBpbiB0aGUgbGlzdCByZXBvcnQgaXQncyBub3QgbmVlZGVkIC0gYXMgd2UgYW55d2F5IHdpbGwgcmVtb3ZlIHRoaXMgbG9naWNcblx0XHRcdFx0XHQgd2UgY2FuIGxpdmUgd2l0aCB0aGlzXG5cdFx0XHRcdFx0IHdlIG5lZWQgYSBjb250ZXh0IHRvIHNldCB0aGUgdXBwZXIgcGFnZXMgdG8gZGlydHkgLSBpZiB0aGVyZSBhcmUgbW9yZSB0aGFuIG9uZSB3ZSB1c2UgdGhlXG5cdFx0XHRcdFx0IGZpcnN0IG9uZSBhcyB0aGV5IGFyZSBhbnl3YXkgc2libGluZ3Ncblx0XHRcdFx0XHQgKi9cblx0XHRcdFx0aWYgKG1QYXJhbWV0ZXJzLmNvbnRleHRzKSB7XG5cdFx0XHRcdFx0RWRpdFN0YXRlLnNldEVkaXRTdGF0ZURpcnR5KCk7XG5cdFx0XHRcdFx0dGhpcy5fZ2V0SW50ZXJuYWxNb2RlbCgpLnNldFByb3BlcnR5KFwiL3NDdXN0b21BY3Rpb25cIiwgc0FjdGlvbk5hbWUpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChtUGFyYW1ldGVycy5pc05hdmlnYWJsZSkge1xuXHRcdFx0XHRcdGxldCB2Q29udGV4dCA9IG9SZXNwb25zZTtcblx0XHRcdFx0XHRpZiAoQXJyYXkuaXNBcnJheSh2Q29udGV4dCkgJiYgdkNvbnRleHQubGVuZ3RoID09PSAxKSB7XG5cdFx0XHRcdFx0XHR2Q29udGV4dCA9IHZDb250ZXh0WzBdO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAodkNvbnRleHQgJiYgIUFycmF5LmlzQXJyYXkodkNvbnRleHQpKSB7XG5cdFx0XHRcdFx0XHRjb25zdCBvTWV0YU1vZGVsID0gb1ZpZXcuZ2V0TW9kZWwoKS5nZXRNZXRhTW9kZWwoKSBhcyBPRGF0YU1ldGFNb2RlbDtcblx0XHRcdFx0XHRcdGNvbnN0IHNDb250ZXh0TWV0YVBhdGggPSBvTWV0YU1vZGVsLmdldE1ldGFQYXRoKHZDb250ZXh0LmdldFBhdGgoKSk7XG5cdFx0XHRcdFx0XHRjb25zdCBvQWN0aW9uQ29udGV4dCA9IEFycmF5LmlzQXJyYXkobVBhcmFtZXRlcnMuY29udGV4dHMpID8gbVBhcmFtZXRlcnMuY29udGV4dHNbMF0gOiBtUGFyYW1ldGVycy5jb250ZXh0cztcblx0XHRcdFx0XHRcdGNvbnN0IHNBY3Rpb25Db250ZXh0TWV0YVBhdGggPSBvQWN0aW9uQ29udGV4dCAmJiBvTWV0YU1vZGVsLmdldE1ldGFQYXRoKG9BY3Rpb25Db250ZXh0LmdldFBhdGgoKSk7XG5cdFx0XHRcdFx0XHRpZiAoc0NvbnRleHRNZXRhUGF0aCAhPSB1bmRlZmluZWQgJiYgc0NvbnRleHRNZXRhUGF0aCA9PT0gc0FjdGlvbkNvbnRleHRNZXRhUGF0aCkge1xuXHRcdFx0XHRcdFx0XHRpZiAob0FjdGlvbkNvbnRleHQuZ2V0UGF0aCgpICE9PSB2Q29udGV4dC5nZXRQYXRoKCkpIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLl9nZXRSb3V0aW5nTGlzdGVuZXIoKS5uYXZpZ2F0ZUZvcndhcmRUb0NvbnRleHQodkNvbnRleHQsIHtcblx0XHRcdFx0XHRcdFx0XHRcdG5vSGlzdG9yeUVudHJ5OiBmYWxzZVxuXHRcdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdExvZy5pbmZvKFwiTmF2aWdhdGlvbiB0byB0aGUgc2FtZSBjb250ZXh0IGlzIG5vdCBhbGxvd2VkXCIpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdFx0LmNhdGNoKGZ1bmN0aW9uKGVycjogYW55KSB7XG5cdFx0XHRcdGlmIChvQ3VycmVudEFjdGlvbkNhbGxCYWNrcykge1xuXHRcdFx0XHRcdG9DdXJyZW50QWN0aW9uQ2FsbEJhY2tzLmZSZWplY3RvcigpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChlcnIgPT0gQ29uc3RhbnRzLkNhbmNlbEFjdGlvbkRpYWxvZykge1xuXHRcdFx0XHRcdHJldHVybiBQcm9taXNlLnJlamVjdChcIkRpYWxvZ8KgY2FuY2VsbGVkLlwiKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJFcnJvciBpbiBFZGl0Rmxvdy5pbnZva2VBY3Rpb246XCIgKyBlcnIpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZWN1cmVkIGV4ZWN1dGlvbiBvZiB0aGUgZ2l2ZW4gZnVuY3Rpb24uIEVuc3VyZXMgdGhhdCB0aGUgZnVuY3Rpb24gaXMgb25seSBleGVjdXRlZCB3aGVuIGNlcnRhaW4gY29uZGl0aW9ucyBhcmUgZnVsZmlsbGVkLlxuXHQgKlxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuY29udHJvbGxlcmV4dGVuc2lvbnMuRWRpdEZsb3dcblx0ICogQHBhcmFtIHtGdW5jdGlvbn0gZm5GdW5jdGlvbiBUaGUgZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQuIFNob3VsZCByZXR1cm4gYSBwcm9taXNlIHRoYXQgaXMgc2V0dGxlZCBhZnRlciBjb21wbGV0aW9uIG9mIHRoZSBleGVjdXRpb24uIElmIG5vdGhpbmcgaXMgcmV0dXJuZWQsIGltbWVkaWF0ZSBjb21wbGV0aW9uIGlzIGFzc3VtZWQuXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBtUGFyYW1ldGVycyBEZWZpbml0aW9ucyBvZiB0aGUgcHJlY29uZGl0aW9ucyB0byBiZSBjaGVja2VkIGJlZm9yZSBleGVjdXRpb25cblx0ICogQHBhcmFtIHtvYmplY3R9IG1QYXJhbWV0ZXJzLmJ1c3kgRGVmaW5lcyB0aGUgYnVzeSBpbmRpY2F0b3Jcblx0ICogQHBhcmFtIHtib29sZWFufSBtUGFyYW1ldGVycy5idXN5LnNldCBUcmlnZ2VycyBhIGJ1c3kgaW5kaWNhdG9yIHdoZW4gdGhlIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkLlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IG1QYXJhbWV0ZXJzLmJ1c3kuY2hlY2sgRXhlY3V0ZXMgZnVuY3Rpb24gb25seSBpZiBhcHBsaWNhdGlvbiBpc24ndCBidXN5LlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IG1QYXJhbWV0ZXJzLnVwZGF0ZXNEb2N1bWVudCBUaGlzIG9wZXJhdGlvbiB1cGRhdGVzIHRoZSBjdXJyZW50IGRvY3VtZW50IHdpdGhvdXQgdXNpbmcgdGhlIGJvdW5kIG1vZGVsIGFuZCBjb250ZXh0LiBBcyBhIHJlc3VsdCwgdGhlIGRyYWZ0IHN0YXR1cyBpcyB1cGRhdGVkIGlmIGEgZHJhZnQgZG9jdW1lbnQgZXhpc3RzLCBhbmQgdGhlIHVzZXIgaGFzIHRvIGNvbmZpcm0gdGhlIGNhbmNlbGxhdGlvbiBvZiB0aGUgZWRpdGluZyBwcm9jZXNzLlxuXHQgKiBAcmV0dXJucyB7UHJvbWlzZX0gQSBwcm9taXNlIHRoYXQgaXMgcmVqZWN0ZWQgaWYgdGhlIGV4ZWN1dGlvbiBpcyBwcm9oaWJpdGVkIGFuZCByZXNvbHZlZCBieSB0aGUgcHJvbWlzZSByZXR1cm5lZCBieSB0aGUgZm5GdW5jdGlvbi5cblx0ICogQGFsaWFzIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkVkaXRGbG93I3NlY3VyZWRFeGVjdXRpb25cblx0ICogQHB1YmxpY1xuXHQgKiBAZXhwZXJpbWVudGFsIEFzIG9mIHZlcnNpb24gMS45MC4wXG5cdCAqIEBzaW5jZSAxLjkwLjBcblx0ICovXG5cdEBQdWJsaWNcblx0QEZpbmFsXG5cdHNlY3VyZWRFeGVjdXRpb24oXG5cdFx0Zm5GdW5jdGlvbjogRnVuY3Rpb24sXG5cdFx0bVBhcmFtZXRlcnM/OiB7XG5cdFx0XHRidXN5Pzoge1xuXHRcdFx0XHRzZXQ/OiBib29sZWFuO1xuXHRcdFx0XHRjaGVjaz86IGJvb2xlYW47XG5cdFx0XHR9O1xuXHRcdFx0dXBkYXRlc0RvY3VtZW50PzogYm9vbGVhbjtcblx0XHR9XG5cdCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IGJCdXN5U2V0ID0gbVBhcmFtZXRlcnMgJiYgbVBhcmFtZXRlcnMuYnVzeSAmJiBtUGFyYW1ldGVycy5idXN5LnNldCAhPT0gdW5kZWZpbmVkID8gbVBhcmFtZXRlcnMuYnVzeS5zZXQgOiB0cnVlLFxuXHRcdFx0YkJ1c3lDaGVjayA9IG1QYXJhbWV0ZXJzICYmIG1QYXJhbWV0ZXJzLmJ1c3kgJiYgbVBhcmFtZXRlcnMuYnVzeS5jaGVjayAhPT0gdW5kZWZpbmVkID8gbVBhcmFtZXRlcnMuYnVzeS5jaGVjayA6IHRydWUsXG5cdFx0XHRiVXBkYXRlc0RvY3VtZW50ID0gKG1QYXJhbWV0ZXJzICYmIChtUGFyYW1ldGVycyBhcyBhbnkpLnVwZGF0ZXNEb2N1bWVudCkgfHwgZmFsc2UsXG5cdFx0XHRvTG9ja09iamVjdCA9IHRoaXMuX2dldEdsb2JhbFVJTW9kZWwoKSxcblx0XHRcdG9Db250ZXh0ID0gdGhpcy5iYXNlLmdldFZpZXcoKS5nZXRCaW5kaW5nQ29udGV4dCgpLFxuXHRcdFx0YklzRHJhZnQgPSBvQ29udGV4dCAmJiB0aGlzLl9nZXRQcm9ncmFtbWluZ01vZGVsKG9Db250ZXh0KSA9PT0gUHJvZ3JhbW1pbmdNb2RlbC5EcmFmdDtcblxuXHRcdGlmIChiQnVzeUNoZWNrICYmIEJ1c3lMb2NrZXIuaXNMb2NrZWQob0xvY2tPYmplY3QpKSB7XG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJBcHBsaWNhdGlvbiBhbHJlYWR5IGJ1c3kgdGhlcmVmb3JlIGV4ZWN1dGlvbiByZWplY3RlZFwiKTtcblx0XHR9XG5cblx0XHQvLyB3ZSBoYXZlIHRvIHNldCBidXN5IGFuZCBkcmFmdCBpbmRpY2F0b3IgaW1tZWRpYXRlbHkgYWxzbyB0aGUgZnVuY3Rpb24gbWlnaHQgYmUgZXhlY3V0ZWQgbGF0ZXIgaW4gcXVldWVcblx0XHRpZiAoYkJ1c3lTZXQpIHtcblx0XHRcdEJ1c3lMb2NrZXIubG9jayhvTG9ja09iamVjdCk7XG5cdFx0fVxuXHRcdGlmIChiVXBkYXRlc0RvY3VtZW50ICYmIGJJc0RyYWZ0KSB7XG5cdFx0XHR0aGlzLl9zZXREcmFmdFN0YXR1cyhEcmFmdFN0YXR1cy5TYXZpbmcpO1xuXHRcdH1cblxuXHRcdHRoaXMuX2dldE1lc3NhZ2VIYW5kbGVyKCkucmVtb3ZlVHJhbnNpdGlvbk1lc3NhZ2VzKCk7XG5cblx0XHRyZXR1cm4gdGhpcy5fc3luY1Rhc2soZm5GdW5jdGlvbilcblx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0aWYgKGJVcGRhdGVzRG9jdW1lbnQpIHtcblx0XHRcdFx0XHR0aGlzLl9nZXRUcmFuc2FjdGlvbkhlbHBlcigpLmhhbmRsZURvY3VtZW50TW9kaWZpY2F0aW9ucygpO1xuXHRcdFx0XHRcdEVkaXRTdGF0ZS5zZXRFZGl0U3RhdGVEaXJ0eSgpO1xuXHRcdFx0XHRcdGlmIChiSXNEcmFmdCkge1xuXHRcdFx0XHRcdFx0dGhpcy5fc2V0RHJhZnRTdGF0dXMoRHJhZnRTdGF0dXMuU2F2ZWQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHRcdC5jYXRjaCgob0Vycm9yOiBhbnkpID0+IHtcblx0XHRcdFx0aWYgKGJVcGRhdGVzRG9jdW1lbnQgJiYgYklzRHJhZnQpIHtcblx0XHRcdFx0XHR0aGlzLl9zZXREcmFmdFN0YXR1cyhEcmFmdFN0YXR1cy5DbGVhcik7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIFByb21pc2UucmVqZWN0KG9FcnJvcik7XG5cdFx0XHR9KVxuXHRcdFx0LmZpbmFsbHkoKCkgPT4ge1xuXHRcdFx0XHRpZiAoYkJ1c3lTZXQpIHtcblx0XHRcdFx0XHRCdXN5TG9ja2VyLnVubG9jayhvTG9ja09iamVjdCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXMuX2dldE1lc3NhZ2VIYW5kbGVyKCkuc2hvd01lc3NhZ2VEaWFsb2coKTtcblx0XHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEhhbmRsZXMgdGhlIHBhdGNoU2VudCBldmVudDogcmVnaXN0ZXIgZG9jdW1lbnQgbW9kaWZpY2F0aW9uLlxuXHQgKlxuXHQgKiBAcGFyYW0gb0V2ZW50XG5cdCAqL1xuXHRAUHVibGljXG5cdGhhbmRsZVBhdGNoU2VudChvRXZlbnQ6IGFueSkge1xuXHRcdHRoaXMubVBhdGNoUHJvbWlzZXMgPSB0aGlzLm1QYXRjaFByb21pc2VzID8gdGhpcy5tUGF0Y2hQcm9taXNlcyA6IHt9O1xuXHRcdC8vIGRvIHRoaXMgZm9yIGV2ZXJ5IHVuaXF1ZSBvYmplY3QgKGVnOiBldmVyeSB0YWJsZSkgc28gdGhhdCBlYWNoIGFzc29jaWF0ZWQgcHJvbWlzZSBpcyBmdWxmaWxsZWQgYXQgdGhlIGVuZFxuXHRcdGNvbnN0IG9QYXRjaFByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cdFx0XHR0aGlzLm1QYXRjaFByb21pc2VzW29FdmVudC5nZXRTb3VyY2UoKV0gPSB7XG5cdFx0XHRcdHJlc29sdmVQYXRjaFByb21pc2U6IHJlc29sdmUsXG5cdFx0XHRcdHJlamVjdFBhdGNoUHJvbWlzZTogcmVqZWN0XG5cdFx0XHR9O1xuXHRcdH0pO1xuXHRcdHRoaXMudXBkYXRlRG9jdW1lbnQob0V2ZW50LmdldFNvdXJjZSgpLCBvUGF0Y2hQcm9taXNlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBIYW5kbGVzIHRoZSBwYXRjaENvbXBsZXRlZCBldmVudDogcmVzb2x2ZXMgb3IgcmVqZWN0cyBkb2N1bWVudCBtb2RpZmljYXRpb24uXG5cdCAqXG5cdCAqIEBwYXJhbSBvRXZlbnRcblx0ICovXG5cdEBQdWJsaWNcblx0aGFuZGxlUGF0Y2hDb21wbGV0ZWQob0V2ZW50OiBhbnkpIHtcblx0XHRjb25zdCBiU3VjY2VzcyA9IG9FdmVudC5nZXRQYXJhbWV0ZXIoXCJzdWNjZXNzXCIpO1xuXHRcdGlmIChiU3VjY2Vzcykge1xuXHRcdFx0dGhpcy5tUGF0Y2hQcm9taXNlc1tvRXZlbnQuZ2V0U291cmNlKCldLnJlc29sdmVQYXRjaFByb21pc2UoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5tUGF0Y2hQcm9taXNlc1tvRXZlbnQuZ2V0U291cmNlKCldLnJlamVjdFBhdGNoUHJvbWlzZSgpO1xuXHRcdH1cblx0XHRkZWxldGUgdGhpcy5tUGF0Y2hQcm9taXNlc1tvRXZlbnQuZ2V0U291cmNlKCldO1xuXHR9XG5cblx0Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0Ly8gUHJpdmF0ZSBtZXRob2RzXG5cdC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cblx0Lypcblx0XHRcdCBUTyBCRSBDSEVDS0VEIC8gRElTQ1VTU0VEXG5cdFx0XHQgX2NyZWF0ZU11bHRpcGxlRG9jdW1lbnRzIGFuZCBkZWxldGVNdWx0aURvY3VtZW50IC0gY291bGRuJ3Qgd2UgY29tYmluZSB0aGVtIHdpdGggY3JlYXRlIGFuZCBkZWxldGUgZG9jdW1lbnQ/XG5cdFx0XHQgX2NyZWF0ZUFjdGlvblByb21pc2UgYW5kIGRlbGV0ZUN1cnJlbnRBY3Rpb25Qcm9taXNlIC0+IG5leHQgc3RlcFxuXG5cdFx0XHQgKi9cblxuXHRfc2V0RWRpdE1vZGUoc0VkaXRNb2RlOiBhbnksIGJDcmVhdGlvbk1vZGU/OiBib29sZWFuKSB7XG5cdFx0KHRoaXMuYmFzZS5nZXRWaWV3KCkuZ2V0Q29udHJvbGxlcigpIGFzIFBhZ2VDb250cm9sbGVyKS5fZWRpdEZsb3cuc2V0RWRpdE1vZGUoc0VkaXRNb2RlLCBiQ3JlYXRpb25Nb2RlKTtcblx0fVxuXG5cdF9zZXREcmFmdFN0YXR1cyhzRHJhZnRTdGF0ZTogYW55KSB7XG5cdFx0KHRoaXMuYmFzZS5nZXRWaWV3KCkuZ2V0Q29udHJvbGxlcigpIGFzIFBhZ2VDb250cm9sbGVyKS5fZWRpdEZsb3cuc2V0RHJhZnRTdGF0dXMoc0RyYWZ0U3RhdGUpO1xuXHR9XG5cblx0X2dldFJvdXRpbmdMaXN0ZW5lcigpIHtcblx0XHRyZXR1cm4gKHRoaXMuYmFzZS5nZXRWaWV3KCkuZ2V0Q29udHJvbGxlcigpIGFzIFBhZ2VDb250cm9sbGVyKS5fZWRpdEZsb3cuZ2V0Um91dGluZ0xpc3RlbmVyKCk7XG5cdH1cblxuXHRfZ2V0R2xvYmFsVUlNb2RlbCgpIHtcblx0XHRyZXR1cm4gKHRoaXMuYmFzZS5nZXRWaWV3KCkuZ2V0Q29udHJvbGxlcigpIGFzIFBhZ2VDb250cm9sbGVyKS5fZWRpdEZsb3cuZ2V0R2xvYmFsVUlNb2RlbCgpO1xuXHR9XG5cdF9zeW5jVGFzayh2VGFzaz86IGFueSkge1xuXHRcdHJldHVybiAodGhpcy5iYXNlLmdldFZpZXcoKS5nZXRDb250cm9sbGVyKCkgYXMgUGFnZUNvbnRyb2xsZXIpLl9lZGl0Rmxvdy5zeW5jVGFzayh2VGFzayk7XG5cdH1cblxuXHRfZ2V0UHJvZ3JhbW1pbmdNb2RlbChvQ29udGV4dDogYW55KSB7XG5cdFx0cmV0dXJuICh0aGlzLmJhc2UuZ2V0VmlldygpLmdldENvbnRyb2xsZXIoKSBhcyBQYWdlQ29udHJvbGxlcikuX2VkaXRGbG93LmdldFByb2dyYW1taW5nTW9kZWwob0NvbnRleHQpO1xuXHR9XG5cblx0X2RlbGV0ZURvY3VtZW50VHJhbnNhY3Rpb24ob0NvbnRleHQ6IGFueSwgbVBhcmFtZXRlcnM6IGFueSkge1xuXHRcdHJldHVybiAodGhpcy5iYXNlLmdldFZpZXcoKS5nZXRDb250cm9sbGVyKCkgYXMgUGFnZUNvbnRyb2xsZXIpLl9lZGl0Rmxvdy5kZWxldGVEb2N1bWVudFRyYW5zYWN0aW9uKG9Db250ZXh0LCBtUGFyYW1ldGVycyk7XG5cdH1cblxuXHRfaGFuZGxlQ3JlYXRlRXZlbnRzKG9CaW5kaW5nOiBhbnkpIHtcblx0XHQodGhpcy5iYXNlLmdldFZpZXcoKS5nZXRDb250cm9sbGVyKCkgYXMgUGFnZUNvbnRyb2xsZXIpLl9lZGl0Rmxvdy5oYW5kbGVDcmVhdGVFdmVudHMob0JpbmRpbmcpO1xuXHR9XG5cblx0X2dldFRyYW5zYWN0aW9uSGVscGVyKCkge1xuXHRcdHJldHVybiAodGhpcy5iYXNlLmdldFZpZXcoKS5nZXRDb250cm9sbGVyKCkgYXMgUGFnZUNvbnRyb2xsZXIpLl9lZGl0Rmxvdy5nZXRUcmFuc2FjdGlvbkhlbHBlcigpO1xuXHR9XG5cblx0X2dldEludGVybmFsTW9kZWwoKSB7XG5cdFx0cmV0dXJuICh0aGlzLmJhc2UuZ2V0VmlldygpLmdldENvbnRyb2xsZXIoKSBhcyBQYWdlQ29udHJvbGxlcikuX2VkaXRGbG93LmdldEludGVybmFsTW9kZWwoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IHByb21pc2UgdG8gd2FpdCBmb3IgYW4gYWN0aW9uIHRvIGJlIGV4ZWN1dGVkXG5cdCAqXG5cdCAqIEBmdW5jdGlvblxuXHQgKiBAbmFtZSBfY3JlYXRlQWN0aW9uUHJvbWlzZVxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuY29udHJvbGxlcmV4dGVuc2lvbnMuRWRpdEZsb3dcblx0ICpcblx0ICogQHJldHVybnMge0Z1bmN0aW9ufSBUaGUgcmVzb2x2ZXIgZnVuY3Rpb24gd2hpY2ggY2FuIGJlIHVzZWQgdG8gZXh0ZXJuYWxseSByZXNvbHZlIHRoZSBwcm9taXNlXG5cdCAqL1xuXG5cdF9jcmVhdGVBY3Rpb25Qcm9taXNlKHNBY3Rpb25OYW1lOiBhbnksIHNDb250cm9sSWQ6IGFueSkge1xuXHRcdHJldHVybiAodGhpcy5iYXNlLmdldFZpZXcoKS5nZXRDb250cm9sbGVyKCkgYXMgUGFnZUNvbnRyb2xsZXIpLl9lZGl0Rmxvdy5jcmVhdGVBY3Rpb25Qcm9taXNlKHNBY3Rpb25OYW1lLCBzQ29udHJvbElkKTtcblx0fVxuXG5cdF9nZXRDdXJyZW50QWN0aW9uUHJvbWlzZSgpIHtcblx0XHRyZXR1cm4gKHRoaXMuYmFzZS5nZXRWaWV3KCkuZ2V0Q29udHJvbGxlcigpIGFzIFBhZ2VDb250cm9sbGVyKS5fZWRpdEZsb3cuZ2V0Q3VycmVudEFjdGlvblByb21pc2UoKTtcblx0fVxuXG5cdF9kZWxldGVDdXJyZW50QWN0aW9uUHJvbWlzZSgpIHtcblx0XHRyZXR1cm4gKHRoaXMuYmFzZS5nZXRWaWV3KCkuZ2V0Q29udHJvbGxlcigpIGFzIFBhZ2VDb250cm9sbGVyKS5fZWRpdEZsb3cuZGVsZXRlQ3VycmVudEFjdGlvblByb21pc2UoKTtcblx0fVxuXG5cdF9nZXRNZXNzYWdlSGFuZGxlcigpIHtcblx0XHRyZXR1cm4gKHRoaXMuYmFzZS5nZXRWaWV3KCkuZ2V0Q29udHJvbGxlcigpIGFzIFBhZ2VDb250cm9sbGVyKS5fZWRpdEZsb3cuZ2V0TWVzc2FnZUhhbmRsZXIoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAZnVuY3Rpb25cblx0ICogQG5hbWUgX2dldEFjdGlvblJlc3BvbnNlRGF0YUFuZEtleXNcblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkVkaXRGbG93XG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzQWN0aW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgYWN0aW9uIHRoYXQgaXMgZXhlY3V0ZWRcblx0ICogQHBhcmFtIHtvYmplY3R9IG9SZXNwb25zZSBUaGUgYm91bmQgYWN0aW9uJ3MgcmVzcG9uc2UgZGF0YSBvciByZXNwb25zZSBjb250ZXh0XG5cdCAqIEByZXR1cm5zIHtvYmplY3R9IE9iamVjdCB3aXRoIGRhdGEgYW5kIG5hbWVzIG9mIHRoZSBrZXkgZmllbGRzIG9mIHRoZSByZXNwb25zZVxuXHQgKi9cblx0X2dldEFjdGlvblJlc3BvbnNlRGF0YUFuZEtleXMoc0FjdGlvbk5hbWU6IHN0cmluZywgb1Jlc3BvbnNlOiBvYmplY3QpIHtcblx0XHRyZXR1cm4gKHRoaXMuYmFzZS5nZXRWaWV3KCkuZ2V0Q29udHJvbGxlcigpIGFzIFBhZ2VDb250cm9sbGVyKS5fZWRpdEZsb3cuZ2V0QWN0aW9uUmVzcG9uc2VEYXRhQW5kS2V5cyhzQWN0aW9uTmFtZSwgb1Jlc3BvbnNlKTtcblx0fVxuXG5cdF9zdWJtaXRPcGVuQ2hhbmdlcyhvQ29udGV4dDogYW55KSB7XG5cdFx0Y29uc3Qgb01vZGVsID0gb0NvbnRleHQuZ2V0TW9kZWwoKSxcblx0XHRcdG9Mb2NrT2JqZWN0ID0gdGhpcy5fZ2V0R2xvYmFsVUlNb2RlbCgpO1xuXHRcdC8vQ3VycmVudGx5IHdlIGFyZSB1c2luZyBvbmx5IDEgdXBkYXRlR3JvdXBJZCwgaGVuY2Ugc3VibWl0dGluZyB0aGUgYmF0Y2ggZGlyZWN0bHkgaGVyZVxuXHRcdHJldHVybiBvTW9kZWxcblx0XHRcdC5zdWJtaXRCYXRjaChcIiRhdXRvXCIpXG5cdFx0XHQudGhlbihmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKG9Nb2RlbC5oYXNQZW5kaW5nQ2hhbmdlcyhcIiRhdXRvXCIpKSB7XG5cdFx0XHRcdFx0Ly8gdGhlIHN1Ym1pdCB3YXMgbm90IHN1Y2Nlc3NmdWxcblx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJzdWJtaXQgb2Ygb3BlbiBjaGFuZ2VzIGZhaWxlZFwiKTtcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHRcdC5maW5hbGx5KGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoQnVzeUxvY2tlci5pc0xvY2tlZChvTG9ja09iamVjdCkpIHtcblx0XHRcdFx0XHRCdXN5TG9ja2VyLnVubG9jayhvTG9ja09iamVjdCk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHR9XG5cblx0X2hhbmRsZVN0aWNreU9uKG9Db250ZXh0OiBDb250ZXh0KSB7XG5cdFx0cmV0dXJuICh0aGlzLmJhc2UuZ2V0VmlldygpLmdldENvbnRyb2xsZXIoKSBhcyBQYWdlQ29udHJvbGxlcikuX2VkaXRGbG93LmhhbmRsZVN0aWNreU9uKG9Db250ZXh0KTtcblx0fVxuXG5cdF9oYW5kbGVTdGlja3lPZmYoKSB7XG5cdFx0cmV0dXJuICh0aGlzLmJhc2UuZ2V0VmlldygpLmdldENvbnRyb2xsZXIoKSBhcyBQYWdlQ29udHJvbGxlcikuX2VkaXRGbG93LmhhbmRsZVN0aWNreU9mZigpO1xuXHR9XG5cblx0X29uQmFja05hdmlnYXRpb25JblNlc3Npb24oKSB7XG5cdFx0cmV0dXJuICh0aGlzLmJhc2UuZ2V0VmlldygpLmdldENvbnRyb2xsZXIoKSBhcyBQYWdlQ29udHJvbGxlcikuX2VkaXRGbG93Lm9uQmFja05hdmlnYXRpb25JblNlc3Npb24oKTtcblx0fVxuXG5cdF9kaXNjYXJkU3RpY2t5U2Vzc2lvbihvQ29udGV4dDogQ29udGV4dCkge1xuXHRcdHJldHVybiAodGhpcy5iYXNlLmdldFZpZXcoKS5nZXRDb250cm9sbGVyKCkgYXMgUGFnZUNvbnRyb2xsZXIpLl9lZGl0Rmxvdy5kaXNjYXJkU3RpY2t5U2Vzc2lvbihvQ29udGV4dCk7XG5cdH1cblxuXHRfaGFuZGxlTmV3Q29udGV4dChvQ29udGV4dDogYW55LCBiRWRpdGFibGU6IGJvb2xlYW4sIGJSZWNyZWF0ZUNvbnRleHQ6IGJvb2xlYW4sIGJEcmFmdE5hdmlnYXRpb246IGJvb2xlYW4sIGJGb3JjZUZvY3VzPzogYm9vbGVhbikge1xuXHRcdEVkaXRTdGF0ZS5zZXRFZGl0U3RhdGVEaXJ0eSgpO1xuXG5cdFx0cmV0dXJuIHRoaXMuX2dldFJvdXRpbmdMaXN0ZW5lcigpLm5hdmlnYXRlVG9Db250ZXh0KG9Db250ZXh0LCB7XG5cdFx0XHRjaGVja05vSGFzaENoYW5nZTogdHJ1ZSxcblx0XHRcdGVkaXRhYmxlOiBiRWRpdGFibGUsXG5cdFx0XHRiUGVyc2lzdE9QU2Nyb2xsOiB0cnVlLFxuXHRcdFx0YlJlY3JlYXRlQ29udGV4dDogYlJlY3JlYXRlQ29udGV4dCxcblx0XHRcdGJEcmFmdE5hdmlnYXRpb246IGJEcmFmdE5hdmlnYXRpb24sXG5cdFx0XHRzaG93UGxhY2Vob2xkZXI6IGZhbHNlLFxuXHRcdFx0YkZvcmNlRm9jdXM6IGJGb3JjZUZvY3VzXG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZXJlIGFyZSB2YWxpZGF0aW9uIChwYXJzZSkgZXJyb3JzIGZvciBjb250cm9scyBib3VuZCB0byBhIGdpdmVuIGNvbnRleHRcblx0ICpcblx0ICogQGZ1bmN0aW9uXG5cdCAqIEBuYW1lIF9jaGVja0ZvclZhbGlkYXRpb25FcnJvcnNcblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkVkaXRGbG93XG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHJlc29sdmVzIGlmIHRoZXJlIGFyZSBubyB2YWxpZGF0aW9uIGVycm9ycywgYW5kIHJlamVjdHMgaWYgdGhlcmUgYXJlIHZhbGlkYXRpb24gZXJyb3JzXG5cdCAqL1xuXG5cdF9jaGVja0ZvclZhbGlkYXRpb25FcnJvcnMoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX3N5bmNUYXNrKCkudGhlbigoKSA9PiB7XG5cdFx0XHRjb25zdCBzVmlld0lkID0gdGhpcy5iYXNlLmdldFZpZXcoKS5nZXRJZCgpO1xuXHRcdFx0Y29uc3QgYU1lc3NhZ2VzID0gc2FwLnVpXG5cdFx0XHRcdC5nZXRDb3JlKClcblx0XHRcdFx0LmdldE1lc3NhZ2VNYW5hZ2VyKClcblx0XHRcdFx0LmdldE1lc3NhZ2VNb2RlbCgpXG5cdFx0XHRcdC5nZXREYXRhKCk7XG5cdFx0XHRsZXQgb0NvbnRyb2w7XG5cdFx0XHRsZXQgb01lc3NhZ2U7XG5cblx0XHRcdGlmICghYU1lc3NhZ2VzLmxlbmd0aCkge1xuXHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFwiTm8gdmFsaWRhdGlvbiBlcnJvcnMgZm91bmRcIik7XG5cdFx0XHR9XG5cblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYU1lc3NhZ2VzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdG9NZXNzYWdlID0gYU1lc3NhZ2VzW2ldO1xuXHRcdFx0XHRpZiAob01lc3NhZ2UudmFsaWRhdGlvbikge1xuXHRcdFx0XHRcdG9Db250cm9sID0gc2FwLnVpLmdldENvcmUoKS5ieUlkKG9NZXNzYWdlLmdldENvbnRyb2xJZCgpKTtcblx0XHRcdFx0XHR3aGlsZSAob0NvbnRyb2wpIHtcblx0XHRcdFx0XHRcdGlmIChvQ29udHJvbC5nZXRJZCgpID09PSBzVmlld0lkKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBQcm9taXNlLnJlamVjdChcInZhbGlkYXRpb24gZXJyb3JzIGV4aXN0XCIpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0b0NvbnRyb2wgPSBvQ29udHJvbC5nZXRQYXJlbnQoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAZnVuY3Rpb25cblx0ICogQG5hbWUgX3JlZnJlc2hMaXN0SWZSZXF1aXJlZFxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuY29udHJvbGxlcmV4dGVuc2lvbnMuRWRpdEZsb3dcblx0ICogQHBhcmFtIHtvYmplY3R9IG9SZXNwb25zZSBUaGUgcmVzcG9uc2Ugb2YgdGhlIGJvdW5kIGFjdGlvbiBhbmQgdGhlIG5hbWVzIG9mIHRoZSBrZXkgZmllbGRzXG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHR9IG9Db250ZXh0IFRoZSBib3VuZCBjb250ZXh0IG9uIHdoaWNoIHRoZSBhY3Rpb24gd2FzIGV4ZWN1dGVkXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBBbHdheXMgcmVzb2x2ZXMgdG8gcGFyYW0gb1Jlc3BvbnNlXG5cdCAqL1xuXHRfcmVmcmVzaExpc3RJZlJlcXVpcmVkKG9SZXNwb25zZTogYW55LCBvQ29udGV4dDogQ29udGV4dCkge1xuXHRcdGlmICghb0NvbnRleHQgfHwgIW9SZXNwb25zZSB8fCAhb1Jlc3BvbnNlLm9EYXRhKSB7XG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdFx0fVxuXHRcdGNvbnN0IG9CaW5kaW5nID0gb0NvbnRleHQuZ2V0QmluZGluZygpO1xuXHRcdC8vIHJlZnJlc2ggb25seSBsaXN0c1xuXHRcdGlmIChvQmluZGluZyAmJiBvQmluZGluZy5pc0EoXCJzYXAudWkubW9kZWwub2RhdGEudjQuT0RhdGFMaXN0QmluZGluZ1wiKSkge1xuXHRcdFx0Y29uc3Qgb0NvbnRleHREYXRhID0gb1Jlc3BvbnNlLm9EYXRhO1xuXHRcdFx0Y29uc3QgYUtleXMgPSBvUmVzcG9uc2Uua2V5cztcblx0XHRcdGNvbnN0IG9DdXJyZW50RGF0YSA9IG9Db250ZXh0LmdldE9iamVjdCgpO1xuXHRcdFx0bGV0IGJSZXR1cm5lZENvbnRleHRJc1NhbWUgPSB0cnVlO1xuXHRcdFx0Ly8gZW5zdXJlIGNvbnRleHQgaXMgaW4gdGhlIHJlc3BvbnNlXG5cdFx0XHRpZiAoT2JqZWN0LmtleXMob0NvbnRleHREYXRhKS5sZW5ndGgpIHtcblx0XHRcdFx0Ly8gY2hlY2sgaWYgY29udGV4dCBpbiByZXNwb25zZSBpcyBkaWZmZXJlbnQgdGhhbiB0aGUgYm91bmQgY29udGV4dFxuXHRcdFx0XHRiUmV0dXJuZWRDb250ZXh0SXNTYW1lID0gYUtleXMuZXZlcnkoZnVuY3Rpb24oc0tleTogYW55KSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9DdXJyZW50RGF0YVtzS2V5XSA9PT0gb0NvbnRleHREYXRhW3NLZXldO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0aWYgKCFiUmV0dXJuZWRDb250ZXh0SXNTYW1lKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4ge1xuXHRcdFx0XHRcdFx0aWYgKChvQmluZGluZyBhcyBhbnkpLmlzUm9vdCgpKSB7XG5cdFx0XHRcdFx0XHRcdG9CaW5kaW5nLmF0dGFjaEV2ZW50T25jZShcImRhdGFSZWNlaXZlZFwiLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRyZXNvbHZlKCk7XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0XHRvQmluZGluZy5yZWZyZXNoKCk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRjb25zdCBvQXBwQ29tcG9uZW50ID0gQ29tbW9uVXRpbHMuZ2V0QXBwQ29tcG9uZW50KHRoaXMuZ2V0VmlldygpKTtcblx0XHRcdFx0XHRcdFx0b0FwcENvbXBvbmVudFxuXHRcdFx0XHRcdFx0XHRcdC5nZXRTaWRlRWZmZWN0c1NlcnZpY2UoKVxuXHRcdFx0XHRcdFx0XHRcdC5yZXF1ZXN0U2lkZUVmZmVjdHMoW3sgJE5hdmlnYXRpb25Qcm9wZXJ0eVBhdGg6IG9CaW5kaW5nLmdldFBhdGgoKSB9XSwgb0JpbmRpbmcuZ2V0Q29udGV4dCgpIGFzIENvbnRleHQpXG5cdFx0XHRcdFx0XHRcdFx0LnRoZW4oXG5cdFx0XHRcdFx0XHRcdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSgpO1xuXHRcdFx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRMb2cuZXJyb3IoXCJFcnJvciB3aGlsZSByZWZyZXNoaW5nIHRoZSB0YWJsZVwiKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSgpO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0XHQuY2F0Y2goZnVuY3Rpb24oZTogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRMb2cuZXJyb3IoXCJFcnJvciB3aGlsZSByZWZyZXNoaW5nIHRoZSB0YWJsZVwiLCBlKTtcblx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHQvLyByZXNvbHZlIHdpdGggb1Jlc3BvbnNlIHRvIG5vdCBkaXN0dXJiIHRoZSBwcm9taXNlIGNoYWluIGFmdGVyd2FyZHNcblx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdH1cblxuXHRfZmV0Y2hTZW1hbnRpY0tleVZhbHVlcyhvQ29udGV4dDogYW55KSB7XG5cdFx0Y29uc3Qgb01ldGFNb2RlbCA9IG9Db250ZXh0LmdldE1vZGVsKCkuZ2V0TWV0YU1vZGVsKCksXG5cdFx0XHRzRW50aXR5U2V0TmFtZSA9IG9NZXRhTW9kZWwuZ2V0TWV0YUNvbnRleHQob0NvbnRleHQuZ2V0UGF0aCgpKS5nZXRPYmplY3QoXCJAc2FwdWkubmFtZVwiKSxcblx0XHRcdGFTZW1hbnRpY0tleXMgPSBTZW1hbnRpY0tleUhlbHBlci5nZXRTZW1hbnRpY0tleXMob01ldGFNb2RlbCwgc0VudGl0eVNldE5hbWUpO1xuXG5cdFx0aWYgKGFTZW1hbnRpY0tleXMgJiYgYVNlbWFudGljS2V5cy5sZW5ndGgpIHtcblx0XHRcdGNvbnN0IGFSZXF1ZXN0UHJvbWlzZXMgPSBhU2VtYW50aWNLZXlzLm1hcChmdW5jdGlvbihvS2V5OiBhbnkpIHtcblx0XHRcdFx0cmV0dXJuIG9Db250ZXh0LnJlcXVlc3RPYmplY3Qob0tleS4kUHJvcGVydHlQYXRoKTtcblx0XHRcdH0pO1xuXG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5hbGwoYVJlcXVlc3RQcm9taXNlcyk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcblx0XHR9XG5cdH1cblxuXHQvLyBVZ2x5IFdvcmthcm91bmQgdG8gb3ZlcmNvbWUgbWRjIGZpZWxkIGlzc3VlLCB3ZSByZW1vdmUgdGhlIGJpbmRpbmcgY29udGV4dCBiZWZvcmVcblx0Ly8gc3dpdGNoaW5nIHRvIGRpc3BsYXkgbW9kZSB0byBhdm9pZCB0aGUgZmllbGQgcmVhZHMgYWRkaXRpb25hbCB2YWx1ZXMgZm9yIG5vbiBleGlzdGluZ1xuXHQvLyBkcmFmdHMgb3Igc3RpY2t5IHNlc3Npb25zIGluIHRoZSBiYWNrZW5kXG5cdF9yZW1vdmVDb250ZXh0c0Zyb21QYWdlcygpIHtcblx0XHRsZXQgYVBhZ2VzOiBhbnlbXSA9IFtdO1xuXHRcdGNvbnN0IG9BcHBDb21wb25lbnQgPSBDb21tb25VdGlscy5nZXRBcHBDb21wb25lbnQodGhpcy5nZXRWaWV3KCkpO1xuXG5cdFx0aWYgKG9BcHBDb21wb25lbnQuX2lzRmNsRW5hYmxlZCgpKSB7XG5cdFx0XHRjb25zdCBvRkNMID0gb0FwcENvbXBvbmVudC5nZXRSb290Q29udGFpbmVyKCkgYXMgRmxleGlibGVDb2x1bW5MYXlvdXQ7XG5cdFx0XHRhUGFnZXMgPSBhUGFnZXMuY29uY2F0KG9GQ0wuZ2V0TWlkQ29sdW1uUGFnZXMoKSB8fCBbXSk7XG5cdFx0XHRhUGFnZXMgPSBhUGFnZXMuY29uY2F0KG9GQ0wuZ2V0RW5kQ29sdW1uUGFnZXMoKSB8fCBbXSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IG9OYXZDb250YWluZXIgPSBvQXBwQ29tcG9uZW50LmdldFJvb3RDb250YWluZXIoKSBhcyBOYXZDb250YWluZXI7XG5cdFx0XHRhUGFnZXMgPSBvTmF2Q29udGFpbmVyLmdldFBhZ2VzKCkgfHwgW107XG5cdFx0fVxuXG5cdFx0YVBhZ2VzLmZvckVhY2goZnVuY3Rpb24ob1BhZ2U6IGFueSkge1xuXHRcdFx0aWYgKG9QYWdlLmlzQShcInNhcC51aS5jb3JlLkNvbXBvbmVudENvbnRhaW5lclwiKSkge1xuXHRcdFx0XHRvUGFnZSA9IG9QYWdlLmdldENvbXBvbmVudEluc3RhbmNlKCk7IC8vIFRoZSBiaW5kaW5nIGNvbnRleHQgaXMgc2V0IGF0IHRoZSBjb21wb25lbnQgbGV2ZWwsIG5vdCB0aGUgY29tcG9uZW50IGNvbnRhaW5lclxuXHRcdFx0fVxuXG5cdFx0XHRpZiAob1BhZ2UuZ2V0QmluZGluZ0NvbnRleHQoKSkge1xuXHRcdFx0XHRvUGFnZS5zZXRCaW5kaW5nQ29udGV4dChudWxsKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdF9nZXRBY3Rpb25PdmVybG9hZENvbnRleHRGcm9tU3ViU2VjdGlvbnMob0NvbnRyb2w6IGFueSwgc092ZXJsb2FkRW50aXR5VHlwZTogc3RyaW5nKSB7XG5cdFx0bGV0IG9DdXJyZW50Q29udHJvbDogYW55O1xuXG5cdFx0ZnVuY3Rpb24gX2NoZWNrQWN0aW9ucyhhQWN0aW9uczogQXJyYXk8b2JqZWN0Pikge1xuXHRcdFx0bGV0IG9BY3Rpb25CaW5kaW5nQ29udGV4dDogYW55O1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0YUFjdGlvbnMuZm9yRWFjaChmdW5jdGlvbihvQWN0aW9uOiBhbnkpIHtcblx0XHRcdFx0XHRvQWN0aW9uQmluZGluZ0NvbnRleHQgPSBvQWN0aW9uLmdldEJpbmRpbmdDb250ZXh0KCk7XG5cdFx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdFx0b0FjdGlvbkJpbmRpbmdDb250ZXh0XG5cdFx0XHRcdFx0XHRcdC5nZXRNb2RlbCgpXG5cdFx0XHRcdFx0XHRcdC5nZXRNZXRhTW9kZWwoKVxuXHRcdFx0XHRcdFx0XHQuZ2V0TWV0YUNvbnRleHQob0FjdGlvbkJpbmRpbmdDb250ZXh0LmdldFBhdGgoKSlcblx0XHRcdFx0XHRcdFx0LmdldE9iamVjdChcIiRUeXBlXCIpID09PSBzT3ZlcmxvYWRFbnRpdHlUeXBlXG5cdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHR0aHJvdyBcImNvbnRleHQgZm91bmQgLSBzdG9wIGFjdGlvbnMgbG9vcFwiO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdHJldHVybiBvQWN0aW9uQmluZGluZ0NvbnRleHQ7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gX2NoZWNrU3ViU2VjdGlvbnMoYVN1YlNlY3Rpb25zOiBBcnJheTxvYmplY3Q+KSB7XG5cdFx0XHRsZXQgb0FjdGlvbkJpbmRpbmdDb250ZXh0OiBhbnk7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRhU3ViU2VjdGlvbnMuZm9yRWFjaChmdW5jdGlvbihvU3ViU2VjdGlvbjogYW55KSB7XG5cdFx0XHRcdFx0aWYgKG9BY3Rpb25CaW5kaW5nQ29udGV4dCkge1xuXHRcdFx0XHRcdFx0dGhyb3cgXCJjb250ZXh0IGZvdW5kIC0gc3RvcCBTdWJTZWN0aW9ucyBsb29wXCI7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNvbnN0IGFBY3Rpb25zID0gb1N1YlNlY3Rpb24uZ2V0QWdncmVnYXRpb24oXCJhY3Rpb25zXCIpO1xuXHRcdFx0XHRcdG9BY3Rpb25CaW5kaW5nQ29udGV4dCA9IF9jaGVja0FjdGlvbnMoYUFjdGlvbnMpO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0cmV0dXJuIG9BY3Rpb25CaW5kaW5nQ29udGV4dCA/IG9BY3Rpb25CaW5kaW5nQ29udGV4dCA6IHVuZGVmaW5lZDtcblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0cmV0dXJuIG9BY3Rpb25CaW5kaW5nQ29udGV4dDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0cnkge1xuXHRcdFx0aWYgKG9Db250cm9sID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiaW5wdXQgcGFyYW1ldGVyIG9Db250cm9sIHVuZGVmaW5lZCB3aGVuIHRyeWluZyB0byBkZXRlcm1pbmUgdGhlIGFjdGlvbiBvdmVybG9hZCBjb250ZXh0XCIpO1xuXHRcdFx0fVxuXG5cdFx0XHRvQ3VycmVudENvbnRyb2wgPSBvQ29udHJvbDtcblx0XHRcdHdoaWxlICghb0N1cnJlbnRDb250cm9sLmlzQShcInNhcC51eGFwLk9iamVjdFBhZ2VTZWN0aW9uXCIpKSB7XG5cdFx0XHRcdG9DdXJyZW50Q29udHJvbCA9IG9DdXJyZW50Q29udHJvbC5nZXRQYXJlbnQoKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCFvQ3VycmVudENvbnRyb2wpIHtcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiT2JqZWN0UGFnZVNlY3Rpb24gbm90IGZvdW5kIGluIFVJIGhpZXJhcmNoeVwiKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNvbnN0IGFTdWJTZWN0aW9ucyA9IG9DdXJyZW50Q29udHJvbC5nZXRBZ2dyZWdhdGlvbihcInN1YlNlY3Rpb25zXCIpO1xuXHRcdFx0XHRyZXR1cm4gX2NoZWNrU3ViU2VjdGlvbnMoYVN1YlNlY3Rpb25zKTtcblx0XHRcdH1cblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0TG9nLmluZm8oZXJyb3IpO1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRWRpdEZsb3c7XG4iXX0=