@sapui5/sap.fe.core 1.98.0 → 1.101.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 (318) hide show
  1. package/package.json +8 -5
  2. package/src/sap/fe/core/.library +2 -3
  3. package/src/sap/fe/core/AnnotationHelper.js +328 -405
  4. package/src/sap/fe/core/AnnotationHelper.ts +321 -0
  5. package/src/sap/fe/core/AppComponent.js +382 -399
  6. package/src/sap/fe/core/AppComponent.ts +397 -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 +67 -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 +2221 -2399
  14. package/src/sap/fe/core/CommonUtils.ts +2248 -0
  15. package/src/sap/fe/core/ExtensionAPI.js +280 -274
  16. package/src/sap/fe/core/ExtensionAPI.ts +242 -0
  17. package/src/sap/fe/core/PageController.js +219 -131
  18. package/src/sap/fe/core/PageController.ts +129 -0
  19. package/src/sap/fe/core/RouterProxy.js +936 -823
  20. package/src/sap/fe/core/RouterProxy.ts +854 -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 +248 -164
  24. package/src/sap/fe/core/TemplateComponent.ts +161 -0
  25. package/src/sap/fe/core/TemplateModel.js +77 -54
  26. package/src/sap/fe/core/TemplateModel.ts +63 -0
  27. package/src/sap/fe/core/TransactionHelper.js +1575 -1664
  28. package/src/sap/fe/core/TransactionHelper.ts +1736 -0
  29. package/src/sap/fe/core/actions/collaboration/ActivitySync.js +406 -0
  30. package/src/sap/fe/core/actions/collaboration/ActivitySync.ts +362 -0
  31. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.js +146 -0
  32. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.ts +129 -0
  33. package/src/sap/fe/core/actions/collaboration/Manage.js +264 -0
  34. package/src/sap/fe/core/actions/collaboration/Manage.ts +246 -0
  35. package/src/sap/fe/core/actions/collaboration/ManageDialog.fragment.xml +100 -0
  36. package/src/sap/fe/core/actions/collaboration/UserDetails.fragment.xml +13 -0
  37. package/src/sap/fe/core/actions/draft.js +663 -608
  38. package/src/sap/fe/core/actions/draft.ts +669 -0
  39. package/src/sap/fe/core/actions/messageHandling.js +576 -514
  40. package/src/sap/fe/core/actions/messageHandling.ts +562 -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 -1215
  44. package/src/sap/fe/core/actions/operations.ts +1193 -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/buildingBlocks/AttributeModel.js +60 -0
  48. package/src/sap/fe/core/buildingBlocks/AttributeModel.ts +37 -0
  49. package/src/sap/fe/core/buildingBlocks/BuildingBlock.js +165 -0
  50. package/src/sap/fe/core/buildingBlocks/BuildingBlock.ts +178 -0
  51. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.js +707 -0
  52. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.ts +628 -0
  53. package/src/sap/fe/core/buildingBlocks/TraceInfo.js +436 -0
  54. package/src/sap/fe/core/buildingBlocks/TraceInfo.ts +431 -0
  55. package/src/sap/fe/core/controllerextensions/EditFlow.js +1855 -1827
  56. package/src/sap/fe/core/controllerextensions/EditFlow.ts +1792 -0
  57. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +80 -54
  58. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +60 -0
  59. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +717 -512
  60. package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +785 -0
  61. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +797 -815
  62. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +810 -0
  63. package/src/sap/fe/core/controllerextensions/InternalRouting.js +1057 -1004
  64. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +1001 -0
  65. package/src/sap/fe/core/controllerextensions/KPIManagement.js +498 -533
  66. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +36 -32
  67. package/src/sap/fe/core/controllerextensions/MassEdit.js +142 -77
  68. package/src/sap/fe/core/controllerextensions/MassEdit.ts +155 -0
  69. package/src/sap/fe/core/controllerextensions/MessageHandler.js +222 -236
  70. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +215 -0
  71. package/src/sap/fe/core/controllerextensions/PageReady.js +312 -345
  72. package/src/sap/fe/core/controllerextensions/PageReady.ts +63 -55
  73. package/src/sap/fe/core/controllerextensions/Paginator.js +189 -175
  74. package/src/sap/fe/core/controllerextensions/Paginator.ts +169 -0
  75. package/src/sap/fe/core/controllerextensions/Placeholder.js +158 -149
  76. package/src/sap/fe/core/controllerextensions/Placeholder.ts +149 -0
  77. package/src/sap/fe/core/controllerextensions/Routing.js +145 -121
  78. package/src/sap/fe/core/controllerextensions/Routing.ts +131 -0
  79. package/src/sap/fe/core/controllerextensions/RoutingListener.js +8 -6
  80. package/src/sap/fe/core/controllerextensions/RoutingListener.ts +3 -0
  81. package/src/sap/fe/core/controllerextensions/Share.js +231 -268
  82. package/src/sap/fe/core/controllerextensions/Share.ts +231 -0
  83. package/src/sap/fe/core/controllerextensions/SideEffects.js +603 -644
  84. package/src/sap/fe/core/controllerextensions/SideEffects.ts +79 -79
  85. package/src/sap/fe/core/controllerextensions/ViewState.js +775 -806
  86. package/src/sap/fe/core/controllerextensions/ViewState.ts +796 -0
  87. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +2 -2
  88. package/src/sap/fe/core/controls/ActionPartial.fragment.xml +2 -2
  89. package/src/sap/fe/core/controls/Any.js +28 -0
  90. package/src/sap/fe/core/controls/Any.ts +30 -0
  91. package/src/sap/fe/core/controls/CommandExecution.js +93 -68
  92. package/src/sap/fe/core/controls/CommandExecution.ts +72 -0
  93. package/src/sap/fe/core/controls/ConditionalWrapper.js +166 -79
  94. package/src/sap/fe/core/controls/ConditionalWrapper.ts +74 -0
  95. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.js +366 -0
  96. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.ts +278 -0
  97. package/src/sap/fe/core/controls/CustomQuickViewPage.js +168 -125
  98. package/src/sap/fe/core/controls/CustomQuickViewPage.ts +116 -0
  99. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossDraft.fragment.xml +44 -5
  100. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +164 -122
  101. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +155 -0
  102. package/src/sap/fe/core/controls/FieldWrapper.js +213 -153
  103. package/src/sap/fe/core/controls/FieldWrapper.ts +104 -0
  104. package/src/sap/fe/core/controls/FileWrapper.js +313 -0
  105. package/src/sap/fe/core/controls/FileWrapper.ts +169 -0
  106. package/src/sap/fe/core/controls/FilterBar.js +198 -159
  107. package/src/sap/fe/core/controls/FilterBar.ts +148 -0
  108. package/src/sap/fe/core/controls/FormElementWrapper.js +101 -39
  109. package/src/sap/fe/core/controls/FormElementWrapper.ts +37 -0
  110. package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +38 -42
  111. package/src/sap/fe/core/controls/MultiValueParameterDelegate.ts +31 -0
  112. package/src/sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog.fragment.xml +1 -0
  113. package/src/sap/fe/core/controls/filterbar/FilterContainer.js +148 -115
  114. package/src/sap/fe/core/controls/filterbar/FilterContainer.ts +102 -0
  115. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +301 -265
  116. package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +252 -0
  117. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +186 -140
  118. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +125 -0
  119. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +336 -322
  120. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +337 -0
  121. package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +37 -42
  122. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +76 -74
  123. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +71 -0
  124. package/src/sap/fe/core/converters/ConverterContext.js +348 -379
  125. package/src/sap/fe/core/converters/ConverterContext.ts +23 -19
  126. package/src/sap/fe/core/converters/ManifestSettings.js +13 -1
  127. package/src/sap/fe/core/converters/ManifestSettings.ts +18 -2
  128. package/src/sap/fe/core/converters/ManifestWrapper.js +354 -365
  129. package/src/sap/fe/core/converters/ManifestWrapper.ts +19 -0
  130. package/src/sap/fe/core/converters/MetaModelConverter.js +16 -11
  131. package/src/sap/fe/core/converters/MetaModelConverter.ts +21 -18
  132. package/src/sap/fe/core/converters/TemplateConverter.js +1 -1
  133. package/src/sap/fe/core/converters/TemplateConverter.ts +4 -3
  134. package/src/sap/fe/core/converters/annotations/DataField.js +26 -13
  135. package/src/sap/fe/core/converters/annotations/DataField.ts +40 -17
  136. package/src/sap/fe/core/converters/common/AnnotationConverter.js +17 -13
  137. package/src/sap/fe/core/converters/controls/Common/Action.js +11 -11
  138. package/src/sap/fe/core/converters/controls/Common/Action.ts +22 -21
  139. package/src/sap/fe/core/converters/controls/Common/Chart.js +12 -10
  140. package/src/sap/fe/core/converters/controls/Common/Chart.ts +23 -14
  141. package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +3 -3
  142. package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +2 -2
  143. package/src/sap/fe/core/converters/controls/Common/Form.js +9 -7
  144. package/src/sap/fe/core/converters/controls/Common/Form.ts +23 -5
  145. package/src/sap/fe/core/converters/controls/Common/KPI.js +1 -1
  146. package/src/sap/fe/core/converters/controls/Common/KPI.ts +2 -2
  147. package/src/sap/fe/core/converters/controls/Common/Table.js +562 -218
  148. package/src/sap/fe/core/converters/controls/Common/Table.ts +670 -320
  149. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +218 -94
  150. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +265 -159
  151. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +495 -77
  152. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +535 -130
  153. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +6 -6
  154. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +20 -18
  155. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +10 -7
  156. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +13 -16
  157. package/src/sap/fe/core/converters/helpers/Aggregation.js +117 -127
  158. package/src/sap/fe/core/converters/helpers/Aggregation.ts +20 -5
  159. package/src/sap/fe/core/converters/helpers/BindingHelper.js +20 -6
  160. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +16 -4
  161. package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +12 -1
  162. package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +11 -0
  163. package/src/sap/fe/core/converters/helpers/IssueManager.js +4 -1
  164. package/src/sap/fe/core/converters/helpers/IssueManager.ts +3 -0
  165. package/src/sap/fe/core/converters/helpers/Key.js +42 -57
  166. package/src/sap/fe/core/converters/helpers/Key.ts +1 -1
  167. package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +1 -1
  168. package/src/sap/fe/core/converters/objectPage/FormMenuActions.ts +0 -4
  169. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +54 -30
  170. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +69 -43
  171. package/src/sap/fe/core/converters/templates/ListReportConverter.js +52 -28
  172. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +111 -74
  173. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +11 -9
  174. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +8 -8
  175. package/src/sap/fe/core/designtime/AppComponent.designtime.js +93 -98
  176. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +91 -0
  177. package/src/sap/fe/core/formatters/CollaborationFormatter.js +104 -0
  178. package/src/sap/fe/core/formatters/CollaborationFormatter.ts +60 -0
  179. package/src/sap/fe/core/formatters/CriticalityFormatter.js +1 -1
  180. package/src/sap/fe/core/formatters/CriticalityFormatter.ts +1 -1
  181. package/src/sap/fe/core/formatters/FPMFormatter.js +1 -1
  182. package/src/sap/fe/core/formatters/FPMFormatter.ts +4 -10
  183. package/src/sap/fe/core/formatters/KPIFormatter.js +3 -12
  184. package/src/sap/fe/core/formatters/KPIFormatter.ts +4 -1
  185. package/src/sap/fe/core/formatters/TableFormatter.js +91 -29
  186. package/src/sap/fe/core/formatters/TableFormatter.ts +94 -28
  187. package/src/sap/fe/core/formatters/ValueFormatter.js +4 -4
  188. package/src/sap/fe/core/formatters/ValueFormatter.ts +5 -7
  189. package/src/sap/fe/core/fpm/Component.js +81 -55
  190. package/src/sap/fe/core/fpm/Component.ts +43 -0
  191. package/src/sap/fe/core/helpers/AppStartupHelper.js +324 -310
  192. package/src/sap/fe/core/helpers/AppStartupHelper.ts +370 -341
  193. package/src/sap/fe/core/helpers/BindingExpression.js +319 -360
  194. package/src/sap/fe/core/helpers/BindingExpression.ts +323 -397
  195. package/src/sap/fe/core/helpers/ClassSupport.js +321 -168
  196. package/src/sap/fe/core/helpers/ClassSupport.ts +362 -158
  197. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +64 -59
  198. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +52 -0
  199. package/src/sap/fe/core/helpers/EditState.js +81 -84
  200. package/src/sap/fe/core/helpers/EditState.ts +81 -0
  201. package/src/sap/fe/core/helpers/ExcelFormatHelper.js +62 -48
  202. package/src/sap/fe/core/helpers/ExcelFormatHelper.ts +49 -0
  203. package/src/sap/fe/core/helpers/FPMHelper.js +52 -56
  204. package/src/sap/fe/core/helpers/FPMHelper.ts +62 -0
  205. package/src/sap/fe/core/helpers/KeepAliveHelper.js +3 -4
  206. package/src/sap/fe/core/helpers/KeepAliveHelper.ts +9 -9
  207. package/src/sap/fe/core/helpers/MassEditHelper.js +736 -676
  208. package/src/sap/fe/core/helpers/MassEditHelper.ts +803 -0
  209. package/src/sap/fe/core/helpers/ModelHelper.js +281 -225
  210. package/src/sap/fe/core/helpers/ModelHelper.ts +273 -0
  211. package/src/sap/fe/core/helpers/PasteHelper.js +210 -132
  212. package/src/sap/fe/core/helpers/PasteHelper.ts +197 -0
  213. package/src/sap/fe/core/helpers/SemanticDateOperators.js +336 -313
  214. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +336 -0
  215. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +66 -67
  216. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +73 -0
  217. package/src/sap/fe/core/helpers/StableIdHelper.js +1 -10
  218. package/src/sap/fe/core/helpers/StableIdHelper.ts +2 -10
  219. package/src/sap/fe/core/jsx-runtime/jsx.js +35 -5
  220. package/src/sap/fe/core/jsx-runtime/jsx.ts +23 -9
  221. package/src/sap/fe/core/library.js +426 -451
  222. package/src/sap/fe/core/library.support.js +23 -33
  223. package/src/sap/fe/core/library.support.ts +23 -0
  224. package/src/sap/fe/core/library.ts +420 -0
  225. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +5 -3
  226. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +5 -5
  227. package/src/sap/fe/core/messagebundle.properties +63 -18
  228. package/src/sap/fe/core/messagebundle_ar.properties +37 -6
  229. package/src/sap/fe/core/messagebundle_bg.properties +37 -6
  230. package/src/sap/fe/core/messagebundle_ca.properties +37 -6
  231. package/src/sap/fe/core/messagebundle_cs.properties +38 -7
  232. package/src/sap/fe/core/messagebundle_cy.properties +37 -6
  233. package/src/sap/fe/core/messagebundle_da.properties +37 -6
  234. package/src/sap/fe/core/messagebundle_de.properties +37 -6
  235. package/src/sap/fe/core/messagebundle_el.properties +37 -6
  236. package/src/sap/fe/core/messagebundle_en.properties +37 -6
  237. package/src/sap/fe/core/messagebundle_en_GB.properties +37 -6
  238. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +37 -6
  239. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +37 -6
  240. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +37 -6
  241. package/src/sap/fe/core/messagebundle_es.properties +37 -6
  242. package/src/sap/fe/core/messagebundle_es_MX.properties +37 -6
  243. package/src/sap/fe/core/messagebundle_et.properties +37 -6
  244. package/src/sap/fe/core/messagebundle_fi.properties +38 -7
  245. package/src/sap/fe/core/messagebundle_fr.properties +43 -12
  246. package/src/sap/fe/core/messagebundle_fr_CA.properties +45 -14
  247. package/src/sap/fe/core/messagebundle_hi.properties +43 -12
  248. package/src/sap/fe/core/messagebundle_hr.properties +43 -12
  249. package/src/sap/fe/core/messagebundle_hu.properties +37 -6
  250. package/src/sap/fe/core/messagebundle_id.properties +38 -7
  251. package/src/sap/fe/core/messagebundle_it.properties +37 -6
  252. package/src/sap/fe/core/messagebundle_iw.properties +37 -6
  253. package/src/sap/fe/core/messagebundle_ja.properties +36 -5
  254. package/src/sap/fe/core/messagebundle_kk.properties +43 -12
  255. package/src/sap/fe/core/messagebundle_ko.properties +37 -6
  256. package/src/sap/fe/core/messagebundle_lt.properties +37 -6
  257. package/src/sap/fe/core/messagebundle_lv.properties +44 -13
  258. package/src/sap/fe/core/messagebundle_ms.properties +42 -11
  259. package/src/sap/fe/core/messagebundle_nl.properties +37 -6
  260. package/src/sap/fe/core/messagebundle_no.properties +37 -6
  261. package/src/sap/fe/core/messagebundle_pl.properties +37 -6
  262. package/src/sap/fe/core/messagebundle_pt.properties +38 -7
  263. package/src/sap/fe/core/messagebundle_pt_PT.properties +37 -6
  264. package/src/sap/fe/core/messagebundle_ro.properties +37 -6
  265. package/src/sap/fe/core/messagebundle_ru.properties +37 -6
  266. package/src/sap/fe/core/messagebundle_sh.properties +39 -8
  267. package/src/sap/fe/core/messagebundle_sk.properties +37 -6
  268. package/src/sap/fe/core/messagebundle_sl.properties +43 -12
  269. package/src/sap/fe/core/messagebundle_sv.properties +38 -7
  270. package/src/sap/fe/core/messagebundle_th.properties +36 -5
  271. package/src/sap/fe/core/messagebundle_tr.properties +39 -8
  272. package/src/sap/fe/core/messagebundle_uk.properties +37 -6
  273. package/src/sap/fe/core/messagebundle_vi.properties +37 -6
  274. package/src/sap/fe/core/messagebundle_zh_CN.properties +37 -6
  275. package/src/sap/fe/core/messagebundle_zh_TW.properties +43 -12
  276. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +47 -73
  277. package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +3 -1
  278. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +231 -202
  279. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +211 -0
  280. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +70 -96
  281. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +10 -8
  282. package/src/sap/fe/core/services/NavigationServiceFactory.js +351 -300
  283. package/src/sap/fe/core/services/NavigationServiceFactory.ts +313 -0
  284. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +114 -81
  285. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +83 -0
  286. package/src/sap/fe/core/services/RoutingServiceFactory.js +963 -899
  287. package/src/sap/fe/core/services/RoutingServiceFactory.ts +907 -0
  288. package/src/sap/fe/core/services/ShellServicesFactory.js +694 -741
  289. package/src/sap/fe/core/services/ShellServicesFactory.ts +45 -40
  290. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +572 -643
  291. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +67 -96
  292. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +429 -487
  293. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +449 -0
  294. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +48 -8
  295. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +11 -0
  296. package/src/sap/fe/core/support/AnnotationIssue.support.js +15 -3
  297. package/src/sap/fe/core/support/AnnotationIssue.support.ts +16 -2
  298. package/src/sap/fe/core/support/CollectionFacetUnsupportedLevel.support.js +2 -2
  299. package/src/sap/fe/core/support/CollectionFacetUnsupportedLevel.support.ts +1 -1
  300. package/src/sap/fe/core/support/CommonHelper.js +1 -1
  301. package/src/sap/fe/core/support/CommonHelper.ts +1 -4
  302. package/src/sap/fe/core/support/Diagnostics.js +36 -48
  303. package/src/sap/fe/core/templating/DataModelPathHelper.js +91 -90
  304. package/src/sap/fe/core/templating/DataModelPathHelper.ts +126 -123
  305. package/src/sap/fe/core/templating/DisplayModeFormatter.js +23 -3
  306. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +26 -5
  307. package/src/sap/fe/core/templating/FieldControlHelper.js +8 -8
  308. package/src/sap/fe/core/templating/FieldControlHelper.ts +25 -7
  309. package/src/sap/fe/core/templating/FilterHelper.js +138 -79
  310. package/src/sap/fe/core/templating/FilterHelper.ts +148 -79
  311. package/src/sap/fe/core/templating/PropertyHelper.js +16 -2
  312. package/src/sap/fe/core/templating/PropertyHelper.ts +31 -24
  313. package/src/sap/fe/core/templating/UIFormatters.js +179 -43
  314. package/src/sap/fe/core/templating/UIFormatters.ts +190 -61
  315. package/src/sap/fe/core/type/Email.js +26 -8
  316. package/src/sap/fe/core/type/Email.ts +10 -11
  317. package/ui5.yaml +0 -3
  318. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +0 -74
@@ -1,1666 +1,1577 @@
1
1
  /*!
2
- * SAPUI5
3
- * (c) Copyright 2009-2022 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/base/Object",
8
- "sap/fe/core/AnnotationHelper",
9
- "sap/fe/core/actions/draft",
10
- "sap/fe/core/actions/sticky",
11
- "sap/fe/core/actions/operations",
12
- "sap/ui/model/json/JSONModel",
13
- "sap/m/Popover",
14
- "sap/m/VBox",
15
- "sap/m/CheckBox",
16
- "sap/m/Text",
17
- "sap/m/Button",
18
- "sap/m/MessageToast",
19
- "sap/m/Dialog",
20
- "sap/ui/model/BindingMode",
21
- "sap/base/Log",
22
- "sap/ui/core/message/Message",
23
- "sap/fe/core/CommonUtils",
24
- "sap/fe/core/BusyLocker",
25
- "sap/ui/core/util/XMLPreprocessor",
26
- "sap/ui/core/XMLTemplateProcessor",
27
- "sap/ui/core/Fragment",
28
- "sap/m/MessageBox",
29
- "sap/fe/core/helpers/ModelHelper",
30
- "sap/fe/core/library",
31
- "sap/ui/core/ValueState",
32
- "sap/fe/core/actions/messageHandling"
33
- ],
34
- function(
35
- BaseObject,
36
- AnnotationHelper,
37
- draft,
38
- sticky,
39
- operations,
40
- JSONModel,
41
- Popover,
42
- VBox,
43
- CheckBox,
44
- Text,
45
- Button,
46
- MessageToast,
47
- Dialog,
48
- BindingMode,
49
- Log,
50
- Message,
51
- CommonUtils,
52
- BusyLocker,
53
- XMLPreprocessor,
54
- XMLTemplateProcessor,
55
- Fragment,
56
- MessageBox,
57
- ModelHelper,
58
- FELibrary,
59
- ValueState,
60
- messageHandling
61
- ) {
62
- "use strict";
63
- var CreationMode = FELibrary.CreationMode,
64
- ProgrammingModel = FELibrary.ProgrammingModel;
65
- /* Make sure that the mParameters is not the oEvent */
66
- function getParameters(mParameters) {
67
- if (mParameters && mParameters.getMetadata && mParameters.getMetadata().getName() === "sap.ui.base.Event") {
68
- mParameters = {};
69
- }
70
- return mParameters || {};
71
- }
72
- return BaseObject.extend("sap.fe.core.TransactionHelper", {
73
- constructor: function(oAppComponent, oLockObject) {
74
- this._oAppComponent = oAppComponent;
75
- this.oLockObject = oLockObject;
76
- },
77
- getProgrammingModel: function(oContext) {
78
- if (!this.sProgrammingModel && oContext) {
79
- var sPath;
80
- if (oContext.isA("sap.ui.model.odata.v4.Context")) {
81
- sPath = oContext.getPath();
82
- } else {
83
- sPath = oContext.isRelative() ? oContext.getResolvedPath() : oContext.getPath();
84
- }
85
- if (ModelHelper.isDraftSupported(oContext.getModel().getMetaModel(), sPath)) {
86
- this.sProgrammingModel = ProgrammingModel.Draft;
87
- } else if (ModelHelper.isStickySessionSupported(oContext.getModel().getMetaModel())) {
88
- this.sProgrammingModel = ProgrammingModel.Sticky;
89
- } else {
90
- // as the transaction helper is a singleton we don't store the non draft as the user could
91
- // start with a non draft child page and navigates back to a draft enabled one
92
- return ProgrammingModel.NonDraft;
93
- }
94
- }
95
- return this.sProgrammingModel;
96
- },
97
- /**
98
- * Creates a new document.
99
- *
100
- * @memberof sap.fe.core.TransactionHelper
101
- * @static
102
- * @param {sap.ui.model.odata.v4.ODataListBinding} oMainListBinding OData V4 ListBinding object
103
- * @param {object} [mParameters] Optional, can contain the following attributes:
104
- * @param {map} [mParameters.data] A map of data that should be sent within the POST
105
- * @param {string} [mParameters.busyMode] Global (default), Local, None TODO: to be refactored
106
- * @param {map} [mParameters.keepTransientContextOnFailed] If set, the context stays in the list if the POST failed and POST will be repeated with the next change
107
- * @param oResourceBundle
108
- * @param messageHandler
109
- * @param bFromCopyPaste
110
- * @returns {Promise} Promise resolves with new binding context
111
- * @ui5-restricted
112
- * @final
113
- */
114
- createDocument: function(oMainListBinding, mParameters, oResourceBundle, messageHandler, bFromCopyPaste) {
115
- var oNewDocumentContext,
116
- that = this,
117
- oModel = oMainListBinding.getModel(),
118
- oMetaModel = oModel.getMetaModel(),
119
- sMetaPath = oMetaModel.getMetaPath(oMainListBinding.getHeaderContext().getPath()),
120
- sCreateHash = this._getAppComponent()
121
- .getRouterProxy()
122
- .getHash(),
123
- oComponentData = this._getAppComponent().getComponentData(),
124
- oStartupParameters = (oComponentData && oComponentData.startupParameters) || {},
125
- sNewAction = !oMainListBinding.isRelative()
126
- ? this._getNewAction(oStartupParameters, sCreateHash, oMetaModel, sMetaPath)
127
- : undefined,
128
- oCreationPromise,
129
- mBindingParameters = { "$$patchWithoutSideEffects": true },
130
- sMessagesPath = oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.Common.v1.Messages/$Path"),
131
- sProgrammingModel,
132
- sBusyPath = "/busy",
133
- sFunctionName =
134
- oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DefaultValuesFunction") ||
135
- oMetaModel.getObject(
136
- ModelHelper.getTargetEntitySet(oMetaModel.getContext(sMetaPath)) +
137
- "@com.sap.vocabularies.Common.v1.DefaultValuesFunction"
138
- ),
139
- bFunctionOnNavProp;
140
- if (sFunctionName) {
141
- if (
142
- oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DefaultValuesFunction") &&
143
- ModelHelper.getTargetEntitySet(oMetaModel.getContext(sMetaPath)) !== sMetaPath
144
- ) {
145
- bFunctionOnNavProp = true;
146
- } else {
147
- bFunctionOnNavProp = false;
148
- }
149
- }
150
- if (sMessagesPath) {
151
- mBindingParameters["$select"] = sMessagesPath;
152
- }
153
- mParameters = getParameters(mParameters);
154
- if (!oMainListBinding) {
155
- return Promise.reject("Binding required for new document creation");
156
- }
157
- sProgrammingModel = this.getProgrammingModel(oMainListBinding);
158
- if (sProgrammingModel !== ProgrammingModel.Draft && sProgrammingModel !== ProgrammingModel.Sticky) {
159
- return Promise.reject("Create document only allowed for draft or sticky session supported services");
160
- }
161
- if (mParameters.busyMode === "Local") {
162
- // in case of local busy mode we use the list binding name
163
- // there's no APY yet so we have to use the .sId TODO provide a public method?
164
- sBusyPath = "/busyLocal/" + oMainListBinding.sId;
165
- }
166
- BusyLocker.lock(this.oLockObject, sBusyPath);
167
- var oResourceBundleCore = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core");
168
- if (sNewAction) {
169
- oCreationPromise = this.callAction(
170
- sNewAction,
171
- {
172
- contexts: oMainListBinding.getHeaderContext(),
173
- showActionParameterDialog: true,
174
- label: this._getSpecificCreateActionDialogLabel(oMetaModel, sMetaPath, sNewAction, oResourceBundleCore),
175
- bindingParameters: mBindingParameters,
176
- parentControl: mParameters.parentControl,
177
- bIsCreateAction: true
178
- },
179
- null,
180
- messageHandler
181
- );
182
- } else {
183
- var bIsNewPageCreation =
184
- mParameters.creationMode !== CreationMode.CreationRow && mParameters.creationMode !== CreationMode.Inline;
185
- var aNonComputedVisibleKeyFields = bIsNewPageCreation
186
- ? CommonUtils.getNonComputedVisibleFields(oMetaModel, sMetaPath)
187
- : [];
188
- sFunctionName = bFromCopyPaste ? null : sFunctionName;
189
- var sFunctionPath, oFunctionContext;
190
- if (sFunctionName) {
191
- //bound to the source entity:
192
- if (bFunctionOnNavProp) {
193
- sFunctionPath =
194
- oMainListBinding.getContext() &&
195
- oMetaModel.getMetaPath(oMainListBinding.getContext().getPath()) + "/" + sFunctionName;
196
- oFunctionContext = oMainListBinding.getContext();
197
- } else {
198
- sFunctionPath =
199
- oMainListBinding.getHeaderContext() &&
200
- oMetaModel.getMetaPath(oMainListBinding.getHeaderContext().getPath()) + "/" + sFunctionName;
201
- oFunctionContext = oMainListBinding.getHeaderContext();
202
- }
203
- }
204
- var oFunction = sFunctionPath && oMetaModel.createBindingContext(sFunctionPath);
205
- if (oFunction && oFunction.getObject() && oFunction.getObject()[0].$IsBound) {
206
- oCreationPromise = operations.callBoundFunction(sFunctionName, oFunctionContext, oModel);
207
- } else {
208
- oCreationPromise = operations.callFunctionImport(sFunctionName, oModel);
209
- }
210
-
211
- oCreationPromise = oCreationPromise
212
- .then(function(oContext) {
213
- if (oContext) {
214
- return oContext.getObject();
215
- } else {
216
- return undefined;
217
- }
218
- })
219
- .catch(function(oError) {
220
- Log.error("Error while executing the function " + sFunctionName, oError);
221
- throw oError;
222
- })
223
- .then(function(oData) {
224
- mParameters.data = oData ? Object.assign({}, oData, mParameters.data) : mParameters.data;
225
- if (mParameters.data) {
226
- delete mParameters.data["@odata.context"];
227
- }
228
- if (aNonComputedVisibleKeyFields.length > 0) {
229
- var oTransientListBinding = oModel.bindList(
230
- oMainListBinding.getPath(),
231
- oMainListBinding.getContext(),
232
- [],
233
- [],
234
- {
235
- $$updateGroupId: "submitLater"
236
- }
237
- );
238
- oTransientListBinding.refreshInternal = function() {};
239
- oNewDocumentContext = oTransientListBinding.create(mParameters.data, true);
240
- return that._launchDialogWithKeyFields(
241
- oMainListBinding,
242
- oTransientListBinding,
243
- oNewDocumentContext,
244
- aNonComputedVisibleKeyFields,
245
- oModel,
246
- mParameters,
247
- messageHandler
248
- );
249
- } else {
250
- oNewDocumentContext = oMainListBinding.create(mParameters.data, true, mParameters.createAtEnd);
251
- return that.onAfterCreateCompletion(
252
- oMainListBinding,
253
- oNewDocumentContext,
254
- mParameters,
255
- oResourceBundleCore
256
- );
257
- }
258
- })
259
- .catch(function(oError) {
260
- Log.error("Error while creating the new document", oError);
261
- throw oError;
262
- });
263
- }
264
- return oCreationPromise
265
- .then(function(oResult) {
266
- if (!oMainListBinding.isRelative()) {
267
- // the create mode shall currently only be set on creating a root document
268
- that._bCreateMode = true;
269
- }
270
- oNewDocumentContext = oNewDocumentContext || (oResult && oResult.response);
271
- // TODO: where does this one coming from???
272
- if (oResult && oResult.bConsiderDocumentModified) {
273
- that.handleDocumentModifications();
274
- }
275
- return messageHandler.showMessageDialog().then(function() {
276
- return oNewDocumentContext;
277
- });
278
- })
279
- .catch(function(oError) {
280
- return messageHandler.showMessageDialog().then(function() {
281
- // for instance, on cancel of create dialog, the promise is rejected
282
- // a return here would restore the promise chain and result in errors while routing
283
- // solution - reject here as well
284
- if (oError && oError.bDeleteTransientContext && oNewDocumentContext.isTransient()) {
285
- // This is a workaround suggested by model as Context.delete results in an error
286
- // TODO: remove the $direct once model resolves this issue
287
- // this line shows the expected console error Uncaught (in promise) Error: Request canceled: POST Travel; group: submitLater
288
- oNewDocumentContext.delete("$direct");
289
- }
290
- return Promise.reject(oError);
291
- });
292
- })
293
- .finally(function() {
294
- BusyLocker.unlock(that.oLockObject, sBusyPath);
295
- });
296
- },
297
- /**
298
- * Find the active contexts of the documents, only for the draft roots.
299
- *
300
- * @memberof sap.fe.core.TransactionHelper
301
- * @static
302
- * @param {sap.ui.model.odata.v4.Context[]} aContexts Contexts Either one context or an array with contexts to be deleted
303
- * @param bFindActiveContexts
304
- * @returns {Array} Array of the active contexts
305
- */
306
- findActiveDraftRootContexts: function(aContexts, bFindActiveContexts) {
307
- if (!bFindActiveContexts) {
308
- return Promise.resolve();
309
- }
310
- var activeContexts = aContexts.reduce(function(aResult, oContext) {
311
- var oMetaModel = oContext.getModel().getMetaModel();
312
- var sMetaPath = oMetaModel.getMetaPath(oContext.getPath());
313
- if (oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DraftRoot")) {
314
- var bIsActiveEntity = oContext.getObject().IsActiveEntity,
315
- bHasActiveEntity = oContext.getObject().HasActiveEntity,
316
- oActiveContext;
317
- if (!bIsActiveEntity && bHasActiveEntity) {
318
- oActiveContext = oContext
319
- .getModel()
320
- .bindContext(oContext.getPath() + "/SiblingEntity")
321
- .getBoundContext();
322
- aResult.push(oActiveContext);
323
- }
324
- }
325
- return aResult;
326
- }, []);
327
- return Promise.all(
328
- activeContexts.map(function(oContext) {
329
- return oContext.requestCanonicalPath().then(
330
- function() {
331
- return oContext;
332
- },
333
- function() {
334
- return;
335
- }
336
- );
337
- })
338
- );
339
- },
340
- afterDeleteProcess: function(mParameters, checkBox, aContexts, oResourceBundle) {
341
- var oInternalModelContext = mParameters.internalModelContext;
342
- if (oInternalModelContext && oInternalModelContext.getProperty("deleteEnabled") != undefined) {
343
- if (checkBox.isCheckBoxVisible === true && checkBox.isCheckBoxSelected === false) {
344
- //if unsaved objects are not deleted then we need to set the enabled to true and update the model data for next deletion
345
- oInternalModelContext.setProperty("deleteEnabled", true);
346
- var obj = Object.assign(oInternalModelContext.getObject(), {});
347
- obj.selectedContexts = obj.selectedContexts.filter(function(element) {
348
- return obj.deletableContexts.indexOf(element) === -1;
349
- });
350
- obj.deletableContexts = [];
351
- obj.selectedContexts = [];
352
- obj.numberOfSelectedContexts = obj.selectedContexts.length;
353
- oInternalModelContext.setProperty("", obj);
354
- } else {
355
- oInternalModelContext.setProperty("deleteEnabled", false);
356
- oInternalModelContext.setProperty("selectedContexts", []);
357
- oInternalModelContext.setProperty("numberOfSelectedContexts", 0);
358
- }
359
- }
360
- if (aContexts.length === 1) {
361
- MessageToast.show(
362
- CommonUtils.getTranslatedText(
363
- "C_TRANSACTION_HELPER_OBJECT_PAGE_DELETE_TOAST_SINGULAR",
364
- oResourceBundle,
365
- null,
366
- mParameters.entitySetName
367
- )
368
- );
369
- } else {
370
- MessageToast.show(
371
- CommonUtils.getTranslatedText(
372
- "C_TRANSACTION_HELPER_OBJECT_PAGE_DELETE_TOAST_PLURAL",
373
- oResourceBundle,
374
- null,
375
- mParameters.entitySetName
376
- )
377
- );
378
- }
379
- },
380
- /**
381
- * Delete one or multiple document(s).
382
- *
383
- * @memberof sap.fe.core.TransactionHelper
384
- * @static
385
- * @param {sap.ui.model.odata.v4.Context} vContexts Contexts Either one context or an array with contexts to be deleted
386
- * @param {object} mParameters Optional, can contain the following attributes:
387
- * @param {string} mParameters.title Title of the object to be deleted
388
- * @param {string} mParameters.description Description of the object to be deleted
389
- * @param {string} mParameters.numberOfSelectedContexts Number of objects selected
390
- * @param {boolean} mParameters.noDialog To disable the confirmation dialog
391
- * @param oResourceBundle
392
- * @param messageHandler
393
- * @returns {Promise}
394
- */
395
- deleteDocument: function(vContexts, mParameters, oResourceBundle, messageHandler) {
396
- var fnReject,
397
- fnResolve,
398
- aDeletableContexts = [],
399
- isCheckBoxVisible = false,
400
- isLockedTextVisible = false,
401
- cannotBeDeletedTextVisible = false,
402
- isCheckBoxSelected,
403
- bDialogConfirmed = false,
404
- that = this,
405
- oResourceBundleCore = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core"),
406
- aParams,
407
- oDeleteMessage = {
408
- title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE")
409
- };
410
- BusyLocker.lock(this.oLockObject);
411
- if (!Array.isArray(vContexts)) {
412
- vContexts = [vContexts];
413
- }
414
- Promise.resolve(this.getProgrammingModel(vContexts[0]))
415
- .then(function(sProgrammingModel) {
416
- if (mParameters) {
417
- if (!mParameters.numberOfSelectedContexts) {
418
- if (sProgrammingModel === ProgrammingModel.Draft) {
419
- for (var i = 0; i < vContexts.length; i++) {
420
- var oContextData = vContexts[i].getObject();
421
- if (
422
- oContextData.IsActiveEntity === true &&
423
- oContextData.HasDraftEntity === true &&
424
- oContextData.DraftAdministrativeData &&
425
- oContextData.DraftAdministrativeData.InProcessByUser &&
426
- !oContextData.DraftAdministrativeData.DraftIsCreatedByMe
427
- ) {
428
- MessageBox.show(
429
- CommonUtils.getTranslatedText(
430
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_SINGLE_OBJECT_LOCKED",
431
- oResourceBundle
432
- ),
433
- {
434
- title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE"),
435
- onClose: fnReject
436
- }
437
- );
438
- return;
439
- }
440
- }
441
- }
442
- mParameters = getParameters(mParameters);
443
- if (mParameters.title) {
444
- aParams = [mParameters.title, mParameters.description];
445
- oDeleteMessage.text = CommonUtils.getTranslatedText(
446
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO",
447
- oResourceBundle,
448
- aParams,
449
- mParameters.entitySetName
450
- );
451
- } else {
452
- oDeleteMessage.text = CommonUtils.getTranslatedText(
453
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR",
454
- oResourceBundle
455
- );
456
- }
457
- aDeletableContexts = vContexts;
458
- } else {
459
- oDeleteMessage = {
460
- title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE")
461
- };
462
- if (
463
- mParameters.numberOfSelectedContexts === 1 &&
464
- mParameters.numberOfSelectedContexts === vContexts.length
465
- ) {
466
- aDeletableContexts = vContexts;
467
- oDeleteMessage.text = CommonUtils.getTranslatedText(
468
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR",
469
- oResourceBundle,
470
- null,
471
- mParameters.entitySetName
472
- );
473
- } else if (mParameters.numberOfSelectedContexts === 1 && mParameters.unSavedContexts.length === 1) {
474
- //only one unsaved object
475
- aDeletableContexts = mParameters.unSavedContexts;
476
- var draftAdminData = aDeletableContexts[0].getObject()["DraftAdministrativeData"];
477
- var sLastChangedByUser = "";
478
- if (draftAdminData) {
479
- sLastChangedByUser =
480
- draftAdminData["LastChangedByUserDescription"] || draftAdminData["LastChangedByUser"] || "";
481
- }
482
- aParams = [sLastChangedByUser];
483
- oDeleteMessage.text = CommonUtils.getTranslatedText(
484
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_CHANGES",
485
- oResourceBundle,
486
- aParams
487
- );
488
- } else if (mParameters.numberOfSelectedContexts === mParameters.unSavedContexts.length) {
489
- //only multiple unsaved objects
490
- aDeletableContexts = mParameters.unSavedContexts;
491
- oDeleteMessage.text = CommonUtils.getTranslatedText(
492
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_CHANGES_MULTIPLE_OBJECTS",
493
- oResourceBundle
494
- );
495
- } else if (
496
- mParameters.numberOfSelectedContexts ===
497
- vContexts.concat(mParameters.unSavedContexts.concat(mParameters.lockedContexts)).length
498
- ) {
499
- //only unsaved, locked ,deletable objects but not non-deletable objects
500
- aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
501
- oDeleteMessage.text =
502
- aDeletableContexts.length === 1
503
- ? CommonUtils.getTranslatedText(
504
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR",
505
- oResourceBundle,
506
- null,
507
- mParameters.entitySetName
508
- )
509
- : CommonUtils.getTranslatedText(
510
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_PLURAL",
511
- oResourceBundle,
512
- null,
513
- mParameters.entitySetName
514
- );
515
- } else {
516
- //if non-deletable objects exists along with any of unsaved ,deletable objects
517
- aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
518
- cannotBeDeletedTextVisible = true;
519
- oDeleteMessage.text =
520
- aDeletableContexts.length === 1
521
- ? CommonUtils.getTranslatedText(
522
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR_NON_DELETABLE",
523
- oResourceBundle,
524
- null,
525
- mParameters.entitySetName
526
- )
527
- : CommonUtils.getTranslatedText(
528
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_PLURAL_NON_DELETABLE",
529
- oResourceBundle,
530
- null,
531
- mParameters.entitySetName
532
- );
533
- oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
534
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_NON_DELETABLE",
535
- oResourceBundle,
536
- [
537
- mParameters.numberOfSelectedContexts - vContexts.concat(mParameters.unSavedContexts).length,
538
- mParameters.numberOfSelectedContexts
539
- ]
540
- );
541
- }
542
- if (mParameters.lockedContexts.length == 1) {
543
- //setting the locked text if locked objects exist
544
- isLockedTextVisible = true;
545
- oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
546
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_ONE_OBJECT_LOCKED",
547
- oResourceBundle,
548
- [mParameters.numberOfSelectedContexts]
549
- );
550
- }
551
- if (mParameters.lockedContexts.length > 1) {
552
- //setting the locked text if locked objects exist
553
- isLockedTextVisible = true;
554
- oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
555
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_LOCKED",
556
- oResourceBundle,
557
- [mParameters.lockedContexts.length, mParameters.numberOfSelectedContexts]
558
- );
559
- }
560
- if (
561
- mParameters.unSavedContexts.length > 0 &&
562
- mParameters.unSavedContexts.length !== mParameters.numberOfSelectedContexts
563
- ) {
564
- if (
565
- (cannotBeDeletedTextVisible || isLockedTextVisible) &&
566
- aDeletableContexts.length === mParameters.unSavedContexts.length
567
- ) {
568
- //if only unsaved and either or both of locked and non-deletable objects exist then we hide the check box
569
- isCheckBoxVisible = false;
570
- aDeletableContexts = mParameters.unSavedContexts;
571
- if (mParameters.unSavedContexts.length === 1) {
572
- oDeleteMessage.text = CommonUtils.getTranslatedText(
573
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_AND_FEW_OBJECTS_LOCKED_SINGULAR",
574
- oResourceBundle
575
- );
576
- } else {
577
- oDeleteMessage.text = CommonUtils.getTranslatedText(
578
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_AND_FEW_OBJECTS_LOCKED_PLURAL",
579
- oResourceBundle
580
- );
581
- }
582
- } else {
583
- if (mParameters.unSavedContexts.length === 1) {
584
- oDeleteMessage.checkBoxText = CommonUtils.getTranslatedText(
585
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_UNSAVED_SINGULAR",
586
- oResourceBundle
587
- );
588
- } else {
589
- oDeleteMessage.checkBoxText = CommonUtils.getTranslatedText(
590
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_UNSAVED_PLURAL",
591
- oResourceBundle
592
- );
593
- }
594
- isCheckBoxVisible = true;
595
- }
596
- }
597
- if (cannotBeDeletedTextVisible && isLockedTextVisible) {
598
- //if both locked and non-deletable objects exist along with deletable objects
599
- if (mParameters.unSavedContexts.length > 1) {
600
- oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
601
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_LOCKED_AND_NON_DELETABLE",
602
- oResourceBundle,
603
- [
604
- mParameters.numberOfSelectedContexts -
605
- vContexts.concat(mParameters.unSavedContexts).length -
606
- mParameters.lockedContexts.length,
607
- mParameters.lockedContexts.length,
608
- mParameters.numberOfSelectedContexts
609
- ]
610
- );
611
- }
612
- if (mParameters.unSavedContexts.length == 1) {
613
- oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
614
- "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_ONE_OBJECT_LOCKED_AND_NON_DELETABLE",
615
- oResourceBundle,
616
- [
617
- mParameters.numberOfSelectedContexts -
618
- vContexts.concat(mParameters.unSavedContexts).length -
619
- mParameters.lockedContexts.length,
620
- mParameters.numberOfSelectedContexts
621
- ]
622
- );
623
- }
624
- }
625
- }
626
- }
627
- var oNonDeletableMessageTextControl,
628
- oDeleteMessageTextControl,
629
- oContent = new VBox({
630
- items: [
631
- (oNonDeletableMessageTextControl = new Text({
632
- text: oDeleteMessage.nonDeletableText,
633
- visible: isLockedTextVisible || cannotBeDeletedTextVisible
634
- })),
635
- (oDeleteMessageTextControl = new Text({
636
- text: oDeleteMessage.text
637
- })),
638
- new CheckBox({
639
- text: oDeleteMessage.checkBoxText,
640
- selected: true,
641
- select: function(oEvent) {
642
- var selected = oEvent.getSource().getSelected();
643
- if (selected) {
644
- aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
645
- isCheckBoxSelected = true;
646
- } else {
647
- aDeletableContexts = vContexts;
648
- isCheckBoxSelected = false;
649
- }
650
- },
651
- visible: isCheckBoxVisible
652
- })
653
- ]
654
- });
655
- var sTitle = oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE");
656
- var fnConfirm = function() {
657
- bDialogConfirmed = true;
658
- BusyLocker.lock(that.oLockObject);
659
- var aContexts = aDeletableContexts;
660
- var onBeforeDeletePromise;
661
- if (mParameters.beforeDeleteCallBack) {
662
- onBeforeDeletePromise = mParameters.beforeDeleteCallBack({ contexts: aContexts });
663
- } else {
664
- onBeforeDeletePromise = Promise.resolve();
665
- }
666
- return onBeforeDeletePromise
667
- .then(that.findActiveDraftRootContexts.bind(that, aContexts, mParameters.bFindActiveContexts))
668
- .then(function(activeContexts) {
669
- //make sure to fetch the active contexts before deleting the drafts
670
- return Promise.all(
671
- aContexts.map(function(oContext) {
672
- //delete the draft
673
- return draft.deleteDraft(oContext);
674
- })
675
- )
676
- .catch(function(oError) {
677
- return messageHandler.showMessages().then(function() {
678
- // re-throw error to enforce rejecting the general promise
679
- throw oError;
680
- });
681
- })
682
- .then(function() {
683
- var checkBox = {
684
- "isCheckBoxVisible": isCheckBoxVisible,
685
- "isCheckBoxSelected": isCheckBoxSelected
686
- };
687
- if (activeContexts && activeContexts.length) {
688
- return Promise.all(
689
- activeContexts.map(function(oContext) {
690
- return oContext.delete();
691
- })
692
- ).then(function() {
693
- that.afterDeleteProcess(mParameters, checkBox, aContexts, oResourceBundle);
694
- return messageHandler.showMessageDialog().then(fnResolve);
695
- });
696
- } else {
697
- that.afterDeleteProcess(mParameters, checkBox, aContexts, oResourceBundle);
698
- return messageHandler.showMessageDialog().then(fnResolve);
699
- }
700
- });
701
- })
702
- .catch(function() {
703
- fnReject();
704
- })
705
- .finally(function() {
706
- BusyLocker.unlock(that.oLockObject);
707
- });
708
- };
709
- var oDialog = new Dialog({
710
- title: sTitle,
711
- state: "Warning",
712
- content: [oContent],
713
- ariaLabelledBy: oNonDeletableMessageTextControl.getVisible()
714
- ? [oNonDeletableMessageTextControl, oDeleteMessageTextControl]
715
- : oDeleteMessageTextControl,
716
- beginButton: new Button({
717
- text: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE"),
718
- type: "Emphasized",
719
- press: function() {
720
- oDialog.close();
721
- return fnConfirm();
722
- }
723
- }),
724
- endButton: new Button({
725
- text: CommonUtils.getTranslatedText("C_COMMON_OBJECT_PAGE_CANCEL", oResourceBundle),
726
- press: function() {
727
- oDialog.close();
728
- }
729
- }),
730
- afterClose: function() {
731
- oDialog.destroy();
732
- // if dialog is closed unconfirmed (e.g. via "Cancel" or Escape button), ensure to reject promise
733
- if (!bDialogConfirmed) {
734
- fnReject();
735
- }
736
- }
737
- });
738
- if (mParameters.noDialog) {
739
- return fnConfirm();
740
- } else {
741
- oDialog.addStyleClass("sapUiContentPadding");
742
- oDialog.open();
743
- }
744
- })
745
- .finally(function() {
746
- BusyLocker.unlock(that.oLockObject);
747
- })
748
- .catch(function() {
749
- Log.warning("Couldn't get Programming model");
750
- fnReject();
751
- });
752
- return new Promise(function(resolve, reject) {
753
- fnReject = reject;
754
- fnResolve = resolve;
755
- });
756
- },
757
- /**
758
- * Edits a document.
759
- *
760
- * @memberof sap.fe.core.TransactionHelper
761
- * @static
762
- * @param {sap.ui.model.odata.v4.Context} oContext Context of the active document
763
- * @param {boolean} bPrepareOnEdit Also call the 'prepare' action for draft-based documents
764
- * @param {object} oView Object of current view
765
- * @param messageHandler
766
- * @returns {Promise} Promise resolves with the new draft context in case of draft programming model
767
- * @ui5-restricted
768
- * @final
769
- */
770
- editDocument: function(oContext, bPrepareOnEdit, oView, messageHandler) {
771
- var that = this,
772
- sProgrammingModel = this.getProgrammingModel(oContext),
773
- oEditPromise;
774
- if (!oContext) {
775
- return Promise.reject(new Error("Binding context to active document is required"));
776
- }
777
- this._bIsModified = false;
778
- BusyLocker.lock(that.oLockObject);
779
- // before triggering the edit action we'll have to remove all bound transition messages
780
- messageHandler.removeTransitionMessages();
781
- if (sProgrammingModel === ProgrammingModel.Draft) {
782
- oEditPromise = draft.createDraftFromActiveDocument(oContext, this._getAppComponent(), {
783
- bPreserveChanges: true,
784
- bPrepareOnEdit: bPrepareOnEdit,
785
- oView: oView
786
- });
787
- } else if (sProgrammingModel === ProgrammingModel.Sticky) {
788
- oEditPromise = sticky.editDocumentInStickySession(oContext);
789
- } else {
790
- BusyLocker.unlock(that.oLockObject);
791
- return Promise.reject(new Error("Edit is only allowed for draft or sticky session supported services"));
792
- }
793
- return oEditPromise
794
- .then(function(oNewContext) {
795
- that._bCreateMode = false;
796
- return messageHandler.showMessageDialog().then(function() {
797
- return oNewContext;
798
- });
799
- })
800
- .catch(function(err) {
801
- return messageHandler.showMessages().then(function() {
802
- return Promise.reject(err);
803
- });
804
- })
805
- .finally(function() {
806
- BusyLocker.unlock(that.oLockObject);
807
- });
808
- },
809
- /**
810
- * Cancel 'edit' mode of a document.
811
- *
812
- * @memberof sap.fe.core.TransactionHelper
813
- * @static
814
- * @param {sap.ui.model.odata.v4.Context} oContext Context of the document to be canceled or deleted
815
- * @param {object} [mParameters] Optional, can contain the following attributes:
816
- * @param {sap.m.Button} mParameters.cancelButton Cancel Button of the discard popover (mandatory for now)
817
- * @param {boolean} mParameters.skipDiscardPopover Optional, supresses the discard popover incase of draft applications while navigating out of OP
818
- * @param oResourceBundle
819
- * @param messageHandler
820
- * @returns {Promise} Promise resolves with ???
821
- * @ui5-restricted
822
- * @final
823
- */
824
- cancelDocument: function(oContext, mParameters, oResourceBundle, messageHandler) {
825
- var that = this,
826
- sProgrammingModel;
827
- //context must always be passed - mandatory parameter
828
- if (!oContext) {
829
- return Promise.reject("No context exists. Pass a meaningful context");
830
- }
831
- BusyLocker.lock(that.oLockObject);
832
- mParameters = getParameters(mParameters);
833
- var oParamsContext = oContext,
834
- oCancelButton = mParameters.cancelButton,
835
- oModel = oParamsContext.getModel(),
836
- onBeforeCancelPromise,
837
- sCanonicalPath;
838
- return Promise.resolve(this.getProgrammingModel(oContext))
839
- .then(function(sPModel) {
840
- sProgrammingModel = sPModel;
841
- if (sPModel === ProgrammingModel.Draft) {
842
- var draftDataContext = oModel
843
- .bindContext(oParamsContext.getPath() + "/DraftAdministrativeData")
844
- .getBoundContext();
845
- if (!that._bIsModified) {
846
- return draftDataContext.requestObject().then(function(draftAdminData) {
847
- if (draftAdminData) {
848
- that._bIsModified = !(draftAdminData.CreationDateTime === draftAdminData.LastChangeDateTime);
849
- }
850
- });
851
- }
852
- }
853
- })
854
- .then(function() {
855
- if (!mParameters.skipDiscardPopover) {
856
- return that._showDiscardPopover(oCancelButton, that._bIsModified, oResourceBundle);
857
- } else {
858
- return Promise.resolve();
859
- }
860
- })
861
- .then(function() {
862
- if (mParameters.beforeCancelCallBack) {
863
- onBeforeCancelPromise = mParameters.beforeCancelCallBack({ context: oContext });
864
- } else {
865
- onBeforeCancelPromise = Promise.resolve();
866
- }
867
- return onBeforeCancelPromise;
868
- })
869
- .then(function() {
870
- // eslint-disable-next-line default-case
871
- switch (sProgrammingModel) {
872
- case ProgrammingModel.Draft:
873
- return oParamsContext.requestObject("HasActiveEntity").then(function(bHasActiveEntity) {
874
- var oDeletePromise;
875
- if (!bHasActiveEntity) {
876
- if (oParamsContext && oParamsContext.hasPendingChanges()) {
877
- oParamsContext.getBinding().resetChanges();
878
- }
879
- oDeletePromise = draft.deleteDraft(oParamsContext);
880
- return oDeletePromise;
881
- } else {
882
- var oActiveContext = oModel
883
- .bindContext(oParamsContext.getPath() + "/SiblingEntity")
884
- .getBoundContext();
885
- return oActiveContext
886
- .requestCanonicalPath()
887
- .then(
888
- function(sPath) {
889
- sCanonicalPath = sPath;
890
- if (oParamsContext && oParamsContext.hasPendingChanges()) {
891
- oParamsContext.getBinding().resetChanges();
892
- }
893
- oDeletePromise = draft.deleteDraft(oParamsContext);
894
- return oDeletePromise;
895
- },
896
- function() {
897
- draft.deleteDraft(oParamsContext);
898
- return;
899
- }
900
- )
901
- .then(function() {
902
- //oParamsContext.delete() in the previous promise doesnt return anything upon success.
903
- if (!sCanonicalPath) {
904
- return;
905
- }
906
- if (oActiveContext.getPath() !== sCanonicalPath) {
907
- // the active context is using the sibling entity - this path is not accessible anymore as we deleted the draft
908
- // document - therefore we need to create a new context with the canonical path
909
- oActiveContext = oModel.bindContext(sCanonicalPath).getBoundContext();
910
- }
911
- return oActiveContext;
912
- });
913
- }
914
- });
915
- case ProgrammingModel.Sticky:
916
- return sticky.discardDocument(oContext).then(function(oContext) {
917
- if (oContext) {
918
- if (oContext.hasPendingChanges()) {
919
- oContext.getBinding().resetChanges();
920
- }
921
- if (!that._bCreateMode) {
922
- oContext.refresh();
923
- return oContext;
924
- }
925
- }
926
- return false;
927
- });
928
- default:
929
- return Promise.reject("Cancel document only allowed for draft or sticky session supported services");
930
- }
931
- })
932
- .then(function(context) {
933
- that._bIsModified = false;
934
- // remove existing bound transition messages
935
- messageHandler.removeTransitionMessages();
936
- // show unbound messages
937
- return messageHandler.showMessages().then(function() {
938
- return context;
939
- });
940
- })
941
- .catch(function(err) {
942
- return messageHandler.showMessages().then(function() {
943
- return Promise.reject(err);
944
- });
945
- })
946
- .finally(function() {
947
- BusyLocker.unlock(that.oLockObject);
948
- });
949
- },
950
- /**
951
- * Saves the document.
952
- *
953
- * @memberof sap.fe.core.TransactionHelper
954
- * @static
955
- * @param {sap.ui.model.odata.v4.Context} oContext Context of the document to be saved
956
- * @param oResourceBundle
957
- * @param bExecuteSideEffectsOnError
958
- * @param aBindings
959
- * @param messageHandler
960
- * @returns {Promise} Promise resolves with ???
961
- * @ui5-restricted
962
- * @final
963
- */
964
- saveDocument: function(oContext, oResourceBundle, bExecuteSideEffectsOnError, aBindings, messageHandler) {
965
- var that = this,
966
- sProgrammingModel = this.getProgrammingModel(oContext),
967
- oSavePromise;
968
- if (!oContext) {
969
- return Promise.reject(new Error("Binding context to draft document is required"));
970
- }
971
- // in case of saving / activating the bound transition messages shall be removed before the PATCH/POST
972
- // is sent to the backend
973
- messageHandler.removeTransitionMessages();
974
- BusyLocker.lock(that.oLockObject);
975
- if (sProgrammingModel === ProgrammingModel.Draft) {
976
- oSavePromise = draft.activateDocument(oContext, this._getAppComponent());
977
- } else if (sProgrammingModel === ProgrammingModel.Sticky) {
978
- oSavePromise = sticky.activateDocument(oContext);
979
- } else {
980
- BusyLocker.unlock(that.oLockObject);
981
- return Promise.reject(new Error("Save is only allowed for draft or sticky session supported services"));
982
- }
983
- return oSavePromise
984
- .then(function(oActiveDocument) {
985
- var bNewObject =
986
- that.sProgrammingModel === ProgrammingModel.Sticky ? that._bCreateMode : !oContext.getObject().HasActiveEntity;
987
- MessageToast.show(
988
- bNewObject
989
- ? CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_CREATED", oResourceBundle)
990
- : CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_SAVED", oResourceBundle)
991
- );
992
- that._bIsModified = false;
993
- return messageHandler.showMessageDialog().then(function() {
994
- return oActiveDocument;
995
- });
996
- })
997
- .catch(function(err) {
998
- if (aBindings && aBindings.length > 0) {
999
- /* The sideEffects are executed only for table items in transient state */
1000
- aBindings.forEach(function(oListBinding) {
1001
- if (!CommonUtils.hasTransientContext(oListBinding) && bExecuteSideEffectsOnError) {
1002
- var oAppComponent = that._getAppComponent();
1003
- oAppComponent
1004
- .getSideEffectsService()
1005
- .requestSideEffectsForNavigationProperty(oListBinding.getPath(), oContext);
1006
- }
1007
- });
1008
- }
1009
- return messageHandler.showMessages().then(function() {
1010
- return Promise.reject(err);
1011
- });
1012
- })
1013
- .finally(function() {
1014
- BusyLocker.unlock(that.oLockObject);
1015
- });
1016
- },
1017
- /**
1018
- * Calls a bound or unbound action.
1019
- *
1020
- * @function
1021
- * @static
1022
- * @name sap.fe.core.TransactionHelper.callAction
1023
- * @memberof sap.fe.core.TransactionHelper
1024
- * @param {string} sActionName The name of the action to be called
1025
- * @param {map} [mParameters] Contains the following attributes:
1026
- * @param {sap.ui.model.odata.v4.Context} [mParameters.contexts] Mandatory for a bound action: Either one context or an array with contexts for which the action is to be called
1027
- * @param {sap.ui.model.odata.v4.ODataModel} [mParameters.model] Mandatory for an unbound action: An instance of an OData V4 model
1028
- * @param {string} [mParameters.invocationGrouping] Mode how actions are to be called: 'ChangeSet' to put all action calls into one changeset, 'Isolated' to put them into separate changesets
1029
- * @param {string} [mParameters.label] A human-readable label for the action
1030
- * @param {boolean} [mParameters.bGetBoundContext] If specified, the action promise returns the bound context
1031
- * @param {object} oView Contains the object of the current view
1032
- * @param messageHandler
1033
- * @returns {Promise} Promise resolves with an array of response objects (TODO: to be changed)
1034
- * @ui5-restricted
1035
- * @final
1036
- **/
1037
- callAction: function(sActionName, mParameters, oView, messageHandler) {
1038
- mParameters = getParameters(mParameters);
1039
- var that = this,
1040
- oContext,
1041
- oModel,
1042
- oPromise,
1043
- sName,
1044
- mBindingParameters = mParameters.bindingParameters;
1045
- if (!sActionName) {
1046
- return Promise.reject("Provide name of action to be executed");
1047
- }
1048
- // action imports are not directly obtained from the metaModel by it is present inside the entityContainer
1049
- // and the acions it refers to present outside the entitycontainer, hence to obtain kind of the action
1050
- // split() on its name was required
1051
- sName = sActionName.split("/")[1];
1052
- sActionName = sName || sActionName;
1053
- oContext = sName ? undefined : mParameters.contexts;
1054
- //checking whether the context is an array with more than 0 length or not an array(create action)
1055
- if (oContext && ((Array.isArray(oContext) && oContext.length) || !Array.isArray(oContext))) {
1056
- oContext = Array.isArray(oContext) ? oContext[0] : oContext;
1057
- oModel = oContext.getModel();
1058
- }
1059
- if (mParameters.model) {
1060
- oModel = mParameters.model;
1061
- }
1062
- if (!oModel) {
1063
- return Promise.reject("Pass a context for a bound action or pass the model for an unbound action");
1064
- }
1065
- // get the binding parameters $select and $expand for the side effect on this action
1066
- // also gather additional property paths to be requested such as text associations
1067
- var oAppComponent = that._getAppComponent();
1068
- var mSideEffectsParameters = oAppComponent.getSideEffectsService().getODataActionSideEffects(sActionName, oContext) || {};
1069
- if (oContext && oModel) {
1070
- oPromise = new Promise(function(resolve, reject) {
1071
- var oApplicableContextDialog;
1072
- var oController = {
1073
- onClose: function() {
1074
- // User cancels action
1075
- oApplicableContextDialog.close();
1076
- resolve();
1077
- },
1078
- onContinue: function() {
1079
- // Users continues the action with the bound contexts
1080
- oApplicableContextDialog.close();
1081
- resolve(mParameters.applicableContext);
1082
- }
1083
- };
1084
- var fnOpenAndFillDialog = function() {
1085
- var oDialogContent,
1086
- nNotApplicable = mParameters.notApplicableContext.length,
1087
- aNotApplicableItems = [];
1088
- for (var i = 0; i < mParameters.notApplicableContext.length; i++) {
1089
- oDialogContent = mParameters.notApplicableContext[i].getObject();
1090
- aNotApplicableItems.push(oDialogContent);
1091
- }
1092
- var oNotApplicableItemsModel = new JSONModel(aNotApplicableItems);
1093
- var oTotals = new JSONModel({ total: nNotApplicable, label: mParameters.label });
1094
- oApplicableContextDialog.setModel(oNotApplicableItemsModel, "notApplicable");
1095
- oApplicableContextDialog.setModel(oTotals, "totals");
1096
- oApplicableContextDialog.open();
1097
- };
1098
- if (mParameters.notApplicableContext && mParameters.notApplicableContext.length >= 1) {
1099
- // Show the contexts that are not applicable and will not therefore be processed
1100
- var sFragmentName = "sap.fe.core.controls.ActionPartial";
1101
- var oDialogFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment");
1102
- var oMetaModel = oModel.getMetaModel();
1103
- var sCanonicalPath = mParameters.contexts[0].getCanonicalPath();
1104
- var sEntitySet = sCanonicalPath.substr(0, sCanonicalPath.indexOf("(")) + "/";
1105
- var oDialogLabelModel = new JSONModel({
1106
- title: mParameters.label
1107
- });
1108
- Promise.resolve(
1109
- XMLPreprocessor.process(
1110
- oDialogFragment,
1111
- { name: sFragmentName },
1112
- {
1113
- bindingContexts: {
1114
- entityType: oMetaModel.createBindingContext(sEntitySet),
1115
- label: oDialogLabelModel.createBindingContext("/")
1116
- },
1117
- models: {
1118
- entityType: oMetaModel,
1119
- metaModel: oMetaModel,
1120
- label: oDialogLabelModel
1121
- }
1122
- }
1123
- )
1124
- )
1125
- .then(function(oFragment) {
1126
- return Fragment.load({ definition: oFragment, controller: oController });
1127
- })
1128
- .then(function(oPopover) {
1129
- oApplicableContextDialog = oPopover;
1130
- mParameters.parentControl.addDependent(oPopover);
1131
- fnOpenAndFillDialog();
1132
- })
1133
- .catch(reject);
1134
- } else {
1135
- resolve(mParameters.contexts);
1136
- }
1137
- }).then(function(contextToProcess) {
1138
- if (contextToProcess) {
1139
- return operations.callBoundAction(sActionName, contextToProcess, oModel, oAppComponent, {
1140
- invocationGrouping: mParameters.invocationGrouping,
1141
- label: mParameters.label,
1142
- showActionParameterDialog: true,
1143
- mBindingParameters: mBindingParameters,
1144
- entitySetName: mParameters.entitySetName,
1145
- additionalSideEffect: mSideEffectsParameters,
1146
- onSubmitted: function() {
1147
- messageHandler.removeTransitionMessages();
1148
- BusyLocker.lock(that.oLockObject);
1149
- },
1150
- onResponse: function() {
1151
- BusyLocker.unlock(that.oLockObject);
1152
- },
1153
- parentControl: mParameters.parentControl,
1154
- internalModelContext: mParameters.internalModelContext,
1155
- operationAvailableMap: mParameters.operationAvailableMap,
1156
- bIsCreateAction: mParameters.bIsCreateAction,
1157
- bGetBoundContext: mParameters.bGetBoundContext,
1158
- bObjectPage: mParameters.bObjectPage,
1159
- messageHandler: messageHandler,
1160
- defaultValuesExtensionFunction: mParameters.defaultValuesExtensionFunction
1161
- });
1162
- } else {
1163
- return null;
1164
- }
1165
- });
1166
- } else {
1167
- // TODO: confirm if action import needs side effects.
1168
- oPromise = operations.callActionImport(sActionName, oModel, oAppComponent, {
1169
- label: mParameters.label,
1170
- showActionParameterDialog: true,
1171
- bindingParameters: mBindingParameters,
1172
- entitySetName: mParameters.entitySetName,
1173
- onSubmitted: function() {
1174
- BusyLocker.lock(that.oLockObject);
1175
- },
1176
- onResponse: function() {
1177
- BusyLocker.unlock(that.oLockObject);
1178
- },
1179
- parentControl: mParameters.parentControl,
1180
- internalModelContext: mParameters.internalModelContext,
1181
- operationAvailableMap: mParameters.operationAvailableMap,
1182
- messageHandler: messageHandler,
1183
- bObjectPage: mParameters.bObjectPage
1184
- });
1185
- }
1186
- return oPromise
1187
- .then(function(oResult) {
1188
- // Succeeded
1189
- return that._handleActionResponse(messageHandler, mParameters, sActionName).then(function() {
1190
- return oResult;
1191
- });
1192
- })
1193
- .catch(function(err) {
1194
- return that._handleActionResponse(messageHandler, mParameters, sActionName).then(function() {
1195
- return Promise.reject(err);
1196
- });
1197
- });
1198
- },
1199
- /**
1200
- * Handles messages for action call.
1201
- *
1202
- * @function
1203
- * @name sap.fe.core.TransactionHelper#_handleActionResponse
1204
- * @memberof sap.fe.core.TransactionHelper
1205
- * @param messageHandler
1206
- * @param {object} mParameters Parameters to be considered for the action.
1207
- * @param {string} sActionName The name of the action to be called
1208
- * @returns {Promise} Promise after message dialog is opened if required.
1209
- * @ui5-restricted
1210
- * @final
1211
- */
1212
- _handleActionResponse: function(messageHandler, mParameters, sActionName) {
1213
- var aTransientMessages = messageHandling.getMessages(true, true);
1214
- if (aTransientMessages.length > 0 && mParameters && mParameters.internalModelContext) {
1215
- mParameters.internalModelContext.setProperty("sActionName", mParameters.label ? mParameters.label : sActionName);
1216
- }
1217
- return messageHandler.showMessages();
1218
- },
1219
- /**
1220
- * Handles validation errors for the 'discard' action.
1221
- *
1222
- * @function
1223
- * @name sap.fe.core.TransactionHelper#handleValidationError
1224
- * @memberof sap.fe.core.TransactionHelper
1225
- * @static
1226
- * @ui5-restricted
1227
- * @final
1228
- */
1229
- handleValidationError: function() {
1230
- var oMessageManager = sap.ui.getCore().getMessageManager(),
1231
- errorToRemove = oMessageManager
1232
- .getMessageModel()
1233
- .getData()
1234
- .filter(function(error) {
1235
- // only needs to handle validation messages, technical and persistent errors needs not to be checked here.
1236
- if (error.validation) {
1237
- return error;
1238
- }
1239
- });
1240
- oMessageManager.removeMessages(errorToRemove);
1241
- },
1242
- /**
1243
- * Shows a popover if it needs to be shown.
1244
- * TODO: Popover is shown if user has modified any data.
1245
- * TODO: Popover is shown if there's a difference from draft admin data.
1246
- * @static
1247
- * @name sap.fe.core.TransactionHelper._showDiscardPopover
1248
- * @memberof sap.fe.core.TransactionHelper
1249
- * @param {sap.ui.core.Control} oCancelButton The control which will open the popover
1250
- * @param bIsModified
1251
- * @param oResourceBundle
1252
- * @returns {Promise} Promise resolves if user confirms discard, rejects if otherwise, rejects if no control passed to open popover
1253
- * @ui5-restricted
1254
- * @final
1255
- */
1256
- _showDiscardPopover: function(oCancelButton, bIsModified, oResourceBundle) {
1257
- // TODO: Implement this popover as a fragment as in v2??
1258
- var that = this;
1259
- that._bContinueDiscard = false;
1260
- // to be implemented
1261
- return new Promise(function(resolve, reject) {
1262
- if (!oCancelButton) {
1263
- reject("Cancel button not found");
1264
- }
1265
- //Show popover only when data is changed.
1266
- if (bIsModified) {
1267
- var fnOnAfterDiscard = function() {
1268
- oCancelButton.setEnabled(true);
1269
- if (that._bContinueDiscard) {
1270
- resolve();
1271
- } else {
1272
- reject("Discard operation was rejected. Document has not been discarded");
1273
- }
1274
- that._oPopover.detachAfterClose(fnOnAfterDiscard);
1275
- };
1276
- if (!that._oPopover) {
1277
- var oText = new Text({
1278
- //This text is the same as LR v2.
1279
- //TODO: Display message provided by app developer???
1280
- text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_DRAFT_DISCARD_MESSAGE", oResourceBundle)
1281
- }),
1282
- oButton = new Button({
1283
- text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_DRAFT_DISCARD_BUTTON", oResourceBundle),
1284
- width: "100%",
1285
- press: function() {
1286
- that.handleValidationError();
1287
- that._bContinueDiscard = true;
1288
- that._oPopover.close();
1289
- },
1290
- ariaLabelledBy: oText
1291
- });
1292
- that._oPopover = new Popover({
1293
- showHeader: false,
1294
- placement: "Top",
1295
- content: [
1296
- new VBox({
1297
- items: [oText, oButton]
1298
- })
1299
- ],
1300
- beforeOpen: function() {
1301
- // make sure to NOT trigger multiple cancel flows
1302
- oCancelButton.setEnabled(false);
1303
- that._oPopover.setInitialFocus(oButton);
1304
- }
1305
- });
1306
- that._oPopover.addStyleClass("sapUiContentPadding");
1307
- }
1308
- that._oPopover.attachAfterClose(fnOnAfterDiscard);
1309
- that._oPopover.openBy(oCancelButton);
1310
- } else {
1311
- that.handleValidationError();
1312
- resolve();
1313
- }
1314
- });
1315
- },
1316
- /**
1317
- * Sets the document to modified state on patch event.
1318
- *
1319
- * @function
1320
- * @static
1321
- * @name sap.fe.core.TransactionHelper.handleDocumentModifications
1322
- * @memberof sap.fe.core.TransactionHelper
1323
- * @ui5-restricted
1324
- * @final
1325
- */
1326
- handleDocumentModifications: function() {
1327
- this._bIsModified = true;
1328
- },
1329
- /**
1330
- * Retrieves the owner component.
1331
- *
1332
- * @function
1333
- * @static
1334
- * @private
1335
- * @name sap.fe.core.TransactionHelper._getOwnerComponent
1336
- * @memberof sap.fe.core.TransactionHelper
1337
- * @returns {sap.fe.core.AppComponent} The app component
1338
- * @ui5-restricted
1339
- * @final
1340
- **/
1341
- _getAppComponent: function() {
1342
- return this._oAppComponent;
1343
- },
1344
- _launchDialogWithKeyFields: function(
1345
- oListBinding,
1346
- oTransientListBinding,
1347
- oTransientContext,
1348
- mFields,
1349
- oModel,
1350
- mParameters,
1351
- messageHandler
1352
- ) {
1353
- var that = this,
1354
- oDialog,
1355
- oParentControl = mParameters.parentControl,
1356
- bSuccess = false;
1357
- return new Promise(function(resolve, reject) {
1358
- var sFragmentName = "sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog";
1359
- var oFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment"),
1360
- oResourceBundle = oParentControl.getController().oResourceBundle,
1361
- oMetaModel = oModel.getMetaModel(),
1362
- aImmutableFields = [],
1363
- oAppComponent = that._getAppComponent(),
1364
- sPath = oListBinding.isRelative() ? oListBinding.getResolvedPath() : oListBinding.getPath(),
1365
- oEntitySetContext = oMetaModel.createBindingContext(sPath),
1366
- sMetaPath = oMetaModel.getMetaPath(sPath);
1367
- for (var i in mFields) {
1368
- aImmutableFields.push(oMetaModel.createBindingContext(sMetaPath + "/" + mFields[i]));
1369
- }
1370
- var oImmutableCtx = new JSONModel(aImmutableFields);
1371
- oImmutableCtx = oImmutableCtx.createBindingContext("/");
1372
- return Promise.resolve(
1373
- XMLPreprocessor.process(
1374
- oFragment,
1375
- { name: sFragmentName },
1376
- {
1377
- bindingContexts: {
1378
- entitySet: oEntitySetContext,
1379
- fields: oImmutableCtx
1380
- },
1381
- models: {
1382
- entitySet: oEntitySetContext.getModel(),
1383
- fields: oImmutableCtx.getModel(),
1384
- metaModel: oMetaModel
1385
- }
1386
- }
1387
- )
1388
- ).then(function(oFragment) {
1389
- var aFormElements = [],
1390
- mFieldValueMap = {},
1391
- oCreateButton,
1392
- validateRequiredProperties = function() {
1393
- return Promise.all(
1394
- aFormElements
1395
- .map(function(oFormElement) {
1396
- return oFormElement.getFields()[0];
1397
- })
1398
- .filter(function(oField) {
1399
- return oField.getRequired();
1400
- })
1401
- .map(function(oField) {
1402
- var sFieldId = oField.getId();
1403
- if (sFieldId in mFieldValueMap) {
1404
- return Promise.resolve(mFieldValueMap[sFieldId])
1405
- .then(function(vValue) {
1406
- return vValue;
1407
- })
1408
- .catch(function() {
1409
- return undefined;
1410
- });
1411
- }
1412
- return oField.getValueState() === ValueState.Error ? undefined : oField.getValue();
1413
- })
1414
- )
1415
- .then(function(aResults) {
1416
- return aResults.every(function(vValue) {
1417
- return vValue !== undefined && vValue !== null && vValue !== "";
1418
- });
1419
- })
1420
- .catch(function() {
1421
- return false;
1422
- })
1423
- .then(function(bEnabled) {
1424
- oCreateButton.setEnabled(bEnabled);
1425
- });
1426
- },
1427
- oController = {
1428
- /*
1429
- fired on focus out from field or on selecting a value from the valuehelp.
1430
- the create button is enabled when a value is added.
1431
- liveChange is not fired when value is added from valuehelp.
1432
- value validation is not done for create button enablement.
1433
- */
1434
- handleChange: function(oEvent) {
1435
- messageHandler.removeTransitionMessages();
1436
- var oField = oEvent.getSource();
1437
- var sFieldId = oEvent.getParameter("id");
1438
- var oFieldPromise = oEvent.getParameter("promise");
1439
- if (oFieldPromise) {
1440
- mFieldValueMap[sFieldId] = oFieldPromise.then(function() {
1441
- return oField.getValue();
1442
- });
1443
- }
1444
- validateRequiredProperties();
1445
- },
1446
- /*
1447
- fired on key press. the create button is enabled when a value is added.
1448
- liveChange is not fired when value is added from valuehelp.
1449
- value validation is not done for create button enablement.
1450
- */
1451
- handleLiveChange: function(oEvent) {
1452
- var sFieldId = oEvent.getParameter("id");
1453
- var vValue = oEvent.getParameter("value");
1454
- mFieldValueMap[sFieldId] = vValue;
1455
- validateRequiredProperties();
1456
- }
1457
- };
1458
- return Fragment.load({
1459
- definition: oFragment,
1460
- controller: oController
1461
- }).then(function(oDialogContent) {
1462
- oDialog = new Dialog({
1463
- title: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE", oResourceBundle),
1464
- content: [oDialogContent],
1465
- beginButton: {
1466
- text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE_BUTTON", oResourceBundle),
1467
- type: "Emphasized",
1468
- press: function(oEvent) {
1469
- var oCreateButton = oEvent.getSource();
1470
- oCreateButton.setEnabled(false);
1471
- BusyLocker.lock(oDialog);
1472
- return Promise.all(
1473
- Object.keys(mFieldValueMap).map(function(sKey) {
1474
- return mFieldValueMap[sKey];
1475
- })
1476
- )
1477
- .then(function() {
1478
- var oPromise = that.onAfterCreateCompletion(
1479
- oTransientListBinding,
1480
- oTransientContext,
1481
- mParameters,
1482
- oResourceBundle
1483
- );
1484
- oModel.submitBatch("submitLater");
1485
- return oPromise;
1486
- })
1487
- .then(function(oResponse) {
1488
- oDialog.setBindingContext(null);
1489
- oDialog.close();
1490
- resolve(oResponse);
1491
- })
1492
- .finally(function() {
1493
- BusyLocker.unlock(oDialog);
1494
- oCreateButton.setEnabled(true);
1495
- return messageHandler.showMessages();
1496
- });
1497
- }
1498
- },
1499
- endButton: {
1500
- text: CommonUtils.getTranslatedText("C_COMMON_ACTION_PARAMETER_DIALOG_CANCEL", oResourceBundle),
1501
- press: function() {
1502
- oDialog.close();
1503
- }
1504
- },
1505
- afterClose: function() {
1506
- // show footer as per UX guidelines when dialog is not open
1507
- oDialog.getBindingContext("internal").setProperty("isCreateDialogOpen", false);
1508
- oDialog.destroy();
1509
- if (!bSuccess) {
1510
- reject({
1511
- bDeleteTransientContext: true
1512
- });
1513
- }
1514
- }
1515
- });
1516
- aFormElements = oDialogContent
1517
- .getAggregation("form")
1518
- .getAggregation("formContainers")[0]
1519
- .getAggregation("formElements");
1520
- if (oParentControl && oParentControl.addDependent) {
1521
- // if there is a parent control specified add the dialog as dependent
1522
- oParentControl.addDependent(oDialog);
1523
- }
1524
- oCreateButton = oDialog.getBeginButton();
1525
- oDialog.setBindingContext(oTransientContext);
1526
- return CommonUtils.setUserDefaults(
1527
- oAppComponent,
1528
- aImmutableFields,
1529
- oTransientContext,
1530
- undefined,
1531
- mParameters.createAction,
1532
- mParameters.data
1533
- )
1534
- .then(function() {
1535
- validateRequiredProperties();
1536
- // footer must not be visible when the dialog is open as per UX guidelines
1537
- oDialog.getBindingContext("internal").setProperty("isCreateDialogOpen", true);
1538
- oDialog.open();
1539
- })
1540
- .catch(function(oError) {
1541
- return messageHandler.showMessages().then(function() {
1542
- return Promise.reject(oError);
1543
- });
1544
- });
1545
- });
1546
- });
1547
- });
1548
- },
1549
- onAfterCreateCompletion: function(oListBinding, oNewDocumentContext, mParameters, oResourceBundle) {
1550
- var fnResolve,
1551
- fnReject,
1552
- oPromise = new Promise(function(resolve, reject) {
1553
- fnResolve = resolve;
1554
- fnReject = reject;
1555
- });
1556
- // Workaround suggested by OData model v4 colleagues
1557
- var fnCreateCompleted = function(oEvent) {
1558
- var oContext = oEvent.getParameter("context"),
1559
- bSuccess = oEvent.getParameter("success");
1560
- if (oContext === oNewDocumentContext) {
1561
- oListBinding.detachCreateCompleted(fnCreateCompleted, this);
1562
- if (!bSuccess) {
1563
- var oError = { bDeleteTransientContext: false };
1564
- if (!mParameters.keepTransientContextOnFailed) {
1565
- // the context is deleted
1566
- oError.bDeleteTransientContext = true;
1567
- // this is needed to avoid console errors TO be checked with model colleagues
1568
- oContext
1569
- .created()
1570
- .then(undefined, function() {
1571
- Log.trace("transient creation context deleted");
1572
- })
1573
- .catch(function(oError) {
1574
- Log.trace("transient creation context deletion error", oError);
1575
- });
1576
- // if current state is transient (...), browser will come back to previous state
1577
- oError.navigateBackFromTransientState = true;
1578
- }
1579
- fnReject(oError);
1580
- } else {
1581
- fnResolve();
1582
- }
1583
- }
1584
- };
1585
- oListBinding.attachCreateCompleted(fnCreateCompleted, this);
1586
- return oPromise;
1587
- },
1588
- /**
1589
- * Retrieves the name of the NewAction to be executed.
1590
- *
1591
- * @function
1592
- * @static
1593
- * @private
1594
- * @name sap.fe.core.TransactionHelper._getNewAction
1595
- * @memberof sap.fe.core.TransactionHelper
1596
- * @param {object} oStartupParameters Startup parameters of the application
1597
- * @param {string} sCreateHash Hash to be checked for action type
1598
- * @param {object} oMetaModel The MetaModel used to check for NewAction parameter
1599
- * @param {string} sMetaPath The MetaPath
1600
- * @returns {string} The name of the action
1601
- * @ui5-restricted
1602
- * @final
1603
- **/
1604
- _getNewAction: function(oStartupParameters, sCreateHash, oMetaModel, sMetaPath) {
1605
- var sNewAction;
1606
-
1607
- if (oStartupParameters && oStartupParameters.preferredMode && sCreateHash.indexOf("i-action=createWith") > -1) {
1608
- var sPreferredMode = oStartupParameters.preferredMode[0];
1609
- sNewAction =
1610
- sPreferredMode.indexOf("createWith:") > -1 ? sPreferredMode.substr(sPreferredMode.lastIndexOf(":") + 1) : undefined;
1611
- } else {
1612
- sNewAction =
1613
- oMetaModel && oMetaModel.getObject !== undefined
1614
- ? oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Session.v1.StickySessionSupported/NewAction") ||
1615
- oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DraftRoot/NewAction")
1616
- : undefined;
1617
- }
1618
- return sNewAction;
1619
- },
1620
- /**
1621
- * Retrieves the label for the title of a specific create action dialog, e.g. Create Sales Order from Quotation.
1622
- *
1623
- * The following priority is applied:
1624
- * 1. label of line-item annotation.
1625
- * 2. label annotated in the action.
1626
- * 3. "Create" as a constant from i18n.
1627
- *
1628
- * @function
1629
- * @static
1630
- * @private
1631
- * @name sap.fe.core.TransactionHelper._getSpecificCreateActionDialogLabel
1632
- * @memberof sap.fe.core.TransactionHelper
1633
- * @param {object} oMetaModel The MetaModel used to check for the NewAction parameter
1634
- * @param {string} sMetaPath The MetaPath
1635
- * @param {string} sNewAction Contains the name of the action to be executed
1636
- * @param {object} oResourceBundleCore ResourceBundle to access the default Create label
1637
- * @returns {string} The label for the Create Action Dialog
1638
- * @ui5-restricted
1639
- * @final
1640
- **/
1641
- _getSpecificCreateActionDialogLabel: function(oMetaModel, sMetaPath, sNewAction, oResourceBundleCore) {
1642
- var fnGetLabelFromLineItemAnnotation = function() {
1643
- if (oMetaModel && oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.UI.v1.LineItem")) {
1644
- var iLineItemIndex = oMetaModel
1645
- .getObject(sMetaPath + "/@com.sap.vocabularies.UI.v1.LineItem")
1646
- .findIndex(function(oLineItem) {
1647
- var aLineItemAction = oLineItem.Action ? oLineItem.Action.split("(") : undefined;
1648
- return aLineItemAction ? aLineItemAction[0] === sNewAction : false;
1649
- });
1650
- return iLineItemIndex > -1
1651
- ? oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.UI.v1.LineItem")[iLineItemIndex].Label
1652
- : undefined;
1653
- } else {
1654
- return undefined;
1655
- }
1656
- };
1657
-
1658
- return (
1659
- fnGetLabelFromLineItemAnnotation() ||
1660
- (oMetaModel && oMetaModel.getObject(sMetaPath + "/" + sNewAction + "@com.sap.vocabularies.Common.v1.Label")) ||
1661
- (oResourceBundleCore && oResourceBundleCore.getText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE"))
1662
- );
1663
- }
1664
- });
1665
- }
1666
- );
5
+ sap.ui.define(["sap/base/Log", "sap/fe/core/actions/draft", "sap/fe/core/actions/messageHandling", "sap/fe/core/actions/operations", "sap/fe/core/actions/sticky", "sap/fe/core/BusyLocker", "sap/fe/core/CommonUtils", "sap/fe/core/helpers/FPMHelper", "sap/fe/core/helpers/ModelHelper", "sap/fe/core/library", "sap/m/Button", "sap/m/CheckBox", "sap/m/Dialog", "sap/m/MessageBox", "sap/m/MessageToast", "sap/m/Popover", "sap/m/Text", "sap/m/VBox", "sap/ui/core/Core", "sap/ui/core/Fragment", "sap/ui/core/library", "sap/ui/core/util/XMLPreprocessor", "sap/ui/core/XMLTemplateProcessor", "sap/ui/model/json/JSONModel"], function (Log, draft, messageHandling, operations, sticky, BusyLocker, CommonUtils, FPMHelper, ModelHelper, FELibrary, Button, CheckBox, Dialog, MessageBox, MessageToast, Popover, Text, VBox, Core, Fragment, coreLibrary, XMLPreprocessor, XMLTemplateProcessor, JSONModel) {
6
+ "use strict";
7
+
8
+ var CreationMode = FELibrary.CreationMode;
9
+ var ProgrammingModel = FELibrary.ProgrammingModel;
10
+ var ValueState = coreLibrary.ValueState;
11
+ /* Make sure that the mParameters is not the oEvent */
12
+
13
+ function getParameters(mParameters) {
14
+ if (mParameters && mParameters.getMetadata && mParameters.getMetadata().getName() === "sap.ui.base.Event") {
15
+ mParameters = {};
16
+ }
17
+
18
+ return mParameters || {};
19
+ }
20
+
21
+ var TransactionHelper = /*#__PURE__*/function () {
22
+ function TransactionHelper(oAppComponent, oLockObject) {
23
+ this._bIsModified = false;
24
+ this._bCreateMode = false;
25
+ this._bContinueDiscard = false;
26
+ this._oAppComponent = oAppComponent;
27
+ this.oLockObject = oLockObject;
28
+ }
29
+
30
+ var _proto = TransactionHelper.prototype;
31
+
32
+ _proto.getProgrammingModel = function getProgrammingModel(oContext) {
33
+ if (!this.sProgrammingModel && oContext) {
34
+ var sPath;
35
+
36
+ if (oContext.isA("sap.ui.model.odata.v4.Context")) {
37
+ sPath = oContext.getPath();
38
+ } else {
39
+ sPath = oContext.isRelative() ? oContext.getResolvedPath() : oContext.getPath();
40
+ }
41
+
42
+ if (ModelHelper.isDraftSupported(oContext.getModel().getMetaModel(), sPath)) {
43
+ this.sProgrammingModel = ProgrammingModel.Draft;
44
+ } else if (ModelHelper.isStickySessionSupported(oContext.getModel().getMetaModel())) {
45
+ this.sProgrammingModel = ProgrammingModel.Sticky;
46
+ } else {
47
+ // as the transaction helper is a singleton we don't store the non draft as the user could
48
+ // start with a non draft child page and navigates back to a draft enabled one
49
+ return ProgrammingModel.NonDraft;
50
+ }
51
+ }
52
+
53
+ return this.sProgrammingModel;
54
+ }
55
+ /**
56
+ * Validates a document.
57
+ *
58
+ * @memberof sap.fe.core.TransactionHelper
59
+ * @static
60
+ * @param {sap.ui.model.odata.v4.Context} oContext Context of the document to be validated
61
+ * @param {object} [mParameters] Can contain the following attributes:
62
+ * * @param {object} [mParameters.data] A map of data that should be validated
63
+ * * @param {string} [mParameters.customValidationFunction] A string representing the path to the validation function
64
+ * @param {object} oView Contains the object of the current view
65
+ * @returns {Promise} Promise resolves with result of the custom validation function
66
+ * @ui5-restricted
67
+ * @final
68
+ */
69
+ ;
70
+
71
+ _proto.validateDocument = function validateDocument(oContext, mParameters, oView) {
72
+ var sCustomValidationFunction = mParameters && mParameters.customValidationFunction;
73
+
74
+ if (sCustomValidationFunction) {
75
+ var sModule = sCustomValidationFunction.substring(0, sCustomValidationFunction.lastIndexOf(".") || -1).replace(/\./gi, "/"),
76
+ sFunctionName = sCustomValidationFunction.substring(sCustomValidationFunction.lastIndexOf(".") + 1, sCustomValidationFunction.length),
77
+ mData = mParameters.data;
78
+ delete mData["@$ui5.context.isTransient"];
79
+ return FPMHelper.validationWrapper(sModule, sFunctionName, mData, oView, oContext);
80
+ }
81
+
82
+ return Promise.resolve([]);
83
+ }
84
+ /**
85
+ * Creates a new document.
86
+ *
87
+ * @memberof sap.fe.core.TransactionHelper
88
+ * @static
89
+ * @param {sap.ui.model.odata.v4.ODataListBinding} oMainListBinding OData V4 ListBinding object
90
+ * @param {object} [mInParameters] Optional, can contain the following attributes:
91
+ * @param {map} [mInParameters.data] A map of data that should be sent within the POST
92
+ * @param {string} [mInParameters.busyMode] Global (default), Local, None TODO: to be refactored
93
+ * @param {map} [mInParameters.keepTransientContextOnFailed] If set, the context stays in the list if the POST failed and POST will be repeated with the next change
94
+ * @param oResourceBundle
95
+ * @param messageHandler
96
+ * @param bFromCopyPaste
97
+ * @param oView The current view
98
+ * @returns {Promise} Promise resolves with new binding context
99
+ * @ui5-restricted
100
+ * @final
101
+ */
102
+ ;
103
+
104
+ _proto.createDocument = function createDocument(oMainListBinding, mInParameters, oResourceBundle, messageHandler) {
105
+ var bFromCopyPaste = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
106
+ var oView = arguments.length > 5 ? arguments[5] : undefined;
107
+
108
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
109
+ var that = this,
110
+ oModel = oMainListBinding.getModel(),
111
+ oMetaModel = oModel.getMetaModel(),
112
+ sMetaPath = oMetaModel.getMetaPath(oMainListBinding.getHeaderContext().getPath()),
113
+ sCreateHash = this._getAppComponent().getRouterProxy().getHash(),
114
+ oComponentData = this._getAppComponent().getComponentData(),
115
+ oStartupParameters = oComponentData && oComponentData.startupParameters || {},
116
+ sNewAction = !oMainListBinding.isRelative() ? this._getNewAction(oStartupParameters, sCreateHash, oMetaModel, sMetaPath) : undefined;
117
+
118
+ var oCreationPromise;
119
+ var mBindingParameters = {
120
+ "$$patchWithoutSideEffects": true
121
+ };
122
+ var sMessagesPath = oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.Common.v1.Messages/$Path");
123
+ var sBusyPath = "/busy";
124
+ var sFunctionName = oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DefaultValuesFunction") || oMetaModel.getObject(ModelHelper.getTargetEntitySet(oMetaModel.getContext(sMetaPath)) + "@com.sap.vocabularies.Common.v1.DefaultValuesFunction");
125
+ var bFunctionOnNavProp;
126
+ var oNewDocumentContext;
127
+
128
+ if (sFunctionName) {
129
+ if (oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DefaultValuesFunction") && ModelHelper.getTargetEntitySet(oMetaModel.getContext(sMetaPath)) !== sMetaPath) {
130
+ bFunctionOnNavProp = true;
131
+ } else {
132
+ bFunctionOnNavProp = false;
133
+ }
134
+ }
135
+
136
+ if (sMessagesPath) {
137
+ mBindingParameters["$select"] = sMessagesPath;
138
+ }
139
+
140
+ var mParameters = getParameters(mInParameters);
141
+
142
+ if (!oMainListBinding) {
143
+ return Promise.reject("Binding required for new document creation");
144
+ }
145
+
146
+ var sProgrammingModel = this.getProgrammingModel(oMainListBinding);
147
+
148
+ if (sProgrammingModel !== ProgrammingModel.Draft && sProgrammingModel !== ProgrammingModel.Sticky) {
149
+ return Promise.reject("Create document only allowed for draft or sticky session supported services");
150
+ }
151
+
152
+ if (mParameters.busyMode === "Local") {
153
+ // in case of local busy mode we use the list binding name
154
+ // there's no APY yet so we have to use the .sId TODO provide a public method?
155
+ sBusyPath = "/busyLocal/" + oMainListBinding.sId;
156
+ }
157
+
158
+ mParameters.beforeCreateCallBack = bFromCopyPaste ? null : mParameters.beforeCreateCallBack;
159
+ BusyLocker.lock(this.oLockObject, sBusyPath);
160
+ var oResourceBundleCore = Core.getLibraryResourceBundle("sap.fe.core");
161
+
162
+ if (sNewAction) {
163
+ oCreationPromise = this.callAction(sNewAction, {
164
+ contexts: oMainListBinding.getHeaderContext(),
165
+ showActionParameterDialog: true,
166
+ label: this._getSpecificCreateActionDialogLabel(oMetaModel, sMetaPath, sNewAction, oResourceBundleCore),
167
+ bindingParameters: mBindingParameters,
168
+ parentControl: mParameters.parentControl,
169
+ bIsCreateAction: true
170
+ }, null, messageHandler);
171
+ } else {
172
+ var bIsNewPageCreation = mParameters.creationMode !== CreationMode.CreationRow && mParameters.creationMode !== CreationMode.Inline;
173
+ var aNonComputedVisibleKeyFields = bIsNewPageCreation ? CommonUtils.getNonComputedVisibleFields(oMetaModel, sMetaPath, oView) : [];
174
+ sFunctionName = bFromCopyPaste ? null : sFunctionName;
175
+ var sFunctionPath, oFunctionContext;
176
+
177
+ if (sFunctionName) {
178
+ //bound to the source entity:
179
+ if (bFunctionOnNavProp) {
180
+ sFunctionPath = oMainListBinding.getContext() && oMetaModel.getMetaPath(oMainListBinding.getContext().getPath()) + "/" + sFunctionName;
181
+ oFunctionContext = oMainListBinding.getContext();
182
+ } else {
183
+ sFunctionPath = oMainListBinding.getHeaderContext() && oMetaModel.getMetaPath(oMainListBinding.getHeaderContext().getPath()) + "/" + sFunctionName;
184
+ oFunctionContext = oMainListBinding.getHeaderContext();
185
+ }
186
+ }
187
+
188
+ var oFunction = sFunctionPath && oMetaModel.createBindingContext(sFunctionPath);
189
+
190
+ if (oFunction && oFunction.getObject() && oFunction.getObject()[0].$IsBound) {
191
+ oCreationPromise = operations.callBoundFunction(sFunctionName, oFunctionContext, oModel);
192
+ } else {
193
+ oCreationPromise = operations.callFunctionImport(sFunctionName, oModel);
194
+ }
195
+
196
+ oCreationPromise = oCreationPromise.then(function (oContext) {
197
+ if (oContext) {
198
+ return oContext.getObject();
199
+ } else {
200
+ return undefined;
201
+ }
202
+ }).catch(function (oError) {
203
+ Log.error("Error while executing the function " + sFunctionName, oError);
204
+ throw oError;
205
+ }).then(function (oData) {
206
+ mParameters.data = oData ? Object.assign({}, oData, mParameters.data) : mParameters.data;
207
+
208
+ if (mParameters.data) {
209
+ delete mParameters.data["@odata.context"];
210
+ }
211
+
212
+ if (aNonComputedVisibleKeyFields.length > 0) {
213
+ var oTransientListBinding = oModel.bindList(oMainListBinding.getPath(), oMainListBinding.getContext(), [], [], {
214
+ $$updateGroupId: "submitLater"
215
+ });
216
+
217
+ oTransientListBinding.refreshInternal = function () {
218
+ /* */
219
+ };
220
+
221
+ oNewDocumentContext = oTransientListBinding.create(mParameters.data, true);
222
+ return that._launchDialogWithKeyFields(oMainListBinding, oTransientListBinding, oNewDocumentContext, aNonComputedVisibleKeyFields, oModel, mParameters, messageHandler);
223
+ } else {
224
+ var onBeforeCreatePromise;
225
+
226
+ if (mParameters.beforeCreateCallBack) {
227
+ onBeforeCreatePromise = mParameters.beforeCreateCallBack({
228
+ contextPath: oMainListBinding && oMainListBinding.getPath()
229
+ });
230
+ } else {
231
+ onBeforeCreatePromise = Promise.resolve();
232
+ }
233
+
234
+ return onBeforeCreatePromise.then(function () {
235
+ oNewDocumentContext = oMainListBinding.create(mParameters.data, true, mParameters.createAtEnd);
236
+ return that.onAfterCreateCompletion(oMainListBinding, oNewDocumentContext, mParameters);
237
+ });
238
+ }
239
+ }).catch(function (oError) {
240
+ Log.error("Error while creating the new document", oError);
241
+ throw oError;
242
+ });
243
+ }
244
+
245
+ return oCreationPromise.then(function (oResult) {
246
+ if (!oMainListBinding.isRelative()) {
247
+ // the create mode shall currently only be set on creating a root document
248
+ that._bCreateMode = true;
249
+ }
250
+
251
+ oNewDocumentContext = oNewDocumentContext || oResult && oResult.response; // TODO: where does this one coming from???
252
+
253
+ if (oResult && oResult.bConsiderDocumentModified) {
254
+ that.handleDocumentModifications();
255
+ }
256
+
257
+ return messageHandler.showMessageDialog().then(function () {
258
+ return oNewDocumentContext;
259
+ });
260
+ }).catch(function (oError) {
261
+ return messageHandler.showMessageDialog().then(function () {
262
+ // for instance, on cancel of create dialog, the promise is rejected
263
+ // a return here would restore the promise chain and result in errors while routing
264
+ // solution - reject here as well
265
+ if (oError && oError.bDeleteTransientContext && oNewDocumentContext.isTransient()) {
266
+ // This is a workaround suggested by model as Context.delete results in an error
267
+ // TODO: remove the $direct once model resolves this issue
268
+ // this line shows the expected console error Uncaught (in promise) Error: Request canceled: POST Travel; group: submitLater
269
+ oNewDocumentContext.delete("$direct");
270
+ }
271
+
272
+ return Promise.reject(oError);
273
+ });
274
+ }).finally(function () {
275
+ BusyLocker.unlock(that.oLockObject, sBusyPath);
276
+ });
277
+ }
278
+ /**
279
+ * Find the active contexts of the documents, only for the draft roots.
280
+ *
281
+ * @memberof sap.fe.core.TransactionHelper
282
+ * @static
283
+ * @param {sap.ui.model.odata.v4.Context[]} aContexts Contexts Either one context or an array with contexts to be deleted
284
+ * @param bFindActiveContexts
285
+ * @returns {Array} Array of the active contexts
286
+ */
287
+ ;
288
+
289
+ _proto.findActiveDraftRootContexts = function findActiveDraftRootContexts(aContexts, bFindActiveContexts) {
290
+ if (!bFindActiveContexts) {
291
+ return Promise.resolve();
292
+ }
293
+
294
+ var activeContexts = aContexts.reduce(function (aResult, oContext) {
295
+ var oMetaModel = oContext.getModel().getMetaModel();
296
+ var sMetaPath = oMetaModel.getMetaPath(oContext.getPath());
297
+
298
+ if (oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DraftRoot")) {
299
+ var bIsActiveEntity = oContext.getObject().IsActiveEntity,
300
+ bHasActiveEntity = oContext.getObject().HasActiveEntity;
301
+
302
+ if (!bIsActiveEntity && bHasActiveEntity) {
303
+ var oActiveContext = oContext.getModel().bindContext(oContext.getPath() + "/SiblingEntity").getBoundContext();
304
+ aResult.push(oActiveContext);
305
+ }
306
+ }
307
+
308
+ return aResult;
309
+ }, []);
310
+ return Promise.all(activeContexts.map(function (oContext) {
311
+ return oContext.requestCanonicalPath().then(function () {
312
+ return oContext;
313
+ }, function () {
314
+ return;
315
+ });
316
+ }));
317
+ };
318
+
319
+ _proto.afterDeleteProcess = function afterDeleteProcess(mParameters, checkBox, aContexts, oResourceBundle) {
320
+ var oInternalModelContext = mParameters.internalModelContext;
321
+
322
+ if (oInternalModelContext && oInternalModelContext.getProperty("deleteEnabled") != undefined) {
323
+ if (checkBox.isCheckBoxVisible === true && checkBox.isCheckBoxSelected === false) {
324
+ //if unsaved objects are not deleted then we need to set the enabled to true and update the model data for next deletion
325
+ oInternalModelContext.setProperty("deleteEnabled", true);
326
+ var obj = Object.assign(oInternalModelContext.getObject(), {});
327
+ obj.selectedContexts = obj.selectedContexts.filter(function (element) {
328
+ return obj.deletableContexts.indexOf(element) === -1;
329
+ });
330
+ obj.deletableContexts = [];
331
+ obj.selectedContexts = [];
332
+ obj.numberOfSelectedContexts = obj.selectedContexts.length;
333
+ oInternalModelContext.setProperty("", obj);
334
+ } else {
335
+ oInternalModelContext.setProperty("deleteEnabled", false);
336
+ oInternalModelContext.setProperty("selectedContexts", []);
337
+ oInternalModelContext.setProperty("numberOfSelectedContexts", 0);
338
+ }
339
+ }
340
+
341
+ if (aContexts.length === 1) {
342
+ MessageToast.show(CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_DELETE_TOAST_SINGULAR", oResourceBundle, null, mParameters.entitySetName));
343
+ } else {
344
+ MessageToast.show(CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_DELETE_TOAST_PLURAL", oResourceBundle, null, mParameters.entitySetName));
345
+ }
346
+ }
347
+ /**
348
+ * Delete one or multiple document(s).
349
+ *
350
+ * @memberof sap.fe.core.TransactionHelper
351
+ * @static
352
+ * @param {sap.ui.model.odata.v4.Context} vContexts Contexts Either one context or an array with contexts to be deleted
353
+ * @param {object} mParameters Optional, can contain the following attributes:
354
+ * @param {string} mParameters.title Title of the object to be deleted
355
+ * @param {string} mParameters.description Description of the object to be deleted
356
+ * @param {integer} mParameters.numberOfSelectedContexts Number of objects selected
357
+ * @param {boolean} mParameters.noDialog To disable the confirmation dialog
358
+ * @param oResourceBundle
359
+ * @param messageHandler
360
+ * @returns {Promise}
361
+ */
362
+ ;
363
+
364
+ _proto.deleteDocument = function deleteDocument(vContexts, mParameters, oResourceBundle, messageHandler) {
365
+ var fnReject,
366
+ fnResolve,
367
+ aDeletableContexts = [],
368
+ isCheckBoxVisible = false,
369
+ isLockedTextVisible = false,
370
+ cannotBeDeletedTextVisible = false,
371
+ isCheckBoxSelected,
372
+ bDialogConfirmed = false; // eslint-disable-next-line @typescript-eslint/no-this-alias
373
+
374
+ var that = this,
375
+ oResourceBundleCore = Core.getLibraryResourceBundle("sap.fe.core");
376
+ var aParams;
377
+ var oDeleteMessage = {
378
+ title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE")
379
+ };
380
+ BusyLocker.lock(this.oLockObject);
381
+
382
+ if (!Array.isArray(vContexts)) {
383
+ vContexts = [vContexts];
384
+ }
385
+
386
+ Promise.resolve(this.getProgrammingModel(vContexts[0])).then(function (sProgrammingModel) {
387
+ if (mParameters) {
388
+ if (!mParameters.numberOfSelectedContexts) {
389
+ if (sProgrammingModel === ProgrammingModel.Draft) {
390
+ for (var i = 0; i < vContexts.length; i++) {
391
+ var oContextData = vContexts[i].getObject();
392
+
393
+ if (oContextData.IsActiveEntity === true && oContextData.HasDraftEntity === true && oContextData.DraftAdministrativeData && oContextData.DraftAdministrativeData.InProcessByUser && !oContextData.DraftAdministrativeData.DraftIsCreatedByMe) {
394
+ MessageBox.show(CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_SINGLE_OBJECT_LOCKED", oResourceBundle), {
395
+ title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE"),
396
+ onClose: fnReject
397
+ });
398
+ return;
399
+ }
400
+ }
401
+ }
402
+
403
+ mParameters = getParameters(mParameters);
404
+
405
+ if (mParameters.title) {
406
+ if (mParameters.description) {
407
+ aParams = [mParameters.title, mParameters.description];
408
+ } else {
409
+ aParams = [mParameters.title, ""];
410
+ }
411
+
412
+ oDeleteMessage.text = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO", oResourceBundle, aParams, mParameters.entitySetName);
413
+ } else {
414
+ oDeleteMessage.text = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR", oResourceBundle);
415
+ }
416
+
417
+ aDeletableContexts = vContexts;
418
+ } else {
419
+ oDeleteMessage = {
420
+ title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE")
421
+ };
422
+
423
+ if (mParameters.numberOfSelectedContexts === 1 && mParameters.numberOfSelectedContexts === vContexts.length) {
424
+ aDeletableContexts = vContexts;
425
+ oDeleteMessage.text = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR", oResourceBundle, null, mParameters.entitySetName);
426
+ } else if (mParameters.numberOfSelectedContexts === 1 && mParameters.unSavedContexts.length === 1) {
427
+ //only one unsaved object
428
+ aDeletableContexts = mParameters.unSavedContexts;
429
+ var draftAdminData = aDeletableContexts[0].getObject()["DraftAdministrativeData"];
430
+ var sLastChangedByUser = "";
431
+
432
+ if (draftAdminData) {
433
+ sLastChangedByUser = draftAdminData["LastChangedByUserDescription"] || draftAdminData["LastChangedByUser"] || "";
434
+ }
435
+
436
+ aParams = [sLastChangedByUser];
437
+ oDeleteMessage.text = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_CHANGES", oResourceBundle, aParams);
438
+ } else if (mParameters.numberOfSelectedContexts === mParameters.unSavedContexts.length) {
439
+ //only multiple unsaved objects
440
+ aDeletableContexts = mParameters.unSavedContexts;
441
+ oDeleteMessage.text = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_CHANGES_MULTIPLE_OBJECTS", oResourceBundle);
442
+ } else if (mParameters.numberOfSelectedContexts === vContexts.concat(mParameters.unSavedContexts.concat(mParameters.lockedContexts)).length) {
443
+ //only unsaved, locked ,deletable objects but not non-deletable objects
444
+ aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
445
+ oDeleteMessage.text = aDeletableContexts.length === 1 ? CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR", oResourceBundle, null, mParameters.entitySetName) : CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_PLURAL", oResourceBundle, null, mParameters.entitySetName);
446
+ } else {
447
+ //if non-deletable objects exists along with any of unsaved ,deletable objects
448
+ aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
449
+ cannotBeDeletedTextVisible = true;
450
+ oDeleteMessage.text = aDeletableContexts.length === 1 ? CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR_NON_DELETABLE", oResourceBundle, null, mParameters.entitySetName) : CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_PLURAL_NON_DELETABLE", oResourceBundle, null, mParameters.entitySetName);
451
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_NON_DELETABLE", oResourceBundle, [mParameters.numberOfSelectedContexts - vContexts.concat(mParameters.unSavedContexts).length, mParameters.numberOfSelectedContexts]);
452
+ }
453
+
454
+ if (mParameters.lockedContexts.length == 1) {
455
+ //setting the locked text if locked objects exist
456
+ isLockedTextVisible = true;
457
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_ONE_OBJECT_LOCKED", oResourceBundle, [mParameters.numberOfSelectedContexts]);
458
+ }
459
+
460
+ if (mParameters.lockedContexts.length > 1) {
461
+ //setting the locked text if locked objects exist
462
+ isLockedTextVisible = true;
463
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_LOCKED", oResourceBundle, [mParameters.lockedContexts.length, mParameters.numberOfSelectedContexts]);
464
+ }
465
+
466
+ if (mParameters.unSavedContexts.length > 0 && mParameters.unSavedContexts.length !== mParameters.numberOfSelectedContexts) {
467
+ if ((cannotBeDeletedTextVisible || isLockedTextVisible) && aDeletableContexts.length === mParameters.unSavedContexts.length) {
468
+ //if only unsaved and either or both of locked and non-deletable objects exist then we hide the check box
469
+ isCheckBoxVisible = false;
470
+ aDeletableContexts = mParameters.unSavedContexts;
471
+
472
+ if (mParameters.unSavedContexts.length === 1) {
473
+ oDeleteMessage.text = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_AND_FEW_OBJECTS_LOCKED_SINGULAR", oResourceBundle);
474
+ } else {
475
+ oDeleteMessage.text = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_AND_FEW_OBJECTS_LOCKED_PLURAL", oResourceBundle);
476
+ }
477
+ } else {
478
+ if (mParameters.unSavedContexts.length === 1) {
479
+ oDeleteMessage.checkBoxText = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_UNSAVED_SINGULAR", oResourceBundle);
480
+ } else {
481
+ oDeleteMessage.checkBoxText = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_UNSAVED_PLURAL", oResourceBundle);
482
+ }
483
+
484
+ isCheckBoxVisible = true;
485
+ }
486
+ }
487
+
488
+ if (cannotBeDeletedTextVisible && isLockedTextVisible) {
489
+ //if both locked and non-deletable objects exist along with deletable objects
490
+ if (mParameters.unSavedContexts.length > 1) {
491
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_LOCKED_AND_NON_DELETABLE", oResourceBundle, [mParameters.numberOfSelectedContexts - vContexts.concat(mParameters.unSavedContexts).length - mParameters.lockedContexts.length, mParameters.lockedContexts.length, mParameters.numberOfSelectedContexts]);
492
+ }
493
+
494
+ if (mParameters.unSavedContexts.length == 1) {
495
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_ONE_OBJECT_LOCKED_AND_NON_DELETABLE", oResourceBundle, [mParameters.numberOfSelectedContexts - vContexts.concat(mParameters.unSavedContexts).length - mParameters.lockedContexts.length, mParameters.numberOfSelectedContexts]);
496
+ }
497
+ }
498
+ }
499
+ }
500
+
501
+ var oNonDeletableMessageTextControl, oDeleteMessageTextControl;
502
+ var oContent = new VBox({
503
+ items: [oNonDeletableMessageTextControl = new Text({
504
+ text: oDeleteMessage.nonDeletableText,
505
+ visible: isLockedTextVisible || cannotBeDeletedTextVisible
506
+ }), oDeleteMessageTextControl = new Text({
507
+ text: oDeleteMessage.text
508
+ }), new CheckBox({
509
+ text: oDeleteMessage.checkBoxText,
510
+ selected: true,
511
+ select: function (oEvent) {
512
+ var selected = oEvent.getSource().getSelected();
513
+
514
+ if (selected) {
515
+ aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
516
+ isCheckBoxSelected = true;
517
+ } else {
518
+ aDeletableContexts = vContexts;
519
+ isCheckBoxSelected = false;
520
+ }
521
+ },
522
+ visible: isCheckBoxVisible
523
+ })]
524
+ });
525
+ var sTitle = oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE");
526
+
527
+ var fnConfirm = function () {
528
+ bDialogConfirmed = true;
529
+ BusyLocker.lock(that.oLockObject);
530
+ var aContexts = aDeletableContexts;
531
+ var onBeforeDeletePromise;
532
+
533
+ if (mParameters.beforeDeleteCallBack) {
534
+ onBeforeDeletePromise = mParameters.beforeDeleteCallBack({
535
+ contexts: aContexts
536
+ });
537
+ } else {
538
+ onBeforeDeletePromise = Promise.resolve();
539
+ }
540
+
541
+ return onBeforeDeletePromise.then(that.findActiveDraftRootContexts.bind(that, aContexts, mParameters.bFindActiveContexts)).then(function (activeContexts) {
542
+ //make sure to fetch the active contexts before deleting the drafts
543
+ return Promise.all(aContexts.map(function (oContext) {
544
+ //delete the draft
545
+ return draft.deleteDraft(oContext);
546
+ })).catch(function (oError) {
547
+ return messageHandler.showMessages().then(function () {
548
+ // re-throw error to enforce rejecting the general promise
549
+ throw oError;
550
+ });
551
+ }).then(function () {
552
+ var checkBox = {
553
+ "isCheckBoxVisible": isCheckBoxVisible,
554
+ "isCheckBoxSelected": isCheckBoxSelected
555
+ };
556
+
557
+ if (activeContexts && activeContexts.length) {
558
+ return Promise.all(activeContexts.map(function (oContext) {
559
+ return oContext.delete();
560
+ })).then(function () {
561
+ that.afterDeleteProcess(mParameters, checkBox, aContexts, oResourceBundle);
562
+ return messageHandler.showMessageDialog().then(fnResolve);
563
+ });
564
+ } else {
565
+ that.afterDeleteProcess(mParameters, checkBox, aContexts, oResourceBundle);
566
+ return messageHandler.showMessageDialog().then(fnResolve);
567
+ }
568
+ });
569
+ }).catch(function () {
570
+ fnReject();
571
+ }).finally(function () {
572
+ BusyLocker.unlock(that.oLockObject);
573
+ });
574
+ };
575
+
576
+ var oDialog = new Dialog({
577
+ title: sTitle,
578
+ state: "Warning",
579
+ content: [oContent],
580
+ ariaLabelledBy: oNonDeletableMessageTextControl.getVisible() ? [oNonDeletableMessageTextControl, oDeleteMessageTextControl] : oDeleteMessageTextControl,
581
+ beginButton: new Button({
582
+ text: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE"),
583
+ type: "Emphasized",
584
+ press: function () {
585
+ oDialog.close();
586
+ return fnConfirm();
587
+ }
588
+ }),
589
+ endButton: new Button({
590
+ text: CommonUtils.getTranslatedText("C_COMMON_OBJECT_PAGE_CANCEL", oResourceBundle),
591
+ press: function () {
592
+ oDialog.close();
593
+ }
594
+ }),
595
+ afterClose: function () {
596
+ oDialog.destroy(); // if dialog is closed unconfirmed (e.g. via "Cancel" or Escape button), ensure to reject promise
597
+
598
+ if (!bDialogConfirmed) {
599
+ fnReject();
600
+ }
601
+ }
602
+ });
603
+
604
+ if (mParameters.noDialog) {
605
+ return fnConfirm();
606
+ } else {
607
+ oDialog.addStyleClass("sapUiContentPadding");
608
+ oDialog.open();
609
+ }
610
+ }).finally(function () {
611
+ BusyLocker.unlock(that.oLockObject);
612
+ }).catch(function () {
613
+ Log.warning("Couldn't get Programming model");
614
+ fnReject();
615
+ });
616
+ return new Promise(function (resolve, reject) {
617
+ fnReject = reject;
618
+ fnResolve = resolve;
619
+ });
620
+ }
621
+ /**
622
+ * Edits a document.
623
+ *
624
+ * @memberof sap.fe.core.TransactionHelper
625
+ * @static
626
+ * @param {sap.ui.model.odata.v4.Context} oContext Context of the active document
627
+ * @param {object} oView Current view
628
+ * @param messageHandler
629
+ * @returns {Promise} Promise resolves with the new draft context in case of draft programming model
630
+ * @ui5-restricted
631
+ * @final
632
+ */
633
+ ;
634
+
635
+ _proto.editDocument = function editDocument(oContext, oView, messageHandler) {
636
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
637
+ var that = this;
638
+ var sProgrammingModel = this.getProgrammingModel(oContext);
639
+ var oEditPromise;
640
+
641
+ if (!oContext) {
642
+ return Promise.reject(new Error("Binding context to active document is required"));
643
+ }
644
+
645
+ this._bIsModified = false;
646
+ BusyLocker.lock(that.oLockObject); // before triggering the edit action we'll have to remove all bound transition messages
647
+
648
+ messageHandler.removeTransitionMessages();
649
+
650
+ if (sProgrammingModel === ProgrammingModel.Draft) {
651
+ oEditPromise = draft.createDraftFromActiveDocument(oContext, this._getAppComponent(), {
652
+ bPreserveChanges: true,
653
+ oView: oView
654
+ });
655
+ } else if (sProgrammingModel === ProgrammingModel.Sticky) {
656
+ oEditPromise = sticky.editDocumentInStickySession(oContext, this._getAppComponent());
657
+ } else {
658
+ BusyLocker.unlock(that.oLockObject);
659
+ return Promise.reject(new Error("Edit is only allowed for draft or sticky session supported services"));
660
+ }
661
+
662
+ return oEditPromise.then(function (oNewContext) {
663
+ that._bCreateMode = false;
664
+ return messageHandler.showMessageDialog().then(function () {
665
+ return oNewContext;
666
+ });
667
+ }).catch(function (err) {
668
+ return messageHandler.showMessages().then(function () {
669
+ return Promise.reject(err);
670
+ });
671
+ }).finally(function () {
672
+ BusyLocker.unlock(that.oLockObject);
673
+ });
674
+ }
675
+ /**
676
+ * Cancel 'edit' mode of a document.
677
+ *
678
+ * @memberof sap.fe.core.TransactionHelper
679
+ * @static
680
+ * @param {sap.ui.model.odata.v4.Context} oContext Context of the document to be canceled or deleted
681
+ * @param {object} [mInParameters] Optional, can contain the following attributes:
682
+ * @param {sap.m.Button} mInParameters.cancelButton Cancel Button of the discard popover (mandatory for now)
683
+ * @param {boolean} mInParameters.skipDiscardPopover Optional, supresses the discard popover incase of draft applications while navigating out of OP
684
+ * @param oResourceBundle
685
+ * @param messageHandler
686
+ * @returns {Promise} Promise resolves with ???
687
+ * @ui5-restricted
688
+ * @final
689
+ */
690
+ ;
691
+
692
+ _proto.cancelDocument = function cancelDocument(oContext, mInParameters, oResourceBundle, messageHandler) {
693
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
694
+ var that = this;
695
+ var sProgrammingModel; //context must always be passed - mandatory parameter
696
+
697
+ if (!oContext) {
698
+ return Promise.reject("No context exists. Pass a meaningful context");
699
+ }
700
+
701
+ BusyLocker.lock(that.oLockObject);
702
+ var mParameters = getParameters(mInParameters);
703
+ var oParamsContext = oContext,
704
+ oCancelButton = mParameters.cancelButton,
705
+ oModel = oParamsContext.getModel();
706
+ var onBeforeCancelPromise, sCanonicalPath;
707
+ return Promise.resolve(this.getProgrammingModel(oContext)).then(function (sPModel) {
708
+ sProgrammingModel = sPModel;
709
+
710
+ if (sPModel === ProgrammingModel.Draft) {
711
+ var draftDataContext = oModel.bindContext(oParamsContext.getPath() + "/DraftAdministrativeData").getBoundContext();
712
+
713
+ if (!that._bIsModified) {
714
+ return draftDataContext.requestObject().then(function (draftAdminData) {
715
+ if (draftAdminData) {
716
+ that._bIsModified = !(draftAdminData.CreationDateTime === draftAdminData.LastChangeDateTime);
717
+ }
718
+ });
719
+ }
720
+ }
721
+ }).then(function () {
722
+ if (!mParameters.skipDiscardPopover) {
723
+ return that._showDiscardPopover(oCancelButton, that._bIsModified, oResourceBundle);
724
+ } else {
725
+ return Promise.resolve();
726
+ }
727
+ }).then(function () {
728
+ if (mParameters.beforeCancelCallBack) {
729
+ onBeforeCancelPromise = mParameters.beforeCancelCallBack({
730
+ context: oContext
731
+ });
732
+ } else {
733
+ onBeforeCancelPromise = Promise.resolve();
734
+ }
735
+
736
+ return onBeforeCancelPromise;
737
+ }).then(function () {
738
+ // eslint-disable-next-line default-case
739
+ switch (sProgrammingModel) {
740
+ case ProgrammingModel.Draft:
741
+ return oParamsContext.requestObject("HasActiveEntity").then(function (bHasActiveEntity) {
742
+ var oDeletePromise;
743
+
744
+ if (!bHasActiveEntity) {
745
+ if (oParamsContext && oParamsContext.hasPendingChanges()) {
746
+ oParamsContext.getBinding().resetChanges();
747
+ }
748
+
749
+ oDeletePromise = draft.deleteDraft(oParamsContext);
750
+ return oDeletePromise;
751
+ } else {
752
+ var oActiveContext = oModel.bindContext(oParamsContext.getPath() + "/SiblingEntity").getBoundContext();
753
+ return oActiveContext.requestCanonicalPath().then(function (sPath) {
754
+ sCanonicalPath = sPath;
755
+
756
+ if (oParamsContext && oParamsContext.hasPendingChanges()) {
757
+ oParamsContext.getBinding().resetChanges();
758
+ }
759
+
760
+ oDeletePromise = draft.deleteDraft(oParamsContext);
761
+ return oDeletePromise;
762
+ }, function () {
763
+ draft.deleteDraft(oParamsContext);
764
+ return;
765
+ }).then(function () {
766
+ //oParamsContext.delete() in the previous promise doesnt return anything upon success.
767
+ if (!sCanonicalPath) {
768
+ return;
769
+ }
770
+
771
+ if (oActiveContext.getPath() !== sCanonicalPath) {
772
+ // the active context is using the sibling entity - this path is not accessible anymore as we deleted the draft
773
+ // document - therefore we need to create a new context with the canonical path
774
+ oActiveContext = oModel.bindContext(sCanonicalPath).getBoundContext();
775
+ }
776
+
777
+ return oActiveContext;
778
+ });
779
+ }
780
+ });
781
+
782
+ case ProgrammingModel.Sticky:
783
+ return sticky.discardDocument(oContext).then(function (oContext) {
784
+ if (oContext) {
785
+ if (oContext.hasPendingChanges()) {
786
+ oContext.getBinding().resetChanges();
787
+ }
788
+
789
+ if (!that._bCreateMode) {
790
+ oContext.refresh();
791
+ return oContext;
792
+ }
793
+ }
794
+
795
+ return false;
796
+ });
797
+
798
+ default:
799
+ return Promise.reject("Cancel document only allowed for draft or sticky session supported services");
800
+ }
801
+ }).then(function (context) {
802
+ that._bIsModified = false; // remove existing bound transition messages
803
+
804
+ messageHandler.removeTransitionMessages(); // show unbound messages
805
+
806
+ return messageHandler.showMessages().then(function () {
807
+ return context;
808
+ });
809
+ }).catch(function (err) {
810
+ return messageHandler.showMessages().then(function () {
811
+ return Promise.reject(err);
812
+ });
813
+ }).finally(function () {
814
+ BusyLocker.unlock(that.oLockObject);
815
+ });
816
+ }
817
+ /**
818
+ * Saves the document.
819
+ *
820
+ * @memberof sap.fe.core.TransactionHelper
821
+ * @static
822
+ * @param {sap.ui.model.odata.v4.Context} oContext Context of the document to be saved
823
+ * @param oResourceBundle
824
+ * @param bExecuteSideEffectsOnError
825
+ * @param aBindings
826
+ * @param messageHandler
827
+ * @returns {Promise} Promise resolves with ???
828
+ * @ui5-restricted
829
+ * @final
830
+ */
831
+ ;
832
+
833
+ _proto.saveDocument = function saveDocument(oContext, oResourceBundle, bExecuteSideEffectsOnError, aBindings, messageHandler) {
834
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
835
+ var that = this;
836
+ var sProgrammingModel = this.getProgrammingModel(oContext);
837
+ var oSavePromise;
838
+
839
+ if (!oContext) {
840
+ return Promise.reject(new Error("Binding context to draft document is required"));
841
+ } // in case of saving / activating the bound transition messages shall be removed before the PATCH/POST
842
+ // is sent to the backend
843
+
844
+
845
+ messageHandler.removeTransitionMessages();
846
+ BusyLocker.lock(that.oLockObject);
847
+
848
+ if (sProgrammingModel === ProgrammingModel.Draft) {
849
+ oSavePromise = draft.activateDocument(oContext, this._getAppComponent(), {});
850
+ } else if (sProgrammingModel === ProgrammingModel.Sticky) {
851
+ oSavePromise = sticky.activateDocument(oContext);
852
+ } else {
853
+ BusyLocker.unlock(that.oLockObject);
854
+ return Promise.reject(new Error("Save is only allowed for draft or sticky session supported services"));
855
+ }
856
+
857
+ return oSavePromise.then(function (oActiveDocument) {
858
+ var bNewObject = that.sProgrammingModel === ProgrammingModel.Sticky ? that._bCreateMode : !oContext.getObject().HasActiveEntity;
859
+ MessageToast.show(bNewObject ? CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_CREATED", oResourceBundle) : CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_SAVED", oResourceBundle));
860
+ that._bIsModified = false;
861
+ return messageHandler.showMessageDialog().then(function () {
862
+ return oActiveDocument;
863
+ });
864
+ }).catch(function (err) {
865
+ if (aBindings && aBindings.length > 0) {
866
+ /* The sideEffects are executed only for table items in transient state */
867
+ aBindings.forEach(function (oListBinding) {
868
+ if (!CommonUtils.hasTransientContext(oListBinding) && bExecuteSideEffectsOnError) {
869
+ var oAppComponent = that._getAppComponent();
870
+
871
+ oAppComponent.getSideEffectsService().requestSideEffectsForNavigationProperty(oListBinding.getPath(), oContext);
872
+ }
873
+ });
874
+ }
875
+
876
+ return messageHandler.showMessages().then(function () {
877
+ return Promise.reject(err);
878
+ });
879
+ }).finally(function () {
880
+ BusyLocker.unlock(that.oLockObject);
881
+ });
882
+ }
883
+ /**
884
+ * Calls a bound or unbound action.
885
+ *
886
+ * @function
887
+ * @static
888
+ * @name sap.fe.core.TransactionHelper.callAction
889
+ * @memberof sap.fe.core.TransactionHelper
890
+ * @param {string} sActionName The name of the action to be called
891
+ * @param {map} [mParameters] Contains the following attributes:
892
+ * @param {sap.ui.model.odata.v4.Context} [mParameters.contexts] Mandatory for a bound action: Either one context or an array with contexts for which the action is to be called
893
+ * @param {sap.ui.model.odata.v4.ODataModel} [mParameters.model] Mandatory for an unbound action: An instance of an OData V4 model
894
+ * @param {string} [mParameters.invocationGrouping] Mode how actions are to be called: 'ChangeSet' to put all action calls into one changeset, 'Isolated' to put them into separate changesets
895
+ * @param {string} [mParameters.label] A human-readable label for the action
896
+ * @param {boolean} [mParameters.bGetBoundContext] If specified, the action promise returns the bound context
897
+ * @param {object} oView Contains the object of the current view
898
+ * @param messageHandler
899
+ * @returns {Promise} Promise resolves with an array of response objects (TODO: to be changed)
900
+ * @ui5-restricted
901
+ * @final
902
+ **/
903
+ ;
904
+
905
+ _proto.callAction = function callAction(sActionName, mParameters, oView, messageHandler) {
906
+ mParameters = getParameters(mParameters); // eslint-disable-next-line @typescript-eslint/no-this-alias
907
+
908
+ var that = this;
909
+ var oContext, oModel, oPromise;
910
+ var mBindingParameters = mParameters.bindingParameters;
911
+
912
+ if (!sActionName) {
913
+ return Promise.reject("Provide name of action to be executed");
914
+ } // action imports are not directly obtained from the metaModel by it is present inside the entityContainer
915
+ // and the acions it refers to present outside the entitycontainer, hence to obtain kind of the action
916
+ // split() on its name was required
917
+
918
+
919
+ var sName = sActionName.split("/")[1];
920
+ sActionName = sName || sActionName;
921
+ oContext = sName ? undefined : mParameters.contexts; //checking whether the context is an array with more than 0 length or not an array(create action)
922
+
923
+ if (oContext && (Array.isArray(oContext) && oContext.length || !Array.isArray(oContext))) {
924
+ oContext = Array.isArray(oContext) ? oContext[0] : oContext;
925
+ oModel = oContext.getModel();
926
+ }
927
+
928
+ if (mParameters.model) {
929
+ oModel = mParameters.model;
930
+ }
931
+
932
+ if (!oModel) {
933
+ return Promise.reject("Pass a context for a bound action or pass the model for an unbound action");
934
+ } // get the binding parameters $select and $expand for the side effect on this action
935
+ // also gather additional property paths to be requested such as text associations
936
+
937
+
938
+ var oAppComponent = that._getAppComponent();
939
+
940
+ var mSideEffectsParameters = oAppComponent.getSideEffectsService().getODataActionSideEffects(sActionName, oContext) || {};
941
+
942
+ if (oContext && oModel) {
943
+ oPromise = new Promise(function (resolve, reject) {
944
+ var oApplicableContextDialog;
945
+ var oController = {
946
+ onClose: function () {
947
+ // User cancels action
948
+ oApplicableContextDialog.close();
949
+ resolve();
950
+ },
951
+ onContinue: function () {
952
+ // Users continues the action with the bound contexts
953
+ oApplicableContextDialog.close();
954
+ resolve(mParameters.applicableContext);
955
+ }
956
+ };
957
+
958
+ var fnOpenAndFillDialog = function () {
959
+ var oDialogContent;
960
+ var nNotApplicable = mParameters.notApplicableContext.length,
961
+ aNotApplicableItems = [];
962
+
963
+ for (var i = 0; i < mParameters.notApplicableContext.length; i++) {
964
+ oDialogContent = mParameters.notApplicableContext[i].getObject();
965
+ aNotApplicableItems.push(oDialogContent);
966
+ }
967
+
968
+ var oNotApplicableItemsModel = new JSONModel(aNotApplicableItems);
969
+ var oTotals = new JSONModel({
970
+ total: nNotApplicable,
971
+ label: mParameters.label
972
+ });
973
+ oApplicableContextDialog.setModel(oNotApplicableItemsModel, "notApplicable");
974
+ oApplicableContextDialog.setModel(oTotals, "totals");
975
+ oApplicableContextDialog.open();
976
+ };
977
+
978
+ if (mParameters.notApplicableContext && mParameters.notApplicableContext.length >= 1) {
979
+ // Show the contexts that are not applicable and will not therefore be processed
980
+ var sFragmentName = "sap.fe.core.controls.ActionPartial";
981
+ var oDialogFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment");
982
+ var oMetaModel = oModel.getMetaModel();
983
+ var sCanonicalPath = mParameters.contexts[0].getCanonicalPath();
984
+ var sEntitySet = sCanonicalPath.substr(0, sCanonicalPath.indexOf("(")) + "/";
985
+ var oDialogLabelModel = new JSONModel({
986
+ title: mParameters.label
987
+ });
988
+ Promise.resolve(XMLPreprocessor.process(oDialogFragment, {
989
+ name: sFragmentName
990
+ }, {
991
+ bindingContexts: {
992
+ entityType: oMetaModel.createBindingContext(sEntitySet),
993
+ label: oDialogLabelModel.createBindingContext("/")
994
+ },
995
+ models: {
996
+ entityType: oMetaModel,
997
+ metaModel: oMetaModel,
998
+ label: oDialogLabelModel
999
+ }
1000
+ })).then(function (oFragment) {
1001
+ return Fragment.load({
1002
+ definition: oFragment,
1003
+ controller: oController
1004
+ });
1005
+ }).then(function (oPopover) {
1006
+ oApplicableContextDialog = oPopover;
1007
+ mParameters.parentControl.addDependent(oPopover);
1008
+ fnOpenAndFillDialog();
1009
+ }).catch(reject);
1010
+ } else {
1011
+ resolve(mParameters.contexts);
1012
+ }
1013
+ }).then(function (contextToProcess) {
1014
+ if (contextToProcess) {
1015
+ return operations.callBoundAction(sActionName, contextToProcess, oModel, oAppComponent, {
1016
+ invocationGrouping: mParameters.invocationGrouping,
1017
+ label: mParameters.label,
1018
+ showActionParameterDialog: true,
1019
+ mBindingParameters: mBindingParameters,
1020
+ entitySetName: mParameters.entitySetName,
1021
+ additionalSideEffect: mSideEffectsParameters,
1022
+ onSubmitted: function () {
1023
+ messageHandler.removeTransitionMessages();
1024
+ BusyLocker.lock(that.oLockObject);
1025
+ },
1026
+ onResponse: function () {
1027
+ BusyLocker.unlock(that.oLockObject);
1028
+ },
1029
+ parentControl: mParameters.parentControl,
1030
+ internalModelContext: mParameters.internalModelContext,
1031
+ operationAvailableMap: mParameters.operationAvailableMap,
1032
+ bIsCreateAction: mParameters.bIsCreateAction,
1033
+ bGetBoundContext: mParameters.bGetBoundContext,
1034
+ bObjectPage: mParameters.bObjectPage,
1035
+ messageHandler: messageHandler,
1036
+ defaultValuesExtensionFunction: mParameters.defaultValuesExtensionFunction
1037
+ });
1038
+ } else {
1039
+ return null;
1040
+ }
1041
+ });
1042
+ } else {
1043
+ // TODO: confirm if action import needs side effects.
1044
+ oPromise = operations.callActionImport(sActionName, oModel, oAppComponent, {
1045
+ label: mParameters.label,
1046
+ showActionParameterDialog: true,
1047
+ bindingParameters: mBindingParameters,
1048
+ entitySetName: mParameters.entitySetName,
1049
+ onSubmitted: function () {
1050
+ BusyLocker.lock(that.oLockObject);
1051
+ },
1052
+ onResponse: function () {
1053
+ BusyLocker.unlock(that.oLockObject);
1054
+ },
1055
+ parentControl: mParameters.parentControl,
1056
+ internalModelContext: mParameters.internalModelContext,
1057
+ operationAvailableMap: mParameters.operationAvailableMap,
1058
+ messageHandler: messageHandler,
1059
+ bObjectPage: mParameters.bObjectPage
1060
+ });
1061
+ }
1062
+
1063
+ return oPromise.then(function (oResult) {
1064
+ // Succeeded
1065
+ return that._handleActionResponse(messageHandler, mParameters, sActionName).then(function () {
1066
+ return oResult;
1067
+ });
1068
+ }).catch(function (err) {
1069
+ return that._handleActionResponse(messageHandler, mParameters, sActionName).then(function () {
1070
+ return Promise.reject(err);
1071
+ });
1072
+ });
1073
+ }
1074
+ /**
1075
+ * Handles messages for action call.
1076
+ *
1077
+ * @function
1078
+ * @name sap.fe.core.TransactionHelper#_handleActionResponse
1079
+ * @memberof sap.fe.core.TransactionHelper
1080
+ * @param messageHandler
1081
+ * @param {object} mParameters Parameters to be considered for the action.
1082
+ * @param {string} sActionName The name of the action to be called
1083
+ * @returns {Promise} Promise after message dialog is opened if required.
1084
+ * @ui5-restricted
1085
+ * @final
1086
+ */
1087
+ ;
1088
+
1089
+ _proto._handleActionResponse = function _handleActionResponse(messageHandler, mParameters, sActionName) {
1090
+ var aTransientMessages = messageHandling.getMessages(true, true);
1091
+
1092
+ if (aTransientMessages.length > 0 && mParameters && mParameters.internalModelContext) {
1093
+ mParameters.internalModelContext.setProperty("sActionName", mParameters.label ? mParameters.label : sActionName);
1094
+ }
1095
+
1096
+ return messageHandler.showMessages();
1097
+ }
1098
+ /**
1099
+ * Handles validation errors for the 'discard' action.
1100
+ *
1101
+ * @function
1102
+ * @name sap.fe.core.TransactionHelper#handleValidationError
1103
+ * @memberof sap.fe.core.TransactionHelper
1104
+ * @static
1105
+ * @ui5-restricted
1106
+ * @final
1107
+ */
1108
+ ;
1109
+
1110
+ _proto.handleValidationError = function handleValidationError() {
1111
+ var oMessageManager = Core.getMessageManager(),
1112
+ errorToRemove = oMessageManager.getMessageModel().getData().filter(function (error) {
1113
+ // only needs to handle validation messages, technical and persistent errors needs not to be checked here.
1114
+ if (error.validation) {
1115
+ return error;
1116
+ }
1117
+ });
1118
+ oMessageManager.removeMessages(errorToRemove);
1119
+ }
1120
+ /**
1121
+ * Shows a popover if it needs to be shown.
1122
+ * TODO: Popover is shown if user has modified any data.
1123
+ * TODO: Popover is shown if there's a difference from draft admin data.
1124
+ * @static
1125
+ * @name sap.fe.core.TransactionHelper._showDiscardPopover
1126
+ * @memberof sap.fe.core.TransactionHelper
1127
+ * @param {sap.ui.core.Control} oCancelButton The control which will open the popover
1128
+ * @param bIsModified
1129
+ * @param oResourceBundle
1130
+ * @returns {Promise} Promise resolves if user confirms discard, rejects if otherwise, rejects if no control passed to open popover
1131
+ * @ui5-restricted
1132
+ * @final
1133
+ */
1134
+ ;
1135
+
1136
+ _proto._showDiscardPopover = function _showDiscardPopover(oCancelButton, bIsModified, oResourceBundle) {
1137
+ // TODO: Implement this popover as a fragment as in v2??
1138
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
1139
+ var that = this;
1140
+ that._bContinueDiscard = false; // to be implemented
1141
+
1142
+ return new Promise(function (resolve, reject) {
1143
+ if (!oCancelButton) {
1144
+ reject("Cancel button not found");
1145
+ } //Show popover only when data is changed.
1146
+
1147
+
1148
+ if (bIsModified) {
1149
+ var fnOnAfterDiscard = function () {
1150
+ oCancelButton.setEnabled(true);
1151
+
1152
+ if (that._bContinueDiscard) {
1153
+ resolve();
1154
+ } else {
1155
+ reject("Discard operation was rejected. Document has not been discarded");
1156
+ }
1157
+
1158
+ that._oPopover.detachAfterClose(fnOnAfterDiscard);
1159
+ };
1160
+
1161
+ if (!that._oPopover) {
1162
+ var oText = new Text({
1163
+ //This text is the same as LR v2.
1164
+ //TODO: Display message provided by app developer???
1165
+ text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_DRAFT_DISCARD_MESSAGE", oResourceBundle)
1166
+ }),
1167
+ oButton = new Button({
1168
+ text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_DRAFT_DISCARD_BUTTON", oResourceBundle),
1169
+ width: "100%",
1170
+ press: function () {
1171
+ that.handleValidationError();
1172
+ that._bContinueDiscard = true;
1173
+
1174
+ that._oPopover.close();
1175
+ },
1176
+ ariaLabelledBy: oText
1177
+ });
1178
+ that._oPopover = new Popover({
1179
+ showHeader: false,
1180
+ placement: "Top",
1181
+ content: [new VBox({
1182
+ items: [oText, oButton]
1183
+ })],
1184
+ beforeOpen: function () {
1185
+ // make sure to NOT trigger multiple cancel flows
1186
+ oCancelButton.setEnabled(false);
1187
+
1188
+ that._oPopover.setInitialFocus(oButton);
1189
+ }
1190
+ });
1191
+
1192
+ that._oPopover.addStyleClass("sapUiContentPadding");
1193
+ }
1194
+
1195
+ that._oPopover.attachAfterClose(fnOnAfterDiscard);
1196
+
1197
+ that._oPopover.openBy(oCancelButton, false);
1198
+ } else {
1199
+ that.handleValidationError();
1200
+ resolve();
1201
+ }
1202
+ });
1203
+ }
1204
+ /**
1205
+ * Sets the document to modified state on patch event.
1206
+ *
1207
+ * @function
1208
+ * @static
1209
+ * @name sap.fe.core.TransactionHelper.handleDocumentModifications
1210
+ * @memberof sap.fe.core.TransactionHelper
1211
+ * @ui5-restricted
1212
+ * @final
1213
+ */
1214
+ ;
1215
+
1216
+ _proto.handleDocumentModifications = function handleDocumentModifications() {
1217
+ this._bIsModified = true;
1218
+ }
1219
+ /**
1220
+ * Retrieves the owner component.
1221
+ *
1222
+ * @function
1223
+ * @static
1224
+ * @private
1225
+ * @name sap.fe.core.TransactionHelper._getOwnerComponent
1226
+ * @memberof sap.fe.core.TransactionHelper
1227
+ * @returns {sap.fe.core.AppComponent} The app component
1228
+ * @ui5-restricted
1229
+ * @final
1230
+ **/
1231
+ ;
1232
+
1233
+ _proto._getAppComponent = function _getAppComponent() {
1234
+ return this._oAppComponent;
1235
+ };
1236
+
1237
+ _proto._onFieldChange = function _onFieldChange(oEvent, oCreateButton, messageHandler, fnValidateRequiredProperties) {
1238
+ messageHandler.removeTransitionMessages();
1239
+ var oField = oEvent.getSource();
1240
+ var oFieldPromise = oEvent.getParameter("promise");
1241
+
1242
+ if (oFieldPromise) {
1243
+ return oFieldPromise.then(function (value) {
1244
+ // Setting value of field as '' in case of value help and validating other fields
1245
+ oField.setValue(value);
1246
+ fnValidateRequiredProperties();
1247
+ return oField.getValue();
1248
+ }).catch(function (value) {
1249
+ if (value !== "") {
1250
+ //disabling the continue button in case of invalid value in field
1251
+ oCreateButton.setEnabled(false);
1252
+ } else {
1253
+ // validating all the fields in case of empty value in field
1254
+ oField.setValue(value);
1255
+ fnValidateRequiredProperties();
1256
+ }
1257
+ });
1258
+ }
1259
+ };
1260
+
1261
+ _proto._launchDialogWithKeyFields = function _launchDialogWithKeyFields(oListBinding, oTransientListBinding, oTransientContext, mFields, oModel, mParameters, messageHandler) {
1262
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
1263
+ var that = this;
1264
+ var oDialog;
1265
+ var oParentControl = mParameters.parentControl,
1266
+ bSuccess = false;
1267
+ return new Promise(function (resolve, reject) {
1268
+ var sFragmentName = "sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog";
1269
+
1270
+ var oFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment"),
1271
+ oResourceBundle = oParentControl.getController().oResourceBundle,
1272
+ oMetaModel = oModel.getMetaModel(),
1273
+ aImmutableFields = [],
1274
+ oAppComponent = that._getAppComponent(),
1275
+ sPath = oListBinding.isRelative() ? oListBinding.getResolvedPath() : oListBinding.getPath(),
1276
+ oEntitySetContext = oMetaModel.createBindingContext(sPath),
1277
+ sMetaPath = oMetaModel.getMetaPath(sPath);
1278
+
1279
+ for (var i in mFields) {
1280
+ aImmutableFields.push(oMetaModel.createBindingContext(sMetaPath + "/" + mFields[i]));
1281
+ }
1282
+
1283
+ var oImmutableCtxModel = new JSONModel(aImmutableFields);
1284
+ var oImmutableCtx = oImmutableCtxModel.createBindingContext("/");
1285
+ return Promise.resolve(XMLPreprocessor.process(oFragment, {
1286
+ name: sFragmentName
1287
+ }, {
1288
+ bindingContexts: {
1289
+ entitySet: oEntitySetContext,
1290
+ fields: oImmutableCtx
1291
+ },
1292
+ models: {
1293
+ entitySet: oEntitySetContext.getModel(),
1294
+ fields: oImmutableCtx.getModel(),
1295
+ metaModel: oMetaModel
1296
+ }
1297
+ })).then(function (oFragment) {
1298
+ var aFormElements = [];
1299
+ var mFieldValueMap = {};
1300
+ var oCreateButton;
1301
+
1302
+ var validateRequiredProperties = function () {
1303
+ return Promise.all(aFormElements.map(function (oFormElement) {
1304
+ return oFormElement.getFields()[0];
1305
+ }).filter(function (oField) {
1306
+ // The continue button should remain disabled in case of error in any field of the create dialog
1307
+ return oField.getRequired() || oField.getValueState() === ValueState.Error && oField.getValue() !== "";
1308
+ }).map(function (oField) {
1309
+ var sFieldId = oField.getId();
1310
+
1311
+ if (sFieldId in mFieldValueMap) {
1312
+ return Promise.resolve(mFieldValueMap[sFieldId]).then(function (vValue) {
1313
+ return oField.getValueState() === ValueState.Error ? undefined : vValue;
1314
+ }).catch(function () {
1315
+ return undefined;
1316
+ });
1317
+ }
1318
+
1319
+ return oField.getValueState() === ValueState.Error ? undefined : oField.getValue();
1320
+ })).then(function (aResults) {
1321
+ return aResults.every(function (vValue) {
1322
+ return vValue !== undefined && vValue !== null && vValue !== "";
1323
+ });
1324
+ }).catch(function () {
1325
+ return false;
1326
+ }).then(function (bEnabled) {
1327
+ oCreateButton.setEnabled(bEnabled);
1328
+ });
1329
+ };
1330
+
1331
+ var oController = {
1332
+ /*
1333
+ fired on focus out from field or on selecting a value from the valuehelp.
1334
+ the create button is enabled when a value is added.
1335
+ liveChange is not fired when value is added from valuehelp.
1336
+ value validation is not done for create button enablement.
1337
+ */
1338
+ handleChange: function (oEvent) {
1339
+ var sFieldId = oEvent.getParameter("id");
1340
+ mFieldValueMap[sFieldId] = that._onFieldChange(oEvent, oCreateButton, messageHandler, validateRequiredProperties);
1341
+ },
1342
+
1343
+ /*
1344
+ fired on key press. the create button is enabled when a value is added.
1345
+ liveChange is not fired when value is added from valuehelp.
1346
+ value validation is not done for create button enablement.
1347
+ */
1348
+ handleLiveChange: function (oEvent) {
1349
+ var sFieldId = oEvent.getParameter("id");
1350
+ var vValue = oEvent.getParameter("value");
1351
+ mFieldValueMap[sFieldId] = vValue;
1352
+ validateRequiredProperties();
1353
+ }
1354
+ };
1355
+ return Fragment.load({
1356
+ definition: oFragment,
1357
+ controller: oController
1358
+ }).then(function (oDialogContent) {
1359
+ oDialog = new Dialog({
1360
+ title: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE", oResourceBundle),
1361
+ content: [oDialogContent],
1362
+ beginButton: {
1363
+ text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE_BUTTON", oResourceBundle),
1364
+ type: "Emphasized",
1365
+ press: function (oEvent) {
1366
+ var oCreateButton = oEvent.getSource();
1367
+ oCreateButton.setEnabled(false);
1368
+ BusyLocker.lock(oDialog);
1369
+ mParameters.bIsCreateDialog = true;
1370
+ return Promise.all(Object.keys(mFieldValueMap).map(function (sKey) {
1371
+ return mFieldValueMap[sKey].then(function (oValue) {
1372
+ var oDialogValue = {};
1373
+ oDialogValue[sKey] = oValue;
1374
+ return oDialogValue;
1375
+ });
1376
+ })).then(function (aValues) {
1377
+ var onBeforeCreatePromise;
1378
+
1379
+ if (mParameters.beforeCreateCallBack) {
1380
+ onBeforeCreatePromise = mParameters.beforeCreateCallBack({
1381
+ contextPath: oListBinding && oListBinding.getPath(),
1382
+ createParameters: aValues
1383
+ });
1384
+ } else {
1385
+ onBeforeCreatePromise = Promise.resolve();
1386
+ }
1387
+
1388
+ return onBeforeCreatePromise;
1389
+ }).then(function () {
1390
+ var oPromise = that.onAfterCreateCompletion(oTransientListBinding, oTransientContext, mParameters);
1391
+ oModel.submitBatch("submitLater");
1392
+ return oPromise;
1393
+ }).then(function (oResponse) {
1394
+ if (!oResponse || oResponse && oResponse.bKeepDialogOpen !== true) {
1395
+ oDialog.setBindingContext(null);
1396
+ oDialog.close();
1397
+ resolve(oResponse);
1398
+ }
1399
+ }).catch(function (oError) {
1400
+ reject(oError);
1401
+ }).finally(function () {
1402
+ BusyLocker.unlock(oDialog);
1403
+ oCreateButton.setEnabled(true);
1404
+ return messageHandler.showMessages();
1405
+ });
1406
+ }
1407
+ },
1408
+ endButton: {
1409
+ text: CommonUtils.getTranslatedText("C_COMMON_ACTION_PARAMETER_DIALOG_CANCEL", oResourceBundle),
1410
+ press: function () {
1411
+ oDialog.close();
1412
+ }
1413
+ },
1414
+ afterClose: function () {
1415
+ var _oDialog$getBindingCo;
1416
+
1417
+ // show footer as per UX guidelines when dialog is not open
1418
+ (_oDialog$getBindingCo = oDialog.getBindingContext("internal")) === null || _oDialog$getBindingCo === void 0 ? void 0 : _oDialog$getBindingCo.setProperty("isCreateDialogOpen", false);
1419
+ oDialog.destroy();
1420
+
1421
+ if (!bSuccess) {
1422
+ reject({
1423
+ bDeleteTransientContext: true,
1424
+ navigateBackFromTransientState: true
1425
+ });
1426
+ }
1427
+ }
1428
+ });
1429
+ aFormElements = oDialogContent.getAggregation("form").getAggregation("formContainers")[0].getAggregation("formElements");
1430
+
1431
+ if (oParentControl && oParentControl.addDependent) {
1432
+ // if there is a parent control specified add the dialog as dependent
1433
+ oParentControl.addDependent(oDialog);
1434
+ }
1435
+
1436
+ oCreateButton = oDialog.getBeginButton();
1437
+ oDialog.setBindingContext(oTransientContext);
1438
+ return CommonUtils.setUserDefaults(oAppComponent, aImmutableFields, oTransientContext, false, mParameters.createAction, mParameters.data).then(function () {
1439
+ validateRequiredProperties(); // footer must not be visible when the dialog is open as per UX guidelines
1440
+
1441
+ oDialog.getBindingContext("internal").setProperty("isCreateDialogOpen", true);
1442
+ oDialog.open();
1443
+ }).catch(function (oError) {
1444
+ return messageHandler.showMessages().then(function () {
1445
+ return Promise.reject(oError);
1446
+ });
1447
+ });
1448
+ });
1449
+ });
1450
+ });
1451
+ };
1452
+
1453
+ _proto.onAfterCreateCompletion = function onAfterCreateCompletion(oListBinding, oNewDocumentContext, mParameters) {
1454
+ var fnResolve, fnReject;
1455
+ var oPromise = new Promise(function (resolve, reject) {
1456
+ fnResolve = resolve;
1457
+ fnReject = reject;
1458
+ }); // eslint-disable-next-line @typescript-eslint/no-this-alias
1459
+
1460
+ var that = this; // Workaround suggested by OData model v4 colleagues
1461
+
1462
+ var fnCreateCompleted = function (oEvent) {
1463
+ var oContext = oEvent.getParameter("context"),
1464
+ bSuccess = oEvent.getParameter("success");
1465
+
1466
+ if (oContext === oNewDocumentContext) {
1467
+ oListBinding.detachCreateCompleted(fnCreateCompleted, that);
1468
+
1469
+ if (!bSuccess) {
1470
+ var oError = {
1471
+ bDeleteTransientContext: false
1472
+ };
1473
+
1474
+ if (!mParameters.keepTransientContextOnFailed) {
1475
+ // the context is deleted
1476
+ // this is needed to avoid console errors TO be checked with model colleagues
1477
+ oContext.created().then(undefined, function () {
1478
+ Log.trace("transient creation context deleted");
1479
+ }).catch(function (oError) {
1480
+ Log.trace("transient creation context deletion error", oError);
1481
+ });
1482
+
1483
+ if (!mParameters.bIsCreateDialog) {
1484
+ // if current state is transient (...), browser will come back to previous state
1485
+ oError.navigateBackFromTransientState = true;
1486
+ oError.bDeleteTransientContext = true;
1487
+ fnReject(oError);
1488
+ }
1489
+ }
1490
+
1491
+ fnResolve({
1492
+ bKeepDialogOpen: true
1493
+ });
1494
+ } else {
1495
+ fnResolve();
1496
+ }
1497
+ }
1498
+ };
1499
+
1500
+ oListBinding.attachCreateCompleted(fnCreateCompleted, this);
1501
+ return oPromise;
1502
+ }
1503
+ /**
1504
+ * Retrieves the name of the NewAction to be executed.
1505
+ *
1506
+ * @function
1507
+ * @static
1508
+ * @private
1509
+ * @name sap.fe.core.TransactionHelper._getNewAction
1510
+ * @memberof sap.fe.core.TransactionHelper
1511
+ * @param {object} oStartupParameters Startup parameters of the application
1512
+ * @param {string} sCreateHash Hash to be checked for action type
1513
+ * @param {object} oMetaModel The MetaModel used to check for NewAction parameter
1514
+ * @param {string} sMetaPath The MetaPath
1515
+ * @returns {string} The name of the action
1516
+ * @ui5-restricted
1517
+ * @final
1518
+ **/
1519
+ ;
1520
+
1521
+ _proto._getNewAction = function _getNewAction(oStartupParameters, sCreateHash, oMetaModel, sMetaPath) {
1522
+ var sNewAction;
1523
+
1524
+ if (oStartupParameters && oStartupParameters.preferredMode && sCreateHash.indexOf("i-action=createWith") > -1) {
1525
+ var sPreferredMode = oStartupParameters.preferredMode[0];
1526
+ sNewAction = sPreferredMode.indexOf("createWith:") > -1 ? sPreferredMode.substr(sPreferredMode.lastIndexOf(":") + 1) : undefined;
1527
+ } else {
1528
+ sNewAction = oMetaModel && oMetaModel.getObject !== undefined ? oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Session.v1.StickySessionSupported/NewAction") || oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DraftRoot/NewAction") : undefined;
1529
+ }
1530
+
1531
+ return sNewAction;
1532
+ }
1533
+ /**
1534
+ * Retrieves the label for the title of a specific create action dialog, e.g. Create Sales Order from Quotation.
1535
+ *
1536
+ * The following priority is applied:
1537
+ * 1. label of line-item annotation.
1538
+ * 2. label annotated in the action.
1539
+ * 3. "Create" as a constant from i18n.
1540
+ *
1541
+ * @function
1542
+ * @static
1543
+ * @private
1544
+ * @name sap.fe.core.TransactionHelper._getSpecificCreateActionDialogLabel
1545
+ * @memberof sap.fe.core.TransactionHelper
1546
+ * @param {object} oMetaModel The MetaModel used to check for the NewAction parameter
1547
+ * @param {string} sMetaPath The MetaPath
1548
+ * @param {string} sNewAction Contains the name of the action to be executed
1549
+ * @param {object} oResourceBundleCore ResourceBundle to access the default Create label
1550
+ * @returns {string} The label for the Create Action Dialog
1551
+ * @ui5-restricted
1552
+ * @final
1553
+ **/
1554
+ ;
1555
+
1556
+ _proto._getSpecificCreateActionDialogLabel = function _getSpecificCreateActionDialogLabel(oMetaModel, sMetaPath, sNewAction, oResourceBundleCore) {
1557
+ var fnGetLabelFromLineItemAnnotation = function () {
1558
+ if (oMetaModel && oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.UI.v1.LineItem")) {
1559
+ var iLineItemIndex = oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.UI.v1.LineItem").findIndex(function (oLineItem) {
1560
+ var aLineItemAction = oLineItem.Action ? oLineItem.Action.split("(") : undefined;
1561
+ return aLineItemAction ? aLineItemAction[0] === sNewAction : false;
1562
+ });
1563
+ return iLineItemIndex > -1 ? oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.UI.v1.LineItem")[iLineItemIndex].Label : undefined;
1564
+ } else {
1565
+ return undefined;
1566
+ }
1567
+ };
1568
+
1569
+ return fnGetLabelFromLineItemAnnotation() || oMetaModel && oMetaModel.getObject(sMetaPath + "/" + sNewAction + "@com.sap.vocabularies.Common.v1.Label") || oResourceBundleCore && oResourceBundleCore.getText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE");
1570
+ };
1571
+
1572
+ return TransactionHelper;
1573
+ }();
1574
+
1575
+ return TransactionHelper;
1576
+ }, false);
1577
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlRyYW5zYWN0aW9uSGVscGVyLnRzIl0sIm5hbWVzIjpbIkNyZWF0aW9uTW9kZSIsIkZFTGlicmFyeSIsIlByb2dyYW1taW5nTW9kZWwiLCJWYWx1ZVN0YXRlIiwiY29yZUxpYnJhcnkiLCJnZXRQYXJhbWV0ZXJzIiwibVBhcmFtZXRlcnMiLCJnZXRNZXRhZGF0YSIsImdldE5hbWUiLCJUcmFuc2FjdGlvbkhlbHBlciIsIm9BcHBDb21wb25lbnQiLCJvTG9ja09iamVjdCIsIl9iSXNNb2RpZmllZCIsIl9iQ3JlYXRlTW9kZSIsIl9iQ29udGludWVEaXNjYXJkIiwiX29BcHBDb21wb25lbnQiLCJnZXRQcm9ncmFtbWluZ01vZGVsIiwib0NvbnRleHQiLCJzUHJvZ3JhbW1pbmdNb2RlbCIsInNQYXRoIiwiaXNBIiwiZ2V0UGF0aCIsImlzUmVsYXRpdmUiLCJnZXRSZXNvbHZlZFBhdGgiLCJNb2RlbEhlbHBlciIsImlzRHJhZnRTdXBwb3J0ZWQiLCJnZXRNb2RlbCIsImdldE1ldGFNb2RlbCIsIkRyYWZ0IiwiaXNTdGlja3lTZXNzaW9uU3VwcG9ydGVkIiwiU3RpY2t5IiwiTm9uRHJhZnQiLCJ2YWxpZGF0ZURvY3VtZW50Iiwib1ZpZXciLCJzQ3VzdG9tVmFsaWRhdGlvbkZ1bmN0aW9uIiwiY3VzdG9tVmFsaWRhdGlvbkZ1bmN0aW9uIiwic01vZHVsZSIsInN1YnN0cmluZyIsImxhc3RJbmRleE9mIiwicmVwbGFjZSIsInNGdW5jdGlvbk5hbWUiLCJsZW5ndGgiLCJtRGF0YSIsImRhdGEiLCJGUE1IZWxwZXIiLCJ2YWxpZGF0aW9uV3JhcHBlciIsIlByb21pc2UiLCJyZXNvbHZlIiwiY3JlYXRlRG9jdW1lbnQiLCJvTWFpbkxpc3RCaW5kaW5nIiwibUluUGFyYW1ldGVycyIsIm9SZXNvdXJjZUJ1bmRsZSIsIm1lc3NhZ2VIYW5kbGVyIiwiYkZyb21Db3B5UGFzdGUiLCJ0aGF0Iiwib01vZGVsIiwib01ldGFNb2RlbCIsInNNZXRhUGF0aCIsImdldE1ldGFQYXRoIiwiZ2V0SGVhZGVyQ29udGV4dCIsInNDcmVhdGVIYXNoIiwiX2dldEFwcENvbXBvbmVudCIsImdldFJvdXRlclByb3h5IiwiZ2V0SGFzaCIsIm9Db21wb25lbnREYXRhIiwiZ2V0Q29tcG9uZW50RGF0YSIsIm9TdGFydHVwUGFyYW1ldGVycyIsInN0YXJ0dXBQYXJhbWV0ZXJzIiwic05ld0FjdGlvbiIsIl9nZXROZXdBY3Rpb24iLCJ1bmRlZmluZWQiLCJvQ3JlYXRpb25Qcm9taXNlIiwibUJpbmRpbmdQYXJhbWV0ZXJzIiwic01lc3NhZ2VzUGF0aCIsImdldE9iamVjdCIsInNCdXN5UGF0aCIsImdldFRhcmdldEVudGl0eVNldCIsImdldENvbnRleHQiLCJiRnVuY3Rpb25Pbk5hdlByb3AiLCJvTmV3RG9jdW1lbnRDb250ZXh0IiwicmVqZWN0IiwiYnVzeU1vZGUiLCJzSWQiLCJiZWZvcmVDcmVhdGVDYWxsQmFjayIsIkJ1c3lMb2NrZXIiLCJsb2NrIiwib1Jlc291cmNlQnVuZGxlQ29yZSIsIkNvcmUiLCJnZXRMaWJyYXJ5UmVzb3VyY2VCdW5kbGUiLCJjYWxsQWN0aW9uIiwiY29udGV4dHMiLCJzaG93QWN0aW9uUGFyYW1ldGVyRGlhbG9nIiwibGFiZWwiLCJfZ2V0U3BlY2lmaWNDcmVhdGVBY3Rpb25EaWFsb2dMYWJlbCIsImJpbmRpbmdQYXJhbWV0ZXJzIiwicGFyZW50Q29udHJvbCIsImJJc0NyZWF0ZUFjdGlvbiIsImJJc05ld1BhZ2VDcmVhdGlvbiIsImNyZWF0aW9uTW9kZSIsIkNyZWF0aW9uUm93IiwiSW5saW5lIiwiYU5vbkNvbXB1dGVkVmlzaWJsZUtleUZpZWxkcyIsIkNvbW1vblV0aWxzIiwiZ2V0Tm9uQ29tcHV0ZWRWaXNpYmxlRmllbGRzIiwic0Z1bmN0aW9uUGF0aCIsIm9GdW5jdGlvbkNvbnRleHQiLCJvRnVuY3Rpb24iLCJjcmVhdGVCaW5kaW5nQ29udGV4dCIsIiRJc0JvdW5kIiwib3BlcmF0aW9ucyIsImNhbGxCb3VuZEZ1bmN0aW9uIiwiY2FsbEZ1bmN0aW9uSW1wb3J0IiwidGhlbiIsImNhdGNoIiwib0Vycm9yIiwiTG9nIiwiZXJyb3IiLCJvRGF0YSIsIk9iamVjdCIsImFzc2lnbiIsIm9UcmFuc2llbnRMaXN0QmluZGluZyIsImJpbmRMaXN0IiwiJCR1cGRhdGVHcm91cElkIiwicmVmcmVzaEludGVybmFsIiwiY3JlYXRlIiwiX2xhdW5jaERpYWxvZ1dpdGhLZXlGaWVsZHMiLCJvbkJlZm9yZUNyZWF0ZVByb21pc2UiLCJjb250ZXh0UGF0aCIsImNyZWF0ZUF0RW5kIiwib25BZnRlckNyZWF0ZUNvbXBsZXRpb24iLCJvUmVzdWx0IiwicmVzcG9uc2UiLCJiQ29uc2lkZXJEb2N1bWVudE1vZGlmaWVkIiwiaGFuZGxlRG9jdW1lbnRNb2RpZmljYXRpb25zIiwic2hvd01lc3NhZ2VEaWFsb2ciLCJiRGVsZXRlVHJhbnNpZW50Q29udGV4dCIsImlzVHJhbnNpZW50IiwiZGVsZXRlIiwiZmluYWxseSIsInVubG9jayIsImZpbmRBY3RpdmVEcmFmdFJvb3RDb250ZXh0cyIsImFDb250ZXh0cyIsImJGaW5kQWN0aXZlQ29udGV4dHMiLCJhY3RpdmVDb250ZXh0cyIsInJlZHVjZSIsImFSZXN1bHQiLCJiSXNBY3RpdmVFbnRpdHkiLCJJc0FjdGl2ZUVudGl0eSIsImJIYXNBY3RpdmVFbnRpdHkiLCJIYXNBY3RpdmVFbnRpdHkiLCJvQWN0aXZlQ29udGV4dCIsImJpbmRDb250ZXh0IiwiZ2V0Qm91bmRDb250ZXh0IiwicHVzaCIsImFsbCIsIm1hcCIsInJlcXVlc3RDYW5vbmljYWxQYXRoIiwiYWZ0ZXJEZWxldGVQcm9jZXNzIiwiY2hlY2tCb3giLCJvSW50ZXJuYWxNb2RlbENvbnRleHQiLCJpbnRlcm5hbE1vZGVsQ29udGV4dCIsImdldFByb3BlcnR5IiwiaXNDaGVja0JveFZpc2libGUiLCJpc0NoZWNrQm94U2VsZWN0ZWQiLCJzZXRQcm9wZXJ0eSIsIm9iaiIsInNlbGVjdGVkQ29udGV4dHMiLCJmaWx0ZXIiLCJlbGVtZW50IiwiZGVsZXRhYmxlQ29udGV4dHMiLCJpbmRleE9mIiwibnVtYmVyT2ZTZWxlY3RlZENvbnRleHRzIiwiTWVzc2FnZVRvYXN0Iiwic2hvdyIsImdldFRyYW5zbGF0ZWRUZXh0IiwiZW50aXR5U2V0TmFtZSIsImRlbGV0ZURvY3VtZW50IiwidkNvbnRleHRzIiwiZm5SZWplY3QiLCJmblJlc29sdmUiLCJhRGVsZXRhYmxlQ29udGV4dHMiLCJpc0xvY2tlZFRleHRWaXNpYmxlIiwiY2Fubm90QmVEZWxldGVkVGV4dFZpc2libGUiLCJiRGlhbG9nQ29uZmlybWVkIiwiYVBhcmFtcyIsIm9EZWxldGVNZXNzYWdlIiwidGl0bGUiLCJnZXRUZXh0IiwiQXJyYXkiLCJpc0FycmF5IiwiaSIsIm9Db250ZXh0RGF0YSIsIkhhc0RyYWZ0RW50aXR5IiwiRHJhZnRBZG1pbmlzdHJhdGl2ZURhdGEiLCJJblByb2Nlc3NCeVVzZXIiLCJEcmFmdElzQ3JlYXRlZEJ5TWUiLCJNZXNzYWdlQm94Iiwib25DbG9zZSIsImRlc2NyaXB0aW9uIiwidGV4dCIsInVuU2F2ZWRDb250ZXh0cyIsImRyYWZ0QWRtaW5EYXRhIiwic0xhc3RDaGFuZ2VkQnlVc2VyIiwiY29uY2F0IiwibG9ja2VkQ29udGV4dHMiLCJub25EZWxldGFibGVUZXh0IiwiY2hlY2tCb3hUZXh0Iiwib05vbkRlbGV0YWJsZU1lc3NhZ2VUZXh0Q29udHJvbCIsIm9EZWxldGVNZXNzYWdlVGV4dENvbnRyb2wiLCJvQ29udGVudCIsIlZCb3giLCJpdGVtcyIsIlRleHQiLCJ2aXNpYmxlIiwiQ2hlY2tCb3giLCJzZWxlY3RlZCIsInNlbGVjdCIsIm9FdmVudCIsImdldFNvdXJjZSIsImdldFNlbGVjdGVkIiwic1RpdGxlIiwiZm5Db25maXJtIiwib25CZWZvcmVEZWxldGVQcm9taXNlIiwiYmVmb3JlRGVsZXRlQ2FsbEJhY2siLCJiaW5kIiwiZHJhZnQiLCJkZWxldGVEcmFmdCIsInNob3dNZXNzYWdlcyIsIm9EaWFsb2ciLCJEaWFsb2ciLCJzdGF0ZSIsImNvbnRlbnQiLCJhcmlhTGFiZWxsZWRCeSIsImdldFZpc2libGUiLCJiZWdpbkJ1dHRvbiIsIkJ1dHRvbiIsInR5cGUiLCJwcmVzcyIsImNsb3NlIiwiZW5kQnV0dG9uIiwiYWZ0ZXJDbG9zZSIsImRlc3Ryb3kiLCJub0RpYWxvZyIsImFkZFN0eWxlQ2xhc3MiLCJvcGVuIiwid2FybmluZyIsImVkaXREb2N1bWVudCIsIm9FZGl0UHJvbWlzZSIsIkVycm9yIiwicmVtb3ZlVHJhbnNpdGlvbk1lc3NhZ2VzIiwiY3JlYXRlRHJhZnRGcm9tQWN0aXZlRG9jdW1lbnQiLCJiUHJlc2VydmVDaGFuZ2VzIiwic3RpY2t5IiwiZWRpdERvY3VtZW50SW5TdGlja3lTZXNzaW9uIiwib05ld0NvbnRleHQiLCJlcnIiLCJjYW5jZWxEb2N1bWVudCIsIm9QYXJhbXNDb250ZXh0Iiwib0NhbmNlbEJ1dHRvbiIsImNhbmNlbEJ1dHRvbiIsIm9uQmVmb3JlQ2FuY2VsUHJvbWlzZSIsInNDYW5vbmljYWxQYXRoIiwic1BNb2RlbCIsImRyYWZ0RGF0YUNvbnRleHQiLCJyZXF1ZXN0T2JqZWN0IiwiQ3JlYXRpb25EYXRlVGltZSIsIkxhc3RDaGFuZ2VEYXRlVGltZSIsInNraXBEaXNjYXJkUG9wb3ZlciIsIl9zaG93RGlzY2FyZFBvcG92ZXIiLCJiZWZvcmVDYW5jZWxDYWxsQmFjayIsImNvbnRleHQiLCJvRGVsZXRlUHJvbWlzZSIsImhhc1BlbmRpbmdDaGFuZ2VzIiwiZ2V0QmluZGluZyIsInJlc2V0Q2hhbmdlcyIsImRpc2NhcmREb2N1bWVudCIsInJlZnJlc2giLCJzYXZlRG9jdW1lbnQiLCJiRXhlY3V0ZVNpZGVFZmZlY3RzT25FcnJvciIsImFCaW5kaW5ncyIsIm9TYXZlUHJvbWlzZSIsImFjdGl2YXRlRG9jdW1lbnQiLCJvQWN0aXZlRG9jdW1lbnQiLCJiTmV3T2JqZWN0IiwiZm9yRWFjaCIsIm9MaXN0QmluZGluZyIsImhhc1RyYW5zaWVudENvbnRleHQiLCJnZXRTaWRlRWZmZWN0c1NlcnZpY2UiLCJyZXF1ZXN0U2lkZUVmZmVjdHNGb3JOYXZpZ2F0aW9uUHJvcGVydHkiLCJzQWN0aW9uTmFtZSIsIm9Qcm9taXNlIiwic05hbWUiLCJzcGxpdCIsIm1vZGVsIiwibVNpZGVFZmZlY3RzUGFyYW1ldGVycyIsImdldE9EYXRhQWN0aW9uU2lkZUVmZmVjdHMiLCJvQXBwbGljYWJsZUNvbnRleHREaWFsb2ciLCJvQ29udHJvbGxlciIsIm9uQ29udGludWUiLCJhcHBsaWNhYmxlQ29udGV4dCIsImZuT3BlbkFuZEZpbGxEaWFsb2ciLCJvRGlhbG9nQ29udGVudCIsIm5Ob3RBcHBsaWNhYmxlIiwibm90QXBwbGljYWJsZUNvbnRleHQiLCJhTm90QXBwbGljYWJsZUl0ZW1zIiwib05vdEFwcGxpY2FibGVJdGVtc01vZGVsIiwiSlNPTk1vZGVsIiwib1RvdGFscyIsInRvdGFsIiwic2V0TW9kZWwiLCJzRnJhZ21lbnROYW1lIiwib0RpYWxvZ0ZyYWdtZW50IiwiWE1MVGVtcGxhdGVQcm9jZXNzb3IiLCJsb2FkVGVtcGxhdGUiLCJnZXRDYW5vbmljYWxQYXRoIiwic0VudGl0eVNldCIsInN1YnN0ciIsIm9EaWFsb2dMYWJlbE1vZGVsIiwiWE1MUHJlcHJvY2Vzc29yIiwicHJvY2VzcyIsIm5hbWUiLCJiaW5kaW5nQ29udGV4dHMiLCJlbnRpdHlUeXBlIiwibW9kZWxzIiwibWV0YU1vZGVsIiwib0ZyYWdtZW50IiwiRnJhZ21lbnQiLCJsb2FkIiwiZGVmaW5pdGlvbiIsImNvbnRyb2xsZXIiLCJvUG9wb3ZlciIsImFkZERlcGVuZGVudCIsImNvbnRleHRUb1Byb2Nlc3MiLCJjYWxsQm91bmRBY3Rpb24iLCJpbnZvY2F0aW9uR3JvdXBpbmciLCJhZGRpdGlvbmFsU2lkZUVmZmVjdCIsIm9uU3VibWl0dGVkIiwib25SZXNwb25zZSIsIm9wZXJhdGlvbkF2YWlsYWJsZU1hcCIsImJHZXRCb3VuZENvbnRleHQiLCJiT2JqZWN0UGFnZSIsImRlZmF1bHRWYWx1ZXNFeHRlbnNpb25GdW5jdGlvbiIsImNhbGxBY3Rpb25JbXBvcnQiLCJfaGFuZGxlQWN0aW9uUmVzcG9uc2UiLCJhVHJhbnNpZW50TWVzc2FnZXMiLCJtZXNzYWdlSGFuZGxpbmciLCJnZXRNZXNzYWdlcyIsImhhbmRsZVZhbGlkYXRpb25FcnJvciIsIm9NZXNzYWdlTWFuYWdlciIsImdldE1lc3NhZ2VNYW5hZ2VyIiwiZXJyb3JUb1JlbW92ZSIsImdldE1lc3NhZ2VNb2RlbCIsImdldERhdGEiLCJ2YWxpZGF0aW9uIiwicmVtb3ZlTWVzc2FnZXMiLCJiSXNNb2RpZmllZCIsImZuT25BZnRlckRpc2NhcmQiLCJzZXRFbmFibGVkIiwiX29Qb3BvdmVyIiwiZGV0YWNoQWZ0ZXJDbG9zZSIsIm9UZXh0Iiwib0J1dHRvbiIsIndpZHRoIiwiUG9wb3ZlciIsInNob3dIZWFkZXIiLCJwbGFjZW1lbnQiLCJiZWZvcmVPcGVuIiwic2V0SW5pdGlhbEZvY3VzIiwiYXR0YWNoQWZ0ZXJDbG9zZSIsIm9wZW5CeSIsIl9vbkZpZWxkQ2hhbmdlIiwib0NyZWF0ZUJ1dHRvbiIsImZuVmFsaWRhdGVSZXF1aXJlZFByb3BlcnRpZXMiLCJvRmllbGQiLCJvRmllbGRQcm9taXNlIiwiZ2V0UGFyYW1ldGVyIiwidmFsdWUiLCJzZXRWYWx1ZSIsImdldFZhbHVlIiwib1RyYW5zaWVudENvbnRleHQiLCJtRmllbGRzIiwib1BhcmVudENvbnRyb2wiLCJiU3VjY2VzcyIsImdldENvbnRyb2xsZXIiLCJhSW1tdXRhYmxlRmllbGRzIiwib0VudGl0eVNldENvbnRleHQiLCJvSW1tdXRhYmxlQ3R4TW9kZWwiLCJvSW1tdXRhYmxlQ3R4IiwiZW50aXR5U2V0IiwiZmllbGRzIiwiYUZvcm1FbGVtZW50cyIsIm1GaWVsZFZhbHVlTWFwIiwidmFsaWRhdGVSZXF1aXJlZFByb3BlcnRpZXMiLCJvRm9ybUVsZW1lbnQiLCJnZXRGaWVsZHMiLCJnZXRSZXF1aXJlZCIsImdldFZhbHVlU3RhdGUiLCJzRmllbGRJZCIsImdldElkIiwidlZhbHVlIiwiYVJlc3VsdHMiLCJldmVyeSIsImJFbmFibGVkIiwiaGFuZGxlQ2hhbmdlIiwiaGFuZGxlTGl2ZUNoYW5nZSIsImJJc0NyZWF0ZURpYWxvZyIsImtleXMiLCJzS2V5Iiwib1ZhbHVlIiwib0RpYWxvZ1ZhbHVlIiwiYVZhbHVlcyIsImNyZWF0ZVBhcmFtZXRlcnMiLCJzdWJtaXRCYXRjaCIsIm9SZXNwb25zZSIsImJLZWVwRGlhbG9nT3BlbiIsInNldEJpbmRpbmdDb250ZXh0IiwiZ2V0QmluZGluZ0NvbnRleHQiLCJuYXZpZ2F0ZUJhY2tGcm9tVHJhbnNpZW50U3RhdGUiLCJnZXRBZ2dyZWdhdGlvbiIsImdldEJlZ2luQnV0dG9uIiwic2V0VXNlckRlZmF1bHRzIiwiY3JlYXRlQWN0aW9uIiwiZm5DcmVhdGVDb21wbGV0ZWQiLCJkZXRhY2hDcmVhdGVDb21wbGV0ZWQiLCJrZWVwVHJhbnNpZW50Q29udGV4dE9uRmFpbGVkIiwiY3JlYXRlZCIsInRyYWNlIiwiYXR0YWNoQ3JlYXRlQ29tcGxldGVkIiwicHJlZmVycmVkTW9kZSIsInNQcmVmZXJyZWRNb2RlIiwiZm5HZXRMYWJlbEZyb21MaW5lSXRlbUFubm90YXRpb24iLCJpTGluZUl0ZW1JbmRleCIsImZpbmRJbmRleCIsIm9MaW5lSXRlbSIsImFMaW5lSXRlbUFjdGlvbiIsIkFjdGlvbiIsIkxhYmVsIl0sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBOzs7O0FBNkJBLE1BQU1BLFlBQVksR0FBR0MsU0FBUyxDQUFDRCxZQUEvQjtBQUNBLE1BQU1FLGdCQUFnQixHQUFHRCxTQUFTLENBQUNDLGdCQUFuQztBQUNBLE1BQU1DLFVBQVUsR0FBR0MsV0FBVyxDQUFDRCxVQUEvQjtBQUNBOztBQUNBLFdBQVNFLGFBQVQsQ0FBdUJDLFdBQXZCLEVBQXlDO0FBQ3hDLFFBQUlBLFdBQVcsSUFBSUEsV0FBVyxDQUFDQyxXQUEzQixJQUEwQ0QsV0FBVyxDQUFDQyxXQUFaLEdBQTBCQyxPQUExQixPQUF3QyxtQkFBdEYsRUFBMkc7QUFDMUdGLE1BQUFBLFdBQVcsR0FBRyxFQUFkO0FBQ0E7O0FBQ0QsV0FBT0EsV0FBVyxJQUFJLEVBQXRCO0FBQ0E7O01BRUtHLGlCO0FBUUwsK0JBQVlDLGFB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QXVCOVcsVUFBMUIsR0FBdUMsS0FBN0Q7QUFDQSxXQUxxQixDQUF2QjtBQU1BLGlCQUFPMlcsY0FBYyxHQUFHLENBQUMsQ0FBbEIsR0FDSnZYLFVBQVUsQ0FBQ2tCLFNBQVgsQ0FBcUJqQixTQUFTLEdBQUcsdUNBQWpDLEVBQTBFc1gsY0FBMUUsRUFBMEZLLEtBRHRGLEdBRUo5VyxTQUZIO0FBR0EsU0FWRCxNQVVPO0FBQ04saUJBQU9BLFNBQVA7QUFDQTtBQUNELE9BZEQ7O0FBZ0JBLGFBQ0N3VyxnQ0FBZ0MsTUFDL0J0WCxVQUFVLElBQUlBLFVBQVUsQ0FBQ2tCLFNBQVgsQ0FBcUJqQixTQUFTLEdBQUcsR0FBWixHQUFrQlcsVUFBbEIsR0FBK0IsdUNBQXBELENBRGYsSUFFQ2tCLG1CQUFtQixJQUFJQSxtQkFBbUIsQ0FBQ3FHLE9BQXBCLENBQTRCLDBDQUE1QixDQUh6QjtBQUtBLEs7Ozs7O1NBR2FsTCxpQiIsInNvdXJjZVJvb3QiOiIuIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlc291cmNlQnVuZGxlIGZyb20gXCJzYXAvYmFzZS9pMThuL1Jlc291cmNlQnVuZGxlXCI7XG5pbXBvcnQgTG9nIGZyb20gXCJzYXAvYmFzZS9Mb2dcIjtcbmltcG9ydCBkcmFmdCBmcm9tIFwic2FwL2ZlL2NvcmUvYWN0aW9ucy9kcmFmdFwiO1xuaW1wb3J0IG1lc3NhZ2VIYW5kbGluZyBmcm9tIFwic2FwL2ZlL2NvcmUvYWN0aW9ucy9tZXNzYWdlSGFuZGxpbmdcIjtcbmltcG9ydCBvcGVyYXRpb25zIGZyb20gXCJzYXAvZmUvY29yZS9hY3Rpb25zL29wZXJhdGlvbnNcIjtcbmltcG9ydCBzdGlja3kgZnJvbSBcInNhcC9mZS9jb3JlL2FjdGlvbnMvc3RpY2t5XCI7XG5pbXBvcnQgQXBwQ29tcG9uZW50IGZyb20gXCJzYXAvZmUvY29yZS9BcHBDb21wb25lbnRcIjtcbmltcG9ydCBCdXN5TG9ja2VyIGZyb20gXCJzYXAvZmUvY29yZS9CdXN5TG9ja2VyXCI7XG5pbXBvcnQgQ29tbW9uVXRpbHMgZnJvbSBcInNhcC9mZS9jb3JlL0NvbW1vblV0aWxzXCI7XG5pbXBvcnQgRlBNSGVscGVyIGZyb20gXCJzYXAvZmUvY29yZS9oZWxwZXJzL0ZQTUhlbHBlclwiO1xuaW1wb3J0IE1vZGVsSGVscGVyLCB7IEludGVybmFsTW9kZWxDb250ZXh0IH0gZnJvbSBcInNhcC9mZS9jb3JlL2hlbHBlcnMvTW9kZWxIZWxwZXJcIjtcbmltcG9ydCBGRUxpYnJhcnkgZnJvbSBcInNhcC9mZS9jb3JlL2xpYnJhcnlcIjtcbmltcG9ydCBCdXR0b24gZnJvbSBcInNhcC9tL0J1dHRvblwiO1xuaW1wb3J0IENoZWNrQm94IGZyb20gXCJzYXAvbS9DaGVja0JveFwiO1xuaW1wb3J0IERpYWxvZyBmcm9tIFwic2FwL20vRGlhbG9nXCI7XG5pbXBvcnQgTWVzc2FnZUJveCBmcm9tIFwic2FwL20vTWVzc2FnZUJveFwiO1xuaW1wb3J0IE1lc3NhZ2VUb2FzdCBmcm9tIFwic2FwL20vTWVzc2FnZVRvYXN0XCI7XG5pbXBvcnQgUG9wb3ZlciBmcm9tIFwic2FwL20vUG9wb3ZlclwiO1xuaW1wb3J0IFRleHQgZnJvbSBcInNhcC9tL1RleHRcIjtcbmltcG9ydCBWQm94IGZyb20gXCJzYXAvbS9WQm94XCI7XG5pbXBvcnQgQ29yZSBmcm9tIFwic2FwL3VpL2NvcmUvQ29yZVwiO1xuaW1wb3J0IEZyYWdtZW50IGZyb20gXCJzYXAvdWkvY29yZS9GcmFnbWVudFwiO1xuaW1wb3J0IGNvcmVMaWJyYXJ5IGZyb20gXCJzYXAvdWkvY29yZS9saWJyYXJ5XCI7XG5pbXBvcnQgVmlldyBmcm9tIFwic2FwL3VpL2NvcmUvbXZjL1ZpZXdcIjtcbmltcG9ydCBYTUxQcmVwcm9jZXNzb3IgZnJvbSBcInNhcC91aS9jb3JlL3V0aWwvWE1MUHJlcHJvY2Vzc29yXCI7XG5pbXBvcnQgWE1MVGVtcGxhdGVQcm9jZXNzb3IgZnJvbSBcInNhcC91aS9jb3JlL1hNTFRlbXBsYXRlUHJvY2Vzc29yXCI7XG5pbXBvcnQgQ29udGV4dCBmcm9tIFwic2FwL3VpL21vZGVsL0NvbnRleHRcIjtcbmltcG9ydCBKU09OTW9kZWwgZnJvbSBcInNhcC91aS9tb2RlbC9qc29uL0pTT05Nb2RlbFwiO1xuaW1wb3J0IE9EYXRhTWV0YU1vZGVsIGZyb20gXCJzYXAvdWkvbW9kZWwvb2RhdGEvdjQvT0RhdGFNZXRhTW9kZWxcIjtcbmltcG9ydCB7IENvcmVFeCB9IGZyb20gXCJ0eXBlcy9leHRlbnNpb25fdHlwZXNcIjtcblxuY29uc3QgQ3JlYXRpb25Nb2RlID0gRkVMaWJyYXJ5LkNyZWF0aW9uTW9kZTtcbmNvbnN0IFByb2dyYW1taW5nTW9kZWwgPSBGRUxpYnJhcnkuUHJvZ3JhbW1pbmdNb2RlbDtcbmNvbnN0IFZhbHVlU3RhdGUgPSBjb3JlTGlicmFyeS5WYWx1ZVN0YXRlO1xuLyogTWFrZSBzdXJlIHRoYXQgdGhlIG1QYXJhbWV0ZXJzIGlzIG5vdCB0aGUgb0V2ZW50ICovXG5mdW5jdGlvbiBnZXRQYXJhbWV0ZXJzKG1QYXJhbWV0ZXJzOiBhbnkpIHtcblx0aWYgKG1QYXJhbWV0ZXJzICYmIG1QYXJhbWV0ZXJzLmdldE1ldGFkYXRhICYmIG1QYXJhbWV0ZXJzLmdldE1ldGFkYXRhKCkuZ2V0TmFtZSgpID09PSBcInNhcC51aS5iYXNlLkV2ZW50XCIpIHtcblx0XHRtUGFyYW1ldGVycyA9IHt9O1xuXHR9XG5cdHJldHVybiBtUGFyYW1ldGVycyB8fCB7fTtcbn1cblxuY2xhc3MgVHJhbnNhY3Rpb25IZWxwZXIge1xuXHRfb0FwcENvbXBvbmVudDogQXBwQ29tcG9uZW50O1xuXHRvTG9ja09iamVjdDogYW55O1xuXHRzUHJvZ3JhbW1pbmdNb2RlbD86IHR5cGVvZiBQcm9ncmFtbWluZ01vZGVsO1xuXHRfYklzTW9kaWZpZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblx0X2JDcmVhdGVNb2RlOiBib29sZWFuID0gZmFsc2U7XG5cdF9iQ29udGludWVEaXNjYXJkOiBib29sZWFuID0gZmFsc2U7XG5cdF9vUG9wb3ZlciE6IFBvcG92ZXI7XG5cdGNvbnN0cnVjdG9yKG9BcHBDb21wb25lbnQ6IEFwcENvbXBvbmVudCwgb0xvY2tPYmplY3Q6IGFueSkge1xuXHRcdHRoaXMuX29BcHBDb21wb25lbnQgPSBvQXBwQ29tcG9uZW50O1xuXHRcdHRoaXMub0xvY2tPYmplY3QgPSBvTG9ja09iamVjdDtcblx0fVxuXHRnZXRQcm9ncmFtbWluZ01vZGVsKG9Db250ZXh0PzogYW55KTogdHlwZW9mIFByb2dyYW1taW5nTW9kZWwge1xuXHRcdGlmICghdGhpcy5zUHJvZ3JhbW1pbmdNb2RlbCAmJiBvQ29udGV4dCkge1xuXHRcdFx0bGV0IHNQYXRoO1xuXHRcdFx0aWYgKG9Db250ZXh0LmlzQShcInNhcC51aS5tb2RlbC5vZGF0YS52NC5Db250ZXh0XCIpKSB7XG5cdFx0XHRcdHNQYXRoID0gb0NvbnRleHQuZ2V0UGF0aCgpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0c1BhdGggPSBvQ29udGV4dC5pc1JlbGF0aXZlKCkgPyBvQ29udGV4dC5nZXRSZXNvbHZlZFBhdGgoKSA6IG9Db250ZXh0LmdldFBhdGgoKTtcblx0XHRcdH1cblx0XHRcdGlmIChNb2RlbEhlbHBlci5pc0RyYWZ0U3VwcG9ydGVkKG9Db250ZXh0LmdldE1vZGVsKCkuZ2V0TWV0YU1vZGVsKCksIHNQYXRoKSkge1xuXHRcdFx0XHR0aGlzLnNQcm9ncmFtbWluZ01vZGVsID0gUHJvZ3JhbW1pbmdNb2RlbC5EcmFmdDtcblx0XHRcdH0gZWxzZSBpZiAoTW9kZWxIZWxwZXIuaXNTdGlja3lTZXNzaW9uU3VwcG9ydGVkKG9Db250ZXh0LmdldE1vZGVsKCkuZ2V0TWV0YU1vZGVsKCkpKSB7XG5cdFx0XHRcdHRoaXMuc1Byb2dyYW1taW5nTW9kZWwgPSBQcm9ncmFtbWluZ01vZGVsLlN0aWNreTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIGFzIHRoZSB0cmFuc2FjdGlvbiBoZWxwZXIgaXMgYSBzaW5nbGV0b24gd2UgZG9uJ3Qgc3RvcmUgdGhlIG5vbiBkcmFmdCBhcyB0aGUgdXNlciBjb3VsZFxuXHRcdFx0XHQvLyBzdGFydCB3aXRoIGEgbm9uIGRyYWZ0IGNoaWxkIHBhZ2UgYW5kIG5hdmlnYXRlcyBiYWNrIHRvIGEgZHJhZnQgZW5hYmxlZCBvbmVcblx0XHRcdFx0cmV0dXJuIFByb2dyYW1taW5nTW9kZWwuTm9uRHJhZnQ7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLnNQcm9ncmFtbWluZ01vZGVsIGFzIHR5cGVvZiBQcm9ncmFtbWluZ01vZGVsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFZhbGlkYXRlcyBhIGRvY3VtZW50LlxuXHQgKlxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXJcblx0ICogQHN0YXRpY1xuXHQgKiBAcGFyYW0ge3NhcC51aS5tb2RlbC5vZGF0YS52NC5Db250ZXh0fSBvQ29udGV4dCBDb250ZXh0IG9mIHRoZSBkb2N1bWVudCB0byBiZSB2YWxpZGF0ZWRcblx0ICogQHBhcmFtIHtvYmplY3R9IFttUGFyYW1ldGVyc10gQ2FuIGNvbnRhaW4gdGhlIGZvbGxvd2luZyBhdHRyaWJ1dGVzOlxuXHQgKiAqIEBwYXJhbSB7b2JqZWN0fSBbbVBhcmFtZXRlcnMuZGF0YV0gQSBtYXAgb2YgZGF0YSB0aGF0IHNob3VsZCBiZSB2YWxpZGF0ZWRcblx0ICogKiBAcGFyYW0ge3N0cmluZ30gW21QYXJhbWV0ZXJzLmN1c3RvbVZhbGlkYXRpb25GdW5jdGlvbl0gQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBwYXRoIHRvIHRoZSB2YWxpZGF0aW9uIGZ1bmN0aW9uXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvVmlldyBDb250YWlucyB0aGUgb2JqZWN0IG9mIHRoZSBjdXJyZW50IHZpZXdcblx0ICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgcmVzb2x2ZXMgd2l0aCByZXN1bHQgb2YgdGhlIGN1c3RvbSB2YWxpZGF0aW9uIGZ1bmN0aW9uXG5cdCAqIEB1aTUtcmVzdHJpY3RlZFxuXHQgKiBAZmluYWxcblx0ICovXG5cdHZhbGlkYXRlRG9jdW1lbnQob0NvbnRleHQ6IGFueSwgbVBhcmFtZXRlcnM6IGFueSwgb1ZpZXc6IFZpZXcpOiBQcm9taXNlPGFueT4ge1xuXHRcdGNvbnN0IHNDdXN0b21WYWxpZGF0aW9uRnVuY3Rpb24gPSBtUGFyYW1ldGVycyAmJiBtUGFyYW1ldGVycy5jdXN0b21WYWxpZGF0aW9uRnVuY3Rpb247XG5cdFx0aWYgKHNDdXN0b21WYWxpZGF0aW9uRnVuY3Rpb24pIHtcblx0XHRcdGNvbnN0IHNNb2R1bGUgPSBzQ3VzdG9tVmFsaWRhdGlvbkZ1bmN0aW9uLnN1YnN0cmluZygwLCBzQ3VzdG9tVmFsaWRhdGlvbkZ1bmN0aW9uLmxhc3RJbmRleE9mKFwiLlwiKSB8fCAtMSkucmVwbGFjZSgvXFwuL2dpLCBcIi9cIiksXG5cdFx0XHRcdHNGdW5jdGlvbk5hbWUgPSBzQ3VzdG9tVmFsaWRhdGlvbkZ1bmN0aW9uLnN1YnN0cmluZyhcblx0XHRcdFx0XHRzQ3VzdG9tVmFsaWRhdGlvbkZ1bmN0aW9uLmxhc3RJbmRleE9mKFwiLlwiKSArIDEsXG5cdFx0XHRcdFx0c0N1c3RvbVZhbGlkYXRpb25GdW5jdGlvbi5sZW5ndGhcblx0XHRcdFx0KSxcblx0XHRcdFx0bURhdGEgPSBtUGFyYW1ldGVycy5kYXRhO1xuXHRcdFx0ZGVsZXRlIG1EYXRhW1wiQCR1aTUuY29udGV4dC5pc1RyYW5zaWVudFwiXTtcblx0XHRcdHJldHVybiBGUE1IZWxwZXIudmFsaWRhdGlvbldyYXBwZXIoc01vZHVsZSwgc0Z1bmN0aW9uTmFtZSwgbURhdGEsIG9WaWV3LCBvQ29udGV4dCk7XG5cdFx0fVxuXHRcdHJldHVybiBQcm9taXNlLnJlc29sdmUoW10pO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgZG9jdW1lbnQuXG5cdCAqXG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5UcmFuc2FjdGlvbkhlbHBlclxuXHQgKiBAc3RhdGljXG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0Lk9EYXRhTGlzdEJpbmRpbmd9IG9NYWluTGlzdEJpbmRpbmcgT0RhdGEgVjQgTGlzdEJpbmRpbmcgb2JqZWN0XG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBbbUluUGFyYW1ldGVyc10gT3B0aW9uYWwsIGNhbiBjb250YWluIHRoZSBmb2xsb3dpbmcgYXR0cmlidXRlczpcblx0ICogQHBhcmFtIHttYXB9IFttSW5QYXJhbWV0ZXJzLmRhdGFdIEEgbWFwIG9mIGRhdGEgdGhhdCBzaG91bGQgYmUgc2VudCB3aXRoaW4gdGhlIFBPU1Rcblx0ICogQHBhcmFtIHtzdHJpbmd9IFttSW5QYXJhbWV0ZXJzLmJ1c3lNb2RlXSBHbG9iYWwgKGRlZmF1bHQpLCBMb2NhbCwgTm9uZSBUT0RPOiB0byBiZSByZWZhY3RvcmVkXG5cdCAqIEBwYXJhbSB7bWFwfSBbbUluUGFyYW1ldGVycy5rZWVwVHJhbnNpZW50Q29udGV4dE9uRmFpbGVkXSBJZiBzZXQsIHRoZSBjb250ZXh0IHN0YXlzIGluIHRoZSBsaXN0IGlmIHRoZSBQT1NUIGZhaWxlZCBhbmQgUE9TVCB3aWxsIGJlIHJlcGVhdGVkIHdpdGggdGhlIG5leHQgY2hhbmdlXG5cdCAqIEBwYXJhbSBvUmVzb3VyY2VCdW5kbGVcblx0ICogQHBhcmFtIG1lc3NhZ2VIYW5kbGVyXG5cdCAqIEBwYXJhbSBiRnJvbUNvcHlQYXN0ZVxuXHQgKiBAcGFyYW0gb1ZpZXcgVGhlIGN1cnJlbnQgdmlld1xuXHQgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSByZXNvbHZlcyB3aXRoIG5ldyBiaW5kaW5nIGNvbnRleHRcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKi9cblx0Y3JlYXRlRG9jdW1lbnQoXG5cdFx0b01haW5MaXN0QmluZGluZzogYW55LFxuXHRcdG1JblBhcmFtZXRlcnM6IHsgZGF0YT86IGFueTsgYnVzeU1vZGU/OiBzdHJpbmcgfCB1bmRlZmluZWQ7IGtlZXBUcmFuc2llbnRDb250ZXh0T25GYWlsZWQ/OiBhbnkgfSB8IHVuZGVmaW5lZCxcblx0XHRvUmVzb3VyY2VCdW5kbGU6IGFueSxcblx0XHRtZXNzYWdlSGFuZGxlcjogYW55LFxuXHRcdGJGcm9tQ29weVBhc3RlOiBib29sZWFuID0gZmFsc2UsXG5cdFx0b1ZpZXc6IGFueVxuXHQpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXNcblx0XHRjb25zdCB0aGF0ID0gdGhpcyxcblx0XHRcdG9Nb2RlbCA9IG9NYWluTGlzdEJpbmRpbmcuZ2V0TW9kZWwoKSxcblx0XHRcdG9NZXRhTW9kZWwgPSBvTW9kZWwuZ2V0TWV0YU1vZGVsKCksXG5cdFx0XHRzTWV0YVBhdGggPSBvTWV0YU1vZGVsLmdldE1ldGFQYXRoKG9NYWluTGlzdEJpbmRpbmcuZ2V0SGVhZGVyQ29udGV4dCgpLmdldFBhdGgoKSksXG5cdFx0XHRzQ3JlYXRlSGFzaCA9IHRoaXMuX2dldEFwcENvbXBvbmVudCgpLmdldFJvdXRlclByb3h5KCkuZ2V0SGFzaCgpLFxuXHRcdFx0b0NvbXBvbmVudERhdGEgPSB0aGlzLl9nZXRBcHBDb21wb25lbnQoKS5nZXRDb21wb25lbnREYXRhKCksXG5cdFx0XHRvU3RhcnR1cFBhcmFtZXRlcnMgPSAob0NvbXBvbmVudERhdGEgJiYgb0NvbXBvbmVudERhdGEuc3RhcnR1cFBhcmFtZXRlcnMpIHx8IHt9LFxuXHRcdFx0c05ld0FjdGlvbiA9ICFvTWFpbkxpc3RCaW5kaW5nLmlzUmVsYXRpdmUoKVxuXHRcdFx0XHQ/IHRoaXMuX2dldE5ld0FjdGlvbihvU3RhcnR1cFBhcmFtZXRlcnMsIHNDcmVhdGVIYXNoLCBvTWV0YU1vZGVsLCBzTWV0YVBhdGgpXG5cdFx0XHRcdDogdW5kZWZpbmVkO1xuXHRcdGxldCBvQ3JlYXRpb25Qcm9taXNlO1xuXHRcdGNvbnN0IG1CaW5kaW5nUGFyYW1ldGVyczogYW55ID0geyBcIiQkcGF0Y2hXaXRob3V0U2lkZUVmZmVjdHNcIjogdHJ1ZSB9O1xuXHRcdGNvbnN0IHNNZXNzYWdlc1BhdGggPSBvTWV0YU1vZGVsLmdldE9iamVjdChzTWV0YVBhdGggKyBcIi9AY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLk1lc3NhZ2VzLyRQYXRoXCIpO1xuXHRcdGxldCBzQnVzeVBhdGggPSBcIi9idXN5XCI7XG5cdFx0bGV0IHNGdW5jdGlvbk5hbWUgPVxuXHRcdFx0b01ldGFNb2RlbC5nZXRPYmplY3Qoc01ldGFQYXRoICsgXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLkRlZmF1bHRWYWx1ZXNGdW5jdGlvblwiKSB8fFxuXHRcdFx0b01ldGFNb2RlbC5nZXRPYmplY3QoXG5cdFx0XHRcdE1vZGVsSGVscGVyLmdldFRhcmdldEVudGl0eVNldChvTWV0YU1vZGVsLmdldENvbnRleHQoc01ldGFQYXRoKSkgKyBcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuRGVmYXVsdFZhbHVlc0Z1bmN0aW9uXCJcblx0XHRcdCk7XG5cdFx0bGV0IGJGdW5jdGlvbk9uTmF2UHJvcDtcblx0XHRsZXQgb05ld0RvY3VtZW50Q29udGV4dDogYW55O1xuXHRcdGlmIChzRnVuY3Rpb25OYW1lKSB7XG5cdFx0XHRpZiAoXG5cdFx0XHRcdG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNNZXRhUGF0aCArIFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5EZWZhdWx0VmFsdWVzRnVuY3Rpb25cIikgJiZcblx0XHRcdFx0TW9kZWxIZWxwZXIuZ2V0VGFyZ2V0RW50aXR5U2V0KG9NZXRhTW9kZWwuZ2V0Q29udGV4dChzTWV0YVBhdGgpKSAhPT0gc01ldGFQYXRoXG5cdFx0XHQpIHtcblx0XHRcdFx0YkZ1bmN0aW9uT25OYXZQcm9wID0gdHJ1ZTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGJGdW5jdGlvbk9uTmF2UHJvcCA9IGZhbHNlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAoc01lc3NhZ2VzUGF0aCkge1xuXHRcdFx0bUJpbmRpbmdQYXJhbWV0ZXJzW1wiJHNlbGVjdFwiXSA9IHNNZXNzYWdlc1BhdGg7XG5cdFx0fVxuXHRcdGNvbnN0IG1QYXJhbWV0ZXJzID0gZ2V0UGFyYW1ldGVycyhtSW5QYXJhbWV0ZXJzKTtcblx0XHRpZiAoIW9NYWluTGlzdEJpbmRpbmcpIHtcblx0XHRcdHJldHVybiBQcm9taXNlLnJlamVjdChcIkJpbmRpbmcgcmVxdWlyZWQgZm9yIG5ldyBkb2N1bWVudCBjcmVhdGlvblwiKTtcblx0XHR9XG5cdFx0Y29uc3Qgc1Byb2dyYW1taW5nTW9kZWwgPSB0aGlzLmdldFByb2dyYW1taW5nTW9kZWwob01haW5MaXN0QmluZGluZyk7XG5cdFx0aWYgKHNQcm9ncmFtbWluZ01vZGVsICE9PSBQcm9ncmFtbWluZ01vZGVsLkRyYWZ0ICYmIHNQcm9ncmFtbWluZ01vZGVsICE9PSBQcm9ncmFtbWluZ01vZGVsLlN0aWNreSkge1xuXHRcdFx0cmV0dXJuIFByb21pc2UucmVqZWN0KFwiQ3JlYXRlIGRvY3VtZW50IG9ubHkgYWxsb3dlZCBmb3IgZHJhZnQgb3Igc3RpY2t5IHNlc3Npb24gc3VwcG9ydGVkIHNlcnZpY2VzXCIpO1xuXHRcdH1cblx0XHRpZiAobVBhcmFtZXRlcnMuYnVzeU1vZGUgPT09IFwiTG9jYWxcIikge1xuXHRcdFx0Ly8gaW4gY2FzZSBvZiBsb2NhbCBidXN5IG1vZGUgd2UgdXNlIHRoZSBsaXN0IGJpbmRpbmcgbmFtZVxuXHRcdFx0Ly8gdGhlcmUncyBubyBBUFkgeWV0IHNvIHdlIGhhdmUgdG8gdXNlIHRoZSAuc0lkIFRPRE8gcHJvdmlkZSBhIHB1YmxpYyBtZXRob2Q/XG5cdFx0XHRzQnVzeVBhdGggPSBcIi9idXN5TG9jYWwvXCIgKyBvTWFpbkxpc3RCaW5kaW5nLnNJZDtcblx0XHR9XG5cdFx0bVBhcmFtZXRlcnMuYmVmb3JlQ3JlYXRlQ2FsbEJhY2sgPSBiRnJvbUNvcHlQYXN0ZSA/IG51bGwgOiBtUGFyYW1ldGVycy5iZWZvcmVDcmVhdGVDYWxsQmFjaztcblx0XHRCdXN5TG9ja2VyLmxvY2sodGhpcy5vTG9ja09iamVjdCwgc0J1c3lQYXRoKTtcblx0XHRjb25zdCBvUmVzb3VyY2VCdW5kbGVDb3JlID0gKENvcmUgYXMgQ29yZUV4KS5nZXRMaWJyYXJ5UmVzb3VyY2VCdW5kbGUoXCJzYXAuZmUuY29yZVwiKTtcblx0XHRpZiAoc05ld0FjdGlvbikge1xuXHRcdFx0b0NyZWF0aW9uUHJvbWlzZSA9IHRoaXMuY2FsbEFjdGlvbihcblx0XHRcdFx0c05ld0FjdGlvbixcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGNvbnRleHRzOiBvTWFpbkxpc3RCaW5kaW5nLmdldEhlYWRlckNvbnRleHQoKSxcblx0XHRcdFx0XHRzaG93QWN0aW9uUGFyYW1ldGVyRGlhbG9nOiB0cnVlLFxuXHRcdFx0XHRcdGxhYmVsOiB0aGlzLl9nZXRTcGVjaWZpY0NyZWF0ZUFjdGlvbkRpYWxvZ0xhYmVsKFxuXHRcdFx0XHRcdFx0b01ldGFNb2RlbCxcblx0XHRcdFx0XHRcdHNNZXRhUGF0aCxcblx0XHRcdFx0XHRcdHNOZXdBY3Rpb24sXG5cdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGVDb3JlIGFzIFJlc291cmNlQnVuZGxlXG5cdFx0XHRcdFx0KSxcblx0XHRcdFx0XHRiaW5kaW5nUGFyYW1ldGVyczogbUJpbmRpbmdQYXJhbWV0ZXJzLFxuXHRcdFx0XHRcdHBhcmVudENvbnRyb2w6IG1QYXJhbWV0ZXJzLnBhcmVudENvbnRyb2wsXG5cdFx0XHRcdFx0YklzQ3JlYXRlQWN0aW9uOiB0cnVlXG5cdFx0XHRcdH0sXG5cdFx0XHRcdG51bGwsXG5cdFx0XHRcdG1lc3NhZ2VIYW5kbGVyXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCBiSXNOZXdQYWdlQ3JlYXRpb24gPVxuXHRcdFx0XHRtUGFyYW1ldGVycy5jcmVhdGlvbk1vZGUgIT09IENyZWF0aW9uTW9kZS5DcmVhdGlvblJvdyAmJiBtUGFyYW1ldGVycy5jcmVhdGlvbk1vZGUgIT09IENyZWF0aW9uTW9kZS5JbmxpbmU7XG5cdFx0XHRjb25zdCBhTm9uQ29tcHV0ZWRWaXNpYmxlS2V5RmllbGRzID0gYklzTmV3UGFnZUNyZWF0aW9uXG5cdFx0XHRcdD8gQ29tbW9uVXRpbHMuZ2V0Tm9uQ29tcHV0ZWRWaXNpYmxlRmllbGRzKG9NZXRhTW9kZWwsIHNNZXRhUGF0aCwgb1ZpZXcpXG5cdFx0XHRcdDogW107XG5cdFx0XHRzRnVuY3Rpb25OYW1lID0gYkZyb21Db3B5UGFzdGUgPyBudWxsIDogc0Z1bmN0aW9uTmFtZTtcblx0XHRcdGxldCBzRnVuY3Rpb25QYXRoLCBvRnVuY3Rpb25Db250ZXh0O1xuXHRcdFx0aWYgKHNGdW5jdGlvbk5hbWUpIHtcblx0XHRcdFx0Ly9ib3VuZCB0byB0aGUgc291cmNlIGVudGl0eTpcblx0XHRcdFx0aWYgKGJGdW5jdGlvbk9uTmF2UHJvcCkge1xuXHRcdFx0XHRcdHNGdW5jdGlvblBhdGggPVxuXHRcdFx0XHRcdFx0b01haW5MaXN0QmluZGluZy5nZXRDb250ZXh0KCkgJiZcblx0XHRcdFx0XHRcdG9NZXRhTW9kZWwuZ2V0TWV0YVBhdGgob01haW5MaXN0QmluZGluZy5nZXRDb250ZXh0KCkuZ2V0UGF0aCgpKSArIFwiL1wiICsgc0Z1bmN0aW9uTmFtZTtcblx0XHRcdFx0XHRvRnVuY3Rpb25Db250ZXh0ID0gb01haW5MaXN0QmluZGluZy5nZXRDb250ZXh0KCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c0Z1bmN0aW9uUGF0aCA9XG5cdFx0XHRcdFx0XHRvTWFpbkxpc3RCaW5kaW5nLmdldEhlYWRlckNvbnRleHQoKSAmJlxuXHRcdFx0XHRcdFx0b01ldGFNb2RlbC5nZXRNZXRhUGF0aChvTWFpbkxpc3RCaW5kaW5nLmdldEhlYWRlckNvbnRleHQoKS5nZXRQYXRoKCkpICsgXCIvXCIgKyBzRnVuY3Rpb25OYW1lO1xuXHRcdFx0XHRcdG9GdW5jdGlvbkNvbnRleHQgPSBvTWFpbkxpc3RCaW5kaW5nLmdldEhlYWRlckNvbnRleHQoKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Y29uc3Qgb0Z1bmN0aW9uID0gc0Z1bmN0aW9uUGF0aCAmJiBvTWV0YU1vZGVsLmNyZWF0ZUJpbmRpbmdDb250ZXh0KHNGdW5jdGlvblBhdGgpO1xuXHRcdFx0aWYgKG9GdW5jdGlvbiAmJiBvRnVuY3Rpb24uZ2V0T2JqZWN0KCkgJiYgb0Z1bmN0aW9uLmdldE9iamVjdCgpWzBdLiRJc0JvdW5kKSB7XG5cdFx0XHRcdG9DcmVhdGlvblByb21pc2UgPSBvcGVyYXRpb25zLmNhbGxCb3VuZEZ1bmN0aW9uKHNGdW5jdGlvbk5hbWUsIG9GdW5jdGlvbkNvbnRleHQsIG9Nb2RlbCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRvQ3JlYXRpb25Qcm9taXNlID0gb3BlcmF0aW9ucy5jYWxsRnVuY3Rpb25JbXBvcnQoc0Z1bmN0aW9uTmFtZSwgb01vZGVsKTtcblx0XHRcdH1cblxuXHRcdFx0b0NyZWF0aW9uUHJvbWlzZSA9IG9DcmVhdGlvblByb21pc2Vcblx0XHRcdFx0LnRoZW4oZnVuY3Rpb24gKG9Db250ZXh0OiBhbnkpIHtcblx0XHRcdFx0XHRpZiAob0NvbnRleHQpIHtcblx0XHRcdFx0XHRcdHJldHVybiBvQ29udGV4dC5nZXRPYmplY3QoKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5jYXRjaChmdW5jdGlvbiAob0Vycm9yOiBhbnkpIHtcblx0XHRcdFx0XHRMb2cuZXJyb3IoXCJFcnJvciB3aGlsZSBleGVjdXRpbmcgdGhlIGZ1bmN0aW9uIFwiICsgc0Z1bmN0aW9uTmFtZSwgb0Vycm9yKTtcblx0XHRcdFx0XHR0aHJvdyBvRXJyb3I7XG5cdFx0XHRcdH0pXG5cdFx0XHRcdC50aGVuKGZ1bmN0aW9uIChvRGF0YTogYW55KSB7XG5cdFx0XHRcdFx0bVBhcmFtZXRlcnMuZGF0YSA9IG9EYXRhID8gT2JqZWN0LmFzc2lnbih7fSwgb0RhdGEsIG1QYXJhbWV0ZXJzLmRhdGEpIDogbVBhcmFtZXRlcnMuZGF0YTtcblx0XHRcdFx0XHRpZiAobVBhcmFtZXRlcnMuZGF0YSkge1xuXHRcdFx0XHRcdFx0ZGVsZXRlIG1QYXJhbWV0ZXJzLmRhdGFbXCJAb2RhdGEuY29udGV4dFwiXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKGFOb25Db21wdXRlZFZpc2libGVLZXlGaWVsZHMubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRcdFx0Y29uc3Qgb1RyYW5zaWVudExpc3RCaW5kaW5nID0gb01vZGVsLmJpbmRMaXN0KG9NYWluTGlzdEJpbmRpbmcuZ2V0UGF0aCgpLCBvTWFpbkxpc3RCaW5kaW5nLmdldENvbnRleHQoKSwgW10sIFtdLCB7XG5cdFx0XHRcdFx0XHRcdCQkdXBkYXRlR3JvdXBJZDogXCJzdWJtaXRMYXRlclwiXG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdG9UcmFuc2llbnRMaXN0QmluZGluZy5yZWZyZXNoSW50ZXJuYWwgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHRcdC8qICovXG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0b05ld0RvY3VtZW50Q29udGV4dCA9IG9UcmFuc2llbnRMaXN0QmluZGluZy5jcmVhdGUobVBhcmFtZXRlcnMuZGF0YSwgdHJ1ZSk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdGhhdC5fbGF1bmNoRGlhbG9nV2l0aEtleUZpZWxkcyhcblx0XHRcdFx0XHRcdFx0b01haW5MaXN0QmluZGluZyxcblx0XHRcdFx0XHRcdFx0b1RyYW5zaWVudExpc3RCaW5kaW5nLFxuXHRcdFx0XHRcdFx0XHRvTmV3RG9jdW1lbnRDb250ZXh0LFxuXHRcdFx0XHRcdFx0XHRhTm9uQ29tcHV0ZWRWaXNpYmxlS2V5RmllbGRzLFxuXHRcdFx0XHRcdFx0XHRvTW9kZWwsXG5cdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLFxuXHRcdFx0XHRcdFx0XHRtZXNzYWdlSGFuZGxlclxuXHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0bGV0IG9uQmVmb3JlQ3JlYXRlUHJvbWlzZTtcblx0XHRcdFx0XHRcdGlmIChtUGFyYW1ldGVycy5iZWZvcmVDcmVhdGVDYWxsQmFjaykge1xuXHRcdFx0XHRcdFx0XHRvbkJlZm9yZUNyZWF0ZVByb21pc2UgPSBtUGFyYW1ldGVycy5iZWZvcmVDcmVhdGVDYWxsQmFjayh7XG5cdFx0XHRcdFx0XHRcdFx0Y29udGV4dFBhdGg6IG9NYWluTGlzdEJpbmRpbmcgJiYgb01haW5MaXN0QmluZGluZy5nZXRQYXRoKClcblx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRvbkJlZm9yZUNyZWF0ZVByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdHJldHVybiBvbkJlZm9yZUNyZWF0ZVByb21pc2UudGhlbihmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHRcdG9OZXdEb2N1bWVudENvbnRleHQgPSBvTWFpbkxpc3RCaW5kaW5nLmNyZWF0ZShtUGFyYW1ldGVycy5kYXRhLCB0cnVlLCBtUGFyYW1ldGVycy5jcmVhdGVBdEVuZCk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB0aGF0Lm9uQWZ0ZXJDcmVhdGVDb21wbGV0aW9uKG9NYWluTGlzdEJpbmRpbmcsIG9OZXdEb2N1bWVudENvbnRleHQsIG1QYXJhbWV0ZXJzKTtcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSlcblx0XHRcdFx0LmNhdGNoKGZ1bmN0aW9uIChvRXJyb3I6IGFueSkge1xuXHRcdFx0XHRcdExvZy5lcnJvcihcIkVycm9yIHdoaWxlIGNyZWF0aW5nIHRoZSBuZXcgZG9jdW1lbnRcIiwgb0Vycm9yKTtcblx0XHRcdFx0XHR0aHJvdyBvRXJyb3I7XG5cdFx0XHRcdH0pO1xuXHRcdH1cblx0XHRyZXR1cm4gb0NyZWF0aW9uUHJvbWlzZVxuXHRcdFx0LnRoZW4oZnVuY3Rpb24gKG9SZXN1bHQ6IGFueSkge1xuXHRcdFx0XHRpZiAoIW9NYWluTGlzdEJpbmRpbmcuaXNSZWxhdGl2ZSgpKSB7XG5cdFx0XHRcdFx0Ly8gdGhlIGNyZWF0ZSBtb2RlIHNoYWxsIGN1cnJlbnRseSBvbmx5IGJlIHNldCBvbiBjcmVhdGluZyBhIHJvb3QgZG9jdW1lbnRcblx0XHRcdFx0XHR0aGF0Ll9iQ3JlYXRlTW9kZSA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0b05ld0RvY3VtZW50Q29udGV4dCA9IG9OZXdEb2N1bWVudENvbnRleHQgfHwgKG9SZXN1bHQgJiYgb1Jlc3VsdC5yZXNwb25zZSk7XG5cdFx0XHRcdC8vIFRPRE86IHdoZXJlIGRvZXMgdGhpcyBvbmUgY29taW5nIGZyb20/Pz9cblx0XHRcdFx0aWYgKG9SZXN1bHQgJiYgb1Jlc3VsdC5iQ29uc2lkZXJEb2N1bWVudE1vZGlmaWVkKSB7XG5cdFx0XHRcdFx0dGhhdC5oYW5kbGVEb2N1bWVudE1vZGlmaWNhdGlvbnMoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gbWVzc2FnZUhhbmRsZXIuc2hvd01lc3NhZ2VEaWFsb2coKS50aGVuKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRyZXR1cm4gb05ld0RvY3VtZW50Q29udGV4dDtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KVxuXHRcdFx0LmNhdGNoKGZ1bmN0aW9uIChvRXJyb3I6IGFueSkge1xuXHRcdFx0XHRyZXR1cm4gbWVzc2FnZUhhbmRsZXIuc2hvd01lc3NhZ2VEaWFsb2coKS50aGVuKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHQvLyBmb3IgaW5zdGFuY2UsIG9uIGNhbmNlbCBvZiBjcmVhdGUgZGlhbG9nLCB0aGUgcHJvbWlzZSBpcyByZWplY3RlZFxuXHRcdFx0XHRcdC8vIGEgcmV0dXJuIGhlcmUgd291bGQgcmVzdG9yZSB0aGUgcHJvbWlzZSBjaGFpbiBhbmQgcmVzdWx0IGluIGVycm9ycyB3aGlsZSByb3V0aW5nXG5cdFx0XHRcdFx0Ly8gc29sdXRpb24gLSAgcmVqZWN0IGhlcmUgYXMgd2VsbFxuXHRcdFx0XHRcdGlmIChvRXJyb3IgJiYgb0Vycm9yLmJEZWxldGVUcmFuc2llbnRDb250ZXh0ICYmIG9OZXdEb2N1bWVudENvbnRleHQuaXNUcmFuc2llbnQoKSkge1xuXHRcdFx0XHRcdFx0Ly8gVGhpcyBpcyBhIHdvcmthcm91bmQgc3VnZ2VzdGVkIGJ5IG1vZGVsIGFzIENvbnRleHQuZGVsZXRlIHJlc3VsdHMgaW4gYW4gZXJyb3Jcblx0XHRcdFx0XHRcdC8vIFRPRE86IHJlbW92ZSB0aGUgJGRpcmVjdCBvbmNlIG1vZGVsIHJlc29sdmVzIHRoaXMgaXNzdWVcblx0XHRcdFx0XHRcdC8vIHRoaXMgbGluZSBzaG93cyB0aGUgZXhwZWN0ZWQgY29uc29sZSBlcnJvciBVbmNhdWdodCAoaW4gcHJvbWlzZSkgRXJyb3I6IFJlcXVlc3QgY2FuY2VsZWQ6IFBPU1QgVHJhdmVsOyBncm91cDogc3VibWl0TGF0ZXJcblx0XHRcdFx0XHRcdG9OZXdEb2N1bWVudENvbnRleHQuZGVsZXRlKFwiJGRpcmVjdFwiKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIFByb21pc2UucmVqZWN0KG9FcnJvcik7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSlcblx0XHRcdC5maW5hbGx5KGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0QnVzeUxvY2tlci51bmxvY2sodGhhdC5vTG9ja09iamVjdCwgc0J1c3lQYXRoKTtcblx0XHRcdH0pO1xuXHR9XG5cdC8qKlxuXHQgKiBGaW5kIHRoZSBhY3RpdmUgY29udGV4dHMgb2YgdGhlIGRvY3VtZW50cywgb25seSBmb3IgdGhlIGRyYWZ0IHJvb3RzLlxuXHQgKlxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXJcblx0ICogQHN0YXRpY1xuXHQgKiBAcGFyYW0ge3NhcC51aS5tb2RlbC5vZGF0YS52NC5Db250ZXh0W119IGFDb250ZXh0cyBDb250ZXh0cyBFaXRoZXIgb25lIGNvbnRleHQgb3IgYW4gYXJyYXkgd2l0aCBjb250ZXh0cyB0byBiZSBkZWxldGVkXG5cdCAqIEBwYXJhbSBiRmluZEFjdGl2ZUNvbnRleHRzXG5cdCAqIEByZXR1cm5zIHtBcnJheX0gQXJyYXkgb2YgdGhlIGFjdGl2ZSBjb250ZXh0c1xuXHQgKi9cblx0ZmluZEFjdGl2ZURyYWZ0Um9vdENvbnRleHRzKGFDb250ZXh0czogYW55W10sIGJGaW5kQWN0aXZlQ29udGV4dHM6IGFueSkge1xuXHRcdGlmICghYkZpbmRBY3RpdmVDb250ZXh0cykge1xuXHRcdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXHRcdH1cblx0XHRjb25zdCBhY3RpdmVDb250ZXh0cyA9IGFDb250ZXh0cy5yZWR1Y2UoZnVuY3Rpb24gKGFSZXN1bHQ6IGFueSwgb0NvbnRleHQ6IGFueSkge1xuXHRcdFx0Y29uc3Qgb01ldGFNb2RlbCA9IG9Db250ZXh0LmdldE1vZGVsKCkuZ2V0TWV0YU1vZGVsKCk7XG5cdFx0XHRjb25zdCBzTWV0YVBhdGggPSBvTWV0YU1vZGVsLmdldE1ldGFQYXRoKG9Db250ZXh0LmdldFBhdGgoKSk7XG5cdFx0XHRpZiAob01ldGFNb2RlbC5nZXRPYmplY3Qoc01ldGFQYXRoICsgXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLkRyYWZ0Um9vdFwiKSkge1xuXHRcdFx0XHRjb25zdCBiSXNBY3RpdmVFbnRpdHkgPSBvQ29udGV4dC5nZXRPYmplY3QoKS5Jc0FjdGl2ZUVudGl0eSxcblx0XHRcdFx0XHRiSGFzQWN0aXZlRW50aXR5ID0gb0NvbnRleHQuZ2V0T2JqZWN0KCkuSGFzQWN0aXZlRW50aXR5O1xuXHRcdFx0XHRpZiAoIWJJc0FjdGl2ZUVudGl0eSAmJiBiSGFzQWN0aXZlRW50aXR5KSB7XG5cdFx0XHRcdFx0Y29uc3Qgb0FjdGl2ZUNvbnRleHQgPSBvQ29udGV4dFxuXHRcdFx0XHRcdFx0LmdldE1vZGVsKClcblx0XHRcdFx0XHRcdC5iaW5kQ29udGV4dChvQ29udGV4dC5nZXRQYXRoKCkgKyBcIi9TaWJsaW5nRW50aXR5XCIpXG5cdFx0XHRcdFx0XHQuZ2V0Qm91bmRDb250ZXh0KCk7XG5cdFx0XHRcdFx0YVJlc3VsdC5wdXNoKG9BY3RpdmVDb250ZXh0KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGFSZXN1bHQ7XG5cdFx0fSwgW10pO1xuXHRcdHJldHVybiBQcm9taXNlLmFsbChcblx0XHRcdGFjdGl2ZUNvbnRleHRzLm1hcChmdW5jdGlvbiAob0NvbnRleHQ6IGFueSkge1xuXHRcdFx0XHRyZXR1cm4gb0NvbnRleHQucmVxdWVzdENhbm9uaWNhbFBhdGgoKS50aGVuKFxuXHRcdFx0XHRcdGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdHJldHVybiBvQ29udGV4dDtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdCk7XG5cdFx0XHR9KVxuXHRcdCk7XG5cdH1cblx0YWZ0ZXJEZWxldGVQcm9jZXNzKG1QYXJhbWV0ZXJzOiBhbnksIGNoZWNrQm94OiBhbnksIGFDb250ZXh0czogYW55LCBvUmVzb3VyY2VCdW5kbGU6IGFueSkge1xuXHRcdGNvbnN0IG9JbnRlcm5hbE1vZGVsQ29udGV4dCA9IG1QYXJhbWV0ZXJzLmludGVybmFsTW9kZWxDb250ZXh0O1xuXHRcdGlmIChvSW50ZXJuYWxNb2RlbENvbnRleHQgJiYgb0ludGVybmFsTW9kZWxDb250ZXh0LmdldFByb3BlcnR5KFwiZGVsZXRlRW5hYmxlZFwiKSAhPSB1bmRlZmluZWQpIHtcblx0XHRcdGlmIChjaGVja0JveC5pc0NoZWNrQm94VmlzaWJsZSA9PT0gdHJ1ZSAmJiBjaGVja0JveC5pc0NoZWNrQm94U2VsZWN0ZWQgPT09IGZhbHNlKSB7XG5cdFx0XHRcdC8vaWYgdW5zYXZlZCBvYmplY3RzIGFyZSBub3QgZGVsZXRlZCB0aGVuIHdlIG5lZWQgdG8gc2V0IHRoZSBlbmFibGVkIHRvIHRydWUgYW5kIHVwZGF0ZSB0aGUgbW9kZWwgZGF0YSBmb3IgbmV4dCBkZWxldGlvblxuXHRcdFx0XHRvSW50ZXJuYWxNb2RlbENvbnRleHQuc2V0UHJvcGVydHkoXCJkZWxldGVFbmFibGVkXCIsIHRydWUpO1xuXHRcdFx0XHRjb25zdCBvYmogPSBPYmplY3QuYXNzaWduKG9JbnRlcm5hbE1vZGVsQ29udGV4dC5nZXRPYmplY3QoKSwge30pO1xuXHRcdFx0XHRvYmouc2VsZWN0ZWRDb250ZXh0cyA9IG9iai5zZWxlY3RlZENvbnRleHRzLmZpbHRlcihmdW5jdGlvbiAoZWxlbWVudDogYW55KSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9iai5kZWxldGFibGVDb250ZXh0cy5pbmRleE9mKGVsZW1lbnQpID09PSAtMTtcblx0XHRcdFx0fSk7XG5cdFx0XHRcdG9iai5kZWxldGFibGVDb250ZXh0cyA9IFtdO1xuXHRcdFx0XHRvYmouc2VsZWN0ZWRDb250ZXh0cyA9IFtdO1xuXHRcdFx0XHRvYmoubnVtYmVyT2ZTZWxlY3RlZENvbnRleHRzID0gb2JqLnNlbGVjdGVkQ29udGV4dHMubGVuZ3RoO1xuXHRcdFx0XHRvSW50ZXJuYWxNb2RlbENvbnRleHQuc2V0UHJvcGVydHkoXCJcIiwgb2JqKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG9JbnRlcm5hbE1vZGVsQ29udGV4dC5zZXRQcm9wZXJ0eShcImRlbGV0ZUVuYWJsZWRcIiwgZmFsc2UpO1xuXHRcdFx0XHRvSW50ZXJuYWxNb2RlbENvbnRleHQuc2V0UHJvcGVydHkoXCJzZWxlY3RlZENvbnRleHRzXCIsIFtdKTtcblx0XHRcdFx0b0ludGVybmFsTW9kZWxDb250ZXh0LnNldFByb3BlcnR5KFwibnVtYmVyT2ZTZWxlY3RlZENvbnRleHRzXCIsIDApO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAoYUNvbnRleHRzLmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0TWVzc2FnZVRvYXN0LnNob3coXG5cdFx0XHRcdENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfREVMRVRFX1RPQVNUX1NJTkdVTEFSXCIsXG5cdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlLFxuXHRcdFx0XHRcdG51bGwsXG5cdFx0XHRcdFx0bVBhcmFtZXRlcnMuZW50aXR5U2V0TmFtZVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRNZXNzYWdlVG9hc3Quc2hvdyhcblx0XHRcdFx0Q29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXG5cdFx0XHRcdFx0XCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9PQkpFQ1RfUEFHRV9ERUxFVEVfVE9BU1RfUExVUkFMXCIsXG5cdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlLFxuXHRcdFx0XHRcdG51bGwsXG5cdFx0XHRcdFx0bVBhcmFtZXRlcnMuZW50aXR5U2V0TmFtZVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXHQvKipcblx0ICogRGVsZXRlIG9uZSBvciBtdWx0aXBsZSBkb2N1bWVudChzKS5cblx0ICpcblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyXG5cdCAqIEBzdGF0aWNcblx0ICogQHBhcmFtIHtzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dH0gdkNvbnRleHRzIENvbnRleHRzIEVpdGhlciBvbmUgY29udGV4dCBvciBhbiBhcnJheSB3aXRoIGNvbnRleHRzIHRvIGJlIGRlbGV0ZWRcblx0ICogQHBhcmFtIHtvYmplY3R9IG1QYXJhbWV0ZXJzIE9wdGlvbmFsLCBjYW4gY29udGFpbiB0aGUgZm9sbG93aW5nIGF0dHJpYnV0ZXM6XG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBtUGFyYW1ldGVycy50aXRsZSBUaXRsZSBvZiB0aGUgb2JqZWN0IHRvIGJlIGRlbGV0ZWRcblx0ICogQHBhcmFtIHtzdHJpbmd9IG1QYXJhbWV0ZXJzLmRlc2NyaXB0aW9uIERlc2NyaXB0aW9uIG9mIHRoZSBvYmplY3QgdG8gYmUgZGVsZXRlZFxuXHQgKiBAcGFyYW0ge2ludGVnZXJ9IG1QYXJhbWV0ZXJzLm51bWJlck9mU2VsZWN0ZWRDb250ZXh0cyBOdW1iZXIgb2Ygb2JqZWN0cyBzZWxlY3RlZFxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IG1QYXJhbWV0ZXJzLm5vRGlhbG9nIFRvIGRpc2FibGUgdGhlIGNvbmZpcm1hdGlvbiBkaWFsb2dcblx0ICogQHBhcmFtIG9SZXNvdXJjZUJ1bmRsZVxuXHQgKiBAcGFyYW0gbWVzc2FnZUhhbmRsZXJcblx0ICogQHJldHVybnMge1Byb21pc2V9XG5cdCAqL1xuXHRkZWxldGVEb2N1bWVudCh2Q29udGV4dHM6IGFueSwgbVBhcmFtZXRlcnM6IGFueSwgb1Jlc291cmNlQnVuZGxlOiBhbnksIG1lc3NhZ2VIYW5kbGVyOiBhbnkpIHtcblx0XHRsZXQgZm5SZWplY3Q6IEZ1bmN0aW9uLFxuXHRcdFx0Zm5SZXNvbHZlOiBGdW5jdGlvbixcblx0XHRcdGFEZWxldGFibGVDb250ZXh0czogYW55W10gPSBbXSxcblx0XHRcdGlzQ2hlY2tCb3hWaXNpYmxlID0gZmFsc2UsXG5cdFx0XHRpc0xvY2tlZFRleHRWaXNpYmxlID0gZmFsc2UsXG5cdFx0XHRjYW5ub3RCZURlbGV0ZWRUZXh0VmlzaWJsZSA9IGZhbHNlLFxuXHRcdFx0aXNDaGVja0JveFNlbGVjdGVkOiBib29sZWFuLFxuXHRcdFx0YkRpYWxvZ0NvbmZpcm1lZCA9IGZhbHNlO1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuXHRcdGNvbnN0IHRoYXQgPSB0aGlzLFxuXHRcdFx0b1Jlc291cmNlQnVuZGxlQ29yZSA9IChDb3JlIGFzIENvcmVFeCkuZ2V0TGlicmFyeVJlc291cmNlQnVuZGxlKFwic2FwLmZlLmNvcmVcIikgYXMgUmVzb3VyY2VCdW5kbGU7XG5cdFx0bGV0IGFQYXJhbXM7XG5cdFx0bGV0IG9EZWxldGVNZXNzYWdlOiBhbnkgPSB7XG5cdFx0XHR0aXRsZTogb1Jlc291cmNlQnVuZGxlQ29yZS5nZXRUZXh0KFwiQ19DT01NT05fT0JKRUNUX1BBR0VfREVMRVRFXCIpXG5cdFx0fTtcblx0XHRCdXN5TG9ja2VyLmxvY2sodGhpcy5vTG9ja09iamVjdCk7XG5cdFx0aWYgKCFBcnJheS5pc0FycmF5KHZDb250ZXh0cykpIHtcblx0XHRcdHZDb250ZXh0cyA9IFt2Q29udGV4dHNdO1xuXHRcdH1cblx0XHRQcm9taXNlLnJlc29sdmUodGhpcy5nZXRQcm9ncmFtbWluZ01vZGVsKHZDb250ZXh0c1swXSkpXG5cdFx0XHQudGhlbihmdW5jdGlvbiAoc1Byb2dyYW1taW5nTW9kZWw6IGFueSkge1xuXHRcdFx0XHRpZiAobVBhcmFtZXRlcnMpIHtcblx0XHRcdFx0XHRpZiAoIW1QYXJhbWV0ZXJzLm51bWJlck9mU2VsZWN0ZWRDb250ZXh0cykge1xuXHRcdFx0XHRcdFx0aWYgKHNQcm9ncmFtbWluZ01vZGVsID09PSBQcm9ncmFtbWluZ01vZGVsLkRyYWZ0KSB7XG5cdFx0XHRcdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdkNvbnRleHRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29uc3Qgb0NvbnRleHREYXRhID0gdkNvbnRleHRzW2ldLmdldE9iamVjdCgpO1xuXHRcdFx0XHRcdFx0XHRcdGlmIChcblx0XHRcdFx0XHRcdFx0XHRcdG9Db250ZXh0RGF0YS5Jc0FjdGl2ZUVudGl0eSA9PT0gdHJ1ZSAmJlxuXHRcdFx0XHRcdFx0XHRcdFx0b0NvbnRleHREYXRhLkhhc0RyYWZ0RW50aXR5ID09PSB0cnVlICYmXG5cdFx0XHRcdFx0XHRcdFx0XHRvQ29udGV4dERhdGEuRHJhZnRBZG1pbmlzdHJhdGl2ZURhdGEgJiZcblx0XHRcdFx0XHRcdFx0XHRcdG9Db250ZXh0RGF0YS5EcmFmdEFkbWluaXN0cmF0aXZlRGF0YS5JblByb2Nlc3NCeVVzZXIgJiZcblx0XHRcdFx0XHRcdFx0XHRcdCFvQ29udGV4dERhdGEuRHJhZnRBZG1pbmlzdHJhdGl2ZURhdGEuRHJhZnRJc0NyZWF0ZWRCeU1lXG5cdFx0XHRcdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRNZXNzYWdlQm94LnNob3coXG5cdFx0XHRcdFx0XHRcdFx0XHRcdENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfQ09ORklSTV9ERUxFVEVfV0lUSF9TSU5HTEVfT0JKRUNUX0xPQ0tFRFwiLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG9SZXNvdXJjZUJ1bmRsZVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQpLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGl0bGU6IG9SZXNvdXJjZUJ1bmRsZUNvcmUuZ2V0VGV4dChcIkNfQ09NTU9OX09CSkVDVF9QQUdFX0RFTEVURVwiKSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvbkNsb3NlOiBmblJlamVjdFxuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMgPSBnZXRQYXJhbWV0ZXJzKG1QYXJhbWV0ZXJzKTtcblx0XHRcdFx0XHRcdGlmIChtUGFyYW1ldGVycy50aXRsZSkge1xuXHRcdFx0XHRcdFx0XHRpZiAobVBhcmFtZXRlcnMuZGVzY3JpcHRpb24pIHtcblx0XHRcdFx0XHRcdFx0XHRhUGFyYW1zID0gW21QYXJhbWV0ZXJzLnRpdGxlLCBtUGFyYW1ldGVycy5kZXNjcmlwdGlvbl07XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0YVBhcmFtcyA9IFttUGFyYW1ldGVycy50aXRsZSwgXCJcIl07XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0b0RlbGV0ZU1lc3NhZ2UudGV4dCA9IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfQ09ORklSTV9ERUxFVEVfV0lUSF9PQkpFQ1RJTkZPXCIsXG5cdFx0XHRcdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlLFxuXHRcdFx0XHRcdFx0XHRcdGFQYXJhbXMsXG5cdFx0XHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMuZW50aXR5U2V0TmFtZVxuXHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0b0RlbGV0ZU1lc3NhZ2UudGV4dCA9IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfQ09ORklSTV9ERUxFVEVfV0lUSF9PQkpFQ1RUSVRMRV9TSU5HVUxBUlwiLFxuXHRcdFx0XHRcdFx0XHRcdG9SZXNvdXJjZUJ1bmRsZVxuXHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0YURlbGV0YWJsZUNvbnRleHRzID0gdkNvbnRleHRzO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRvRGVsZXRlTWVzc2FnZSA9IHtcblx0XHRcdFx0XHRcdFx0dGl0bGU6IG9SZXNvdXJjZUJ1bmRsZUNvcmUuZ2V0VGV4dChcIkNfQ09NTU9OX09CSkVDVF9QQUdFX0RFTEVURVwiKVxuXHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRcdGlmIChtUGFyYW1ldGVycy5udW1iZXJPZlNlbGVjdGVkQ29udGV4dHMgPT09IDEgJiYgbVBhcmFtZXRlcnMubnVtYmVyT2ZTZWxlY3RlZENvbnRleHRzID09PSB2Q29udGV4dHMubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRcdGFEZWxldGFibGVDb250ZXh0cyA9IHZDb250ZXh0cztcblx0XHRcdFx0XHRcdFx0b0RlbGV0ZU1lc3NhZ2UudGV4dCA9IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfQ09ORklSTV9ERUxFVEVfV0lUSF9PQkpFQ1RUSVRMRV9TSU5HVUxBUlwiLFxuXHRcdFx0XHRcdFx0XHRcdG9SZXNvdXJjZUJ1bmRsZSxcblx0XHRcdFx0XHRcdFx0XHRudWxsLFxuXHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmVudGl0eVNldE5hbWVcblx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAobVBhcmFtZXRlcnMubnVtYmVyT2ZTZWxlY3RlZENvbnRleHRzID09PSAxICYmIG1QYXJhbWV0ZXJzLnVuU2F2ZWRDb250ZXh0cy5sZW5ndGggPT09IDEpIHtcblx0XHRcdFx0XHRcdFx0Ly9vbmx5IG9uZSB1bnNhdmVkIG9iamVjdFxuXHRcdFx0XHRcdFx0XHRhRGVsZXRhYmxlQ29udGV4dHMgPSBtUGFyYW1ldGVycy51blNhdmVkQ29udGV4dHM7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IGRyYWZ0QWRtaW5EYXRhID0gYURlbGV0YWJsZUNvbnRleHRzWzBdLmdldE9iamVjdCgpW1wiRHJhZnRBZG1pbmlzdHJhdGl2ZURhdGFcIl07XG5cdFx0XHRcdFx0XHRcdGxldCBzTGFzdENoYW5nZWRCeVVzZXIgPSBcIlwiO1xuXHRcdFx0XHRcdFx0XHRpZiAoZHJhZnRBZG1pbkRhdGEpIHtcblx0XHRcdFx0XHRcdFx0XHRzTGFzdENoYW5nZWRCeVVzZXIgPVxuXHRcdFx0XHRcdFx0XHRcdFx0ZHJhZnRBZG1pbkRhdGFbXCJMYXN0Q2hhbmdlZEJ5VXNlckRlc2NyaXB0aW9uXCJdIHx8IGRyYWZ0QWRtaW5EYXRhW1wiTGFzdENoYW5nZWRCeVVzZXJcIl0gfHwgXCJcIjtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRhUGFyYW1zID0gW3NMYXN0Q2hhbmdlZEJ5VXNlcl07XG5cdFx0XHRcdFx0XHRcdG9EZWxldGVNZXNzYWdlLnRleHQgPSBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0NPTkZJUk1fREVMRVRFX1dJVEhfVU5TQVZFRF9DSEFOR0VTXCIsXG5cdFx0XHRcdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlLFxuXHRcdFx0XHRcdFx0XHRcdGFQYXJhbXNcblx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAobVBhcmFtZXRlcnMubnVtYmVyT2ZTZWxlY3RlZENvbnRleHRzID09PSBtUGFyYW1ldGVycy51blNhdmVkQ29udGV4dHMubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRcdC8vb25seSBtdWx0aXBsZSB1bnNhdmVkIG9iamVjdHNcblx0XHRcdFx0XHRcdFx0YURlbGV0YWJsZUNvbnRleHRzID0gbVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzO1xuXHRcdFx0XHRcdFx0XHRvRGVsZXRlTWVzc2FnZS50ZXh0ID0gQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXG5cdFx0XHRcdFx0XHRcdFx0XCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9PQkpFQ1RfUEFHRV9DT05GSVJNX0RFTEVURV9XSVRIX1VOU0FWRURfQ0hBTkdFU19NVUxUSVBMRV9PQkpFQ1RTXCIsXG5cdFx0XHRcdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlXG5cdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKFxuXHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5udW1iZXJPZlNlbGVjdGVkQ29udGV4dHMgPT09XG5cdFx0XHRcdFx0XHRcdHZDb250ZXh0cy5jb25jYXQobVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzLmNvbmNhdChtUGFyYW1ldGVycy5sb2NrZWRDb250ZXh0cykpLmxlbmd0aFxuXHRcdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHRcdC8vb25seSB1bnNhdmVkLCBsb2NrZWQgLGRlbGV0YWJsZSBvYmplY3RzIGJ1dCBub3Qgbm9uLWRlbGV0YWJsZSBvYmplY3RzXG5cdFx0XHRcdFx0XHRcdGFEZWxldGFibGVDb250ZXh0cyA9IHZDb250ZXh0cy5jb25jYXQobVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzKTtcblx0XHRcdFx0XHRcdFx0b0RlbGV0ZU1lc3NhZ2UudGV4dCA9XG5cdFx0XHRcdFx0XHRcdFx0YURlbGV0YWJsZUNvbnRleHRzLmxlbmd0aCA9PT0gMVxuXHRcdFx0XHRcdFx0XHRcdFx0PyBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0NPTkZJUk1fREVMRVRFX1dJVEhfT0JKRUNUVElUTEVfU0lOR1VMQVJcIixcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGUsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bnVsbCxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5lbnRpdHlTZXROYW1lXG5cdFx0XHRcdFx0XHRcdFx0XHQgIClcblx0XHRcdFx0XHRcdFx0XHRcdDogQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9PQkpFQ1RfUEFHRV9DT05GSVJNX0RFTEVURV9XSVRIX09CSkVDVFRJVExFX1BMVVJBTFwiLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG9SZXNvdXJjZUJ1bmRsZSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRudWxsLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmVudGl0eVNldE5hbWVcblx0XHRcdFx0XHRcdFx0XHRcdCAgKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdC8vaWYgbm9uLWRlbGV0YWJsZSBvYmplY3RzIGV4aXN0cyBhbG9uZyB3aXRoIGFueSBvZiB1bnNhdmVkICxkZWxldGFibGUgb2JqZWN0c1xuXHRcdFx0XHRcdFx0XHRhRGVsZXRhYmxlQ29udGV4dHMgPSB2Q29udGV4dHMuY29uY2F0KG1QYXJhbWV0ZXJzLnVuU2F2ZWRDb250ZXh0cyk7XG5cdFx0XHRcdFx0XHRcdGNhbm5vdEJlRGVsZXRlZFRleHRWaXNpYmxlID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0b0RlbGV0ZU1lc3NhZ2UudGV4dCA9XG5cdFx0XHRcdFx0XHRcdFx0YURlbGV0YWJsZUNvbnRleHRzLmxlbmd0aCA9PT0gMVxuXHRcdFx0XHRcdFx0XHRcdFx0PyBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0NPTkZJUk1fREVMRVRFX1dJVEhfT0JKRUNUVElUTEVfU0lOR1VMQVJfTk9OX0RFTEVUQUJMRVwiLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG9SZXNvdXJjZUJ1bmRsZSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRudWxsLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmVudGl0eVNldE5hbWVcblx0XHRcdFx0XHRcdFx0XHRcdCAgKVxuXHRcdFx0XHRcdFx0XHRcdFx0OiBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0NPTkZJUk1fREVMRVRFX1dJVEhfT0JKRUNUVElUTEVfUExVUkFMX05PTl9ERUxFVEFCTEVcIixcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGUsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bnVsbCxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5lbnRpdHlTZXROYW1lXG5cdFx0XHRcdFx0XHRcdFx0XHQgICk7XG5cdFx0XHRcdFx0XHRcdG9EZWxldGVNZXNzYWdlLm5vbkRlbGV0YWJsZVRleHQgPSBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0NPTkZJUk1fREVMRVRFX1dJVEhfT0JKRUNUSU5GT19BTkRfRkVXX09CSkVDVFNfTk9OX0RFTEVUQUJMRVwiLFxuXHRcdFx0XHRcdFx0XHRcdG9SZXNvdXJjZUJ1bmRsZSxcblx0XHRcdFx0XHRcdFx0XHRbXG5cdFx0XHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5udW1iZXJPZlNlbGVjdGVkQ29udGV4dHMgLSB2Q29udGV4dHMuY29uY2F0KG1QYXJhbWV0ZXJzLnVuU2F2ZWRDb250ZXh0cykubGVuZ3RoLFxuXHRcdFx0XHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMubnVtYmVyT2ZTZWxlY3RlZENvbnRleHRzXG5cdFx0XHRcdFx0XHRcdFx0XVxuXHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKG1QYXJhbWV0ZXJzLmxvY2tlZENvbnRleHRzLmxlbmd0aCA9PSAxKSB7XG5cdFx0XHRcdFx0XHRcdC8vc2V0dGluZyB0aGUgbG9ja2VkIHRleHQgaWYgbG9ja2VkIG9iamVjdHMgZXhpc3Rcblx0XHRcdFx0XHRcdFx0aXNMb2NrZWRUZXh0VmlzaWJsZSA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdG9EZWxldGVNZXNzYWdlLm5vbkRlbGV0YWJsZVRleHQgPSBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0NPTkZJUk1fREVMRVRFX1dJVEhfT0JKRUNUSU5GT19BTkRfT05FX09CSkVDVF9MT0NLRURcIixcblx0XHRcdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGUsXG5cdFx0XHRcdFx0XHRcdFx0W21QYXJhbWV0ZXJzLm51bWJlck9mU2VsZWN0ZWRDb250ZXh0c11cblx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmIChtUGFyYW1ldGVycy5sb2NrZWRDb250ZXh0cy5sZW5ndGggPiAxKSB7XG5cdFx0XHRcdFx0XHRcdC8vc2V0dGluZyB0aGUgbG9ja2VkIHRleHQgaWYgbG9ja2VkIG9iamVjdHMgZXhpc3Rcblx0XHRcdFx0XHRcdFx0aXNMb2NrZWRUZXh0VmlzaWJsZSA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdG9EZWxldGVNZXNzYWdlLm5vbkRlbGV0YWJsZVRleHQgPSBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0NPTkZJUk1fREVMRVRFX1dJVEhfT0JKRUNUSU5GT19BTkRfRkVXX09CSkVDVFNfTE9DS0VEXCIsXG5cdFx0XHRcdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlLFxuXHRcdFx0XHRcdFx0XHRcdFttUGFyYW1ldGVycy5sb2NrZWRDb250ZXh0cy5sZW5ndGgsIG1QYXJhbWV0ZXJzLm51bWJlck9mU2VsZWN0ZWRDb250ZXh0c11cblx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmIChcblx0XHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzLmxlbmd0aCA+IDAgJiZcblx0XHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzLmxlbmd0aCAhPT0gbVBhcmFtZXRlcnMubnVtYmVyT2ZTZWxlY3RlZENvbnRleHRzXG5cdFx0XHRcdFx0XHQpIHtcblx0XHRcdFx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdFx0XHRcdChjYW5ub3RCZURlbGV0ZWRUZXh0VmlzaWJsZSB8fCBpc0xvY2tlZFRleHRWaXNpYmxlKSAmJlxuXHRcdFx0XHRcdFx0XHRcdGFEZWxldGFibGVDb250ZXh0cy5sZW5ndGggPT09IG1QYXJhbWV0ZXJzLnVuU2F2ZWRDb250ZXh0cy5sZW5ndGhcblx0XHRcdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHRcdFx0Ly9pZiBvbmx5IHVuc2F2ZWQgYW5kIGVpdGhlciBvciBib3RoIG9mIGxvY2tlZCBhbmQgbm9uLWRlbGV0YWJsZSBvYmplY3RzIGV4aXN0IHRoZW4gd2UgaGlkZSB0aGUgY2hlY2sgYm94XG5cdFx0XHRcdFx0XHRcdFx0aXNDaGVja0JveFZpc2libGUgPSBmYWxzZTtcblx0XHRcdFx0XHRcdFx0XHRhRGVsZXRhYmxlQ29udGV4dHMgPSBtUGFyYW1ldGVycy51blNhdmVkQ29udGV4dHM7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKG1QYXJhbWV0ZXJzLnVuU2F2ZWRDb250ZXh0cy5sZW5ndGggPT09IDEpIHtcblx0XHRcdFx0XHRcdFx0XHRcdG9EZWxldGVNZXNzYWdlLnRleHQgPSBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9PQkpFQ1RfUEFHRV9DT05GSVJNX0RFTEVURV9XSVRIX1VOU0FWRURfQU5EX0ZFV19PQkpFQ1RTX0xPQ0tFRF9TSU5HVUxBUlwiLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGVcblx0XHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdG9EZWxldGVNZXNzYWdlLnRleHQgPSBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9PQkpFQ1RfUEFHRV9DT05GSVJNX0RFTEVURV9XSVRIX1VOU0FWRURfQU5EX0ZFV19PQkpFQ1RTX0xPQ0tFRF9QTFVSQUxcIixcblx0XHRcdFx0XHRcdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlXG5cdFx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAobVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzLmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0b0RlbGV0ZU1lc3NhZ2UuY2hlY2tCb3hUZXh0ID0gQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfQ09ORklSTV9ERUxFVEVfV0lUSF9PQkpFQ1RJTkZPX0FORF9GRVdfT0JKRUNUU19VTlNBVkVEX1NJTkdVTEFSXCIsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdG9SZXNvdXJjZUJ1bmRsZVxuXHRcdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0b0RlbGV0ZU1lc3NhZ2UuY2hlY2tCb3hUZXh0ID0gQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfT0JKRUNUX1BBR0VfQ09ORklSTV9ERUxFVEVfV0lUSF9PQkpFQ1RJTkZPX0FORF9GRVdfT0JKRUNUU19VTlNBVkVEX1BMVVJBTFwiLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRvUmVzb3VyY2VCdW5kbGVcblx0XHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGlzQ2hlY2tCb3hWaXNpYmxlID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKGNhbm5vdEJlRGVsZXRlZFRleHRWaXNpYmxlICYmIGlzTG9ja2VkVGV4dFZpc2libGUpIHtcblx0XHRcdFx0XHRcdFx0Ly9pZiBib3RoIGxvY2tlZCBhbmQgbm9uLWRlbGV0YWJsZSBvYmplY3RzIGV4aXN0IGFsb25nIHdpdGggZGVsZXRhYmxlIG9iamVjdHNcblx0XHRcdFx0XHRcdFx0aWYgKG1QYXJhbWV0ZXJzLnVuU2F2ZWRDb250ZXh0cy5sZW5ndGggPiAxKSB7XG5cdFx0XHRcdFx0XHRcdFx0b0RlbGV0ZU1lc3NhZ2Uubm9uRGVsZXRhYmxlVGV4dCA9IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFxuXHRcdFx0XHRcdFx0XHRcdFx0XCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9PQkpFQ1RfUEFHRV9DT05GSVJNX0RFTEVURV9XSVRIX09CSkVDVElORk9fQU5EX0ZFV19PQkpFQ1RTX0xPQ0tFRF9BTkRfTk9OX0RFTEVUQUJMRVwiLFxuXHRcdFx0XHRcdFx0XHRcdFx0b1Jlc291cmNlQnVuZGxlLFxuXHRcdFx0XHRcdFx0XHRcdFx0W1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5udW1iZXJPZlNlbGVjdGVkQ29udGV4dHMgLVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHZDb250ZXh0cy5jb25jYXQobVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzKS5sZW5ndGggLVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmxvY2tlZENvbnRleHRzLmxlbmd0aCxcblx0XHRcdFx0XHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMubG9ja2VkQ29udGV4dHMubGVuZ3RoLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5udW1iZXJPZlNlbGVjdGVkQ29udGV4dHNcblx0XHRcdFx0XHRcdFx0XHRcdF1cblx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGlmIChtUGFyYW1ldGVycy51blNhdmVkQ29udGV4dHMubGVuZ3RoID09IDEpIHtcblx0XHRcdFx0XHRcdFx0XHRvRGVsZXRlTWVzc2FnZS5ub25EZWxldGFibGVUZXh0ID0gQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXG5cdFx0XHRcdFx0XHRcdFx0XHRcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9QQUdFX0NPTkZJUk1fREVMRVRFX1dJVEhfT0JKRUNUSU5GT19BTkRfT05FX09CSkVDVF9MT0NLRURfQU5EX05PTl9ERUxFVEFCTEVcIixcblx0XHRcdFx0XHRcdFx0XHRcdG9SZXNvdXJjZUJ1bmRsZSxcblx0XHRcdFx0XHRcdFx0XHRcdFtcblx0XHRcdFx0XHRcdFx0XHRcdFx0bVBhcmFtZXRlcnMubnVtYmVyT2ZTZWxlY3RlZENvbnRleHRzIC1cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR2Q29udGV4dHMuY29uY2F0KG1QYXJhbWV0ZXJzLnVuU2F2ZWRDb250ZXh0cykubGVuZ3RoIC1cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5sb2NrZWRDb250ZXh0cy5sZW5ndGgsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLm51bWJlck9mU2VsZWN0ZWRDb250ZXh0c1xuXHRcdFx0XHRcdFx0XHRcdFx0XVxuXHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0bGV0IG9Ob25EZWxldGFibGVNZXNzYWdlVGV4dENvbnRyb2wsIG9EZWxldGVNZXNzYWdlVGV4dENvbnRyb2w7XG5cdFx0XHRcdGNvbnN0IG9Db250ZW50ID0gbmV3IFZCb3goe1xuXHRcdFx0XHRcdGl0ZW1zOiBbXG5cdFx0XHRcdFx0XHQob05vbkRlbGV0YWJsZU1lc3NhZ2VUZXh0Q29udHJvbCA9IG5ldyBUZXh0KHtcblx0XHRcdFx0XHRcdFx0dGV4dDogb0RlbGV0ZU1lc3NhZ2Uubm9uRGVsZXRhYmxlVGV4dCxcblx0XHRcdFx0XHRcdFx0dmlzaWJsZTogaXNMb2NrZWRUZXh0VmlzaWJsZSB8fCBjYW5ub3RCZURlbGV0ZWRUZXh0VmlzaWJsZVxuXHRcdFx0XHRcdFx0fSkpLFxuXHRcdFx0XHRcdFx0KG9EZWxldGVNZXNzYWdlVGV4dENvbnRyb2wgPSBuZXcgVGV4dCh7XG5cdFx0XHRcdFx0XHRcdHRleHQ6IG9EZWxldGVNZXNzYWdlLnRleHRcblx0XHRcdFx0XHRcdH0pKSxcblx0XHRcdFx0XHRcdG5ldyBDaGVja0JveCh7XG5cdFx0XHRcdFx0XHRcdHRleHQ6IG9EZWxldGVNZXNzYWdlLmNoZWNrQm94VGV4dCxcblx0XHRcdFx0XHRcdFx0c2VsZWN0ZWQ6IHRydWUsXG5cdFx0XHRcdFx0XHRcdHNlbGVjdDogZnVuY3Rpb24gKG9FdmVudDogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29uc3Qgc2VsZWN0ZWQgPSBvRXZlbnQuZ2V0U291cmNlKCkuZ2V0U2VsZWN0ZWQoKTtcblx0XHRcdFx0XHRcdFx0XHRpZiAoc2VsZWN0ZWQpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGFEZWxldGFibGVDb250ZXh0cyA9IHZDb250ZXh0cy5jb25jYXQobVBhcmFtZXRlcnMudW5TYXZlZENvbnRleHRzKTtcblx0XHRcdFx0XHRcdFx0XHRcdGlzQ2hlY2tCb3hTZWxlY3RlZCA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdGFEZWxldGFibGVDb250ZXh0cyA9IHZDb250ZXh0cztcblx0XHRcdFx0XHRcdFx0XHRcdGlzQ2hlY2tCb3hTZWxlY3RlZCA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFx0dmlzaWJsZTogaXNDaGVja0JveFZpc2libGVcblx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XVxuXHRcdFx0XHR9KTtcblx0XHRcdFx0Y29uc3Qgc1RpdGxlID0gb1Jlc291cmNlQnVuZGxlQ29yZS5nZXRUZXh0KFwiQ19DT01NT05fT0JKRUNUX1BBR0VfREVMRVRFXCIpO1xuXHRcdFx0XHRjb25zdCBmbkNvbmZpcm0gPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0YkRpYWxvZ0NvbmZpcm1lZCA9IHRydWU7XG5cdFx0XHRcdFx0QnVzeUxvY2tlci5sb2NrKHRoYXQub0xvY2tPYmplY3QpO1xuXHRcdFx0XHRcdGNvbnN0IGFDb250ZXh0cyA9IGFEZWxldGFibGVDb250ZXh0cztcblx0XHRcdFx0XHRsZXQgb25CZWZvcmVEZWxldGVQcm9taXNlO1xuXHRcdFx0XHRcdGlmIChtUGFyYW1ldGVycy5iZWZvcmVEZWxldGVDYWxsQmFjaykge1xuXHRcdFx0XHRcdFx0b25CZWZvcmVEZWxldGVQcm9taXNlID0gbVBhcmFtZXRlcnMuYmVmb3JlRGVsZXRlQ2FsbEJhY2soeyBjb250ZXh0czogYUNvbnRleHRzIH0pO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRvbkJlZm9yZURlbGV0ZVByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIG9uQmVmb3JlRGVsZXRlUHJvbWlzZVxuXHRcdFx0XHRcdFx0LnRoZW4odGhhdC5maW5kQWN0aXZlRHJhZnRSb290Q29udGV4dHMuYmluZCh0aGF0LCBhQ29udGV4dHMsIG1QYXJhbWV0ZXJzLmJGaW5kQWN0aXZlQ29udGV4dHMpKVxuXHRcdFx0XHRcdFx0LnRoZW4oZnVuY3Rpb24gKGFjdGl2ZUNvbnRleHRzOiBhbnkpIHtcblx0XHRcdFx0XHRcdFx0Ly9tYWtlIHN1cmUgdG8gZmV0Y2ggdGhlIGFjdGl2ZSBjb250ZXh0cyBiZWZvcmUgZGVsZXRpbmcgdGhlIGRyYWZ0c1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5hbGwoXG5cdFx0XHRcdFx0XHRcdFx0YUNvbnRleHRzLm1hcChmdW5jdGlvbiAob0NvbnRleHQ6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Ly9kZWxldGUgdGhlIGRyYWZ0XG5cdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gZHJhZnQuZGVsZXRlRHJhZnQob0NvbnRleHQpO1xuXHRcdFx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0XHQuY2F0Y2goZnVuY3Rpb24gKG9FcnJvcjogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gbWVzc2FnZUhhbmRsZXIuc2hvd01lc3NhZ2VzKCkudGhlbihmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIHJlLXRocm93IGVycm9yIHRvIGVuZm9yY2UgcmVqZWN0aW5nIHRoZSBnZW5lcmFsIHByb21pc2Vcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGhyb3cgb0Vycm9yO1xuXHRcdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdFx0XHQudGhlbihmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjb25zdCBjaGVja0JveCA9IHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XCJpc0NoZWNrQm94VmlzaWJsZVwiOiBpc0NoZWNrQm94VmlzaWJsZSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XCJpc0NoZWNrQm94U2VsZWN0ZWRcIjogaXNDaGVja0JveFNlbGVjdGVkXG5cdFx0XHRcdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKGFjdGl2ZUNvbnRleHRzICYmIGFjdGl2ZUNvbnRleHRzLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5hbGwoXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0YWN0aXZlQ29udGV4dHMubWFwKGZ1bmN0aW9uIChvQ29udGV4dDogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gb0NvbnRleHQuZGVsZXRlKCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdFx0XHRcdFx0KS50aGVuKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGF0LmFmdGVyRGVsZXRlUHJvY2VzcyhtUGFyYW1ldGVycywgY2hlY2tCb3gsIGFDb250ZXh0cywgb1Jlc291cmNlQnVuZGxlKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gbWVzc2FnZUhhbmRsZXIuc2hvd01lc3NhZ2VEaWFsb2coKS50aGVuKGZuUmVzb2x2ZSk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGhhdC5hZnRlckRlbGV0ZVByb2Nlc3MobVBhcmFtZXRlcnMsIGNoZWNrQm94LCBhQ29udGV4dHMsIG9SZXNvdXJjZUJ1bmRsZSk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBtZXNzYWdlSGFuZGxlci5zaG93TWVzc2FnZURpYWxvZygpLnRoZW4oZm5SZXNvbHZlKTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHQuY2F0Y2goZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0XHRmblJlamVjdCgpO1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdC5maW5hbGx5KGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdFx0QnVzeUxvY2tlci51bmxvY2sodGhhdC5vTG9ja09iamVjdCk7XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fTtcblx0XHRcdFx0Y29uc3Qgb0RpYWxvZyA9IG5ldyBEaWFsb2coe1xuXHRcdFx0XHRcdHRpdGxlOiBzVGl0bGUsXG5cdFx0XHRcdFx0c3RhdGU6IFwiV2FybmluZ1wiLFxuXHRcdFx0XHRcdGNvbnRlbnQ6IFtvQ29udGVudF0sXG5cdFx0XHRcdFx0YXJpYUxhYmVsbGVkQnk6IG9Ob25EZWxldGFibGVNZXNzYWdlVGV4dENvbnRyb2wuZ2V0VmlzaWJsZSgpXG5cdFx0XHRcdFx0XHQ/IFtvTm9uRGVsZXRhYmxlTWVzc2FnZVRleHRDb250cm9sLCBvRGVsZXRlTWVzc2FnZVRleHRDb250cm9sXVxuXHRcdFx0XHRcdFx0OiBvRGVsZXRlTWVzc2FnZVRleHRDb250cm9sLFxuXHRcdFx0XHRcdGJlZ2luQnV0dG9uOiBuZXcgQnV0dG9uKHtcblx0XHRcdFx0XHRcdHRleHQ6IG9SZXNvdXJjZUJ1bmRsZUNvcmUuZ2V0VGV4dChcIkNfQ09NTU9OX09CSkVDVF9QQUdFX0RFTEVURVwiKSxcblx0XHRcdFx0XHRcdHR5cGU6IFwiRW1waGFzaXplZFwiLFxuXHRcdFx0XHRcdFx0cHJlc3M6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdFx0b0RpYWxvZy5jbG9zZSgpO1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gZm5Db25maXJtKCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0ZW5kQnV0dG9uOiBuZXcgQnV0dG9uKHtcblx0XHRcdFx0XHRcdHRleHQ6IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFwiQ19DT01NT05fT0JKRUNUX1BBR0VfQ0FOQ0VMXCIsIG9SZXNvdXJjZUJ1bmRsZSksXG5cdFx0XHRcdFx0XHRwcmVzczogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0XHRvRGlhbG9nLmNsb3NlKCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0YWZ0ZXJDbG9zZTogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0b0RpYWxvZy5kZXN0cm95KCk7XG5cdFx0XHRcdFx0XHQvLyBpZiBkaWFsb2cgaXMgY2xvc2VkIHVuY29uZmlybWVkIChlLmcuIHZpYSBcIkNhbmNlbFwiIG9yIEVzY2FwZSBidXR0b24pLCBlbnN1cmUgdG8gcmVqZWN0IHByb21pc2Vcblx0XHRcdFx0XHRcdGlmICghYkRpYWxvZ0NvbmZpcm1lZCkge1xuXHRcdFx0XHRcdFx0XHRmblJlamVjdCgpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBhcyBhbnkpO1xuXHRcdFx0XHRpZiAobVBhcmFtZXRlcnMubm9EaWFsb2cpIHtcblx0XHRcdFx0XHRyZXR1cm4gZm5Db25maXJtKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0b0RpYWxvZy5hZGRTdHlsZUNsYXNzKFwic2FwVWlDb250ZW50UGFkZGluZ1wiKTtcblx0XHRcdFx0XHRvRGlhbG9nLm9wZW4oKTtcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHRcdC5maW5hbGx5KGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0QnVzeUxvY2tlci51bmxvY2sodGhhdC5vTG9ja09iamVjdCk7XG5cdFx0XHR9KVxuXHRcdFx0LmNhdGNoKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0TG9nLndhcm5pbmcoXCJDb3VsZG4ndCBnZXQgUHJvZ3JhbW1pbmcgbW9kZWxcIik7XG5cdFx0XHRcdGZuUmVqZWN0KCk7XG5cdFx0XHR9KTtcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmU6ICh2YWx1ZTogYW55KSA9PiB2b2lkLCByZWplY3Q6IChyZWFzb24/OiBhbnkpID0+IHZvaWQpIHtcblx0XHRcdGZuUmVqZWN0ID0gcmVqZWN0O1xuXHRcdFx0Zm5SZXNvbHZlID0gcmVzb2x2ZTtcblx0XHR9KTtcblx0fVxuXHQvKipcblx0ICogRWRpdHMgYSBkb2N1bWVudC5cblx0ICpcblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyXG5cdCAqIEBzdGF0aWNcblx0ICogQHBhcmFtIHtzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dH0gb0NvbnRleHQgQ29udGV4dCBvZiB0aGUgYWN0aXZlIGRvY3VtZW50XG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvVmlldyBDdXJyZW50IHZpZXdcblx0ICogQHBhcmFtIG1lc3NhZ2VIYW5kbGVyXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHJlc29sdmVzIHdpdGggdGhlIG5ldyBkcmFmdCBjb250ZXh0IGluIGNhc2Ugb2YgZHJhZnQgcHJvZ3JhbW1pbmcgbW9kZWxcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKi9cblx0ZWRpdERvY3VtZW50KG9Db250ZXh0OiBhbnksIG9WaWV3OiBvYmplY3QsIG1lc3NhZ2VIYW5kbGVyOiBhbnkpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXNcblx0XHRjb25zdCB0aGF0ID0gdGhpcztcblx0XHRjb25zdCBzUHJvZ3JhbW1pbmdNb2RlbCA9IHRoaXMuZ2V0UHJvZ3JhbW1pbmdNb2RlbChvQ29udGV4dCk7XG5cdFx0bGV0IG9FZGl0UHJvbWlzZTtcblx0XHRpZiAoIW9Db250ZXh0KSB7XG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQmluZGluZyBjb250ZXh0IHRvIGFjdGl2ZSBkb2N1bWVudCBpcyByZXF1aXJlZFwiKSk7XG5cdFx0fVxuXHRcdHRoaXMuX2JJc01vZGlmaWVkID0gZmFsc2U7XG5cdFx0QnVzeUxvY2tlci5sb2NrKHRoYXQub0xvY2tPYmplY3QpO1xuXHRcdC8vIGJlZm9yZSB0cmlnZ2VyaW5nIHRoZSBlZGl0IGFjdGlvbiB3ZSdsbCBoYXZlIHRvIHJlbW92ZSBhbGwgYm91bmQgdHJhbnNpdGlvbiBtZXNzYWdlc1xuXHRcdG1lc3NhZ2VIYW5kbGVyLnJlbW92ZVRyYW5zaXRpb25NZXNzYWdlcygpO1xuXHRcdGlmIChzUHJvZ3JhbW1pbmdNb2RlbCA9PT0gUHJvZ3JhbW1pbmdNb2RlbC5EcmFmdCkge1xuXHRcdFx0b0VkaXRQcm9taXNlID0gZHJhZnQuY3JlYXRlRHJhZnRGcm9tQWN0aXZlRG9jdW1lbnQob0NvbnRleHQsIHRoaXMuX2dldEFwcENvbXBvbmVudCgpLCB7XG5cdFx0XHRcdGJQcmVzZXJ2ZUNoYW5nZXM6IHRydWUsXG5cdFx0XHRcdG9WaWV3OiBvVmlld1xuXHRcdFx0fSBhcyBhbnkpO1xuXHRcdH0gZWxzZSBpZiAoc1Byb2dyYW1taW5nTW9kZWwgPT09IFByb2dyYW1taW5nTW9kZWwuU3RpY2t5KSB7XG5cdFx0XHRvRWRpdFByb21pc2UgPSBzdGlja3kuZWRpdERvY3VtZW50SW5TdGlja3lTZXNzaW9uKG9Db250ZXh0LCB0aGlzLl9nZXRBcHBDb21wb25lbnQoKSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdEJ1c3lMb2NrZXIudW5sb2NrKHRoYXQub0xvY2tPYmplY3QpO1xuXHRcdFx0cmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkVkaXQgaXMgb25seSBhbGxvd2VkIGZvciBkcmFmdCBvciBzdGlja3kgc2Vzc2lvbiBzdXBwb3J0ZWQgc2VydmljZXNcIikpO1xuXHRcdH1cblx0XHRyZXR1cm4gb0VkaXRQcm9taXNlXG5cdFx0XHQudGhlbihmdW5jdGlvbiAob05ld0NvbnRleHQ6IGFueSkge1xuXHRcdFx0XHR0aGF0Ll9iQ3JlYXRlTW9kZSA9IGZhbHNlO1xuXHRcdFx0XHRyZXR1cm4gbWVzc2FnZUhhbmRsZXIuc2hvd01lc3NhZ2VEaWFsb2coKS50aGVuKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRyZXR1cm4gb05ld0NvbnRleHQ7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSlcblx0XHRcdC5jYXRjaChmdW5jdGlvbiAoZXJyOiBhbnkpIHtcblx0XHRcdFx0cmV0dXJuIG1lc3NhZ2VIYW5kbGVyLnNob3dNZXNzYWdlcygpLnRoZW4oZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdHJldHVybiBQcm9taXNlLnJlamVjdChlcnIpO1xuXHRcdFx0XHR9KTtcblx0XHRcdH0pXG5cdFx0XHQuZmluYWxseShmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdEJ1c3lMb2NrZXIudW5sb2NrKHRoYXQub0xvY2tPYmplY3QpO1xuXHRcdFx0fSk7XG5cdH1cblx0LyoqXG5cdCAqIENhbmNlbCAnZWRpdCcgbW9kZSBvZiBhIGRvY3VtZW50LlxuXHQgKlxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXJcblx0ICogQHN0YXRpY1xuXHQgKiBAcGFyYW0ge3NhcC51aS5tb2RlbC5vZGF0YS52NC5Db250ZXh0fSBvQ29udGV4dCBDb250ZXh0IG9mIHRoZSBkb2N1bWVudCB0byBiZSBjYW5jZWxlZCBvciBkZWxldGVkXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBbbUluUGFyYW1ldGVyc10gT3B0aW9uYWwsIGNhbiBjb250YWluIHRoZSBmb2xsb3dpbmcgYXR0cmlidXRlczpcblx0ICogQHBhcmFtIHtzYXAubS5CdXR0b259IG1JblBhcmFtZXRlcnMuY2FuY2VsQnV0dG9uIENhbmNlbCBCdXR0b24gb2YgdGhlIGRpc2NhcmQgcG9wb3ZlciAobWFuZGF0b3J5IGZvciBub3cpXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gbUluUGFyYW1ldGVycy5za2lwRGlzY2FyZFBvcG92ZXIgT3B0aW9uYWwsIHN1cHJlc3NlcyB0aGUgZGlzY2FyZCBwb3BvdmVyIGluY2FzZSBvZiBkcmFmdCBhcHBsaWNhdGlvbnMgd2hpbGUgbmF2aWdhdGluZyBvdXQgb2YgT1Bcblx0ICogQHBhcmFtIG9SZXNvdXJjZUJ1bmRsZVxuXHQgKiBAcGFyYW0gbWVzc2FnZUhhbmRsZXJcblx0ICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgcmVzb2x2ZXMgd2l0aCA/Pz9cblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKi9cblx0Y2FuY2VsRG9jdW1lbnQoXG5cdFx0b0NvbnRleHQ6IGFueSxcblx0XHRtSW5QYXJhbWV0ZXJzOiB7IGNhbmNlbEJ1dHRvbjogYW55OyBza2lwRGlzY2FyZFBvcG92ZXI6IGJvb2xlYW4gfSB8IHVuZGVmaW5lZCxcblx0XHRvUmVzb3VyY2VCdW5kbGU6IGFueSxcblx0XHRtZXNzYWdlSGFuZGxlcjogYW55XG5cdCkge1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuXHRcdGNvbnN0IHRoYXQgPSB0aGlzO1xuXHRcdGxldCBzUHJvZ3JhbW1pbmdNb2RlbDogdHlwZW9mIFByb2dyYW1taW5nTW9kZWw7XG5cdFx0Ly9jb250ZXh0IG11c3QgYWx3YXlzIGJlIHBhc3NlZCAtIG1hbmRhdG9yeSBwYXJhbWV0ZXJcblx0XHRpZiAoIW9Db250ZXh0KSB7XG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJObyBjb250ZXh0IGV4aXN0cy4gUGFzcyBhIG1lYW5pbmdmdWwgY29udGV4dFwiKTtcblx0XHR9XG5cdFx0QnVzeUxvY2tlci5sb2NrKHRoYXQub0xvY2tPYmplY3QpO1xuXHRcdGNvbnN0IG1QYXJhbWV0ZXJzID0gZ2V0UGFyYW1ldGVycyhtSW5QYXJhbWV0ZXJzKTtcblx0XHRjb25zdCBvUGFyYW1zQ29udGV4dCA9IG9Db250ZXh0LFxuXHRcdFx0b0NhbmNlbEJ1dHRvbiA9IG1QYXJhbWV0ZXJzLmNhbmNlbEJ1dHRvbixcblx0XHRcdG9Nb2RlbCA9IG9QYXJhbXNDb250ZXh0LmdldE1vZGVsKCk7XG5cdFx0bGV0IG9uQmVmb3JlQ2FuY2VsUHJvbWlzZSwgc0Nhbm9uaWNhbFBhdGg6IHN0cmluZztcblx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuZ2V0UHJvZ3JhbW1pbmdNb2RlbChvQ29udGV4dCkpXG5cdFx0XHQudGhlbihmdW5jdGlvbiAoc1BNb2RlbDogYW55KSB7XG5cdFx0XHRcdHNQcm9ncmFtbWluZ01vZGVsID0gc1BNb2RlbDtcblx0XHRcdFx0aWYgKHNQTW9kZWwgPT09IFByb2dyYW1taW5nTW9kZWwuRHJhZnQpIHtcblx0XHRcdFx0XHRjb25zdCBkcmFmdERhdGFDb250ZXh0ID0gb01vZGVsLmJpbmRDb250ZXh0KG9QYXJhbXNDb250ZXh0LmdldFBhdGgoKSArIFwiL0RyYWZ0QWRtaW5pc3RyYXRpdmVEYXRhXCIpLmdldEJvdW5kQ29udGV4dCgpO1xuXHRcdFx0XHRcdGlmICghdGhhdC5fYklzTW9kaWZpZWQpIHtcblx0XHRcdFx0XHRcdHJldHVybiBkcmFmdERhdGFDb250ZXh0LnJlcXVlc3RPYmplY3QoKS50aGVuKGZ1bmN0aW9uIChkcmFmdEFkbWluRGF0YTogYW55KSB7XG5cdFx0XHRcdFx0XHRcdGlmIChkcmFmdEFkbWluRGF0YSkge1xuXHRcdFx0XHRcdFx0XHRcdHRoYXQuX2JJc01vZGlmaWVkID0gIShkcmFmdEFkbWluRGF0YS5DcmVhdGlvbkRhdGVUaW1lID09PSBkcmFmdEFkbWluRGF0YS5MYXN0Q2hhbmdlRGF0ZVRpbWUpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cdFx0XHQudGhlbihmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGlmICghbVBhcmFtZXRlcnMuc2tpcERpc2NhcmRQb3BvdmVyKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoYXQuX3Nob3dEaXNjYXJkUG9wb3ZlcihvQ2FuY2VsQnV0dG9uLCB0aGF0Ll9iSXNNb2RpZmllZCwgb1Jlc291cmNlQnVuZGxlKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cdFx0XHQudGhlbihmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGlmIChtUGFyYW1ldGVycy5iZWZvcmVDYW5jZWxDYWxsQmFjaykge1xuXHRcdFx0XHRcdG9uQmVmb3JlQ2FuY2VsUHJvbWlzZSA9IG1QYXJhbWV0ZXJzLmJlZm9yZUNhbmNlbENhbGxCYWNrKHsgY29udGV4dDogb0NvbnRleHQgfSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0b25CZWZvcmVDYW5jZWxQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIG9uQmVmb3JlQ2FuY2VsUHJvbWlzZTtcblx0XHRcdH0pXG5cdFx0XHQudGhlbihmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZWZhdWx0LWNhc2Vcblx0XHRcdFx0c3dpdGNoIChzUHJvZ3JhbW1pbmdNb2RlbCkge1xuXHRcdFx0XHRcdGNhc2UgUHJvZ3JhbW1pbmdNb2RlbC5EcmFmdDpcblx0XHRcdFx0XHRcdHJldHVybiBvUGFyYW1zQ29udGV4dC5yZXF1ZXN0T2JqZWN0KFwiSGFzQWN0aXZlRW50aXR5XCIpLnRoZW4oZnVuY3Rpb24gKGJIYXNBY3RpdmVFbnRpdHk6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRsZXQgb0RlbGV0ZVByb21pc2U7XG5cdFx0XHRcdFx0XHRcdGlmICghYkhhc0FjdGl2ZUVudGl0eSkge1xuXHRcdFx0XHRcdFx0XHRcdGlmIChvUGFyYW1zQ29udGV4dCAmJiBvUGFyYW1zQ29udGV4dC5oYXNQZW5kaW5nQ2hhbmdlcygpKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRvUGFyYW1zQ29udGV4dC5nZXRCaW5kaW5nKCkucmVzZXRDaGFuZ2VzKCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdG9EZWxldGVQcm9taXNlID0gZHJhZnQuZGVsZXRlRHJhZnQob1BhcmFtc0NvbnRleHQpO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiBvRGVsZXRlUHJvbWlzZTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRsZXQgb0FjdGl2ZUNvbnRleHQgPSBvTW9kZWwuYmluZENvbnRleHQob1BhcmFtc0NvbnRleHQuZ2V0UGF0aCgpICsgXCIvU2libGluZ0VudGl0eVwiKS5nZXRCb3VuZENvbnRleHQoKTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gb0FjdGl2ZUNvbnRleHRcblx0XHRcdFx0XHRcdFx0XHRcdC5yZXF1ZXN0Q2Fub25pY2FsUGF0aCgpXG5cdFx0XHRcdFx0XHRcdFx0XHQudGhlbihcblx0XHRcdFx0XHRcdFx0XHRcdFx0ZnVuY3Rpb24gKHNQYXRoOiBhbnkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRzQ2Fub25pY2FsUGF0aCA9IHNQYXRoO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlmIChvUGFyYW1zQ29udGV4dCAmJiBvUGFyYW1zQ29udGV4dC5oYXNQZW5kaW5nQ2hhbmdlcygpKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvUGFyYW1zQ29udGV4dC5nZXRCaW5kaW5nKCkucmVzZXRDaGFuZ2VzKCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG9EZWxldGVQcm9taXNlID0gZHJhZnQuZGVsZXRlRHJhZnQob1BhcmFtc0NvbnRleHQpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBvRGVsZXRlUHJvbWlzZTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0ZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGRyYWZ0LmRlbGV0ZURyYWZ0KG9QYXJhbXNDb250ZXh0KTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0XHRcdC50aGVuKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly9vUGFyYW1zQ29udGV4dC5kZWxldGUoKSBpbiB0aGUgcHJldmlvdXMgcHJvbWlzZSBkb2VzbnQgcmV0dXJuIGFueXRoaW5nIHVwb24gc3VjY2Vzcy5cblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCFzQ2Fub25pY2FsUGF0aCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAob0FjdGl2ZUNvbnRleHQuZ2V0UGF0aCgpICE9PSBzQ2Fub25pY2FsUGF0aCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIHRoZSBhY3RpdmUgY29udGV4dCBpcyB1c2luZyB0aGUgc2libGluZyBlbnRpdHkgLSB0aGlzIHBhdGggaXMgbm90IGFjY2Vzc2libGUgYW55bW9yZSBhcyB3ZSBkZWxldGVkIHRoZSBkcmFmdFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGRvY3VtZW50IC0gdGhlcmVmb3JlIHdlIG5lZWQgdG8gY3JlYXRlIGEgbmV3IGNvbnRleHQgd2l0aCB0aGUgY2Fub25pY2FsIHBhdGhcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvQWN0aXZlQ29udGV4dCA9IG9Nb2RlbC5iaW5kQ29udGV4dChzQ2Fub25pY2FsUGF0aCkuZ2V0Qm91bmRDb250ZXh0KCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG9BY3RpdmVDb250ZXh0O1xuXHRcdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdGNhc2UgUHJvZ3JhbW1pbmdNb2RlbC5TdGlja3k6XG5cdFx0XHRcdFx0XHRyZXR1cm4gc3RpY2t5LmRpc2NhcmREb2N1bWVudChvQ29udGV4dCkudGhlbihmdW5jdGlvbiAob0NvbnRleHQ6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRpZiAob0NvbnRleHQpIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAob0NvbnRleHQuaGFzUGVuZGluZ0NoYW5nZXMoKSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0b0NvbnRleHQuZ2V0QmluZGluZygpLnJlc2V0Q2hhbmdlcygpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRpZiAoIXRoYXQuX2JDcmVhdGVNb2RlKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRvQ29udGV4dC5yZWZyZXNoKCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gb0NvbnRleHQ7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJDYW5jZWwgZG9jdW1lbnQgb25seSBhbGxvd2VkIGZvciBkcmFmdCBvciBzdGlja3kgc2Vzc2lvbiBzdXBwb3J0ZWQgc2VydmljZXNcIik7XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cdFx0XHQudGhlbihmdW5jdGlvbiAoY29udGV4dDogYW55KSB7XG5cdFx0XHRcdHRoYXQuX2JJc01vZGlmaWVkID0gZmFsc2U7XG5cdFx0XHRcdC8vIHJlbW92ZSBleGlzdGluZyBib3VuZCB0cmFuc2l0aW9uIG1lc3NhZ2VzXG5cdFx0XHRcdG1lc3NhZ2VIYW5kbGVyLnJlbW92ZVRyYW5zaXRpb25NZXNzYWdlcygpO1xuXHRcdFx0XHQvLyBzaG93IHVuYm91bmQgbWVzc2FnZXNcblx0XHRcdFx0cmV0dXJuIG1lc3NhZ2VIYW5kbGVyLnNob3dNZXNzYWdlcygpLnRoZW4oZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdHJldHVybiBjb250ZXh0O1xuXHRcdFx0XHR9KTtcblx0XHRcdH0pXG5cdFx0XHQuY2F0Y2goZnVuY3Rpb24gKGVycjogYW55KSB7XG5cdFx0XHRcdHJldHVybiBtZXNzYWdlSGFuZGxlci5zaG93TWVzc2FnZXMoKS50aGVuKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KVxuXHRcdFx0LmZpbmFsbHkoZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRCdXN5TG9ja2VyLnVubG9jayh0aGF0Lm9Mb2NrT2JqZWN0KTtcblx0XHRcdH0pO1xuXHR9XG5cdC8qKlxuXHQgKiBTYXZlcyB0aGUgZG9jdW1lbnQuXG5cdCAqXG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5UcmFuc2FjdGlvbkhlbHBlclxuXHQgKiBAc3RhdGljXG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHR9IG9Db250ZXh0IENvbnRleHQgb2YgdGhlIGRvY3VtZW50IHRvIGJlIHNhdmVkXG5cdCAqIEBwYXJhbSBvUmVzb3VyY2VCdW5kbGVcblx0ICogQHBhcmFtIGJFeGVjdXRlU2lkZUVmZmVjdHNPbkVycm9yXG5cdCAqIEBwYXJhbSBhQmluZGluZ3Ncblx0ICogQHBhcmFtIG1lc3NhZ2VIYW5kbGVyXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHJlc29sdmVzIHdpdGggPz8/XG5cdCAqIEB1aTUtcmVzdHJpY3RlZFxuXHQgKiBAZmluYWxcblx0ICovXG5cdHNhdmVEb2N1bWVudChvQ29udGV4dDogYW55LCBvUmVzb3VyY2VCdW5kbGU6IGFueSwgYkV4ZWN1dGVTaWRlRWZmZWN0c09uRXJyb3I6IGFueSwgYUJpbmRpbmdzOiBhbnksIG1lc3NhZ2VIYW5kbGVyOiBhbnkpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXNcblx0XHRjb25zdCB0aGF0ID0gdGhpcztcblx0XHRjb25zdCBzUHJvZ3JhbW1pbmdNb2RlbCA9IHRoaXMuZ2V0UHJvZ3JhbW1pbmdNb2RlbChvQ29udGV4dCk7XG5cdFx0bGV0IG9TYXZlUHJvbWlzZTtcblx0XHRpZiAoIW9Db250ZXh0KSB7XG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQmluZGluZyBjb250ZXh0IHRvIGRyYWZ0IGRvY3VtZW50IGlzIHJlcXVpcmVkXCIpKTtcblx0XHR9XG5cdFx0Ly8gaW4gY2FzZSBvZiBzYXZpbmcgLyBhY3RpdmF0aW5nIHRoZSBib3VuZCB0cmFuc2l0aW9uIG1lc3NhZ2VzIHNoYWxsIGJlIHJlbW92ZWQgYmVmb3JlIHRoZSBQQVRDSC9QT1NUXG5cdFx0Ly8gaXMgc2VudCB0byB0aGUgYmFja2VuZFxuXHRcdG1lc3NhZ2VIYW5kbGVyLnJlbW92ZVRyYW5zaXRpb25NZXNzYWdlcygpO1xuXHRcdEJ1c3lMb2NrZXIubG9jayh0aGF0Lm9Mb2NrT2JqZWN0KTtcblx0XHRpZiAoc1Byb2dyYW1taW5nTW9kZWwgPT09IFByb2dyYW1taW5nTW9kZWwuRHJhZnQpIHtcblx0XHRcdG9TYXZlUHJvbWlzZSA9IGRyYWZ0LmFjdGl2YXRlRG9jdW1lbnQob0NvbnRleHQsIHRoaXMuX2dldEFwcENvbXBvbmVudCgpLCB7fSk7XG5cdFx0fSBlbHNlIGlmIChzUHJvZ3JhbW1pbmdNb2RlbCA9PT0gUHJvZ3JhbW1pbmdNb2RlbC5TdGlja3kpIHtcblx0XHRcdG9TYXZlUHJvbWlzZSA9IHN0aWNreS5hY3RpdmF0ZURvY3VtZW50KG9Db250ZXh0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0QnVzeUxvY2tlci51bmxvY2sodGhhdC5vTG9ja09iamVjdCk7XG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiU2F2ZSBpcyBvbmx5IGFsbG93ZWQgZm9yIGRyYWZ0IG9yIHN0aWNreSBzZXNzaW9uIHN1cHBvcnRlZCBzZXJ2aWNlc1wiKSk7XG5cdFx0fVxuXHRcdHJldHVybiBvU2F2ZVByb21pc2Vcblx0XHRcdC50aGVuKGZ1bmN0aW9uIChvQWN0aXZlRG9jdW1lbnQ6IGFueSkge1xuXHRcdFx0XHRjb25zdCBiTmV3T2JqZWN0ID1cblx0XHRcdFx0XHR0aGF0LnNQcm9ncmFtbWluZ01vZGVsID09PSBQcm9ncmFtbWluZ01vZGVsLlN0aWNreSA/IHRoYXQuX2JDcmVhdGVNb2RlIDogIW9Db250ZXh0LmdldE9iamVjdCgpLkhhc0FjdGl2ZUVudGl0eTtcblx0XHRcdFx0TWVzc2FnZVRvYXN0LnNob3coXG5cdFx0XHRcdFx0Yk5ld09iamVjdFxuXHRcdFx0XHRcdFx0PyBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX09CSkVDVF9DUkVBVEVEXCIsIG9SZXNvdXJjZUJ1bmRsZSlcblx0XHRcdFx0XHRcdDogQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9PQkpFQ1RfU0FWRURcIiwgb1Jlc291cmNlQnVuZGxlKVxuXHRcdFx0XHQpO1xuXHRcdFx0XHR0aGF0Ll9iSXNNb2RpZmllZCA9IGZhbHNlO1xuXHRcdFx0XHRyZXR1cm4gbWVzc2FnZUhhbmRsZXIuc2hvd01lc3NhZ2VEaWFsb2coKS50aGVuKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRyZXR1cm4gb0FjdGl2ZURvY3VtZW50O1xuXHRcdFx0XHR9KTtcblx0XHRcdH0pXG5cdFx0XHQuY2F0Y2goZnVuY3Rpb24gKGVycjogYW55KSB7XG5cdFx0XHRcdGlmIChhQmluZGluZ3MgJiYgYUJpbmRpbmdzLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHQvKiBUaGUgc2lkZUVmZmVjdHMgYXJlIGV4ZWN1dGVkIG9ubHkgZm9yIHRhYmxlIGl0ZW1zIGluIHRyYW5zaWVudCBzdGF0ZSAqL1xuXHRcdFx0XHRcdGFCaW5kaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChvTGlzdEJpbmRpbmc6IGFueSkge1xuXHRcdFx0XHRcdFx0aWYgKCFDb21tb25VdGlscy5oYXNUcmFuc2llbnRDb250ZXh0KG9MaXN0QmluZGluZykgJiYgYkV4ZWN1dGVTaWRlRWZmZWN0c09uRXJyb3IpIHtcblx0XHRcdFx0XHRcdFx0Y29uc3Qgb0FwcENvbXBvbmVudCA9IHRoYXQuX2dldEFwcENvbXBvbmVudCgpO1xuXHRcdFx0XHRcdFx0XHRvQXBwQ29tcG9uZW50LmdldFNpZGVFZmZlY3RzU2VydmljZSgpLnJlcXVlc3RTaWRlRWZmZWN0c0Zvck5hdmlnYXRpb25Qcm9wZXJ0eShvTGlzdEJpbmRpbmcuZ2V0UGF0aCgpLCBvQ29udGV4dCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIG1lc3NhZ2VIYW5kbGVyLnNob3dNZXNzYWdlcygpLnRoZW4oZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdHJldHVybiBQcm9taXNlLnJlamVjdChlcnIpO1xuXHRcdFx0XHR9KTtcblx0XHRcdH0pXG5cdFx0XHQuZmluYWxseShmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdEJ1c3lMb2NrZXIudW5sb2NrKHRoYXQub0xvY2tPYmplY3QpO1xuXHRcdFx0fSk7XG5cdH1cblx0LyoqXG5cdCAqIENhbGxzIGEgYm91bmQgb3IgdW5ib3VuZCBhY3Rpb24uXG5cdCAqXG5cdCAqIEBmdW5jdGlvblxuXHQgKiBAc3RhdGljXG5cdCAqIEBuYW1lIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyLmNhbGxBY3Rpb25cblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzQWN0aW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgYWN0aW9uIHRvIGJlIGNhbGxlZFxuXHQgKiBAcGFyYW0ge21hcH0gW21QYXJhbWV0ZXJzXSBDb250YWlucyB0aGUgZm9sbG93aW5nIGF0dHJpYnV0ZXM6XG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHR9IFttUGFyYW1ldGVycy5jb250ZXh0c10gTWFuZGF0b3J5IGZvciBhIGJvdW5kIGFjdGlvbjogRWl0aGVyIG9uZSBjb250ZXh0IG9yIGFuIGFycmF5IHdpdGggY29udGV4dHMgZm9yIHdoaWNoIHRoZSBhY3Rpb24gaXMgdG8gYmUgY2FsbGVkXG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0Lk9EYXRhTW9kZWx9IFttUGFyYW1ldGVycy5tb2RlbF0gTWFuZGF0b3J5IGZvciBhbiB1bmJvdW5kIGFjdGlvbjogQW4gaW5zdGFuY2Ugb2YgYW4gT0RhdGEgVjQgbW9kZWxcblx0ICogQHBhcmFtIHtzdHJpbmd9IFttUGFyYW1ldGVycy5pbnZvY2F0aW9uR3JvdXBpbmddIE1vZGUgaG93IGFjdGlvbnMgYXJlIHRvIGJlIGNhbGxlZDogJ0NoYW5nZVNldCcgdG8gcHV0IGFsbCBhY3Rpb24gY2FsbHMgaW50byBvbmUgY2hhbmdlc2V0LCAnSXNvbGF0ZWQnIHRvIHB1dCB0aGVtIGludG8gc2VwYXJhdGUgY2hhbmdlc2V0c1xuXHQgKiBAcGFyYW0ge3N0cmluZ30gW21QYXJhbWV0ZXJzLmxhYmVsXSBBIGh1bWFuLXJlYWRhYmxlIGxhYmVsIGZvciB0aGUgYWN0aW9uXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gW21QYXJhbWV0ZXJzLmJHZXRCb3VuZENvbnRleHRdIElmIHNwZWNpZmllZCwgdGhlIGFjdGlvbiBwcm9taXNlIHJldHVybnMgdGhlIGJvdW5kIGNvbnRleHRcblx0ICogQHBhcmFtIHtvYmplY3R9IG9WaWV3IENvbnRhaW5zIHRoZSBvYmplY3Qgb2YgdGhlIGN1cnJlbnQgdmlld1xuXHQgKiBAcGFyYW0gbWVzc2FnZUhhbmRsZXJcblx0ICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgcmVzb2x2ZXMgd2l0aCBhbiBhcnJheSBvZiByZXNwb25zZSBvYmplY3RzIChUT0RPOiB0byBiZSBjaGFuZ2VkKVxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICogQGZpbmFsXG5cdCAqKi9cblx0Y2FsbEFjdGlvbihzQWN0aW9uTmFtZTogc3RyaW5nLCBtUGFyYW1ldGVyczogYW55LCBvVmlldzogVmlldyB8IG51bGwsIG1lc3NhZ2VIYW5kbGVyOiBhbnkpIHtcblx0XHRtUGFyYW1ldGVycyA9IGdldFBhcmFtZXRlcnMobVBhcmFtZXRlcnMpO1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuXHRcdGNvbnN0IHRoYXQgPSB0aGlzO1xuXHRcdGxldCBvQ29udGV4dCwgb01vZGVsOiBhbnksIG9Qcm9taXNlO1xuXHRcdGNvbnN0IG1CaW5kaW5nUGFyYW1ldGVycyA9IG1QYXJhbWV0ZXJzLmJpbmRpbmdQYXJhbWV0ZXJzO1xuXHRcdGlmICghc0FjdGlvbk5hbWUpIHtcblx0XHRcdHJldHVybiBQcm9taXNlLnJlamVjdChcIlByb3ZpZGUgbmFtZSBvZiBhY3Rpb24gdG8gYmUgZXhlY3V0ZWRcIik7XG5cdFx0fVxuXHRcdC8vIGFjdGlvbiBpbXBvcnRzIGFyZSBub3QgZGlyZWN0bHkgb2J0YWluZWQgZnJvbSB0aGUgbWV0YU1vZGVsIGJ5IGl0IGlzIHByZXNlbnQgaW5zaWRlIHRoZSBlbnRpdHlDb250YWluZXJcblx0XHQvLyBhbmQgdGhlIGFjaW9ucyBpdCByZWZlcnMgdG8gcHJlc2VudCBvdXRzaWRlIHRoZSBlbnRpdHljb250YWluZXIsIGhlbmNlIHRvIG9idGFpbiBraW5kIG9mIHRoZSBhY3Rpb25cblx0XHQvLyBzcGxpdCgpIG9uIGl0cyBuYW1lIHdhcyByZXF1aXJlZFxuXHRcdGNvbnN0IHNOYW1lID0gc0FjdGlvbk5hbWUuc3BsaXQoXCIvXCIpWzFdO1xuXHRcdHNBY3Rpb25OYW1lID0gc05hbWUgfHwgc0FjdGlvbk5hbWU7XG5cdFx0b0NvbnRleHQgPSBzTmFtZSA/IHVuZGVmaW5lZCA6IG1QYXJhbWV0ZXJzLmNvbnRleHRzO1xuXHRcdC8vY2hlY2tpbmcgd2hldGhlciB0aGUgY29udGV4dCBpcyBhbiBhcnJheSB3aXRoIG1vcmUgdGhhbiAwIGxlbmd0aCBvciBub3QgYW4gYXJyYXkoY3JlYXRlIGFjdGlvbilcblx0XHRpZiAob0NvbnRleHQgJiYgKChBcnJheS5pc0FycmF5KG9Db250ZXh0KSAmJiBvQ29udGV4dC5sZW5ndGgpIHx8ICFBcnJheS5pc0FycmF5KG9Db250ZXh0KSkpIHtcblx0XHRcdG9Db250ZXh0ID0gQXJyYXkuaXNBcnJheShvQ29udGV4dCkgPyBvQ29udGV4dFswXSA6IG9Db250ZXh0O1xuXHRcdFx0b01vZGVsID0gb0NvbnRleHQuZ2V0TW9kZWwoKTtcblx0XHR9XG5cdFx0aWYgKG1QYXJhbWV0ZXJzLm1vZGVsKSB7XG5cdFx0XHRvTW9kZWwgPSBtUGFyYW1ldGVycy5tb2RlbDtcblx0XHR9XG5cdFx0aWYgKCFvTW9kZWwpIHtcblx0XHRcdHJldHVybiBQcm9taXNlLnJlamVjdChcIlBhc3MgYSBjb250ZXh0IGZvciBhIGJvdW5kIGFjdGlvbiBvciBwYXNzIHRoZSBtb2RlbCBmb3IgYW4gdW5ib3VuZCBhY3Rpb25cIik7XG5cdFx0fVxuXHRcdC8vIGdldCB0aGUgYmluZGluZyBwYXJhbWV0ZXJzICRzZWxlY3QgYW5kICRleHBhbmQgZm9yIHRoZSBzaWRlIGVmZmVjdCBvbiB0aGlzIGFjdGlvblxuXHRcdC8vIGFsc28gZ2F0aGVyIGFkZGl0aW9uYWwgcHJvcGVydHkgcGF0aHMgdG8gYmUgcmVxdWVzdGVkIHN1Y2ggYXMgdGV4dCBhc3NvY2lhdGlvbnNcblx0XHRjb25zdCBvQXBwQ29tcG9uZW50ID0gdGhhdC5fZ2V0QXBwQ29tcG9uZW50KCk7XG5cdFx0Y29uc3QgbVNpZGVFZmZlY3RzUGFyYW1ldGVycyA9IG9BcHBDb21wb25lbnQuZ2V0U2lkZUVmZmVjdHNTZXJ2aWNlKCkuZ2V0T0RhdGFBY3Rpb25TaWRlRWZmZWN0cyhzQWN0aW9uTmFtZSwgb0NvbnRleHQpIHx8IHt9O1xuXHRcdGlmIChvQ29udGV4dCAmJiBvTW9kZWwpIHtcblx0XHRcdG9Qcm9taXNlID0gbmV3IFByb21pc2U8dm9pZD4oZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXHRcdFx0XHRsZXQgb0FwcGxpY2FibGVDb250ZXh0RGlhbG9nOiBEaWFsb2c7XG5cdFx0XHRcdGNvbnN0IG9Db250cm9sbGVyID0ge1xuXHRcdFx0XHRcdG9uQ2xvc2U6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdC8vIFVzZXIgY2FuY2VscyBhY3Rpb25cblx0XHRcdFx0XHRcdG9BcHBsaWNhYmxlQ29udGV4dERpYWxvZy5jbG9zZSgpO1xuXHRcdFx0XHRcdFx0cmVzb2x2ZSgpO1xuXHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0b25Db250aW51ZTogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0Ly8gVXNlcnMgY29udGludWVzIHRoZSBhY3Rpb24gd2l0aCB0aGUgYm91bmQgY29udGV4dHNcblx0XHRcdFx0XHRcdG9BcHBsaWNhYmxlQ29udGV4dERpYWxvZy5jbG9zZSgpO1xuXHRcdFx0XHRcdFx0cmVzb2x2ZShtUGFyYW1ldGVycy5hcHBsaWNhYmxlQ29udGV4dCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9O1xuXHRcdFx0XHRjb25zdCBmbk9wZW5BbmRGaWxsRGlhbG9nID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdGxldCBvRGlhbG9nQ29udGVudDtcblx0XHRcdFx0XHRjb25zdCBuTm90QXBwbGljYWJsZSA9IG1QYXJhbWV0ZXJzLm5vdEFwcGxpY2FibGVDb250ZXh0Lmxlbmd0aCxcblx0XHRcdFx0XHRcdGFOb3RBcHBsaWNhYmxlSXRlbXMgPSBbXTtcblx0XHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IG1QYXJhbWV0ZXJzLm5vdEFwcGxpY2FibGVDb250ZXh0Lmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0XHRvRGlhbG9nQ29udGVudCA9IG1QYXJhbWV0ZXJzLm5vdEFwcGxpY2FibGVDb250ZXh0W2ldLmdldE9iamVjdCgpO1xuXHRcdFx0XHRcdFx0YU5vdEFwcGxpY2FibGVJdGVtcy5wdXNoKG9EaWFsb2dDb250ZW50KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y29uc3Qgb05vdEFwcGxpY2FibGVJdGVtc01vZGVsID0gbmV3IEpTT05Nb2RlbChhTm90QXBwbGljYWJsZUl0ZW1zKTtcblx0XHRcdFx0XHRjb25zdCBvVG90YWxzID0gbmV3IEpTT05Nb2RlbCh7IHRvdGFsOiBuTm90QXBwbGljYWJsZSwgbGFiZWw6IG1QYXJhbWV0ZXJzLmxhYmVsIH0pO1xuXHRcdFx0XHRcdG9BcHBsaWNhYmxlQ29udGV4dERpYWxvZy5zZXRNb2RlbChvTm90QXBwbGljYWJsZUl0ZW1zTW9kZWwsIFwibm90QXBwbGljYWJsZVwiKTtcblx0XHRcdFx0XHRvQXBwbGljYWJsZUNvbnRleHREaWFsb2cuc2V0TW9kZWwob1RvdGFscywgXCJ0b3RhbHNcIik7XG5cdFx0XHRcdFx0b0FwcGxpY2FibGVDb250ZXh0RGlhbG9nLm9wZW4oKTtcblx0XHRcdFx0fTtcblx0XHRcdFx0aWYgKG1QYXJhbWV0ZXJzLm5vdEFwcGxpY2FibGVDb250ZXh0ICYmIG1QYXJhbWV0ZXJzLm5vdEFwcGxpY2FibGVDb250ZXh0Lmxlbmd0aCA+PSAxKSB7XG5cdFx0XHRcdFx0Ly8gU2hvdyB0aGUgY29udGV4dHMgdGhhdCBhcmUgbm90IGFwcGxpY2FibGUgYW5kIHdpbGwgbm90IHRoZXJlZm9yZSBiZSBwcm9jZXNzZWRcblx0XHRcdFx0XHRjb25zdCBzRnJhZ21lbnROYW1lID0gXCJzYXAuZmUuY29yZS5jb250cm9scy5BY3Rpb25QYXJ0aWFsXCI7XG5cdFx0XHRcdFx0Y29uc3Qgb0RpYWxvZ0ZyYWdtZW50ID0gWE1MVGVtcGxhdGVQcm9jZXNzb3IubG9hZFRlbXBsYXRlKHNGcmFnbWVudE5hbWUsIFwiZnJhZ21lbnRcIik7XG5cdFx0XHRcdFx0Y29uc3Qgb01ldGFNb2RlbCA9IG9Nb2RlbC5nZXRNZXRhTW9kZWwoKTtcblx0XHRcdFx0XHRjb25zdCBzQ2Fub25pY2FsUGF0aCA9IG1QYXJhbWV0ZXJzLmNvbnRleHRzWzBdLmdldENhbm9uaWNhbFBhdGgoKTtcblx0XHRcdFx0XHRjb25zdCBzRW50aXR5U2V0ID0gc0Nhbm9uaWNhbFBhdGguc3Vic3RyKDAsIHNDYW5vbmljYWxQYXRoLmluZGV4T2YoXCIoXCIpKSArIFwiL1wiO1xuXHRcdFx0XHRcdGNvbnN0IG9EaWFsb2dMYWJlbE1vZGVsID0gbmV3IEpTT05Nb2RlbCh7XG5cdFx0XHRcdFx0XHR0aXRsZTogbVBhcmFtZXRlcnMubGFiZWxcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRQcm9taXNlLnJlc29sdmUoXG5cdFx0XHRcdFx0XHRYTUxQcmVwcm9jZXNzb3IucHJvY2Vzcyhcblx0XHRcdFx0XHRcdFx0b0RpYWxvZ0ZyYWdtZW50LFxuXHRcdFx0XHRcdFx0XHR7IG5hbWU6IHNGcmFnbWVudE5hbWUgfSxcblx0XHRcdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0XHRcdGJpbmRpbmdDb250ZXh0czoge1xuXHRcdFx0XHRcdFx0XHRcdFx0ZW50aXR5VHlwZTogb01ldGFNb2RlbC5jcmVhdGVCaW5kaW5nQ29udGV4dChzRW50aXR5U2V0KSxcblx0XHRcdFx0XHRcdFx0XHRcdGxhYmVsOiBvRGlhbG9nTGFiZWxNb2RlbC5jcmVhdGVCaW5kaW5nQ29udGV4dChcIi9cIilcblx0XHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XHRcdG1vZGVsczoge1xuXHRcdFx0XHRcdFx0XHRcdFx0ZW50aXR5VHlwZTogb01ldGFNb2RlbCxcblx0XHRcdFx0XHRcdFx0XHRcdG1ldGFNb2RlbDogb01ldGFNb2RlbCxcblx0XHRcdFx0XHRcdFx0XHRcdGxhYmVsOiBvRGlhbG9nTGFiZWxNb2RlbFxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0KVxuXHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdC50aGVuKGZ1bmN0aW9uIChvRnJhZ21lbnQ6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gRnJhZ21lbnQubG9hZCh7IGRlZmluaXRpb246IG9GcmFnbWVudCwgY29udHJvbGxlcjogb0NvbnRyb2xsZXIgfSk7XG5cdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0LnRoZW4oZnVuY3Rpb24gKG9Qb3BvdmVyOiBhbnkpIHtcblx0XHRcdFx0XHRcdFx0b0FwcGxpY2FibGVDb250ZXh0RGlhbG9nID0gb1BvcG92ZXI7XG5cdFx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLnBhcmVudENvbnRyb2wuYWRkRGVwZW5kZW50KG9Qb3BvdmVyKTtcblx0XHRcdFx0XHRcdFx0Zm5PcGVuQW5kRmlsbERpYWxvZygpO1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdC5jYXRjaChyZWplY3QpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc29sdmUobVBhcmFtZXRlcnMuY29udGV4dHMpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KS50aGVuKGZ1bmN0aW9uIChjb250ZXh0VG9Qcm9jZXNzOiBhbnkpIHtcblx0XHRcdFx0aWYgKGNvbnRleHRUb1Byb2Nlc3MpIHtcblx0XHRcdFx0XHRyZXR1cm4gb3BlcmF0aW9ucy5jYWxsQm91bmRBY3Rpb24oc0FjdGlvbk5hbWUsIGNvbnRleHRUb1Byb2Nlc3MsIG9Nb2RlbCwgb0FwcENvbXBvbmVudCwge1xuXHRcdFx0XHRcdFx0aW52b2NhdGlvbkdyb3VwaW5nOiBtUGFyYW1ldGVycy5pbnZvY2F0aW9uR3JvdXBpbmcsXG5cdFx0XHRcdFx0XHRsYWJlbDogbVBhcmFtZXRlcnMubGFiZWwsXG5cdFx0XHRcdFx0XHRzaG93QWN0aW9uUGFyYW1ldGVyRGlhbG9nOiB0cnVlLFxuXHRcdFx0XHRcdFx0bUJpbmRpbmdQYXJhbWV0ZXJzOiBtQmluZGluZ1BhcmFtZXRlcnMsXG5cdFx0XHRcdFx0XHRlbnRpdHlTZXROYW1lOiBtUGFyYW1ldGVycy5lbnRpdHlTZXROYW1lLFxuXHRcdFx0XHRcdFx0YWRkaXRpb25hbFNpZGVFZmZlY3Q6IG1TaWRlRWZmZWN0c1BhcmFtZXRlcnMsXG5cdFx0XHRcdFx0XHRvblN1Ym1pdHRlZDogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0XHRtZXNzYWdlSGFuZGxlci5yZW1vdmVUcmFuc2l0aW9uTWVzc2FnZXMoKTtcblx0XHRcdFx0XHRcdFx0QnVzeUxvY2tlci5sb2NrKHRoYXQub0xvY2tPYmplY3QpO1xuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdG9uUmVzcG9uc2U6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdFx0QnVzeUxvY2tlci51bmxvY2sodGhhdC5vTG9ja09iamVjdCk7XG5cdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0cGFyZW50Q29udHJvbDogbVBhcmFtZXRlcnMucGFyZW50Q29udHJvbCxcblx0XHRcdFx0XHRcdGludGVybmFsTW9kZWxDb250ZXh0OiBtUGFyYW1ldGVycy5pbnRlcm5hbE1vZGVsQ29udGV4dCxcblx0XHRcdFx0XHRcdG9wZXJhdGlvbkF2YWlsYWJsZU1hcDogbVBhcmFtZXRlcnMub3BlcmF0aW9uQXZhaWxhYmxlTWFwLFxuXHRcdFx0XHRcdFx0YklzQ3JlYXRlQWN0aW9uOiBtUGFyYW1ldGVycy5iSXNDcmVhdGVBY3Rpb24sXG5cdFx0XHRcdFx0XHRiR2V0Qm91bmRDb250ZXh0OiBtUGFyYW1ldGVycy5iR2V0Qm91bmRDb250ZXh0LFxuXHRcdFx0XHRcdFx0Yk9iamVjdFBhZ2U6IG1QYXJhbWV0ZXJzLmJPYmplY3RQYWdlLFxuXHRcdFx0XHRcdFx0bWVzc2FnZUhhbmRsZXI6IG1lc3NhZ2VIYW5kbGVyLFxuXHRcdFx0XHRcdFx0ZGVmYXVsdFZhbHVlc0V4dGVuc2lvbkZ1bmN0aW9uOiBtUGFyYW1ldGVycy5kZWZhdWx0VmFsdWVzRXh0ZW5zaW9uRnVuY3Rpb25cblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIFRPRE86IGNvbmZpcm0gaWYgYWN0aW9uIGltcG9ydCBuZWVkcyBzaWRlIGVmZmVjdHMuXG5cdFx0XHRvUHJvbWlzZSA9IG9wZXJhdGlvbnMuY2FsbEFjdGlvbkltcG9ydChzQWN0aW9uTmFtZSwgb01vZGVsLCBvQXBwQ29tcG9uZW50LCB7XG5cdFx0XHRcdGxhYmVsOiBtUGFyYW1ldGVycy5sYWJlbCxcblx0XHRcdFx0c2hvd0FjdGlvblBhcmFtZXRlckRpYWxvZzogdHJ1ZSxcblx0XHRcdFx0YmluZGluZ1BhcmFtZXRlcnM6IG1CaW5kaW5nUGFyYW1ldGVycyxcblx0XHRcdFx0ZW50aXR5U2V0TmFtZTogbVBhcmFtZXRlcnMuZW50aXR5U2V0TmFtZSxcblx0XHRcdFx0b25TdWJtaXR0ZWQ6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRCdXN5TG9ja2VyLmxvY2sodGhhdC5vTG9ja09iamVjdCk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdG9uUmVzcG9uc2U6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRCdXN5TG9ja2VyLnVubG9jayh0aGF0Lm9Mb2NrT2JqZWN0KTtcblx0XHRcdFx0fSxcblx0XHRcdFx0cGFyZW50Q29udHJvbDogbVBhcmFtZXRlcnMucGFyZW50Q29udHJvbCxcblx0XHRcdFx0aW50ZXJuYWxNb2RlbENvbnRleHQ6IG1QYXJhbWV0ZXJzLmludGVybmFsTW9kZWxDb250ZXh0LFxuXHRcdFx0XHRvcGVyYXRpb25BdmFpbGFibGVNYXA6IG1QYXJhbWV0ZXJzLm9wZXJhdGlvbkF2YWlsYWJsZU1hcCxcblx0XHRcdFx0bWVzc2FnZUhhbmRsZXI6IG1lc3NhZ2VIYW5kbGVyLFxuXHRcdFx0XHRiT2JqZWN0UGFnZTogbVBhcmFtZXRlcnMuYk9iamVjdFBhZ2Vcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRyZXR1cm4gb1Byb21pc2Vcblx0XHRcdC50aGVuKGZ1bmN0aW9uIChvUmVzdWx0OiBhbnkpIHtcblx0XHRcdFx0Ly8gU3VjY2VlZGVkXG5cdFx0XHRcdHJldHVybiB0aGF0Ll9oYW5kbGVBY3Rpb25SZXNwb25zZShtZXNzYWdlSGFuZGxlciwgbVBhcmFtZXRlcnMsIHNBY3Rpb25OYW1lKS50aGVuKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRyZXR1cm4gb1Jlc3VsdDtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KVxuXHRcdFx0LmNhdGNoKGZ1bmN0aW9uIChlcnI6IGFueSkge1xuXHRcdFx0XHRyZXR1cm4gdGhhdC5faGFuZGxlQWN0aW9uUmVzcG9uc2UobWVzc2FnZUhhbmRsZXIsIG1QYXJhbWV0ZXJzLCBzQWN0aW9uTmFtZSkudGhlbihmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0cmV0dXJuIFByb21pc2UucmVqZWN0KGVycik7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cdH1cblx0LyoqXG5cdCAqIEhhbmRsZXMgbWVzc2FnZXMgZm9yIGFjdGlvbiBjYWxsLlxuXHQgKlxuXHQgKiBAZnVuY3Rpb25cblx0ICogQG5hbWUgc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXIjX2hhbmRsZUFjdGlvblJlc3BvbnNlXG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5UcmFuc2FjdGlvbkhlbHBlclxuXHQgKiBAcGFyYW0gbWVzc2FnZUhhbmRsZXJcblx0ICogQHBhcmFtIHtvYmplY3R9IG1QYXJhbWV0ZXJzIFBhcmFtZXRlcnMgdG8gYmUgY29uc2lkZXJlZCBmb3IgdGhlIGFjdGlvbi5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHNBY3Rpb25OYW1lIFRoZSBuYW1lIG9mIHRoZSBhY3Rpb24gdG8gYmUgY2FsbGVkXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIGFmdGVyIG1lc3NhZ2UgZGlhbG9nIGlzIG9wZW5lZCBpZiByZXF1aXJlZC5cblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKi9cblx0X2hhbmRsZUFjdGlvblJlc3BvbnNlKG1lc3NhZ2VIYW5kbGVyOiBhbnksIG1QYXJhbWV0ZXJzOiBhbnksIHNBY3Rpb25OYW1lOiBzdHJpbmcpIHtcblx0XHRjb25zdCBhVHJhbnNpZW50TWVzc2FnZXMgPSBtZXNzYWdlSGFuZGxpbmcuZ2V0TWVzc2FnZXModHJ1ZSwgdHJ1ZSk7XG5cdFx0aWYgKGFUcmFuc2llbnRNZXNzYWdlcy5sZW5ndGggPiAwICYmIG1QYXJhbWV0ZXJzICYmIG1QYXJhbWV0ZXJzLmludGVybmFsTW9kZWxDb250ZXh0KSB7XG5cdFx0XHRtUGFyYW1ldGVycy5pbnRlcm5hbE1vZGVsQ29udGV4dC5zZXRQcm9wZXJ0eShcInNBY3Rpb25OYW1lXCIsIG1QYXJhbWV0ZXJzLmxhYmVsID8gbVBhcmFtZXRlcnMubGFiZWwgOiBzQWN0aW9uTmFtZSk7XG5cdFx0fVxuXHRcdHJldHVybiBtZXNzYWdlSGFuZGxlci5zaG93TWVzc2FnZXMoKTtcblx0fVxuXHQvKipcblx0ICogSGFuZGxlcyB2YWxpZGF0aW9uIGVycm9ycyBmb3IgdGhlICdkaXNjYXJkJyBhY3Rpb24uXG5cdCAqXG5cdCAqIEBmdW5jdGlvblxuXHQgKiBAbmFtZSBzYXAuZmUuY29yZS5UcmFuc2FjdGlvbkhlbHBlciNoYW5kbGVWYWxpZGF0aW9uRXJyb3Jcblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyXG5cdCAqIEBzdGF0aWNcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKi9cblx0aGFuZGxlVmFsaWRhdGlvbkVycm9yKCkge1xuXHRcdGNvbnN0IG9NZXNzYWdlTWFuYWdlciA9IENvcmUuZ2V0TWVzc2FnZU1hbmFnZXIoKSxcblx0XHRcdGVycm9yVG9SZW1vdmUgPSBvTWVzc2FnZU1hbmFnZXJcblx0XHRcdFx0LmdldE1lc3NhZ2VNb2RlbCgpXG5cdFx0XHRcdC5nZXREYXRhKClcblx0XHRcdFx0LmZpbHRlcihmdW5jdGlvbiAoZXJyb3I6IGFueSkge1xuXHRcdFx0XHRcdC8vIG9ubHkgbmVlZHMgdG8gaGFuZGxlIHZhbGlkYXRpb24gbWVzc2FnZXMsIHRlY2huaWNhbCBhbmQgcGVyc2lzdGVudCBlcnJvcnMgbmVlZHMgbm90IHRvIGJlIGNoZWNrZWQgaGVyZS5cblx0XHRcdFx0XHRpZiAoZXJyb3IudmFsaWRhdGlvbikge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGVycm9yO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0b01lc3NhZ2VNYW5hZ2VyLnJlbW92ZU1lc3NhZ2VzKGVycm9yVG9SZW1vdmUpO1xuXHR9XG5cdC8qKlxuXHQgKiBTaG93cyBhIHBvcG92ZXIgaWYgaXQgbmVlZHMgdG8gYmUgc2hvd24uXG5cdCAqIFRPRE86IFBvcG92ZXIgaXMgc2hvd24gaWYgdXNlciBoYXMgbW9kaWZpZWQgYW55IGRhdGEuXG5cdCAqIFRPRE86IFBvcG92ZXIgaXMgc2hvd24gaWYgdGhlcmUncyBhIGRpZmZlcmVuY2UgZnJvbSBkcmFmdCBhZG1pbiBkYXRhLlxuXHQgKiBAc3RhdGljXG5cdCAqIEBuYW1lIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyLl9zaG93RGlzY2FyZFBvcG92ZXJcblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyXG5cdCAqIEBwYXJhbSB7c2FwLnVpLmNvcmUuQ29udHJvbH0gb0NhbmNlbEJ1dHRvbiBUaGUgY29udHJvbCB3aGljaCB3aWxsIG9wZW4gdGhlIHBvcG92ZXJcblx0ICogQHBhcmFtIGJJc01vZGlmaWVkXG5cdCAqIEBwYXJhbSBvUmVzb3VyY2VCdW5kbGVcblx0ICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgcmVzb2x2ZXMgaWYgdXNlciBjb25maXJtcyBkaXNjYXJkLCByZWplY3RzIGlmIG90aGVyd2lzZSwgcmVqZWN0cyBpZiBubyBjb250cm9sIHBhc3NlZCB0byBvcGVuIHBvcG92ZXJcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKi9cblx0X3Nob3dEaXNjYXJkUG9wb3ZlcihvQ2FuY2VsQnV0dG9uOiBhbnksIGJJc01vZGlmaWVkOiBhbnksIG9SZXNvdXJjZUJ1bmRsZTogYW55KSB7XG5cdFx0Ly8gVE9ETzogSW1wbGVtZW50IHRoaXMgcG9wb3ZlciBhcyBhIGZyYWdtZW50IGFzIGluIHYyPz9cblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXNcblx0XHRjb25zdCB0aGF0ID0gdGhpcztcblx0XHR0aGF0Ll9iQ29udGludWVEaXNjYXJkID0gZmFsc2U7XG5cdFx0Ly8gdG8gYmUgaW1wbGVtZW50ZWRcblx0XHRyZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXHRcdFx0aWYgKCFvQ2FuY2VsQnV0dG9uKSB7XG5cdFx0XHRcdHJlamVjdChcIkNhbmNlbCBidXR0b24gbm90IGZvdW5kXCIpO1xuXHRcdFx0fVxuXHRcdFx0Ly9TaG93IHBvcG92ZXIgb25seSB3aGVuIGRhdGEgaXMgY2hhbmdlZC5cblx0XHRcdGlmIChiSXNNb2RpZmllZCkge1xuXHRcdFx0XHRjb25zdCBmbk9uQWZ0ZXJEaXNjYXJkID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdG9DYW5jZWxCdXR0b24uc2V0RW5hYmxlZCh0cnVlKTtcblx0XHRcdFx0XHRpZiAodGhhdC5fYkNvbnRpbnVlRGlzY2FyZCkge1xuXHRcdFx0XHRcdFx0cmVzb2x2ZSgpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRyZWplY3QoXCJEaXNjYXJkIG9wZXJhdGlvbiB3YXMgcmVqZWN0ZWQuIERvY3VtZW50IGhhcyBub3QgYmVlbiBkaXNjYXJkZWRcIik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHRoYXQuX29Qb3BvdmVyLmRldGFjaEFmdGVyQ2xvc2UoZm5PbkFmdGVyRGlzY2FyZCk7XG5cdFx0XHRcdH07XG5cdFx0XHRcdGlmICghdGhhdC5fb1BvcG92ZXIpIHtcblx0XHRcdFx0XHRjb25zdCBvVGV4dCA9IG5ldyBUZXh0KHtcblx0XHRcdFx0XHRcdFx0Ly9UaGlzIHRleHQgaXMgdGhlIHNhbWUgYXMgTFIgdjIuXG5cdFx0XHRcdFx0XHRcdC8vVE9ETzogRGlzcGxheSBtZXNzYWdlIHByb3ZpZGVkIGJ5IGFwcCBkZXZlbG9wZXI/Pz9cblx0XHRcdFx0XHRcdFx0dGV4dDogQ29tbW9uVXRpbHMuZ2V0VHJhbnNsYXRlZFRleHQoXCJDX1RSQU5TQUNUSU9OX0hFTFBFUl9EUkFGVF9ESVNDQVJEX01FU1NBR0VcIiwgb1Jlc291cmNlQnVuZGxlKVxuXHRcdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0XHRvQnV0dG9uID0gbmV3IEJ1dHRvbih7XG5cdFx0XHRcdFx0XHRcdHRleHQ6IENvbW1vblV0aWxzLmdldFRyYW5zbGF0ZWRUZXh0KFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfRFJBRlRfRElTQ0FSRF9CVVRUT05cIiwgb1Jlc291cmNlQnVuZGxlKSxcblx0XHRcdFx0XHRcdFx0d2lkdGg6IFwiMTAwJVwiLFxuXHRcdFx0XHRcdFx0XHRwcmVzczogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0XHRcdHRoYXQuaGFuZGxlVmFsaWRhdGlvbkVycm9yKCk7XG5cdFx0XHRcdFx0XHRcdFx0dGhhdC5fYkNvbnRpbnVlRGlzY2FyZCA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdFx0dGhhdC5fb1BvcG92ZXIuY2xvc2UoKTtcblx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFx0YXJpYUxhYmVsbGVkQnk6IG9UZXh0XG5cdFx0XHRcdFx0XHR9IGFzIGFueSk7XG5cdFx0XHRcdFx0dGhhdC5fb1BvcG92ZXIgPSBuZXcgUG9wb3Zlcih7XG5cdFx0XHRcdFx0XHRzaG93SGVhZGVyOiBmYWxzZSxcblx0XHRcdFx0XHRcdHBsYWNlbWVudDogXCJUb3BcIixcblx0XHRcdFx0XHRcdGNvbnRlbnQ6IFtcblx0XHRcdFx0XHRcdFx0bmV3IFZCb3goe1xuXHRcdFx0XHRcdFx0XHRcdGl0ZW1zOiBbb1RleHQsIG9CdXR0b25dXG5cdFx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHRdLFxuXHRcdFx0XHRcdFx0YmVmb3JlT3BlbjogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0XHQvLyBtYWtlIHN1cmUgdG8gTk9UIHRyaWdnZXIgbXVsdGlwbGUgY2FuY2VsIGZsb3dzXG5cdFx0XHRcdFx0XHRcdG9DYW5jZWxCdXR0b24uc2V0RW5hYmxlZChmYWxzZSk7XG5cdFx0XHRcdFx0XHRcdHRoYXQuX29Qb3BvdmVyLnNldEluaXRpYWxGb2N1cyhvQnV0dG9uKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR0aGF0Ll9vUG9wb3Zlci5hZGRTdHlsZUNsYXNzKFwic2FwVWlDb250ZW50UGFkZGluZ1wiKTtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGF0Ll9vUG9wb3Zlci5hdHRhY2hBZnRlckNsb3NlKGZuT25BZnRlckRpc2NhcmQpO1xuXHRcdFx0XHR0aGF0Ll9vUG9wb3Zlci5vcGVuQnkob0NhbmNlbEJ1dHRvbiwgZmFsc2UpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhhdC5oYW5kbGVWYWxpZGF0aW9uRXJyb3IoKTtcblx0XHRcdFx0cmVzb2x2ZSgpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBkb2N1bWVudCB0byBtb2RpZmllZCBzdGF0ZSBvbiBwYXRjaCBldmVudC5cblx0ICpcblx0ICogQGZ1bmN0aW9uXG5cdCAqIEBzdGF0aWNcblx0ICogQG5hbWUgc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXIuaGFuZGxlRG9jdW1lbnRNb2RpZmljYXRpb25zXG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5UcmFuc2FjdGlvbkhlbHBlclxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICogQGZpbmFsXG5cdCAqL1xuXHRoYW5kbGVEb2N1bWVudE1vZGlmaWNhdGlvbnMoKSB7XG5cdFx0dGhpcy5fYklzTW9kaWZpZWQgPSB0cnVlO1xuXHR9XG5cdC8qKlxuXHQgKiBSZXRyaWV2ZXMgdGhlIG93bmVyIGNvbXBvbmVudC5cblx0ICpcblx0ICogQGZ1bmN0aW9uXG5cdCAqIEBzdGF0aWNcblx0ICogQHByaXZhdGVcblx0ICogQG5hbWUgc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXIuX2dldE93bmVyQ29tcG9uZW50XG5cdCAqIEBtZW1iZXJvZiBzYXAuZmUuY29yZS5UcmFuc2FjdGlvbkhlbHBlclxuXHQgKiBAcmV0dXJucyB7c2FwLmZlLmNvcmUuQXBwQ29tcG9uZW50fSBUaGUgYXBwIGNvbXBvbmVudFxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICogQGZpbmFsXG5cdCAqKi9cblx0X2dldEFwcENvbXBvbmVudCgpIHtcblx0XHRyZXR1cm4gdGhpcy5fb0FwcENvbXBvbmVudDtcblx0fVxuXG5cdF9vbkZpZWxkQ2hhbmdlKG9FdmVudDogYW55LCBvQ3JlYXRlQnV0dG9uOiBhbnksIG1lc3NhZ2VIYW5kbGVyOiBhbnksIGZuVmFsaWRhdGVSZXF1aXJlZFByb3BlcnRpZXM6IEZ1bmN0aW9uKSB7XG5cdFx0bWVzc2FnZUhhbmRsZXIucmVtb3ZlVHJhbnNpdGlvbk1lc3NhZ2VzKCk7XG5cdFx0Y29uc3Qgb0ZpZWxkID0gb0V2ZW50LmdldFNvdXJjZSgpO1xuXHRcdGNvbnN0IG9GaWVsZFByb21pc2UgPSBvRXZlbnQuZ2V0UGFyYW1ldGVyKFwicHJvbWlzZVwiKTtcblx0XHRpZiAob0ZpZWxkUHJvbWlzZSkge1xuXHRcdFx0cmV0dXJuIG9GaWVsZFByb21pc2Vcblx0XHRcdFx0LnRoZW4oZnVuY3Rpb24gKHZhbHVlOiBhbnkpIHtcblx0XHRcdFx0XHQvLyBTZXR0aW5nIHZhbHVlIG9mIGZpZWxkIGFzICcnIGluIGNhc2Ugb2YgdmFsdWUgaGVscCBhbmQgdmFsaWRhdGluZyBvdGhlciBmaWVsZHNcblx0XHRcdFx0XHRvRmllbGQuc2V0VmFsdWUodmFsdWUpO1xuXHRcdFx0XHRcdGZuVmFsaWRhdGVSZXF1aXJlZFByb3BlcnRpZXMoKTtcblx0XHRcdFx0XHRyZXR1cm4gb0ZpZWxkLmdldFZhbHVlKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5jYXRjaChmdW5jdGlvbiAodmFsdWU6IGFueSkge1xuXHRcdFx0XHRcdGlmICh2YWx1ZSAhPT0gXCJcIikge1xuXHRcdFx0XHRcdFx0Ly9kaXNhYmxpbmcgdGhlIGNvbnRpbnVlIGJ1dHRvbiBpbiBjYXNlIG9mIGludmFsaWQgdmFsdWUgaW4gZmllbGRcblx0XHRcdFx0XHRcdG9DcmVhdGVCdXR0b24uc2V0RW5hYmxlZChmYWxzZSk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdC8vIHZhbGlkYXRpbmcgYWxsIHRoZSBmaWVsZHMgaW4gY2FzZSBvZiBlbXB0eSB2YWx1ZSBpbiBmaWVsZFxuXHRcdFx0XHRcdFx0b0ZpZWxkLnNldFZhbHVlKHZhbHVlKTtcblx0XHRcdFx0XHRcdGZuVmFsaWRhdGVSZXF1aXJlZFByb3BlcnRpZXMoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdF9sYXVuY2hEaWFsb2dXaXRoS2V5RmllbGRzKFxuXHRcdG9MaXN0QmluZGluZzogYW55LFxuXHRcdG9UcmFuc2llbnRMaXN0QmluZGluZzogYW55LFxuXHRcdG9UcmFuc2llbnRDb250ZXh0OiBhbnksXG5cdFx0bUZpZWxkczogYW55LFxuXHRcdG9Nb2RlbDogYW55LFxuXHRcdG1QYXJhbWV0ZXJzOiBhbnksXG5cdFx0bWVzc2FnZUhhbmRsZXI6IGFueVxuXHQpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXNcblx0XHRjb25zdCB0aGF0ID0gdGhpcztcblx0XHRsZXQgb0RpYWxvZzogRGlhbG9nO1xuXHRcdGNvbnN0IG9QYXJlbnRDb250cm9sID0gbVBhcmFtZXRlcnMucGFyZW50Q29udHJvbCxcblx0XHRcdGJTdWNjZXNzID0gZmFsc2U7XG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlOiAodmFsdWU6IGFueSkgPT4gdm9pZCwgcmVqZWN0OiAocmVhc29uPzogYW55KSA9PiB2b2lkKSB7XG5cdFx0XHRjb25zdCBzRnJhZ21lbnROYW1lID0gXCJzYXAvZmUvY29yZS9jb250cm9scy9Ob25Db21wdXRlZFZpc2libGVLZXlGaWVsZHNEaWFsb2dcIjtcblx0XHRcdGNvbnN0IG9GcmFnbWVudCA9IFhNTFRlbXBsYXRlUHJvY2Vzc29yLmxvYWRUZW1wbGF0ZShzRnJhZ21lbnROYW1lLCBcImZyYWdtZW50XCIpLFxuXHRcdFx0XHRvUmVzb3VyY2VCdW5kbGUgPSBvUGFyZW50Q29udHJvbC5nZXRDb250cm9sbGVyKCkub1Jlc291cmNlQnVuZGxlLFxuXHRcdFx0XHRvTWV0YU1vZGVsID0gb01vZGVsLmdldE1ldGFNb2RlbCgpLFxuXHRcdFx0XHRhSW1tdXRhYmxlRmllbGRzOiBhbnlbXSA9IFtdLFxuXHRcdFx0XHRvQXBwQ29tcG9uZW50ID0gdGhhdC5fZ2V0QXBwQ29tcG9uZW50KCksXG5cdFx0XHRcdHNQYXRoID0gb0xpc3RCaW5kaW5nLmlzUmVsYXRpdmUoKSA/IG9MaXN0QmluZGluZy5nZXRSZXNvbHZlZFBhdGgoKSA6IG9MaXN0QmluZGluZy5nZXRQYXRoKCksXG5cdFx0XHRcdG9FbnRpdHlTZXRDb250ZXh0ID0gb01ldGFNb2RlbC5jcmVhdGVCaW5kaW5nQ29udGV4dChzUGF0aCksXG5cdFx0XHRcdHNNZXRhUGF0aCA9IG9NZXRhTW9kZWwuZ2V0TWV0YVBhdGgoc1BhdGgpO1xuXHRcdFx0Zm9yIChjb25zdCBpIGluIG1GaWVsZHMpIHtcblx0XHRcdFx0YUltbXV0YWJsZUZpZWxkcy5wdXNoKG9NZXRhTW9kZWwuY3JlYXRlQmluZGluZ0NvbnRleHQoc01ldGFQYXRoICsgXCIvXCIgKyBtRmllbGRzW2ldKSk7XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBvSW1tdXRhYmxlQ3R4TW9kZWwgPSBuZXcgSlNPTk1vZGVsKGFJbW11dGFibGVGaWVsZHMpO1xuXHRcdFx0Y29uc3Qgb0ltbXV0YWJsZUN0eCA9IG9JbW11dGFibGVDdHhNb2RlbC5jcmVhdGVCaW5kaW5nQ29udGV4dChcIi9cIikgYXMgQ29udGV4dDtcblx0XHRcdHJldHVybiBQcm9taXNlLnJlc29sdmUoXG5cdFx0XHRcdFhNTFByZXByb2Nlc3Nvci5wcm9jZXNzKFxuXHRcdFx0XHRcdG9GcmFnbWVudCxcblx0XHRcdFx0XHR7IG5hbWU6IHNGcmFnbWVudE5hbWUgfSxcblx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRiaW5kaW5nQ29udGV4dHM6IHtcblx0XHRcdFx0XHRcdFx0ZW50aXR5U2V0OiBvRW50aXR5U2V0Q29udGV4dCxcblx0XHRcdFx0XHRcdFx0ZmllbGRzOiBvSW1tdXRhYmxlQ3R4XG5cdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0bW9kZWxzOiB7XG5cdFx0XHRcdFx0XHRcdGVudGl0eVNldDogb0VudGl0eVNldENvbnRleHQuZ2V0TW9kZWwoKSxcblx0XHRcdFx0XHRcdFx0ZmllbGRzOiBvSW1tdXRhYmxlQ3R4LmdldE1vZGVsKCksXG5cdFx0XHRcdFx0XHRcdG1ldGFNb2RlbDogb01ldGFNb2RlbFxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0KVxuXHRcdFx0KS50aGVuKGZ1bmN0aW9uIChvRnJhZ21lbnQ6IGFueSkge1xuXHRcdFx0XHRsZXQgYUZvcm1FbGVtZW50czogYW55W10gPSBbXTtcblx0XHRcdFx0Y29uc3QgbUZpZWxkVmFsdWVNYXA6IGFueSA9IHt9O1xuXHRcdFx0XHRsZXQgb0NyZWF0ZUJ1dHRvbjogQnV0dG9uO1xuXHRcdFx0XHRjb25zdCB2YWxpZGF0ZVJlcXVpcmVkUHJvcGVydGllcyA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5hbGwoXG5cdFx0XHRcdFx0XHRhRm9ybUVsZW1lbnRzXG5cdFx0XHRcdFx0XHRcdC5tYXAoZnVuY3Rpb24gKG9Gb3JtRWxlbWVudDogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG9Gb3JtRWxlbWVudC5nZXRGaWVsZHMoKVswXTtcblx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdFx0LmZpbHRlcihmdW5jdGlvbiAob0ZpZWxkOiBhbnkpIHtcblx0XHRcdFx0XHRcdFx0XHQvLyBUaGUgY29udGludWUgYnV0dG9uIHNob3VsZCByZW1haW4gZGlzYWJsZWQgaW4gY2FzZSBvZiBlcnJvciBpbiBhbnkgZmllbGQgb2YgdGhlIGNyZWF0ZSBkaWFsb2dcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gb0ZpZWxkLmdldFJlcXVpcmVkKCkgfHwgKG9GaWVsZC5nZXRWYWx1ZVN0YXRlKCkgPT09IFZhbHVlU3RhdGUuRXJyb3IgJiYgb0ZpZWxkLmdldFZhbHVlKCkgIT09IFwiXCIpO1xuXHRcdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0XHQubWFwKGZ1bmN0aW9uIChvRmllbGQ6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IHNGaWVsZElkID0gb0ZpZWxkLmdldElkKCk7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKHNGaWVsZElkIGluIG1GaWVsZFZhbHVlTWFwKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG1GaWVsZFZhbHVlTWFwW3NGaWVsZElkXSlcblx0XHRcdFx0XHRcdFx0XHRcdFx0LnRoZW4oZnVuY3Rpb24gKHZWYWx1ZTogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG9GaWVsZC5nZXRWYWx1ZVN0YXRlKCkgPT09IFZhbHVlU3RhdGUuRXJyb3IgPyB1bmRlZmluZWQgOiB2VmFsdWU7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5jYXRjaChmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdHJldHVybiBvRmllbGQuZ2V0VmFsdWVTdGF0ZSgpID09PSBWYWx1ZVN0YXRlLkVycm9yID8gdW5kZWZpbmVkIDogb0ZpZWxkLmdldFZhbHVlKCk7XG5cdFx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0KVxuXHRcdFx0XHRcdFx0LnRoZW4oZnVuY3Rpb24gKGFSZXN1bHRzOiBhbnlbXSkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gYVJlc3VsdHMuZXZlcnkoZnVuY3Rpb24gKHZWYWx1ZTogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHZWYWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZWYWx1ZSAhPT0gbnVsbCAmJiB2VmFsdWUgIT09IFwiXCI7XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdC5jYXRjaChmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHQudGhlbihmdW5jdGlvbiAoYkVuYWJsZWQ6IGJvb2xlYW4pIHtcblx0XHRcdFx0XHRcdFx0b0NyZWF0ZUJ1dHRvbi5zZXRFbmFibGVkKGJFbmFibGVkKTtcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9O1xuXHRcdFx0XHRjb25zdCBvQ29udHJvbGxlciA9IHtcblx0XHRcdFx0XHQvKlxuICAgIFx0XHRcdFx0XHRcdFx0XHRcdGZpcmVkIG9uIGZvY3VzIG91dCBmcm9tIGZpZWxkIG9yIG9uIHNlbGVjdGluZyBhIHZhbHVlIGZyb20gdGhlIHZhbHVlaGVscC5cbiAgICBcdFx0XHRcdFx0XHRcdFx0XHR0aGUgY3JlYXRlIGJ1dHRvbiBpcyBlbmFibGVkIHdoZW4gYSB2YWx1ZSBpcyBhZGRlZC5cbiAgICBcdFx0XHRcdFx0XHRcdFx0XHRsaXZlQ2hhbmdlIGlzIG5vdCBmaXJlZCB3aGVuIHZhbHVlIGlzIGFkZGVkIGZyb20gdmFsdWVoZWxwLlxuICAgIFx0XHRcdFx0XHRcdFx0XHRcdHZhbHVlIHZhbGlkYXRpb24gaXMgbm90IGRvbmUgZm9yIGNyZWF0ZSBidXR0b24gZW5hYmxlbWVudC5cbiAgICBcdFx0XHRcdFx0XHRcdFx0Ki9cblx0XHRcdFx0XHRoYW5kbGVDaGFuZ2U6IGZ1bmN0aW9uIChvRXZlbnQ6IGFueSkge1xuXHRcdFx0XHRcdFx0Y29uc3Qgc0ZpZWxkSWQgPSBvRXZlbnQuZ2V0UGFyYW1ldGVyKFwiaWRcIik7XG5cdFx0XHRcdFx0XHRtRmllbGRWYWx1ZU1hcFtzRmllbGRJZF0gPSB0aGF0Ll9vbkZpZWxkQ2hhbmdlKG9FdmVudCwgb0NyZWF0ZUJ1dHRvbiwgbWVzc2FnZUhhbmRsZXIsIHZhbGlkYXRlUmVxdWlyZWRQcm9wZXJ0aWVzKTtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdC8qXG4gICAgXHRcdFx0XHRcdFx0XHRcdFx0ZmlyZWQgb24ga2V5IHByZXNzLiB0aGUgY3JlYXRlIGJ1dHRvbiBpcyBlbmFibGVkIHdoZW4gYSB2YWx1ZSBpcyBhZGRlZC5cbiAgICBcdFx0XHRcdFx0XHRcdFx0XHRsaXZlQ2hhbmdlIGlzIG5vdCBmaXJlZCB3aGVuIHZhbHVlIGlzIGFkZGVkIGZyb20gdmFsdWVoZWxwLlxuICAgIFx0XHRcdFx0XHRcdFx0XHRcdHZhbHVlIHZhbGlkYXRpb24gaXMgbm90IGRvbmUgZm9yIGNyZWF0ZSBidXR0b24gZW5hYmxlbWVudC5cbiAgICBcdFx0XHRcdFx0XHRcdFx0Ki9cblx0XHRcdFx0XHRoYW5kbGVMaXZlQ2hhbmdlOiBmdW5jdGlvbiAob0V2ZW50OiBhbnkpIHtcblx0XHRcdFx0XHRcdGNvbnN0IHNGaWVsZElkID0gb0V2ZW50LmdldFBhcmFtZXRlcihcImlkXCIpO1xuXHRcdFx0XHRcdFx0Y29uc3QgdlZhbHVlID0gb0V2ZW50LmdldFBhcmFtZXRlcihcInZhbHVlXCIpO1xuXHRcdFx0XHRcdFx0bUZpZWxkVmFsdWVNYXBbc0ZpZWxkSWRdID0gdlZhbHVlO1xuXHRcdFx0XHRcdFx0dmFsaWRhdGVSZXF1aXJlZFByb3BlcnRpZXMoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH07XG5cdFx0XHRcdHJldHVybiBGcmFnbWVudC5sb2FkKHtcblx0XHRcdFx0XHRkZWZpbml0aW9uOiBvRnJhZ21lbnQsXG5cdFx0XHRcdFx0Y29udHJvbGxlcjogb0NvbnRyb2xsZXJcblx0XHRcdFx0fSkudGhlbihmdW5jdGlvbiAob0RpYWxvZ0NvbnRlbnQ6IGFueSkge1xuXHRcdFx0XHRcdG9EaWFsb2cgPSBuZXcgRGlhbG9nKHtcblx0XHRcdFx0XHRcdHRpdGxlOiBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX1NBUEZFX0FDVElPTl9DUkVBVEVcIiwgb1Jlc291cmNlQnVuZGxlKSxcblx0XHRcdFx0XHRcdGNvbnRlbnQ6IFtvRGlhbG9nQ29udGVudF0sXG5cdFx0XHRcdFx0XHRiZWdpbkJ1dHRvbjoge1xuXHRcdFx0XHRcdFx0XHR0ZXh0OiBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcIkNfVFJBTlNBQ1RJT05fSEVMUEVSX1NBUEZFX0FDVElPTl9DUkVBVEVfQlVUVE9OXCIsIG9SZXNvdXJjZUJ1bmRsZSksXG5cdFx0XHRcdFx0XHRcdHR5cGU6IFwiRW1waGFzaXplZFwiLFxuXHRcdFx0XHRcdFx0XHRwcmVzczogZnVuY3Rpb24gKG9FdmVudDogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29uc3Qgb0NyZWF0ZUJ1dHRvbiA9IG9FdmVudC5nZXRTb3VyY2UoKTtcblx0XHRcdFx0XHRcdFx0XHRvQ3JlYXRlQnV0dG9uLnNldEVuYWJsZWQoZmFsc2UpO1xuXHRcdFx0XHRcdFx0XHRcdEJ1c3lMb2NrZXIubG9jayhvRGlhbG9nKTtcblx0XHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVycy5iSXNDcmVhdGVEaWFsb2cgPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiBQcm9taXNlLmFsbChcblx0XHRcdFx0XHRcdFx0XHRcdE9iamVjdC5rZXlzKG1GaWVsZFZhbHVlTWFwKS5tYXAoZnVuY3Rpb24gKHNLZXk6IHN0cmluZykge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gbUZpZWxkVmFsdWVNYXBbc0tleV0udGhlbihmdW5jdGlvbiAob1ZhbHVlOiBhbnkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRjb25zdCBvRGlhbG9nVmFsdWU6IGFueSA9IHt9O1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG9EaWFsb2dWYWx1ZVtzS2V5XSA9IG9WYWx1ZTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gb0RpYWxvZ1ZhbHVlO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHRcdFx0KVxuXHRcdFx0XHRcdFx0XHRcdFx0LnRoZW4oZnVuY3Rpb24gKGFWYWx1ZXM6IGFueVtdKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGxldCBvbkJlZm9yZUNyZWF0ZVByb21pc2U7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmIChtUGFyYW1ldGVycy5iZWZvcmVDcmVhdGVDYWxsQmFjaykge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG9uQmVmb3JlQ3JlYXRlUHJvbWlzZSA9IG1QYXJhbWV0ZXJzLmJlZm9yZUNyZWF0ZUNhbGxCYWNrKHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGNvbnRleHRQYXRoOiBvTGlzdEJpbmRpbmcgJiYgb0xpc3RCaW5kaW5nLmdldFBhdGgoKSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGNyZWF0ZVBhcmFtZXRlcnM6IGFWYWx1ZXNcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvbkJlZm9yZUNyZWF0ZVByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gb25CZWZvcmVDcmVhdGVQcm9taXNlO1xuXHRcdFx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdFx0XHRcdC50aGVuKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0Y29uc3Qgb1Byb21pc2UgPSB0aGF0Lm9uQWZ0ZXJDcmVhdGVDb21wbGV0aW9uKFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG9UcmFuc2llbnRMaXN0QmluZGluZyxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvVHJhbnNpZW50Q29udGV4dCxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRtUGFyYW1ldGVyc1xuXHRcdFx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRvTW9kZWwuc3VibWl0QmF0Y2goXCJzdWJtaXRMYXRlclwiKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG9Qcm9taXNlO1xuXHRcdFx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdFx0XHRcdC50aGVuKGZ1bmN0aW9uIChvUmVzcG9uc2U6IGFueSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIW9SZXNwb25zZSB8fCAob1Jlc3BvbnNlICYmIG9SZXNwb25zZS5iS2VlcERpYWxvZ09wZW4gIT09IHRydWUpKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0b0RpYWxvZy5zZXRCaW5kaW5nQ29udGV4dChudWxsIGFzIGFueSk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0b0RpYWxvZy5jbG9zZSgpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJlc29sdmUob1Jlc3BvbnNlKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdFx0XHRcdC5jYXRjaChmdW5jdGlvbiAob0Vycm9yOiBhbnkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmVqZWN0KG9FcnJvcik7XG5cdFx0XHRcdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0XHRcdFx0LmZpbmFsbHkoZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRCdXN5TG9ja2VyLnVubG9jayhvRGlhbG9nKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0b0NyZWF0ZUJ1dHRvbi5zZXRFbmFibGVkKHRydWUpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gbWVzc2FnZUhhbmRsZXIuc2hvd01lc3NhZ2VzKCk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdGVuZEJ1dHRvbjoge1xuXHRcdFx0XHRcdFx0XHR0ZXh0OiBDb21tb25VdGlscy5nZXRUcmFuc2xhdGVkVGV4dChcIkNfQ09NTU9OX0FDVElPTl9QQVJBTUVURVJfRElBTE9HX0NBTkNFTFwiLCBvUmVzb3VyY2VCdW5kbGUpLFxuXHRcdFx0XHRcdFx0XHRwcmVzczogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0XHRcdG9EaWFsb2cuY2xvc2UoKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdGFmdGVyQ2xvc2U6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdFx0Ly8gc2hvdyBmb290ZXIgYXMgcGVyIFVYIGd1aWRlbGluZXMgd2hlbiBkaWFsb2cgaXMgbm90IG9wZW5cblx0XHRcdFx0XHRcdFx0KG9EaWFsb2cuZ2V0QmluZGluZ0NvbnRleHQoXCJpbnRlcm5hbFwiKSBhcyBJbnRlcm5hbE1vZGVsQ29udGV4dCk/LnNldFByb3BlcnR5KFwiaXNDcmVhdGVEaWFsb2dPcGVuXCIsIGZhbHNlKTtcblx0XHRcdFx0XHRcdFx0b0RpYWxvZy5kZXN0cm95KCk7XG5cdFx0XHRcdFx0XHRcdGlmICghYlN1Y2Nlc3MpIHtcblx0XHRcdFx0XHRcdFx0XHRyZWplY3Qoe1xuXHRcdFx0XHRcdFx0XHRcdFx0YkRlbGV0ZVRyYW5zaWVudENvbnRleHQ6IHRydWUsXG5cdFx0XHRcdFx0XHRcdFx0XHRuYXZpZ2F0ZUJhY2tGcm9tVHJhbnNpZW50U3RhdGU6IHRydWVcblx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gYXMgYW55KTtcblx0XHRcdFx0XHRhRm9ybUVsZW1lbnRzID0gb0RpYWxvZ0NvbnRlbnRcblx0XHRcdFx0XHRcdC5nZXRBZ2dyZWdhdGlvbihcImZvcm1cIilcblx0XHRcdFx0XHRcdC5nZXRBZ2dyZWdhdGlvbihcImZvcm1Db250YWluZXJzXCIpWzBdXG5cdFx0XHRcdFx0XHQuZ2V0QWdncmVnYXRpb24oXCJmb3JtRWxlbWVudHNcIik7XG5cdFx0XHRcdFx0aWYgKG9QYXJlbnRDb250cm9sICYmIG9QYXJlbnRDb250cm9sLmFkZERlcGVuZGVudCkge1xuXHRcdFx0XHRcdFx0Ly8gaWYgdGhlcmUgaXMgYSBwYXJlbnQgY29udHJvbCBzcGVjaWZpZWQgYWRkIHRoZSBkaWFsb2cgYXMgZGVwZW5kZW50XG5cdFx0XHRcdFx0XHRvUGFyZW50Q29udHJvbC5hZGREZXBlbmRlbnQob0RpYWxvZyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdG9DcmVhdGVCdXR0b24gPSBvRGlhbG9nLmdldEJlZ2luQnV0dG9uKCk7XG5cdFx0XHRcdFx0b0RpYWxvZy5zZXRCaW5kaW5nQ29udGV4dChvVHJhbnNpZW50Q29udGV4dCk7XG5cdFx0XHRcdFx0cmV0dXJuIENvbW1vblV0aWxzLnNldFVzZXJEZWZhdWx0cyhcblx0XHRcdFx0XHRcdG9BcHBDb21wb25lbnQsXG5cdFx0XHRcdFx0XHRhSW1tdXRhYmxlRmllbGRzLFxuXHRcdFx0XHRcdFx0b1RyYW5zaWVudENvbnRleHQsXG5cdFx0XHRcdFx0XHRmYWxzZSxcblx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmNyZWF0ZUFjdGlvbixcblx0XHRcdFx0XHRcdG1QYXJhbWV0ZXJzLmRhdGFcblx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQudGhlbihmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHRcdHZhbGlkYXRlUmVxdWlyZWRQcm9wZXJ0aWVzKCk7XG5cdFx0XHRcdFx0XHRcdC8vIGZvb3RlciBtdXN0IG5vdCBiZSB2aXNpYmxlIHdoZW4gdGhlIGRpYWxvZyBpcyBvcGVuIGFzIHBlciBVWCBndWlkZWxpbmVzXG5cdFx0XHRcdFx0XHRcdChvRGlhbG9nLmdldEJpbmRpbmdDb250ZXh0KFwiaW50ZXJuYWxcIikgYXMgSW50ZXJuYWxNb2RlbENvbnRleHQpLnNldFByb3BlcnR5KFwiaXNDcmVhdGVEaWFsb2dPcGVuXCIsIHRydWUpO1xuXHRcdFx0XHRcdFx0XHRvRGlhbG9nLm9wZW4oKTtcblx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHQuY2F0Y2goZnVuY3Rpb24gKG9FcnJvcjogYW55KSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBtZXNzYWdlSGFuZGxlci5zaG93TWVzc2FnZXMoKS50aGVuKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZWplY3Qob0Vycm9yKTtcblx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXHRvbkFmdGVyQ3JlYXRlQ29tcGxldGlvbihvTGlzdEJpbmRpbmc6IGFueSwgb05ld0RvY3VtZW50Q29udGV4dDogYW55LCBtUGFyYW1ldGVyczogYW55KSB7XG5cdFx0bGV0IGZuUmVzb2x2ZTogRnVuY3Rpb24sIGZuUmVqZWN0OiBGdW5jdGlvbjtcblx0XHRjb25zdCBvUHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcblx0XHRcdGZuUmVzb2x2ZSA9IHJlc29sdmU7XG5cdFx0XHRmblJlamVjdCA9IHJlamVjdDtcblx0XHR9KTtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXNcblx0XHRjb25zdCB0aGF0ID0gdGhpcztcblx0XHQvLyBXb3JrYXJvdW5kIHN1Z2dlc3RlZCBieSBPRGF0YSBtb2RlbCB2NCBjb2xsZWFndWVzXG5cdFx0Y29uc3QgZm5DcmVhdGVDb21wbGV0ZWQgPSBmdW5jdGlvbiAob0V2ZW50OiBhbnkpIHtcblx0XHRcdGNvbnN0IG9Db250ZXh0ID0gb0V2ZW50LmdldFBhcmFtZXRlcihcImNvbnRleHRcIiksXG5cdFx0XHRcdGJTdWNjZXNzID0gb0V2ZW50LmdldFBhcmFtZXRlcihcInN1Y2Nlc3NcIik7XG5cdFx0XHRpZiAob0NvbnRleHQgPT09IG9OZXdEb2N1bWVudENvbnRleHQpIHtcblx0XHRcdFx0b0xpc3RCaW5kaW5nLmRldGFjaENyZWF0ZUNvbXBsZXRlZChmbkNyZWF0ZUNvbXBsZXRlZCwgdGhhdCk7XG5cdFx0XHRcdGlmICghYlN1Y2Nlc3MpIHtcblx0XHRcdFx0XHRjb25zdCBvRXJyb3I6IGFueSA9IHsgYkRlbGV0ZVRyYW5zaWVudENvbnRleHQ6IGZhbHNlIH07XG5cdFx0XHRcdFx0aWYgKCFtUGFyYW1ldGVycy5rZWVwVHJhbnNpZW50Q29udGV4dE9uRmFpbGVkKSB7XG5cdFx0XHRcdFx0XHQvLyB0aGUgY29udGV4dCBpcyBkZWxldGVkXG5cblx0XHRcdFx0XHRcdC8vIHRoaXMgaXMgbmVlZGVkIHRvIGF2b2lkIGNvbnNvbGUgZXJyb3JzIFRPIGJlIGNoZWNrZWQgd2l0aCBtb2RlbCBjb2xsZWFndWVzXG5cdFx0XHRcdFx0XHRvQ29udGV4dFxuXHRcdFx0XHRcdFx0XHQuY3JlYXRlZCgpXG5cdFx0XHRcdFx0XHRcdC50aGVuKHVuZGVmaW5lZCwgZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0XHRcdExvZy50cmFjZShcInRyYW5zaWVudCBjcmVhdGlvbiBjb250ZXh0IGRlbGV0ZWRcIik7XG5cdFx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHRcdC5jYXRjaChmdW5jdGlvbiAob0Vycm9yOiBhbnkpIHtcblx0XHRcdFx0XHRcdFx0XHRMb2cudHJhY2UoXCJ0cmFuc2llbnQgY3JlYXRpb24gY29udGV4dCBkZWxldGlvbiBlcnJvclwiLCBvRXJyb3IpO1xuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdGlmICghbVBhcmFtZXRlcnMuYklzQ3JlYXRlRGlhbG9nKSB7XG5cdFx0XHRcdFx0XHRcdC8vIGlmIGN1cnJlbnQgc3RhdGUgaXMgdHJhbnNpZW50ICguLi4pLCBicm93c2VyIHdpbGwgY29tZSBiYWNrIHRvIHByZXZpb3VzIHN0YXRlXG5cdFx0XHRcdFx0XHRcdG9FcnJvci5uYXZpZ2F0ZUJhY2tGcm9tVHJhbnNpZW50U3RhdGUgPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRvRXJyb3IuYkRlbGV0ZVRyYW5zaWVudENvbnRleHQgPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRmblJlamVjdChvRXJyb3IpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRmblJlc29sdmUoeyBiS2VlcERpYWxvZ09wZW46IHRydWUgfSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Zm5SZXNvbHZlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHRcdG9MaXN0QmluZGluZy5hdHRhY2hDcmVhdGVDb21wbGV0ZWQoZm5DcmVhdGVDb21wbGV0ZWQsIHRoaXMpO1xuXHRcdHJldHVybiBvUHJvbWlzZTtcblx0fVxuXHQvKipcblx0ICogUmV0cmlldmVzIHRoZSBuYW1lIG9mIHRoZSBOZXdBY3Rpb24gdG8gYmUgZXhlY3V0ZWQuXG5cdCAqXG5cdCAqIEBmdW5jdGlvblxuXHQgKiBAc3RhdGljXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBuYW1lIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyLl9nZXROZXdBY3Rpb25cblx0ICogQG1lbWJlcm9mIHNhcC5mZS5jb3JlLlRyYW5zYWN0aW9uSGVscGVyXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvU3RhcnR1cFBhcmFtZXRlcnMgU3RhcnR1cCBwYXJhbWV0ZXJzIG9mIHRoZSBhcHBsaWNhdGlvblxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc0NyZWF0ZUhhc2ggSGFzaCB0byBiZSBjaGVja2VkIGZvciBhY3Rpb24gdHlwZVxuXHQgKiBAcGFyYW0ge29iamVjdH0gb01ldGFNb2RlbCBUaGUgTWV0YU1vZGVsIHVzZWQgdG8gY2hlY2sgZm9yIE5ld0FjdGlvbiBwYXJhbWV0ZXJcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNNZXRhUGF0aCBUaGUgTWV0YVBhdGhcblx0ICogQHJldHVybnMge3N0cmluZ30gVGhlIG5hbWUgb2YgdGhlIGFjdGlvblxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICogQGZpbmFsXG5cdCAqKi9cblx0X2dldE5ld0FjdGlvbihvU3RhcnR1cFBhcmFtZXRlcnM6IGFueSwgc0NyZWF0ZUhhc2g6IHN0cmluZywgb01ldGFNb2RlbDogT0RhdGFNZXRhTW9kZWwsIHNNZXRhUGF0aDogc3RyaW5nKSB7XG5cdFx0bGV0IHNOZXdBY3Rpb247XG5cblx0XHRpZiAob1N0YXJ0dXBQYXJhbWV0ZXJzICYmIG9TdGFydHVwUGFyYW1ldGVycy5wcmVmZXJyZWRNb2RlICYmIHNDcmVhdGVIYXNoLmluZGV4T2YoXCJpLWFjdGlvbj1jcmVhdGVXaXRoXCIpID4gLTEpIHtcblx0XHRcdGNvbnN0IHNQcmVmZXJyZWRNb2RlID0gb1N0YXJ0dXBQYXJhbWV0ZXJzLnByZWZlcnJlZE1vZGVbMF07XG5cdFx0XHRzTmV3QWN0aW9uID1cblx0XHRcdFx0c1ByZWZlcnJlZE1vZGUuaW5kZXhPZihcImNyZWF0ZVdpdGg6XCIpID4gLTEgPyBzUHJlZmVycmVkTW9kZS5zdWJzdHIoc1ByZWZlcnJlZE1vZGUubGFzdEluZGV4T2YoXCI6XCIpICsgMSkgOiB1bmRlZmluZWQ7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHNOZXdBY3Rpb24gPVxuXHRcdFx0XHRvTWV0YU1vZGVsICYmIG9NZXRhTW9kZWwuZ2V0T2JqZWN0ICE9PSB1bmRlZmluZWRcblx0XHRcdFx0XHQ/IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNNZXRhUGF0aCArIFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLlNlc3Npb24udjEuU3RpY2t5U2Vzc2lvblN1cHBvcnRlZC9OZXdBY3Rpb25cIikgfHxcblx0XHRcdFx0XHQgIG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNNZXRhUGF0aCArIFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5EcmFmdFJvb3QvTmV3QWN0aW9uXCIpXG5cdFx0XHRcdFx0OiB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdHJldHVybiBzTmV3QWN0aW9uO1xuXHR9XG5cdC8qKlxuXHQgKiBSZXRyaWV2ZXMgdGhlIGxhYmVsIGZvciB0aGUgdGl0bGUgb2YgYSBzcGVjaWZpYyBjcmVhdGUgYWN0aW9uIGRpYWxvZywgZS5nLiBDcmVhdGUgU2FsZXMgT3JkZXIgZnJvbSBRdW90YXRpb24uXG5cdCAqXG5cdCAqIFRoZSBmb2xsb3dpbmcgcHJpb3JpdHkgaXMgYXBwbGllZDpcblx0ICogMS4gbGFiZWwgb2YgbGluZS1pdGVtIGFubm90YXRpb24uXG5cdCAqIDIuIGxhYmVsIGFubm90YXRlZCBpbiB0aGUgYWN0aW9uLlxuXHQgKiAzLiBcIkNyZWF0ZVwiIGFzIGEgY29uc3RhbnQgZnJvbSBpMThuLlxuXHQgKlxuXHQgKiBAZnVuY3Rpb25cblx0ICogQHN0YXRpY1xuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAbmFtZSBzYXAuZmUuY29yZS5UcmFuc2FjdGlvbkhlbHBlci5fZ2V0U3BlY2lmaWNDcmVhdGVBY3Rpb25EaWFsb2dMYWJlbFxuXHQgKiBAbWVtYmVyb2Ygc2FwLmZlLmNvcmUuVHJhbnNhY3Rpb25IZWxwZXJcblx0ICogQHBhcmFtIHtvYmplY3R9IG9NZXRhTW9kZWwgVGhlIE1ldGFNb2RlbCB1c2VkIHRvIGNoZWNrIGZvciB0aGUgTmV3QWN0aW9uIHBhcmFtZXRlclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc01ldGFQYXRoIFRoZSBNZXRhUGF0aFxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc05ld0FjdGlvbiBDb250YWlucyB0aGUgbmFtZSBvZiB0aGUgYWN0aW9uIHRvIGJlIGV4ZWN1dGVkXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvUmVzb3VyY2VCdW5kbGVDb3JlIFJlc291cmNlQnVuZGxlIHRvIGFjY2VzcyB0aGUgZGVmYXVsdCBDcmVhdGUgbGFiZWxcblx0ICogQHJldHVybnMge3N0cmluZ30gVGhlIGxhYmVsIGZvciB0aGUgQ3JlYXRlIEFjdGlvbiBEaWFsb2dcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqIEBmaW5hbFxuXHQgKiovXG5cdF9nZXRTcGVjaWZpY0NyZWF0ZUFjdGlvbkRpYWxvZ0xhYmVsKFxuXHRcdG9NZXRhTW9kZWw6IE9EYXRhTWV0YU1vZGVsLFxuXHRcdHNNZXRhUGF0aDogc3RyaW5nLFxuXHRcdHNOZXdBY3Rpb246IHN0cmluZyxcblx0XHRvUmVzb3VyY2VCdW5kbGVDb3JlOiBSZXNvdXJjZUJ1bmRsZVxuXHQpIHtcblx0XHRjb25zdCBmbkdldExhYmVsRnJvbUxpbmVJdGVtQW5ub3RhdGlvbiA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmIChvTWV0YU1vZGVsICYmIG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNNZXRhUGF0aCArIFwiL0Bjb20uc2FwLnZvY2FidWxhcmllcy5VSS52MS5MaW5lSXRlbVwiKSkge1xuXHRcdFx0XHRjb25zdCBpTGluZUl0ZW1JbmRleCA9IG9NZXRhTW9kZWxcblx0XHRcdFx0XHQuZ2V0T2JqZWN0KHNNZXRhUGF0aCArIFwiL0Bjb20uc2FwLnZvY2FidWxhcmllcy5VSS52MS5MaW5lSXRlbVwiKVxuXHRcdFx0XHRcdC5maW5kSW5kZXgoZnVuY3Rpb24gKG9MaW5lSXRlbTogYW55KSB7XG5cdFx0XHRcdFx0XHRjb25zdCBhTGluZUl0ZW1BY3Rpb24gPSBvTGluZUl0ZW0uQWN0aW9uID8gb0xpbmVJdGVtLkFjdGlvbi5zcGxpdChcIihcIikgOiB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0XHRyZXR1cm4gYUxpbmVJdGVtQWN0aW9uID8gYUxpbmVJdGVtQWN0aW9uWzBdID09PSBzTmV3QWN0aW9uIDogZmFsc2U7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdHJldHVybiBpTGluZUl0ZW1JbmRleCA+IC0xXG5cdFx0XHRcdFx0PyBvTWV0YU1vZGVsLmdldE9iamVjdChzTWV0YVBhdGggKyBcIi9AY29tLnNhcC52b2NhYnVsYXJpZXMuVUkudjEuTGluZUl0ZW1cIilbaUxpbmVJdGVtSW5kZXhdLkxhYmVsXG5cdFx0XHRcdFx0OiB1bmRlZmluZWQ7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHRyZXR1cm4gKFxuXHRcdFx0Zm5HZXRMYWJlbEZyb21MaW5lSXRlbUFubm90YXRpb24oKSB8fFxuXHRcdFx0KG9NZXRhTW9kZWwgJiYgb01ldGFNb2RlbC5nZXRPYmplY3Qoc01ldGFQYXRoICsgXCIvXCIgKyBzTmV3QWN0aW9uICsgXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLkxhYmVsXCIpKSB8fFxuXHRcdFx0KG9SZXNvdXJjZUJ1bmRsZUNvcmUgJiYgb1Jlc291cmNlQnVuZGxlQ29yZS5nZXRUZXh0KFwiQ19UUkFOU0FDVElPTl9IRUxQRVJfU0FQRkVfQUNUSU9OX0NSRUFURVwiKSlcblx0XHQpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFRyYW5zYWN0aW9uSGVscGVyO1xuIl19