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