@sapui5/sap.fe.core 1.99.0 → 1.101.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/package.json +6 -4
  2. package/src/sap/fe/core/.library +2 -3
  3. package/src/sap/fe/core/AnnotationHelper.js +43 -92
  4. package/src/sap/fe/core/AnnotationHelper.ts +43 -107
  5. package/src/sap/fe/core/AppComponent.js +381 -399
  6. package/src/sap/fe/core/AppComponent.ts +397 -0
  7. package/src/sap/fe/core/AppStateHandler.js +131 -162
  8. package/src/sap/fe/core/AppStateHandler.ts +2 -2
  9. package/src/sap/fe/core/BaseController.js +82 -58
  10. package/src/sap/fe/core/BaseController.ts +67 -0
  11. package/src/sap/fe/core/CommonUtils.js +179 -31
  12. package/src/sap/fe/core/CommonUtils.ts +295 -125
  13. package/src/sap/fe/core/ExtensionAPI.js +279 -274
  14. package/src/sap/fe/core/ExtensionAPI.ts +242 -0
  15. package/src/sap/fe/core/PageController.js +158 -29
  16. package/src/sap/fe/core/PageController.ts +65 -37
  17. package/src/sap/fe/core/RouterProxy.js +700 -750
  18. package/src/sap/fe/core/RouterProxy.ts +47 -31
  19. package/src/sap/fe/core/Synchronization.js +21 -31
  20. package/src/sap/fe/core/TemplateComponent.js +193 -118
  21. package/src/sap/fe/core/TemplateComponent.ts +104 -109
  22. package/src/sap/fe/core/TemplateModel.js +24 -44
  23. package/src/sap/fe/core/TemplateModel.ts +3 -3
  24. package/src/sap/fe/core/TransactionHelper.js +1368 -1369
  25. package/src/sap/fe/core/TransactionHelper.ts +201 -171
  26. package/src/sap/fe/core/actions/collaboration/ActivitySync.js +406 -0
  27. package/src/sap/fe/core/actions/collaboration/ActivitySync.ts +362 -0
  28. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.js +146 -0
  29. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.ts +129 -0
  30. package/src/sap/fe/core/actions/collaboration/Manage.js +264 -0
  31. package/src/sap/fe/core/actions/collaboration/Manage.ts +246 -0
  32. package/src/sap/fe/core/actions/collaboration/ManageDialog.fragment.xml +100 -0
  33. package/src/sap/fe/core/actions/collaboration/UserDetails.fragment.xml +13 -0
  34. package/src/sap/fe/core/actions/draft.js +324 -220
  35. package/src/sap/fe/core/actions/draft.ts +209 -133
  36. package/src/sap/fe/core/actions/messageHandling.js +79 -48
  37. package/src/sap/fe/core/actions/messageHandling.ts +113 -83
  38. package/src/sap/fe/core/actions/operations.js +37 -18
  39. package/src/sap/fe/core/actions/operations.ts +51 -20
  40. package/src/sap/fe/core/actions/sticky.js +17 -4
  41. package/src/sap/fe/core/actions/sticky.ts +21 -4
  42. package/src/sap/fe/core/buildingBlocks/AttributeModel.js +60 -0
  43. package/src/sap/fe/core/buildingBlocks/AttributeModel.ts +37 -0
  44. package/src/sap/fe/core/buildingBlocks/BuildingBlock.js +165 -0
  45. package/src/sap/fe/core/buildingBlocks/BuildingBlock.ts +178 -0
  46. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.js +707 -0
  47. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.ts +628 -0
  48. package/src/sap/fe/core/buildingBlocks/TraceInfo.js +436 -0
  49. package/src/sap/fe/core/buildingBlocks/TraceInfo.ts +431 -0
  50. package/src/sap/fe/core/controllerextensions/EditFlow.js +1854 -1669
  51. package/src/sap/fe/core/controllerextensions/EditFlow.ts +1792 -0
  52. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +79 -54
  53. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +60 -0
  54. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +716 -779
  55. package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +785 -0
  56. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +796 -816
  57. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +810 -0
  58. package/src/sap/fe/core/controllerextensions/InternalRouting.js +1056 -1005
  59. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +1001 -0
  60. package/src/sap/fe/core/controllerextensions/KPIManagement.js +498 -532
  61. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +13 -12
  62. package/src/sap/fe/core/controllerextensions/MassEdit.js +141 -169
  63. package/src/sap/fe/core/controllerextensions/MassEdit.ts +155 -0
  64. package/src/sap/fe/core/controllerextensions/MessageHandler.js +221 -244
  65. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +215 -0
  66. package/src/sap/fe/core/controllerextensions/PageReady.js +312 -345
  67. package/src/sap/fe/core/controllerextensions/PageReady.ts +57 -53
  68. package/src/sap/fe/core/controllerextensions/Paginator.js +188 -175
  69. package/src/sap/fe/core/controllerextensions/Paginator.ts +169 -0
  70. package/src/sap/fe/core/controllerextensions/Placeholder.js +157 -149
  71. package/src/sap/fe/core/controllerextensions/Placeholder.ts +149 -0
  72. package/src/sap/fe/core/controllerextensions/Routing.js +144 -125
  73. package/src/sap/fe/core/controllerextensions/Routing.ts +131 -0
  74. package/src/sap/fe/core/controllerextensions/RoutingListener.js +7 -6
  75. package/src/sap/fe/core/controllerextensions/RoutingListener.ts +3 -0
  76. package/src/sap/fe/core/controllerextensions/Share.js +230 -268
  77. package/src/sap/fe/core/controllerextensions/Share.ts +231 -0
  78. package/src/sap/fe/core/controllerextensions/SideEffects.js +603 -644
  79. package/src/sap/fe/core/controllerextensions/SideEffects.ts +68 -68
  80. package/src/sap/fe/core/controllerextensions/ViewState.js +774 -806
  81. package/src/sap/fe/core/controllerextensions/ViewState.ts +796 -0
  82. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +2 -2
  83. package/src/sap/fe/core/controls/ActionPartial.fragment.xml +2 -2
  84. package/src/sap/fe/core/controls/Any.js +28 -0
  85. package/src/sap/fe/core/controls/Any.ts +30 -0
  86. package/src/sap/fe/core/controls/CommandExecution.js +92 -68
  87. package/src/sap/fe/core/controls/CommandExecution.ts +72 -0
  88. package/src/sap/fe/core/controls/ConditionalWrapper.js +165 -79
  89. package/src/sap/fe/core/controls/ConditionalWrapper.ts +74 -0
  90. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.js +366 -0
  91. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.ts +278 -0
  92. package/src/sap/fe/core/controls/CustomQuickViewPage.js +167 -125
  93. package/src/sap/fe/core/controls/CustomQuickViewPage.ts +116 -0
  94. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossDraft.fragment.xml +44 -5
  95. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +163 -122
  96. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +155 -0
  97. package/src/sap/fe/core/controls/FieldWrapper.js +212 -141
  98. package/src/sap/fe/core/controls/FieldWrapper.ts +104 -0
  99. package/src/sap/fe/core/controls/FileWrapper.js +313 -0
  100. package/src/sap/fe/core/controls/FileWrapper.ts +169 -0
  101. package/src/sap/fe/core/controls/FilterBar.js +197 -159
  102. package/src/sap/fe/core/controls/FilterBar.ts +148 -0
  103. package/src/sap/fe/core/controls/FormElementWrapper.js +100 -39
  104. package/src/sap/fe/core/controls/FormElementWrapper.ts +37 -0
  105. package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +37 -42
  106. package/src/sap/fe/core/controls/MultiValueParameterDelegate.ts +31 -0
  107. package/src/sap/fe/core/controls/filterbar/FilterContainer.js +147 -115
  108. package/src/sap/fe/core/controls/filterbar/FilterContainer.ts +102 -0
  109. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +300 -265
  110. package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +252 -0
  111. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +185 -140
  112. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +125 -0
  113. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +335 -322
  114. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +337 -0
  115. package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +37 -42
  116. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +75 -74
  117. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +71 -0
  118. package/src/sap/fe/core/converters/ConverterContext.js +348 -379
  119. package/src/sap/fe/core/converters/ConverterContext.ts +19 -16
  120. package/src/sap/fe/core/converters/ManifestSettings.js +13 -1
  121. package/src/sap/fe/core/converters/ManifestSettings.ts +17 -2
  122. package/src/sap/fe/core/converters/ManifestWrapper.js +354 -378
  123. package/src/sap/fe/core/converters/ManifestWrapper.ts +10 -0
  124. package/src/sap/fe/core/converters/MetaModelConverter.js +6 -4
  125. package/src/sap/fe/core/converters/MetaModelConverter.ts +5 -2
  126. package/src/sap/fe/core/converters/TemplateConverter.js +1 -1
  127. package/src/sap/fe/core/converters/TemplateConverter.ts +2 -1
  128. package/src/sap/fe/core/converters/annotations/DataField.js +26 -13
  129. package/src/sap/fe/core/converters/annotations/DataField.ts +40 -17
  130. package/src/sap/fe/core/converters/controls/Common/Action.js +10 -10
  131. package/src/sap/fe/core/converters/controls/Common/Action.ts +20 -19
  132. package/src/sap/fe/core/converters/controls/Common/Chart.js +8 -8
  133. package/src/sap/fe/core/converters/controls/Common/Chart.ts +12 -11
  134. package/src/sap/fe/core/converters/controls/Common/Form.js +6 -6
  135. package/src/sap/fe/core/converters/controls/Common/Form.ts +7 -3
  136. package/src/sap/fe/core/converters/controls/Common/KPI.js +1 -1
  137. package/src/sap/fe/core/converters/controls/Common/KPI.ts +2 -2
  138. package/src/sap/fe/core/converters/controls/Common/Table.js +326 -86
  139. package/src/sap/fe/core/converters/controls/Common/Table.ts +384 -167
  140. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +120 -55
  141. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +158 -98
  142. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +206 -223
  143. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +263 -287
  144. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +6 -6
  145. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +20 -18
  146. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +5 -2
  147. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +4 -1
  148. package/src/sap/fe/core/converters/helpers/Aggregation.js +115 -133
  149. package/src/sap/fe/core/converters/helpers/BindingHelper.js +20 -6
  150. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +16 -4
  151. package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +12 -1
  152. package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +11 -0
  153. package/src/sap/fe/core/converters/helpers/Key.js +42 -57
  154. package/src/sap/fe/core/converters/helpers/Key.ts +1 -1
  155. package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +1 -1
  156. package/src/sap/fe/core/converters/objectPage/FormMenuActions.ts +0 -4
  157. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +51 -27
  158. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +69 -43
  159. package/src/sap/fe/core/converters/templates/ListReportConverter.js +42 -25
  160. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +91 -65
  161. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +11 -9
  162. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +8 -8
  163. package/src/sap/fe/core/designtime/AppComponent.designtime.js +92 -98
  164. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +91 -0
  165. package/src/sap/fe/core/formatters/CollaborationFormatter.js +104 -0
  166. package/src/sap/fe/core/formatters/CollaborationFormatter.ts +60 -0
  167. package/src/sap/fe/core/formatters/KPIFormatter.js +3 -12
  168. package/src/sap/fe/core/formatters/KPIFormatter.ts +3 -2
  169. package/src/sap/fe/core/formatters/TableFormatter.js +53 -2
  170. package/src/sap/fe/core/formatters/TableFormatter.ts +51 -0
  171. package/src/sap/fe/core/formatters/ValueFormatter.js +4 -4
  172. package/src/sap/fe/core/formatters/ValueFormatter.ts +4 -7
  173. package/src/sap/fe/core/fpm/Component.js +80 -55
  174. package/src/sap/fe/core/fpm/Component.ts +43 -0
  175. package/src/sap/fe/core/helpers/AppStartupHelper.js +323 -309
  176. package/src/sap/fe/core/helpers/AppStartupHelper.ts +363 -337
  177. package/src/sap/fe/core/helpers/BindingExpression.js +7 -7
  178. package/src/sap/fe/core/helpers/BindingExpression.ts +7 -7
  179. package/src/sap/fe/core/helpers/ClassSupport.js +307 -166
  180. package/src/sap/fe/core/helpers/ClassSupport.ts +348 -155
  181. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +5 -4
  182. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +1 -5
  183. package/src/sap/fe/core/helpers/FPMHelper.js +1 -1
  184. package/src/sap/fe/core/helpers/FPMHelper.ts +1 -1
  185. package/src/sap/fe/core/helpers/MassEditHelper.js +735 -684
  186. package/src/sap/fe/core/helpers/MassEditHelper.ts +803 -0
  187. package/src/sap/fe/core/helpers/ModelHelper.js +53 -1
  188. package/src/sap/fe/core/helpers/ModelHelper.ts +46 -0
  189. package/src/sap/fe/core/helpers/PasteHelper.js +4 -4
  190. package/src/sap/fe/core/helpers/PasteHelper.ts +4 -3
  191. package/src/sap/fe/core/helpers/SemanticDateOperators.js +7 -3
  192. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +7 -1
  193. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +1 -1
  194. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +1 -1
  195. package/src/sap/fe/core/helpers/StableIdHelper.js +1 -7
  196. package/src/sap/fe/core/helpers/StableIdHelper.ts +0 -4
  197. package/src/sap/fe/core/jsx-runtime/jsx.js +35 -5
  198. package/src/sap/fe/core/jsx-runtime/jsx.ts +22 -8
  199. package/src/sap/fe/core/library.js +425 -451
  200. package/src/sap/fe/core/library.support.js +22 -33
  201. package/src/sap/fe/core/library.support.ts +23 -0
  202. package/src/sap/fe/core/library.ts +420 -0
  203. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +5 -3
  204. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +4 -4
  205. package/src/sap/fe/core/messagebundle.properties +45 -13
  206. package/src/sap/fe/core/messagebundle_ar.properties +29 -7
  207. package/src/sap/fe/core/messagebundle_bg.properties +29 -7
  208. package/src/sap/fe/core/messagebundle_ca.properties +29 -7
  209. package/src/sap/fe/core/messagebundle_cs.properties +29 -7
  210. package/src/sap/fe/core/messagebundle_cy.properties +29 -7
  211. package/src/sap/fe/core/messagebundle_da.properties +29 -7
  212. package/src/sap/fe/core/messagebundle_de.properties +29 -7
  213. package/src/sap/fe/core/messagebundle_el.properties +29 -7
  214. package/src/sap/fe/core/messagebundle_en.properties +29 -7
  215. package/src/sap/fe/core/messagebundle_en_GB.properties +29 -7
  216. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +29 -7
  217. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +29 -7
  218. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +29 -7
  219. package/src/sap/fe/core/messagebundle_es.properties +29 -7
  220. package/src/sap/fe/core/messagebundle_es_MX.properties +29 -7
  221. package/src/sap/fe/core/messagebundle_et.properties +29 -7
  222. package/src/sap/fe/core/messagebundle_fi.properties +30 -8
  223. package/src/sap/fe/core/messagebundle_fr.properties +31 -9
  224. package/src/sap/fe/core/messagebundle_fr_CA.properties +31 -9
  225. package/src/sap/fe/core/messagebundle_hi.properties +29 -7
  226. package/src/sap/fe/core/messagebundle_hr.properties +29 -7
  227. package/src/sap/fe/core/messagebundle_hu.properties +29 -7
  228. package/src/sap/fe/core/messagebundle_id.properties +29 -7
  229. package/src/sap/fe/core/messagebundle_it.properties +29 -7
  230. package/src/sap/fe/core/messagebundle_iw.properties +29 -7
  231. package/src/sap/fe/core/messagebundle_ja.properties +28 -6
  232. package/src/sap/fe/core/messagebundle_kk.properties +29 -7
  233. package/src/sap/fe/core/messagebundle_ko.properties +29 -7
  234. package/src/sap/fe/core/messagebundle_lt.properties +29 -7
  235. package/src/sap/fe/core/messagebundle_lv.properties +30 -8
  236. package/src/sap/fe/core/messagebundle_ms.properties +29 -7
  237. package/src/sap/fe/core/messagebundle_nl.properties +29 -7
  238. package/src/sap/fe/core/messagebundle_no.properties +29 -7
  239. package/src/sap/fe/core/messagebundle_pl.properties +29 -7
  240. package/src/sap/fe/core/messagebundle_pt.properties +30 -8
  241. package/src/sap/fe/core/messagebundle_pt_PT.properties +29 -7
  242. package/src/sap/fe/core/messagebundle_ro.properties +29 -7
  243. package/src/sap/fe/core/messagebundle_ru.properties +29 -7
  244. package/src/sap/fe/core/messagebundle_sh.properties +29 -7
  245. package/src/sap/fe/core/messagebundle_sk.properties +29 -7
  246. package/src/sap/fe/core/messagebundle_sl.properties +29 -7
  247. package/src/sap/fe/core/messagebundle_sv.properties +30 -8
  248. package/src/sap/fe/core/messagebundle_th.properties +28 -6
  249. package/src/sap/fe/core/messagebundle_tr.properties +32 -10
  250. package/src/sap/fe/core/messagebundle_uk.properties +29 -7
  251. package/src/sap/fe/core/messagebundle_vi.properties +29 -7
  252. package/src/sap/fe/core/messagebundle_zh_CN.properties +29 -7
  253. package/src/sap/fe/core/messagebundle_zh_TW.properties +29 -7
  254. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +47 -73
  255. package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +1 -1
  256. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +158 -196
  257. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +5 -6
  258. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +70 -96
  259. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +7 -6
  260. package/src/sap/fe/core/services/NavigationServiceFactory.js +287 -342
  261. package/src/sap/fe/core/services/NavigationServiceFactory.ts +11 -14
  262. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +70 -105
  263. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +6 -3
  264. package/src/sap/fe/core/services/RoutingServiceFactory.js +796 -820
  265. package/src/sap/fe/core/services/RoutingServiceFactory.ts +62 -53
  266. package/src/sap/fe/core/services/ShellServicesFactory.js +694 -741
  267. package/src/sap/fe/core/services/ShellServicesFactory.ts +33 -33
  268. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +570 -595
  269. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +23 -4
  270. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +357 -389
  271. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +25 -29
  272. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +43 -5
  273. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +7 -4
  274. package/src/sap/fe/core/support/CommonHelper.js +1 -1
  275. package/src/sap/fe/core/support/CommonHelper.ts +1 -4
  276. package/src/sap/fe/core/support/Diagnostics.js +36 -48
  277. package/src/sap/fe/core/templating/DataModelPathHelper.js +91 -90
  278. package/src/sap/fe/core/templating/DataModelPathHelper.ts +126 -123
  279. package/src/sap/fe/core/templating/DisplayModeFormatter.js +23 -3
  280. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +26 -5
  281. package/src/sap/fe/core/templating/FilterHelper.js +25 -32
  282. package/src/sap/fe/core/templating/FilterHelper.ts +36 -35
  283. package/src/sap/fe/core/templating/PropertyHelper.js +16 -2
  284. package/src/sap/fe/core/templating/PropertyHelper.ts +31 -24
  285. package/src/sap/fe/core/templating/UIFormatters.js +150 -44
  286. package/src/sap/fe/core/templating/UIFormatters.ts +165 -67
  287. package/src/sap/fe/core/type/Email.js +26 -8
  288. package/src/sap/fe/core/type/Email.ts +8 -7
  289. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +0 -75
@@ -1,1008 +1,1059 @@
1
1
  /*!
2
2
  * SAP UI development toolkit for HTML5 (SAPUI5)
3
- (c) Copyright 2009-2021 SAP SE. All rights reserved
4
-
3
+ * (c) Copyright 2009-2021 SAP SE. All rights reserved
5
4
  */
6
- sap.ui.define(
7
- [
8
- "sap/ui/core/mvc/ControllerExtension",
9
- "sap/fe/core/controllerextensions/ControllerExtensionMetadata",
10
- "sap/ui/core/mvc/OverrideExecution",
11
- "sap/ui/core/Component",
12
- "sap/fe/core/CommonUtils",
13
- "sap/fe/core/BusyLocker",
14
- "sap/fe/core/helpers/SemanticKeyHelper",
15
- "sap/ui/model/Filter",
16
- "sap/ui/model/FilterOperator",
17
- "sap/base/Log",
18
- "sap/fe/core/actions/messageHandling",
19
- "sap/m/MessageBox",
20
- "sap/fe/core/helpers/EditState",
21
- "sap/fe/core/controllerextensions/MessageHandler",
22
- "sap/fe/core/helpers/ModelHelper"
23
- ],
24
- function(
25
- ControllerExtension,
26
- ControllerExtensionMetadata,
27
- OverrideExecution,
28
- Component,
29
- CommonUtils,
30
- BusyLocker,
31
- SemanticKeyHelper,
32
- Filter,
33
- FilterOperator,
34
- Log,
35
- messageHandling,
36
- MessageBox,
37
- EditState,
38
- MessageHandler,
39
- ModelHelper
40
- ) {
41
- "use strict";
42
- /**
43
- * {@link sap.ui.core.mvc.ControllerExtension Controller extension}
44
- *
45
- * @namespace
46
- * @alias sap.fe.core.controllerextensions.InternalRouting
47
- *
48
- * @private
49
- * @since 1.74.0
50
- */
51
- return ControllerExtension.extend(
52
- "sap.fe.core.controllerextensions.InternalRouting",
53
- {
54
- metadata: {
55
- methods: {
56
- "navigateToTarget": { "public": true, "final": false },
57
- "navigateToRoute": { "public": true, "final": false },
58
- "byId": { "public": false },
59
- "getView": { "public": false },
60
- "onRouteMatched": { "public": true, "final": false, overrideExecution: OverrideExecution.After },
61
- "onRouteMatchedFinished": { "public": true, "final": false, overrideExecution: OverrideExecution.After },
62
- "onBeforeBinding": { "public": true, "final": false, overrideExecution: OverrideExecution.After },
63
- "onAfterBinding": { "public": true, "final": false, overrideExecution: OverrideExecution.After },
64
- "navigateToContext": { "public": true, "final": true },
65
- "navigateBackFromContext": { "public": true, "final": true },
66
- "navigateForwardToContext": { "public": true, "final": true },
67
- "navigateBackFromTransientState": { "public": true, "final": true },
68
- "navigateToMessagePage": { "public": true, "final": true },
69
- "enterFullScreen": {
70
- "public": true,
71
- "final": false,
72
- overrideExecution: sap.ui.core.mvc.OverrideExecution.Before
73
- },
74
- "exitFullScreen": {
75
- "public": true,
76
- "final": false,
77
- overrideExecution: sap.ui.core.mvc.OverrideExecution.Before
78
- },
79
- "closeColumn": { "public": true, "final": false, overrideExecution: sap.ui.core.mvc.OverrideExecution.Before },
80
- "isCurrentStateImpactedBy": { "public": true, "final": true }
81
- }
82
- },
83
- /**
84
- * Triggered every time this controller is a navigation target.
85
- */
86
- onRouteMatched: function() {},
87
- onRouteMatchedFinished: function() {},
88
- onBeforeBinding: function(oBindingContext, mParameters) {
89
- var oRouting = this.base.getView().getController().routing;
90
- if (oRouting && oRouting.onBeforeBinding) {
91
- oRouting.onBeforeBinding(oBindingContext, mParameters);
92
- }
93
- },
94
- onAfterBinding: function(oBindingContext, mParameters) {
95
- this._oAppComponent.getRootViewController().onContextBoundToView(oBindingContext);
96
- var oRouting = this.base.getView().getController().routing;
97
- if (oRouting && oRouting.onAfterBinding) {
98
- oRouting.onAfterBinding(oBindingContext, mParameters);
99
- }
100
- },
101
-
102
- ///////////////////////////////////////////////////////////
103
- // Methods triggering a navigation after a user action
104
- // (e.g. click on a table row, button, etc...)
105
- ///////////////////////////////////////////////////////////
106
-
107
- /**
108
- * Navigates to the specified navigation target.
109
- *
110
- * @param {sap.ui.model.odata.v4.Context} oContext Context instance
111
- * @param {string} sNavigationTargetName Navigation target name
112
- * @param {object} oSemanticObject Semantic object
113
- * @param {boolean} bPreserveHistory True to force the new URL to be added at the end of the browser history (no replace)
114
- * @ui5-restricted
115
- */
116
- navigateToTarget: function(oContext, sNavigationTargetName, oSemanticObject, bPreserveHistory) {
117
- var oNavigationConfiguration =
118
- this._oPageComponent &&
119
- this._oPageComponent.getNavigationConfiguration &&
120
- this._oPageComponent.getNavigationConfiguration(sNavigationTargetName);
121
- if (oNavigationConfiguration) {
122
- var oDetailRoute = oNavigationConfiguration.detail;
123
- var sRouteName = oDetailRoute.route;
124
- var mParameterMapping = oDetailRoute.parameters;
125
- this._oRoutingService.navigateTo(oContext, sRouteName, mParameterMapping, bPreserveHistory, oSemanticObject);
126
- } else {
127
- this._oRoutingService.navigateTo(oContext, null, null, bPreserveHistory);
128
- }
129
- this._oView.getViewData();
130
- },
131
-
132
- /**
133
- * Navigates to the specified navigation target route.
134
- *
135
- * @param {string} [sTargetRouteName] Name of the target route
136
- * @param {object} [oParameters] Parameters to be used with route to create the target hash
137
- * @returns {Promise} Promise that is resolved when the navigation is finalized
138
- * @ui5-restricted
139
- */
140
- navigateToRoute: function(sTargetRouteName, oParameters) {
141
- return this._oRoutingService.navigateToRoute(sTargetRouteName, oParameters);
142
- },
143
-
144
- /**
145
- * Navigates to a specific context.
146
- *
147
- * @param {sap.ui.model.odata.v4.Context} oContext The context to be navigated to
148
- * @param {object} mParameters Optional navigation parameters
149
- * @returns {Promise} Promise resolved when the navigation has been triggered
150
- *
151
- * @ui5-restricted
152
- */
153
- navigateToContext: function(oContext, mParameters) {
154
- var that = this;
155
- var oContextInfo = {};
156
- mParameters = mParameters || {};
157
-
158
- if (oContext.isA("sap.ui.model.odata.v4.ODataListBinding")) {
159
- if (mParameters.asyncContext) {
160
- // the context is either created async (Promise)
161
- // We need to activate the routeMatchSynchro on the RouterProxy to avoid that
162
- // the subsequent call to navigateToContext conflicts with the current one
163
- this._oRouterProxy.activateRouteMatchSynchronization();
164
-
165
- mParameters.asyncContext
166
- .then(function(oContext) {
167
- // once the context is returned we navigate into it
168
- that.navigateToContext(oContext, {
169
- checkNoHashChange: mParameters.checkNoHashChange,
170
- editable: mParameters.editable,
171
- bPersistOPScroll: mParameters.bPersistOPScroll,
172
- updateFCLLevel: mParameters.updateFCLLevel,
173
- bForceFocus: mParameters.bForceFocus
174
- });
175
- })
176
- .catch(function(oError) {
177
- Log.error("Error with the async context", oError);
178
- });
179
- } else if (!mParameters.bDeferredContext) {
180
- // Navigate to a list binding not yet supported
181
- throw "navigation to a list binding is not yet supported";
182
- }
183
- }
184
-
185
- if (mParameters.callExtension) {
186
- var oInternalModel = this._oView.getModel("internal");
187
- oInternalModel.setProperty("/paginatorCurrentContext", null);
188
-
189
- oContextInfo.sourceBindingContext = oContext.getObject();
190
- oContextInfo.bindingContext = oContext;
191
- if (mParameters.oEvent) {
192
- oContextInfo.oEvent = mParameters.oEvent;
193
- }
194
- // Storing the selected context to use it in internal route navigation if neccessary.
195
- var bOverrideNav = this.base
196
- .getView()
197
- .getController()
198
- .routing.onBeforeNavigation(oContextInfo);
199
- if (bOverrideNav) {
200
- oInternalModel.setProperty("/paginatorCurrentContext", oContext);
201
- return Promise.resolve();
202
- }
203
- }
204
- mParameters.FCLLevel = this._getFCLLevel();
205
-
206
- return this._oRoutingService.navigateToContext(
207
- oContext,
208
- mParameters,
209
- this._oView.getViewData(),
210
- this._oTargetInformation
211
- );
212
- },
213
-
214
- /**
215
- * Navigates backwards from a context.
216
- *
217
- * @param {sap.ui.model.odata.v4.Context} oContext Context to be navigated from
218
- * @param {object} mParameters Optional navigation parameters
219
- * @returns {Promise} Promise resolved when the navigation has been triggered
220
- *
221
- * @ui5-restricted
222
- */
223
- navigateBackFromContext: function(oContext, mParameters) {
224
- mParameters = mParameters || {};
225
- mParameters.updateFCLLevel = -1;
226
-
227
- return this.navigateToContext(oContext, mParameters);
228
- },
229
-
230
- /**
231
- * Navigates forwards to a context.
232
- *
233
- * @param {sap.ui.model.odata.v4.Context} oContext Context to be navigated to
234
- * @param {object} mParameters Optional navigation parameters
235
- * @returns {Promise} Promise resolved when the navigation has been triggered
236
- *
237
- * @ui5-restricted
238
- */
239
- navigateForwardToContext: function(oContext, mParameters) {
240
- if (this._oView.getBindingContext("internal").getProperty("messageFooterContainsErrors") === true) {
241
- return Promise.resolve();
242
- }
243
- mParameters = mParameters || {};
244
- mParameters.updateFCLLevel = 1;
245
-
246
- return this.navigateToContext(oContext, mParameters, true);
247
- },
248
-
249
- /**
250
- * Navigates back in history if the current hash corresponds to a transient state.
251
- */
252
- navigateBackFromTransientState: function() {
253
- var sHash = this._oRouterProxy.getHash();
254
-
255
- // if triggered while navigating to (...), we need to navigate back
256
- if (sHash.indexOf("(...)") !== -1) {
257
- this._oRouterProxy.navBack();
258
- }
259
- },
260
-
261
- navigateToMessagePage: function(sErrorMessage, mParameters) {
262
- mParameters = mParameters || {};
263
- if (this._oRouterProxy.getHash().indexOf("i-action=create") > -1) {
264
- return this._oRouterProxy.navToHash(this._oRoutingService.getDefaultCreateHash());
265
- } else {
266
- mParameters.FCLLevel = this._getFCLLevel();
267
-
268
- return this._oAppComponent.getRootViewController().displayMessagePage(sErrorMessage, mParameters);
269
- }
270
- },
271
-
272
- /**
273
- * Checks if one of the current views on the screen is bound to a given context.
274
- *
275
- * @param {sap.ui.model.odata.v4.Context} oContext
276
- * @returns {boolean}
277
- *
278
- * @ui5-restricted
279
- */
280
- isCurrentStateImpactedBy: function(oContext) {
281
- return this._oRoutingService.isCurrentStateImpactedBy(oContext);
282
- },
283
-
284
- ///////////////////////////////////////////////////////////
285
- // Methods to bind the page when a route is matched
286
- ///////////////////////////////////////////////////////////
287
-
288
- /**
289
- * Called when a route is matched.
290
- * Builds the binding context from the navigation parameters, and bind the page accordingly.
291
- *
292
- * @param {object} oEvent
293
- *
294
- * @ui5-restricted
295
- */
296
- _onRouteMatched: function(oEvent) {
297
- // Check if the target for this view is part of the event targets
298
- var aTargets = oEvent.getParameter("routeInformation") && oEvent.getParameter("routeInformation").targets;
299
- if (!aTargets || aTargets.indexOf(this._oTargetInformation.targetName) === -1) {
300
- return;
301
- }
302
-
303
- // Retrieve the binding context pattern
304
- var sTarget;
305
- if (this._oPageComponent && this._oPageComponent.getBindingContextPattern) {
306
- sTarget = this._oPageComponent.getBindingContextPattern();
307
- }
308
- sTarget = sTarget || this._oTargetInformation.contextPattern;
309
-
310
- if (sTarget === null || sTarget === undefined) {
311
- // Don't do this if we already got sTarget == '', which is a valid target pattern
312
- sTarget = oEvent.getParameter("routePattern");
313
- }
314
- sTarget = sTarget.replace(":?query:", "");
315
-
316
- // Replace the parameters by their values in the binding context pattern
317
- var mArguments = oEvent.getParameters().arguments,
318
- bDeferred = false,
319
- oNavigationParameters = oEvent.getParameter("navigationInfo");
320
-
321
- for (var sKey in mArguments) {
322
- var sValue = mArguments[sKey];
323
- if (sValue === "..." && sTarget.indexOf("{" + sKey + "}") >= 0) {
324
- bDeferred = true;
325
- // Sometimes in preferredMode = create, the edit button is shown in background when the
326
- // action parameter dialog shows up, setting bTargetEditable passes editable as true
327
- // to onBeforeBinding in _bindTargetPage function
328
- oNavigationParameters.bTargetEditable = true;
329
- }
330
- sTarget = sTarget.replace("{" + sKey + "}", sValue);
331
- }
332
- if (mArguments["?query"] && mArguments["?query"].hasOwnProperty("i-action")) {
333
- oNavigationParameters.bActionCreate = true;
334
- }
335
-
336
- // the binding target is always absolute
337
- if (sTarget && sTarget[0] !== "/") {
338
- sTarget = "/" + sTarget;
339
- }
340
-
341
- this.onRouteMatched();
342
-
343
- var oModel = this._oView.getModel(),
344
- oOut;
345
- if (bDeferred) {
346
- oOut = this._bindDeferred(sTarget, oNavigationParameters);
347
- } else {
348
- oOut = this._bindPage(sTarget, oModel, oNavigationParameters);
349
- }
350
- var that = this;
351
- // eslint-disable-next-line promise/catch-or-return
352
- oOut.finally(function() {
353
- that.onRouteMatchedFinished();
354
- });
355
-
356
- this._oAppComponent.getRootViewController().updateUIStateForView(this._oView, this._getFCLLevel());
357
- },
358
-
359
- /**
360
- * Deferred binding (during object creation).
361
- *
362
- * @param {string} sTargetPath The path to the deffered context
363
- * @param {object} oNavigationParameters Navigation parameters
364
- * @returns {Promise}
365
- * @ui5-restricted
366
- */
367
- _bindDeferred: function(sTargetPath, oNavigationParameters) {
368
- this.onBeforeBinding(null, { editable: oNavigationParameters.bTargetEditable });
369
-
370
- if (oNavigationParameters.bDeferredContext || !oNavigationParameters.oAsyncContext) {
371
- // either the context shall be created in the target page (deferred Context) or it shall
372
- // be created async but the user refreshed the page / bookmarked this URL
373
- // TODO: currently the target component creates this document but we shall move this to
374
- // a central place
375
- if (this._oPageComponent && this._oPageComponent.createDeferredContext) {
376
- this._oPageComponent.createDeferredContext(
377
- sTargetPath,
378
- oNavigationParameters.useContext,
379
- oNavigationParameters.bActionCreate
380
- );
381
- }
382
- }
383
-
384
- if (this._getBindingContext() && this._getBindingContext().hasPendingChanges()) {
385
- // For now remove the pending changes to avoid the model raises errors and the object page is at least bound
386
- // Ideally the user should be asked for
387
- this._getBindingContext()
388
- .getBinding()
389
- .resetChanges();
390
- }
391
-
392
- // remove the context to avoid showing old data
393
- this._setBindingContext(null);
394
-
395
- this.onAfterBinding(null);
396
- return Promise.resolve();
397
- },
398
-
399
- /**
400
- * Sets the binding context of the page from a path.
401
- *
402
- * @param {string} sTargetPath The path to the context
403
- * @param {sap.ui.model.odata.v4.ODataModel} oModel The OData model
404
- * @param {object} oNavigationParameters Navigation parameters
405
- * @returns {Promise}
406
- * @ui5-restricted
407
- */
408
- _bindPage: function(sTargetPath, oModel, oNavigationParameters) {
409
- var that = this;
410
-
411
- if (sTargetPath === "") {
412
- return Promise.resolve(this._bindPageToContext(null, oModel, oNavigationParameters));
413
- } else {
414
- return this._resolveSemanticPath(sTargetPath, oModel)
415
- .then(function(sTechnicalPath) {
416
- that._bindPageToPath(sTechnicalPath, oModel, oNavigationParameters);
417
- })
418
- .catch(function(oError) {
419
- // Error handling for erroneous metadata request
420
- var oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core");
421
-
422
- that.navigateToMessagePage(oResourceBundle.getText("C_COMMON_SAPFE_DATA_RECEIVED_ERROR"), {
423
- title: oResourceBundle.getText("C_COMMON_SAPFE_ERROR"),
424
- description: oError.message
425
- });
426
- });
427
- }
428
- },
429
-
430
- /**
431
- * Creates the filter to retrieve a context corresponding to a semantic path.
432
- *
433
- * @param {string} sSemanticPath The semantic path
434
- * @param {Array} aSemanticKeys The semantic keys for the path
435
- * @param {object} oMetaModel The instance of the meta model
436
- * @returns {sap.ui.model.Filter} The filter
437
- *
438
- * @ui5-restricted
439
- */
440
- _createFilterFromSemanticPath: function(sSemanticPath, aSemanticKeys, oMetaModel) {
441
- var fnUnquoteAndDecode = function(sValue) {
442
- if (sValue.indexOf("'") === 0 && sValue.lastIndexOf("'") === sValue.length - 1) {
443
- // Remove the quotes from the value and decode special chars
444
- sValue = decodeURIComponent(sValue.substring(1, sValue.length - 1));
445
- }
446
- return sValue;
447
- },
448
- aKeyValues = sSemanticPath.substring(sSemanticPath.indexOf("(") + 1, sSemanticPath.length - 1).split(","),
449
- aFilters;
450
-
451
- if (aSemanticKeys.length != aKeyValues.length) {
452
- return null;
453
- }
454
-
455
- var bFilteringCaseSensitive = ModelHelper.isFilteringCaseSensitive(oMetaModel);
456
-
457
- if (aSemanticKeys.length === 1) {
458
- // Take the first key value
459
- var sKeyValue = fnUnquoteAndDecode(aKeyValues[0]);
460
- aFilters = [
461
- new Filter({
462
- path: aSemanticKeys[0].$PropertyPath,
463
- operator: FilterOperator.EQ,
464
- value1: sKeyValue,
465
- caseSensitive: bFilteringCaseSensitive
466
- })
467
- ];
468
- } else {
469
- var mKeyValues = {};
470
- // Create a map of all key values
471
- aKeyValues.forEach(function(sKeyAssignment) {
472
- var aParts = sKeyAssignment.split("="),
473
- sKeyValue = fnUnquoteAndDecode(aParts[1]);
474
-
475
- mKeyValues[aParts[0]] = sKeyValue;
476
- });
477
-
478
- var bFailed = false;
479
- aFilters = aSemanticKeys.map(function(oSemanticKey) {
480
- var sKey = oSemanticKey.$PropertyPath,
481
- sValue = mKeyValues[sKey];
482
-
483
- if (sValue !== undefined) {
484
- return new Filter({
485
- path: sKey,
486
- operator: FilterOperator.EQ,
487
- value1: sValue,
488
- caseSensitive: bFilteringCaseSensitive
489
- });
490
- } else {
491
- bFailed = true;
492
- return "XX";
493
- }
494
- });
495
-
496
- if (bFailed) {
497
- return null;
498
- }
499
- }
500
-
501
- // Add a draft filter to make sure we take the draft entity if there is one
502
- // Or the active entity otherwise
503
- var oDraftFilter = new Filter({
504
- filters: [new Filter("IsActiveEntity", "EQ", false), new Filter("SiblingEntity/IsActiveEntity", "EQ", null)],
505
- and: false
506
- });
507
- aFilters.push(oDraftFilter);
508
-
509
- var oCombinedFilter = new Filter(aFilters, true);
510
- return oCombinedFilter;
511
- },
512
-
513
- /**
514
- * Converts a path with semantic keys to a path with technical keys.
515
- *
516
- * @param {string} sSemanticPath The path with semantic keys
517
- * @param {sap.ui.model.odata.v4.ODataModel} oModel The model for the path
518
- * @param {Array} aSemanticKeys The semantic keys for the path
519
- * @returns {Promise} A Promise containing the path with technical keys if sSemanticPath could be interpreted as a semantic path, null otherwise
520
- *
521
- * @ui5-restricted
522
- */
523
- _getTechnicalPathFromSemanticPath: function(sSemanticPath, oModel, aSemanticKeys) {
524
- var oMetaModel = oModel.getMetaModel(),
525
- sEntitySetName = oMetaModel.getMetaContext(sSemanticPath).getPath();
526
-
527
- if (!aSemanticKeys || aSemanticKeys.length === 0) {
528
- // No semantic keys
529
- return Promise.resolve(null);
530
- }
531
-
532
- // Create a set of filters corresponding to all keys
533
- var oFilter = this._createFilterFromSemanticPath(sSemanticPath, aSemanticKeys, oMetaModel);
534
- if (oFilter === null) {
535
- // Couldn't interpret the path as a semantic one
536
- return Promise.resolve(null);
537
- }
538
-
539
- // Load the corresponding object
540
- var oListBinding = oModel.bindList("/" + sEntitySetName, undefined, undefined, oFilter, {
541
- "$$groupId": "$auto.Heroes"
542
- });
543
-
544
- return oListBinding.requestContexts(0, 2).then(function(oContexts) {
545
- if (oContexts && oContexts.length) {
546
- return oContexts[0].getPath();
547
- } else {
548
- // No data could be loaded
549
- return null;
550
- }
551
- });
552
- },
553
-
554
- /**
555
- * Checks if a path is eligible for semantic bookmarking.
556
- *
557
- * @param {string} sPath The path to test
558
- * @param {sap.ui.model.odata.v4.ODataMetaModel} oMetaModel The associated metadata model
559
- * @returns {boolean} `true` if the path is eligible
560
- *
561
- * @ui5-restricted
562
- */
563
- _checkPathForSemanticBookmarking: function(sPath, oMetaModel) {
564
- // Only path on root objects allow semantic bookmarking, i.e. sPath = xxx(yyy)
565
- var aMatches = /^[\/]?(\w+)\([^\/]+\)$/.exec(sPath);
566
- if (!aMatches) {
567
- return false;
568
- }
569
- // Get the entitySet name
570
- var sEntitySetPath = "/" + aMatches[1];
571
- // Check the entity set supports draft (otherwise we don't support semantic bookmarking)
572
- var oDraftRoot = oMetaModel.getObject(sEntitySetPath + "@com.sap.vocabularies.Common.v1.DraftRoot");
573
- var oDraftNode = oMetaModel.getObject(sEntitySetPath + "@com.sap.vocabularies.Common.v1.DraftNode");
574
- return oDraftRoot || oDraftNode ? true : false;
575
- },
576
-
577
- /**
578
- * Builds a path with semantic keys from a path with technical keys.
579
- * @param {string} sPathToResolve The path to be transformed
580
- * @param oModel
581
- * @returns {Promise} String promise for the new path. If sPathToResolved couldn't be interpreted as a semantic path, it is returned as is.
582
- * @ui5-restricted
583
- */
584
- _resolveSemanticPath: function(sPathToResolve, oModel) {
585
- var oMetaModel = oModel.getMetaModel(),
586
- oLastSemanticMapping = this._oRoutingService.getLastSemanticMapping(),
587
- sCurrentHashNoParams = this._oRouter
588
- .getHashChanger()
589
- .getHash()
590
- .split("?")[0],
591
- that = this;
592
-
593
- if (sCurrentHashNoParams && sCurrentHashNoParams.lastIndexOf("/") === sCurrentHashNoParams.length - 1) {
594
- // Remove trailing '/'
595
- sCurrentHashNoParams = sCurrentHashNoParams.substring(0, sCurrentHashNoParams.length - 1);
596
- }
597
-
598
- var sRootEntityName = sCurrentHashNoParams && sCurrentHashNoParams.substr(0, sCurrentHashNoParams.indexOf("("));
599
- if (sRootEntityName.indexOf("/") === 0) {
600
- sRootEntityName = sRootEntityName.substring(1);
601
- }
602
- var bAllowSemanticBookmark = this._checkPathForSemanticBookmarking(sCurrentHashNoParams, oMetaModel),
603
- aSemanticKeys = bAllowSemanticBookmark && SemanticKeyHelper.getSemanticKeys(oMetaModel, sRootEntityName);
604
- if (!aSemanticKeys) {
605
- // No semantic keys available --> use the path as is
606
- return Promise.resolve(sPathToResolve);
607
- } else if (oLastSemanticMapping && oLastSemanticMapping.semanticPath === sPathToResolve) {
608
- // This semantic path has been resolved previously
609
- return Promise.resolve(oLastSemanticMapping.technicalPath);
610
- } else {
611
- // We need resolve the semantic path to get the technical keys
612
- return this._getTechnicalPathFromSemanticPath(sCurrentHashNoParams, oModel, aSemanticKeys).then(function(
613
- sTechnicalPath
614
- ) {
615
- if (sTechnicalPath && sTechnicalPath !== sPathToResolve) {
616
- // The semantic path was resolved (otherwise keep the original value for target)
617
- that._oRoutingService.setLastSemanticMapping({
618
- technicalPath: sTechnicalPath,
619
- semanticPath: sPathToResolve
620
- });
621
- return sTechnicalPath;
622
- } else {
623
- return sPathToResolve;
624
- }
625
- });
626
- }
627
- },
628
-
629
- /**
630
- * Sets the binding context of the page from a path.
631
- *
632
- * @param {string} sTargetPath The path to build the context. Needs to contain technical keys only.
633
- * @param {sap.ui.model.odata.v4.ODataModel} oModel The OData model
634
- * @param {object} oNavigationParameters Navigation parameters
635
- *
636
- * @ui5-restricted
637
- */
638
- _bindPageToPath: function(sTargetPath, oModel, oNavigationParameters) {
639
- var oCurrentContext = this._getBindingContext(),
640
- sCurrentPath = oCurrentContext && oCurrentContext.getPath(),
641
- oUseContext = oNavigationParameters.useContext;
642
-
643
- // We set the binding context only if it's different from the current one
644
- // or if we have a context already selected
645
- if (sCurrentPath !== sTargetPath || (oUseContext && oUseContext.getPath() === sTargetPath)) {
646
- var oTargetContext;
647
- if (oUseContext && oUseContext.getPath() === sTargetPath) {
648
- // We already have the context to be used
649
- oTargetContext = oUseContext;
650
- } else {
651
- // Otherwise we need to create it from sTargetPath
652
- oTargetContext = this._createBindingContext(sTargetPath, oModel);
653
- }
654
- if (oTargetContext !== oCurrentContext) {
655
- this._bindPageToContext(oTargetContext, oModel, oNavigationParameters);
656
- }
657
- } else if (!oNavigationParameters.bReasonIsIappState && EditState.isEditStateDirty()) {
658
- this._refreshBindingContext(oCurrentContext);
659
- }
660
- },
661
-
662
- /**
663
- * Binds the page to a context.
664
- *
665
- * @param {sap.ui.model.odata.v4.Context} oContext Context to be bound
666
- * @param {sap.ui.model.odata.v4.ODataModel} oModel The OData model
667
- * @param {object} oNavigationParameters Navigation parameters
668
- *
669
- * @ui5-restricted
670
- */
671
- _bindPageToContext: function(oContext, oModel, oNavigationParameters) {
672
- var that = this;
673
- if (!oContext) {
674
- this.onBeforeBinding(null);
675
- this.onAfterBinding(null);
676
- } else {
677
- var oParentListBinding = oContext.getBinding();
678
-
679
- if (!oContext.getBinding() || oContext.getBinding().isA("sap.ui.model.odata.v4.ODataListBinding")) {
680
- // We need to recreate the context otherwise we get errors
681
- oContext = this._createBindingContext(oContext.getPath(), oModel);
682
- if (EditState.isEditStateDirty()) {
683
- // TODO: as a workaround we invalidate the model cache while the app is dirty
684
- // as the manage model sets the parent in an async task and the request side effects
685
- // relies on the parent relationship we have to set a timeout 0
686
- setTimeout(function() {
687
- that._refreshBindingContext(oContext);
688
- }, 0);
689
- }
690
- }
691
-
692
- // Set the binding context with the proper before/after callbacks
693
- this.onBeforeBinding(oContext, {
694
- editable: oNavigationParameters.bTargetEditable,
695
- listBinding: oParentListBinding,
696
- bPersistOPScroll: oNavigationParameters.bPersistOPScroll,
697
- bDraftNavigation: oNavigationParameters.bDraftNavigation,
698
- showPlaceholder: oNavigationParameters.bShowPlaceholder
699
- });
700
-
701
- this._setBindingContext(oContext);
702
- this.onAfterBinding(oContext);
703
- }
704
- },
705
-
706
- /**
707
- * Creates a binding context from a path.
708
- *
709
- * @param {string} sPath The path
710
- * @param {sap.ui.model.odata.v4.ODataModel} oModel The OData model
711
- * @returns {sap.ui.model.odata.v4.Context} Created context
712
- *
713
- * @ui5-restricted
714
- */
715
- _createBindingContext: function(sPath, oModel) {
716
- var oPageComponent = this._oPageComponent,
717
- sEntitySet = oPageComponent && oPageComponent.getEntitySet && oPageComponent.getEntitySet(),
718
- sContextPath =
719
- (oPageComponent && oPageComponent.getContextPath && oPageComponent.getContextPath()) ||
720
- (sEntitySet && "/" + sEntitySet),
721
- oMetaModel = oModel.getMetaModel(),
722
- that = this,
723
- mParameters = {
724
- $$patchWithoutSideEffects: true,
725
- $$groupId: "$auto.Heroes",
726
- $$updateGroupId: "$auto"
727
- };
728
-
729
- if (sEntitySet) {
730
- var sMessagesPath = oMetaModel.getObject(sContextPath + "/@com.sap.vocabularies.Common.v1.Messages/$Path");
731
- if (sMessagesPath) {
732
- mParameters.$select = sMessagesPath;
733
- }
734
- }
735
-
736
- // In case of draft: $select the state flags (HasActiveEntity, HasDraftEntity, and IsActiveEntity)
737
- var oDraftRoot = oMetaModel.getObject(sContextPath + "@com.sap.vocabularies.Common.v1.DraftRoot");
738
- var oDraftNode = oMetaModel.getObject(sContextPath + "@com.sap.vocabularies.Common.v1.DraftNode");
739
- if (oDraftRoot || oDraftNode) {
740
- if (mParameters.$select === undefined) {
741
- mParameters.$select = "HasActiveEntity,HasDraftEntity,IsActiveEntity";
742
- } else {
743
- mParameters.$select += ",HasActiveEntity,HasDraftEntity,IsActiveEntity";
744
- }
745
- }
746
-
747
- var oHiddenBinding = oModel.bindContext(sPath, undefined, mParameters);
748
-
749
- oHiddenBinding.attachEventOnce("dataRequested", function() {
750
- BusyLocker.lock(that._oView);
751
- });
752
- oHiddenBinding.attachEventOnce("dataReceived", this._dataReceivedEventHandler.bind(this));
753
- return oHiddenBinding.getBoundContext();
754
- },
755
-
756
- _dataReceivedEventHandler: function(oEvent) {
757
- var that = this;
758
- var sErrorDescription = oEvent && oEvent.getParameter("error");
759
- BusyLocker.unlock(that._oView);
760
- if (sErrorDescription) {
761
- // TODO: in case of 404 the text shall be different
762
- sap.ui
763
- .getCore()
764
- .getLibraryResourceBundle("sap.fe.core", true)
765
- .then(function(oResourceBundle) {
766
- var messageHandler = that.base.messageHandler;
767
- var mParams = {};
768
- if (sErrorDescription && sErrorDescription.status === 503) {
769
- mParams = {
770
- isInitialLoad503Error: true,
771
- shellBack: true
772
- };
773
- } else {
774
- mParams = {
775
- title: oResourceBundle.getText("SAPFE_ERROR"),
776
- description: sErrorDescription,
777
- isDataReceivedError: true,
778
- shellBack: true
779
- };
780
- }
781
- messageHandler.showMessages(mParams);
782
- })
783
- .catch(function(oError) {
784
- Log.error("Error while getting the core resource bundle", oError);
785
- });
786
- }
787
- },
788
-
789
- /**
790
- * Requests side effects on a binding context to "refresh" it.
791
- * TODO: get rid of this once provided by the model
792
- * a refresh on the binding context does not work in case a creation row with a transient context is
793
- * used. also a requestSideEffects with an empty path would fail due to the transient context
794
- * therefore we get all dependent bindings (via private model method) to determine all paths and then
795
- * request them.
796
- *
797
- * @param {sap.ui.model.odata.v4.Context} oBindingContext Context to be refreshed
798
- *
799
- * @ui5-restricted
800
- */
801
- _refreshBindingContext: function(oBindingContext) {
802
- var oPageComponent = this._oPageComponent,
803
- oSideEffectsService = this._oAppComponent.getSideEffectsService(),
804
- sRootContextPath = oBindingContext.getPath(),
805
- sEntitySet = oPageComponent && oPageComponent.getEntitySet && oPageComponent.getEntitySet(),
806
- sContextPath =
807
- (oPageComponent && oPageComponent.getContextPath && oPageComponent.getContextPath()) ||
808
- (sEntitySet && "/" + sEntitySet),
809
- oMetaModel = this._oView.getModel().getMetaModel(),
810
- sMessagesPath,
811
- aNavigationPropertyPaths = [],
812
- aPropertyPaths = [],
813
- oSideEffects = {
814
- TargetProperties: [],
815
- TargetEntities: []
816
- };
817
-
818
- function getBindingPaths(oBinding) {
819
- var aDependentBindings,
820
- sRelativePath = ((oBinding.getContext() && oBinding.getContext().getPath()) || "").replace(
821
- sRootContextPath,
822
- ""
823
- ), // If no context, this is an absolute binding so no relative path
824
- sPath = (sRelativePath ? sRelativePath.slice(1) + "/" : sRelativePath) + oBinding.getPath();
825
-
826
- if (oBinding.isA("sap.ui.model.odata.v4.ODataContextBinding")) {
827
- // if (sPath === "") {
828
- // now get the dependent bindings
829
- aDependentBindings = oBinding.getDependentBindings();
830
- if (aDependentBindings) {
831
- // ask the dependent bindings (and only those with the specified groupId
832
- //if (aDependentBindings.length > 0) {
833
- for (var i = 0; i < aDependentBindings.length; i++) {
834
- getBindingPaths(aDependentBindings[i]);
835
- }
836
- } else if (aNavigationPropertyPaths.indexOf(sPath) === -1) {
837
- aNavigationPropertyPaths.push(sPath);
838
- }
839
- } else if (oBinding.isA("sap.ui.model.odata.v4.ODataListBinding")) {
840
- if (aNavigationPropertyPaths.indexOf(sPath) === -1) {
841
- aNavigationPropertyPaths.push(sPath);
842
- }
843
- } else if (oBinding.isA("sap.ui.model.odata.v4.ODataPropertyBinding")) {
844
- if (aPropertyPaths.indexOf(sPath) === -1) {
845
- aPropertyPaths.push(sPath);
846
- }
847
- }
848
- }
849
-
850
- if (sContextPath) {
851
- sMessagesPath = oMetaModel.getObject(sContextPath + "/@com.sap.vocabularies.Common.v1.Messages/$Path");
852
- }
853
-
854
- // binding of the context must have $$PatchWithoutSideEffects true, this bound context may be needed to be fetched from the dependent binding
855
- getBindingPaths(oBindingContext.getBinding());
856
-
857
- var i;
858
- for (i = 0; i < aNavigationPropertyPaths.length; i++) {
859
- oSideEffects.TargetEntities.push({
860
- $NavigationPropertyPath: aNavigationPropertyPaths[i]
861
- });
862
- }
863
- oSideEffects.TargetProperties = aPropertyPaths;
864
- if (sMessagesPath) {
865
- oSideEffects.TargetProperties.push({
866
- $PropertyPath: sMessagesPath
867
- });
868
- }
869
- oSideEffectsService.requestSideEffects(
870
- oSideEffects.TargetEntities.concat(oSideEffects.TargetProperties),
871
- oBindingContext
872
- );
873
- },
874
-
875
- /**
876
- * Gets the binding context of the page or the component.
877
- *
878
- * @returns {sap.ui.model.odata.v4.Context} The binding context
879
- *
880
- * @ui5-restricted
881
- */
882
- _getBindingContext: function() {
883
- if (this._oPageComponent) {
884
- return this._oPageComponent.getBindingContext();
885
- } else {
886
- return this._oView.getBindingContext();
887
- }
888
- },
889
-
890
- /**
891
- * Sets the binding context of the page or the component.
892
- *
893
- * @param {sap.ui.model.odata.v4.Context} oContext The binding context
894
- *
895
- * @ui5-restricted
896
- */
897
- _setBindingContext: function(oContext) {
898
- if (this._oPageComponent) {
899
- this._oPageComponent.setBindingContext(oContext);
900
- } else {
901
- this._oView.setBindingContext(oContext);
902
- }
903
- },
904
-
905
- /**
906
- * Gets the flexible column layout (FCL) level corresponding to the view (-1 if the app is not FCL).
907
- *
908
- * @returns {number} The level
909
- *
910
- * @ui5-restricted
911
- */
912
- _getFCLLevel: function() {
913
- return this._oTargetInformation.FCLLevel;
914
- },
915
-
916
- /**
917
- * Switches between column and full-screen mode when FCL is used.
918
- *
919
- * @ui5-restricted
920
- */
921
-
922
- switchFullScreen: function() {
923
- var oSource = this.base.getView();
924
- var oFCLHelperModel = oSource.getModel("fclhelper"),
925
- bIsFullScreen = oFCLHelperModel.getProperty("/actionButtonsInfo/isFullScreen"),
926
- sNextLayout = oFCLHelperModel.getProperty(
927
- bIsFullScreen ? "/actionButtonsInfo/exitFullScreen" : "/actionButtonsInfo/fullScreen"
928
- ),
929
- oRootViewController = this._oAppComponent.getRootViewController();
930
-
931
- var oContext = oRootViewController.getRightmostContext
932
- ? oRootViewController.getRightmostContext()
933
- : oSource.getBindingContext();
934
-
935
- this.base._routing.navigateToContext(oContext, { sLayout: sNextLayout }).catch(function() {
936
- Log.warning("cannot switch between column and fullscreen");
937
- });
938
- },
939
-
940
- /**
941
- * Closes the column for the current view in a FCL.
942
- *
943
- * @ui5-restricted
944
- */
945
- closeColumn: function() {
946
- var oSource = this.base.getView();
947
- var oViewData = oSource.getViewData();
948
- var oContext = oSource.getBindingContext();
949
- var base = this.base;
950
- var oMetaModel = oContext.getModel().getMetaModel();
951
-
952
- if (oViewData && oViewData.viewLevel === 1 && ModelHelper.isDraftSupported(oMetaModel, oContext.getPath())) {
953
- CommonUtils.fnProcessDataLossOrDraftDiscardConfirmation(
954
- function() {
955
- base._routing.navigateBackFromContext(oContext, { noPreservationCache: true });
956
- },
957
- Function.prototype,
958
- oContext,
959
- oSource.getController(),
960
- false
961
- );
962
- } else {
963
- base._routing.navigateBackFromContext(oContext, { noPreservationCache: true });
964
- }
965
- },
966
-
967
- override: {
968
- onExit: function() {
969
- this._oRoutingService && this._oRoutingService.detachRouteMatched(this._fnRouteMatchedBound);
970
- },
971
- onInit: function() {
972
- var that = this;
973
- this._oView = this.base.getView();
974
- this._oAppComponent = CommonUtils.getAppComponent(this._oView);
975
- this._oPageComponent = Component.getOwnerComponentFor(this._oView);
976
- this._oRouter = this._oAppComponent.getRouter();
977
- this._oRouterProxy = this._oAppComponent.getRouterProxy();
978
-
979
- if (!this._oAppComponent || !this._oPageComponent) {
980
- throw new Error("Failed to initialize controler extension 'sap.fe.core.controllerextesions.InternalRouting");
981
- }
982
-
983
- if (this._oAppComponent === this._oPageComponent) {
984
- // The view isn't hosted in a dedicated UIComponent, but directly in the app
985
- // --> just keep the view
986
- this._oPageComponent = null;
987
- }
988
-
989
- this._oAppComponent
990
- .getService("routingService")
991
- .then(function(oRoutingService) {
992
- that._oRoutingService = oRoutingService;
993
- that._fnRouteMatchedBound = that._onRouteMatched.bind(that);
994
- that._oRoutingService.attachRouteMatched(that._fnRouteMatchedBound);
995
- that._oTargetInformation = oRoutingService.getTargetInformationFor(that._oPageComponent || that._oView);
996
- })
997
- .catch(function() {
998
- throw new Error(
999
- "This controller extension cannot work without a 'routingService' on the main AppComponent"
1000
- );
1001
- });
1002
- }
1003
- }
1004
- },
1005
- ControllerExtensionMetadata
1006
- );
1007
- }
1008
- );
5
+ sap.ui.define(["sap/base/Log", "sap/fe/core/actions/collaboration/ActivitySync", "sap/fe/core/actions/draft", "sap/fe/core/BusyLocker", "sap/fe/core/CommonUtils", "sap/fe/core/helpers/ClassSupport", "sap/fe/core/helpers/EditState", "sap/fe/core/helpers/ModelHelper", "sap/fe/core/helpers/SemanticKeyHelper", "sap/fe/core/library", "sap/ui/core/Component", "sap/ui/core/Core", "sap/ui/core/mvc/ControllerExtension", "sap/ui/core/mvc/OverrideExecution", "sap/ui/model/Filter", "sap/ui/model/FilterOperator"], function (Log, ActivitySync, draft, BusyLocker, CommonUtils, ClassSupport, EditState, ModelHelper, SemanticKeyHelper, FELibrary, Component, Core, ControllerExtension, OverrideExecution, Filter, FilterOperator) {
6
+ "use strict";
7
+
8
+ var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _dec9, _dec10, _dec11, _dec12, _dec13, _dec14, _dec15, _dec16, _dec17, _dec18, _dec19, _dec20, _dec21, _dec22, _dec23, _dec24, _dec25, _dec26, _dec27, _dec28, _dec29, _dec30, _class, _class2;
9
+
10
+ var publicExtension = ClassSupport.publicExtension;
11
+ var methodOverride = ClassSupport.methodOverride;
12
+ var finalExtension = ClassSupport.finalExtension;
13
+ var extensible = ClassSupport.extensible;
14
+ var defineUI5Class = ClassSupport.defineUI5Class;
15
+
16
+ function _catch(body, recover) {
17
+ try {
18
+ var result = body();
19
+ } catch (e) {
20
+ return recover(e);
21
+ }
22
+
23
+ if (result && result.then) {
24
+ return result.then(void 0, recover);
25
+ }
26
+
27
+ return result;
28
+ }
29
+
30
+ function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
31
+
32
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
33
+
34
+ function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object.keys(descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object.defineProperty(target, property, desc); desc = null; } return desc; }
35
+
36
+ /**
37
+ * {@link sap.ui.core.mvc.ControllerExtension Controller extension}
38
+ *
39
+ * @namespace
40
+ * @alias sap.fe.core.controllerextensions.InternalRouting
41
+ *
42
+ * @private
43
+ * @since 1.74.0
44
+ */
45
+ var InternalRouting = (_dec = defineUI5Class("sap.fe.core.controllerextensions.InternalRouting"), _dec2 = methodOverride(), _dec3 = methodOverride(), _dec4 = publicExtension(), _dec5 = extensible(OverrideExecution.After), _dec6 = publicExtension(), _dec7 = extensible(OverrideExecution.After), _dec8 = publicExtension(), _dec9 = extensible(OverrideExecution.After), _dec10 = publicExtension(), _dec11 = extensible(OverrideExecution.After), _dec12 = publicExtension(), _dec13 = publicExtension(), _dec14 = publicExtension(), _dec15 = finalExtension(), _dec16 = publicExtension(), _dec17 = finalExtension(), _dec18 = publicExtension(), _dec19 = finalExtension(), _dec20 = publicExtension(), _dec21 = finalExtension(), _dec22 = publicExtension(), _dec23 = finalExtension(), _dec24 = publicExtension(), _dec25 = finalExtension(), _dec26 = publicExtension(), _dec27 = publicExtension(), _dec28 = finalExtension(), _dec29 = publicExtension(), _dec30 = extensible(OverrideExecution.Before), _dec(_class = (_class2 = /*#__PURE__*/function (_ControllerExtension) {
46
+ _inheritsLoose(InternalRouting, _ControllerExtension);
47
+
48
+ function InternalRouting() {
49
+ return _ControllerExtension.apply(this, arguments) || this;
50
+ }
51
+
52
+ var _proto = InternalRouting.prototype;
53
+
54
+ _proto.onExit = function onExit() {
55
+ this._oRoutingService && this._oRoutingService.detachRouteMatched(this._fnRouteMatchedBound);
56
+ };
57
+
58
+ _proto.onInit = function onInit() {
59
+ var _this = this;
60
+
61
+ this._oView = this.base.getView();
62
+ this._oAppComponent = CommonUtils.getAppComponent(this._oView);
63
+ this._oPageComponent = Component.getOwnerComponentFor(this._oView);
64
+ this._oRouter = this._oAppComponent.getRouter();
65
+ this._oRouterProxy = this._oAppComponent.getRouterProxy();
66
+
67
+ if (!this._oAppComponent || !this._oPageComponent) {
68
+ throw new Error("Failed to initialize controler extension 'sap.fe.core.controllerextesions.InternalRouting");
69
+ } // eslint-disable-next-line @typescript-eslint/ban-ts-comment
70
+ // @ts-ignore
71
+
72
+
73
+ if (this._oAppComponent === this._oPageComponent) {
74
+ // The view isn't hosted in a dedicated UIComponent, but directly in the app
75
+ // --> just keep the view
76
+ this._oPageComponent = null;
77
+ }
78
+
79
+ this._oAppComponent.getService("routingService").then(function (oRoutingService) {
80
+ _this._oRoutingService = oRoutingService;
81
+ _this._fnRouteMatchedBound = _this._onRouteMatched.bind(_this);
82
+
83
+ _this._oRoutingService.attachRouteMatched(_this._fnRouteMatchedBound);
84
+
85
+ _this._oTargetInformation = oRoutingService.getTargetInformationFor(_this._oPageComponent || _this._oView);
86
+ }).catch(function () {
87
+ throw new Error("This controller extension cannot work without a 'routingService' on the main AppComponent");
88
+ });
89
+ }
90
+ /**
91
+ * Triggered every time this controller is a navigation target.
92
+ */
93
+ ;
94
+
95
+ _proto.onRouteMatched = function onRouteMatched() {
96
+ /**/
97
+ };
98
+
99
+ _proto.onRouteMatchedFinished = function onRouteMatchedFinished() {
100
+ /**/
101
+ };
102
+
103
+ _proto.onBeforeBinding = function onBeforeBinding(oBindingContext, mParameters) {
104
+ var oRouting = this.base.getView().getController().routing;
105
+
106
+ if (oRouting && oRouting.onBeforeBinding) {
107
+ oRouting.onBeforeBinding(oBindingContext, mParameters);
108
+ }
109
+ };
110
+
111
+ _proto.onAfterBinding = function onAfterBinding(oBindingContext, mParameters) {
112
+ this._oAppComponent.getRootViewController().onContextBoundToView(oBindingContext);
113
+
114
+ var oRouting = this.base.getView().getController().routing;
115
+
116
+ if (oRouting && oRouting.onAfterBinding) {
117
+ oRouting.onAfterBinding(oBindingContext, mParameters);
118
+ }
119
+ } ///////////////////////////////////////////////////////////
120
+ // Methods triggering a navigation after a user action
121
+ // (e.g. click on a table row, button, etc...)
122
+ ///////////////////////////////////////////////////////////
123
+
124
+ /**
125
+ * Navigates to the specified navigation target.
126
+ *
127
+ * @param {sap.ui.model.odata.v4.Context} oContext Context instance
128
+ * @param {string} sNavigationTargetName Navigation target name
129
+ * @param {object} oSemanticObject Semantic object
130
+ * @param {boolean} bPreserveHistory True to force the new URL to be added at the end of the browser history (no replace)
131
+ * @ui5-restricted
132
+ */
133
+ ;
134
+
135
+ _proto.navigateToTarget = function navigateToTarget(oContext, sNavigationTargetName, oSemanticObject, bPreserveHistory) {
136
+ var oNavigationConfiguration = this._oPageComponent && this._oPageComponent.getNavigationConfiguration && this._oPageComponent.getNavigationConfiguration(sNavigationTargetName);
137
+
138
+ if (oNavigationConfiguration) {
139
+ var oDetailRoute = oNavigationConfiguration.detail;
140
+ var sRouteName = oDetailRoute.route;
141
+ var mParameterMapping = oDetailRoute.parameters;
142
+
143
+ this._oRoutingService.navigateTo(oContext, sRouteName, mParameterMapping, bPreserveHistory);
144
+ } else {
145
+ this._oRoutingService.navigateTo(oContext, null, null, bPreserveHistory);
146
+ }
147
+
148
+ this._oView.getViewData();
149
+ }
150
+ /**
151
+ * Navigates to the specified navigation target route.
152
+ *
153
+ * @param {string} sTargetRouteName Name of the target route
154
+ * @param {object} [oParameters] Parameters to be used with route to create the target hash
155
+ * @returns {Promise} Promise that is resolved when the navigation is finalized
156
+ * @ui5-restricted
157
+ */
158
+ ;
159
+
160
+ _proto.navigateToRoute = function navigateToRoute(sTargetRouteName, oParameters) {
161
+ return this._oRoutingService.navigateToRoute(sTargetRouteName, oParameters);
162
+ }
163
+ /**
164
+ * Navigates to a specific context.
165
+ *
166
+ * @param {sap.ui.model.odata.v4.Context} oContext The context to be navigated to
167
+ * @param {object} [mParameters] Optional navigation parameters
168
+ * @returns {Promise} Promise resolved when the navigation has been triggered
169
+ *
170
+ * @ui5-restricted
171
+ */
172
+ ;
173
+
174
+ _proto.navigateToContext = function navigateToContext(oContext, mParameters) {
175
+ var _this2 = this;
176
+
177
+ var oContextInfo = {};
178
+ mParameters = mParameters || {};
179
+
180
+ if (oContext.isA("sap.ui.model.odata.v4.ODataListBinding")) {
181
+ if (mParameters.asyncContext) {
182
+ // the context is either created async (Promise)
183
+ // We need to activate the routeMatchSynchro on the RouterProxy to avoid that
184
+ // the subsequent call to navigateToContext conflicts with the current one
185
+ this._oRouterProxy.activateRouteMatchSynchronization();
186
+
187
+ mParameters.asyncContext.then(function (oContext) {
188
+ // once the context is returned we navigate into it
189
+ _this2.navigateToContext(oContext, {
190
+ checkNoHashChange: mParameters.checkNoHashChange,
191
+ editable: mParameters.editable,
192
+ bPersistOPScroll: mParameters.bPersistOPScroll,
193
+ updateFCLLevel: mParameters.updateFCLLevel,
194
+ bForceFocus: mParameters.bForceFocus,
195
+ bNavigateToSiblingEntity: mParameters.bNavigateToSiblingEntity
196
+ });
197
+ }).catch(function (oError) {
198
+ Log.error("Error with the async context", oError);
199
+ });
200
+ } else if (!mParameters.bDeferredContext) {
201
+ // Navigate to a list binding not yet supported
202
+ throw "navigation to a list binding is not yet supported";
203
+ }
204
+ }
205
+
206
+ if (mParameters.callExtension) {
207
+ var oInternalModel = this._oView.getModel("internal");
208
+
209
+ oInternalModel.setProperty("/paginatorCurrentContext", null);
210
+ oContextInfo.sourceBindingContext = oContext.getObject();
211
+ oContextInfo.bindingContext = oContext;
212
+
213
+ if (mParameters.oEvent) {
214
+ oContextInfo.oEvent = mParameters.oEvent;
215
+ } // Storing the selected context to use it in internal route navigation if neccessary.
216
+
217
+
218
+ var bOverrideNav = this.base.getView().getController().routing.onBeforeNavigation(oContextInfo);
219
+
220
+ if (bOverrideNav) {
221
+ oInternalModel.setProperty("/paginatorCurrentContext", oContext);
222
+ return Promise.resolve();
223
+ }
224
+ }
225
+
226
+ mParameters.FCLLevel = this._getFCLLevel();
227
+ return this._oRoutingService.navigateToContext(oContext, mParameters, this._oView.getViewData(), this._oTargetInformation);
228
+ }
229
+ /**
230
+ * Navigates backwards from a context.
231
+ *
232
+ * @param {sap.ui.model.odata.v4.Context} oContext Context to be navigated from
233
+ * @param {object} [mParameters] Optional navigation parameters
234
+ * @returns {Promise} Promise resolved when the navigation has been triggered
235
+ *
236
+ * @ui5-restricted
237
+ */
238
+ ;
239
+
240
+ _proto.navigateBackFromContext = function navigateBackFromContext(oContext, mParameters) {
241
+ mParameters = mParameters || {};
242
+ mParameters.updateFCLLevel = -1;
243
+ return this.navigateToContext(oContext, mParameters);
244
+ }
245
+ /**
246
+ * Navigates forwards to a context.
247
+ *
248
+ * @param {sap.ui.model.odata.v4.Context} oContext Context to be navigated to
249
+ * @param {object} mParameters Optional navigation parameters
250
+ * @returns {Promise} Promise resolved when the navigation has been triggered
251
+ *
252
+ * @ui5-restricted
253
+ */
254
+ ;
255
+
256
+ _proto.navigateForwardToContext = function navigateForwardToContext(oContext, mParameters) {
257
+ var _this$_oView$getBindi;
258
+
259
+ if (((_this$_oView$getBindi = this._oView.getBindingContext("internal")) === null || _this$_oView$getBindi === void 0 ? void 0 : _this$_oView$getBindi.getProperty("messageFooterContainsErrors")) === true) {
260
+ return Promise.resolve();
261
+ }
262
+
263
+ mParameters = mParameters || {};
264
+ mParameters.updateFCLLevel = 1;
265
+ return this.navigateToContext(oContext, mParameters);
266
+ }
267
+ /**
268
+ * Navigates back in history if the current hash corresponds to a transient state.
269
+ */
270
+ ;
271
+
272
+ _proto.navigateBackFromTransientState = function navigateBackFromTransientState() {
273
+ var sHash = this._oRouterProxy.getHash(); // if triggered while navigating to (...), we need to navigate back
274
+
275
+
276
+ if (sHash.indexOf("(...)") !== -1) {
277
+ this._oRouterProxy.navBack();
278
+ }
279
+ };
280
+
281
+ _proto.navigateToMessagePage = function navigateToMessagePage(sErrorMessage, mParameters) {
282
+ mParameters = mParameters || {};
283
+
284
+ if (this._oRouterProxy.getHash().indexOf("i-action=create") > -1) {
285
+ return this._oRouterProxy.navToHash(this._oRoutingService.getDefaultCreateHash());
286
+ } else {
287
+ mParameters.FCLLevel = this._getFCLLevel();
288
+ return this._oAppComponent.getRootViewController().displayMessagePage(sErrorMessage, mParameters);
289
+ }
290
+ }
291
+ /**
292
+ * Checks if one of the current views on the screen is bound to a given context.
293
+ *
294
+ * @param {sap.ui.model.odata.v4.Context} oContext
295
+ * @returns {boolean}
296
+ *
297
+ * @ui5-restricted
298
+ */
299
+ ;
300
+
301
+ _proto.isCurrentStateImpactedBy = function isCurrentStateImpactedBy(oContext) {
302
+ return this._oRoutingService.isCurrentStateImpactedBy(oContext);
303
+ } ///////////////////////////////////////////////////////////
304
+ // Methods to bind the page when a route is matched
305
+ ///////////////////////////////////////////////////////////
306
+
307
+ /**
308
+ * Called when a route is matched.
309
+ * Builds the binding context from the navigation parameters, and bind the page accordingly.
310
+ *
311
+ * @param {object} oEvent
312
+ *
313
+ * @ui5-restricted
314
+ */
315
+ ;
316
+
317
+ _proto._onRouteMatched = function _onRouteMatched(oEvent) {
318
+ var _this3 = this;
319
+
320
+ // Check if the target for this view is part of the event targets
321
+ var aTargets = oEvent.getParameter("routeInformation") && oEvent.getParameter("routeInformation").targets;
322
+
323
+ if (!aTargets || aTargets.indexOf(this._oTargetInformation.targetName) === -1) {
324
+ return;
325
+ } // Retrieve the binding context pattern
326
+
327
+
328
+ var sTarget;
329
+
330
+ if (this._oPageComponent && this._oPageComponent.getBindingContextPattern) {
331
+ sTarget = this._oPageComponent.getBindingContextPattern();
332
+ }
333
+
334
+ sTarget = sTarget || this._oTargetInformation.contextPattern;
335
+
336
+ if (sTarget === null || sTarget === undefined) {
337
+ // Don't do this if we already got sTarget == '', which is a valid target pattern
338
+ sTarget = oEvent.getParameter("routePattern");
339
+ }
340
+
341
+ sTarget = sTarget.replace(":?query:", ""); // Replace the parameters by their values in the binding context pattern
342
+
343
+ var mArguments = oEvent.getParameters().arguments;
344
+ var bDeferred = false;
345
+ var oNavigationParameters = oEvent.getParameter("navigationInfo");
346
+
347
+ for (var sKey in mArguments) {
348
+ var sValue = mArguments[sKey];
349
+
350
+ if (sValue === "..." && sTarget.indexOf("{" + sKey + "}") >= 0) {
351
+ bDeferred = true; // Sometimes in preferredMode = create, the edit button is shown in background when the
352
+ // action parameter dialog shows up, setting bTargetEditable passes editable as true
353
+ // to onBeforeBinding in _bindTargetPage function
354
+
355
+ oNavigationParameters.bTargetEditable = true;
356
+ }
357
+
358
+ sTarget = sTarget.replace("{" + sKey + "}", sValue);
359
+ }
360
+
361
+ if (mArguments["?query"] && mArguments["?query"].hasOwnProperty("i-action")) {
362
+ oNavigationParameters.bActionCreate = true;
363
+ } // the binding target is always absolute
364
+
365
+
366
+ if (sTarget && sTarget[0] !== "/") {
367
+ sTarget = "/" + sTarget;
368
+ }
369
+
370
+ this.onRouteMatched();
371
+
372
+ var oModel = this._oView.getModel();
373
+
374
+ var oOut;
375
+
376
+ if (bDeferred) {
377
+ oOut = this._bindDeferred(sTarget, oNavigationParameters);
378
+ } else {
379
+ oOut = this._bindPage(sTarget, oModel, oNavigationParameters);
380
+ } // eslint-disable-next-line promise/catch-or-return
381
+
382
+
383
+ oOut.finally(function () {
384
+ _this3.onRouteMatchedFinished();
385
+ });
386
+
387
+ this._oAppComponent.getRootViewController().updateUIStateForView(this._oView, this._getFCLLevel());
388
+ }
389
+ /**
390
+ * Deferred binding (during object creation).
391
+ *
392
+ * @param {string} sTargetPath The path to the deffered context
393
+ * @param {object} oNavigationParameters Navigation parameters
394
+ * @returns {Promise}
395
+ * @ui5-restricted
396
+ */
397
+ ;
398
+
399
+ _proto._bindDeferred = function _bindDeferred(sTargetPath, oNavigationParameters) {
400
+ this.onBeforeBinding(null, {
401
+ editable: oNavigationParameters.bTargetEditable
402
+ });
403
+
404
+ if (oNavigationParameters.bDeferredContext || !oNavigationParameters.oAsyncContext) {
405
+ // either the context shall be created in the target page (deferred Context) or it shall
406
+ // be created async but the user refreshed the page / bookmarked this URL
407
+ // TODO: currently the target component creates this document but we shall move this to
408
+ // a central place
409
+ if (this._oPageComponent && this._oPageComponent.createDeferredContext) {
410
+ this._oPageComponent.createDeferredContext(sTargetPath, oNavigationParameters.useContext, oNavigationParameters.bActionCreate);
411
+ }
412
+ }
413
+
414
+ if (this._getBindingContext() && this._getBindingContext().hasPendingChanges()) {
415
+ // For now remove the pending changes to avoid the model raises errors and the object page is at least bound
416
+ // Ideally the user should be asked for
417
+ this._getBindingContext().getBinding().resetChanges();
418
+ } // remove the context to avoid showing old data
419
+
420
+
421
+ this._setBindingContext(null);
422
+
423
+ this.onAfterBinding(null);
424
+ return Promise.resolve();
425
+ }
426
+ /**
427
+ * Sets the binding context of the page from a path.
428
+ *
429
+ * @param {string} sTargetPath The path to the context
430
+ * @param {sap.ui.model.odata.v4.ODataModel} oModel The OData model
431
+ * @param {object} oNavigationParameters Navigation parameters
432
+ * @returns {Promise}
433
+ * @ui5-restricted
434
+ */
435
+ ;
436
+
437
+ _proto._bindPage = function _bindPage(sTargetPath, oModel, oNavigationParameters) {
438
+ var _this4 = this;
439
+
440
+ if (sTargetPath === "") {
441
+ return Promise.resolve(this._bindPageToContext(null, oModel, oNavigationParameters));
442
+ } else {
443
+ return this._resolveSemanticPath(sTargetPath, oModel).then(function (sTechnicalPath) {
444
+ _this4._bindPageToPath(sTechnicalPath, oModel, oNavigationParameters);
445
+ }).catch(function (oError) {
446
+ // Error handling for erroneous metadata request
447
+ var oResourceBundle = Core.getLibraryResourceBundle("sap.fe.core");
448
+
449
+ _this4.navigateToMessagePage(oResourceBundle.getText("C_COMMON_SAPFE_DATA_RECEIVED_ERROR"), {
450
+ title: oResourceBundle.getText("C_COMMON_SAPFE_ERROR"),
451
+ description: oError.message
452
+ });
453
+ });
454
+ }
455
+ }
456
+ /**
457
+ * Creates the filter to retrieve a context corresponding to a semantic path.
458
+ *
459
+ * @param {string} sSemanticPath The semantic path
460
+ * @param {Array} aSemanticKeys The semantic keys for the path
461
+ * @param {object} oMetaModel The instance of the meta model
462
+ * @returns {sap.ui.model.Filter} The filter
463
+ *
464
+ * @ui5-restricted
465
+ */
466
+ ;
467
+
468
+ _proto._createFilterFromSemanticPath = function _createFilterFromSemanticPath(sSemanticPath, aSemanticKeys, oMetaModel) {
469
+ var fnUnquoteAndDecode = function (sValue) {
470
+ if (sValue.indexOf("'") === 0 && sValue.lastIndexOf("'") === sValue.length - 1) {
471
+ // Remove the quotes from the value and decode special chars
472
+ sValue = decodeURIComponent(sValue.substring(1, sValue.length - 1));
473
+ }
474
+
475
+ return sValue;
476
+ };
477
+
478
+ var aKeyValues = sSemanticPath.substring(sSemanticPath.indexOf("(") + 1, sSemanticPath.length - 1).split(",");
479
+ var aFilters;
480
+
481
+ if (aSemanticKeys.length != aKeyValues.length) {
482
+ return null;
483
+ }
484
+
485
+ var bFilteringCaseSensitive = ModelHelper.isFilteringCaseSensitive(oMetaModel);
486
+
487
+ if (aSemanticKeys.length === 1) {
488
+ // Take the first key value
489
+ var sKeyValue = fnUnquoteAndDecode(aKeyValues[0]);
490
+ aFilters = [new Filter({
491
+ path: aSemanticKeys[0].$PropertyPath,
492
+ operator: FilterOperator.EQ,
493
+ value1: sKeyValue,
494
+ caseSensitive: bFilteringCaseSensitive
495
+ })];
496
+ } else {
497
+ var mKeyValues = {}; // Create a map of all key values
498
+
499
+ aKeyValues.forEach(function (sKeyAssignment) {
500
+ var aParts = sKeyAssignment.split("="),
501
+ sKeyValue = fnUnquoteAndDecode(aParts[1]);
502
+ mKeyValues[aParts[0]] = sKeyValue;
503
+ });
504
+ var bFailed = false;
505
+ aFilters = aSemanticKeys.map(function (oSemanticKey) {
506
+ var sKey = oSemanticKey.$PropertyPath,
507
+ sValue = mKeyValues[sKey];
508
+
509
+ if (sValue !== undefined) {
510
+ return new Filter({
511
+ path: sKey,
512
+ operator: FilterOperator.EQ,
513
+ value1: sValue,
514
+ caseSensitive: bFilteringCaseSensitive
515
+ });
516
+ } else {
517
+ bFailed = true;
518
+ return new Filter({
519
+ path: "XX"
520
+ }); // will be ignore anyway since we return after
521
+ }
522
+ });
523
+
524
+ if (bFailed) {
525
+ return null;
526
+ }
527
+ } // Add a draft filter to make sure we take the draft entity if there is one
528
+ // Or the active entity otherwise
529
+
530
+
531
+ var oDraftFilter = new Filter({
532
+ filters: [new Filter("IsActiveEntity", "EQ", false), new Filter("SiblingEntity/IsActiveEntity", "EQ", null)],
533
+ and: false
534
+ });
535
+ aFilters.push(oDraftFilter);
536
+ var oCombinedFilter = new Filter(aFilters, true);
537
+ return oCombinedFilter;
538
+ }
539
+ /**
540
+ * Converts a path with semantic keys to a path with technical keys.
541
+ *
542
+ * @param {string} sSemanticPath The path with semantic keys
543
+ * @param {sap.ui.model.odata.v4.ODataModel} oModel The model for the path
544
+ * @param {Array} aSemanticKeys The semantic keys for the path
545
+ * @returns {Promise} A Promise containing the path with technical keys if sSemanticPath could be interpreted as a semantic path, null otherwise
546
+ *
547
+ * @ui5-restricted
548
+ */
549
+ ;
550
+
551
+ _proto._getTechnicalPathFromSemanticPath = function _getTechnicalPathFromSemanticPath(sSemanticPath, oModel, aSemanticKeys) {
552
+ var _sEntitySetPath;
553
+
554
+ var oMetaModel = oModel.getMetaModel();
555
+ var sEntitySetPath = oMetaModel.getMetaContext(sSemanticPath).getPath();
556
+
557
+ if (!aSemanticKeys || aSemanticKeys.length === 0) {
558
+ // No semantic keys
559
+ return Promise.resolve(null);
560
+ } // Create a set of filters corresponding to all keys
561
+
562
+
563
+ var oFilter = this._createFilterFromSemanticPath(sSemanticPath, aSemanticKeys, oMetaModel);
564
+
565
+ if (oFilter === null) {
566
+ // Couldn't interpret the path as a semantic one
567
+ return Promise.resolve(null);
568
+ } // Load the corresponding object
569
+
570
+
571
+ if (!((_sEntitySetPath = sEntitySetPath) !== null && _sEntitySetPath !== void 0 && _sEntitySetPath.startsWith("/"))) {
572
+ sEntitySetPath = "/" + sEntitySetPath;
573
+ }
574
+
575
+ var oListBinding = oModel.bindList(sEntitySetPath, undefined, undefined, oFilter, {
576
+ "$$groupId": "$auto.Heroes"
577
+ });
578
+ return oListBinding.requestContexts(0, 2).then(function (oContexts) {
579
+ if (oContexts && oContexts.length) {
580
+ return oContexts[0].getPath();
581
+ } else {
582
+ // No data could be loaded
583
+ return null;
584
+ }
585
+ });
586
+ }
587
+ /**
588
+ * Checks if a path is eligible for semantic bookmarking.
589
+ *
590
+ * @param {string} sPath The path to test
591
+ * @param {sap.ui.model.odata.v4.ODataMetaModel} oMetaModel The associated metadata model
592
+ * @returns {boolean} `true` if the path is eligible
593
+ *
594
+ * @ui5-restricted
595
+ */
596
+ ;
597
+
598
+ _proto._checkPathForSemanticBookmarking = function _checkPathForSemanticBookmarking(sPath, oMetaModel) {
599
+ // Only path on root objects allow semantic bookmarking, i.e. sPath = xxx(yyy)
600
+ var aMatches = /^[\/]?(\w+)\([^\/]+\)$/.exec(sPath);
601
+
602
+ if (!aMatches) {
603
+ return false;
604
+ } // Get the entitySet name
605
+
606
+
607
+ var sEntitySetPath = "/" + aMatches[1]; // Check the entity set supports draft (otherwise we don't support semantic bookmarking)
608
+
609
+ var oDraftRoot = oMetaModel.getObject(sEntitySetPath + "@com.sap.vocabularies.Common.v1.DraftRoot");
610
+ var oDraftNode = oMetaModel.getObject(sEntitySetPath + "@com.sap.vocabularies.Common.v1.DraftNode");
611
+ return oDraftRoot || oDraftNode ? true : false;
612
+ }
613
+ /**
614
+ * Builds a path with semantic keys from a path with technical keys.
615
+ * @param {string} sPathToResolve The path to be transformed
616
+ * @param oModel
617
+ * @returns {Promise} String promise for the new path. If sPathToResolved couldn't be interpreted as a semantic path, it is returned as is.
618
+ * @ui5-restricted
619
+ */
620
+ ;
621
+
622
+ _proto._resolveSemanticPath = function _resolveSemanticPath(sPathToResolve, oModel) {
623
+ var _this5 = this;
624
+
625
+ var oMetaModel = oModel.getMetaModel();
626
+
627
+ var oLastSemanticMapping = this._oRoutingService.getLastSemanticMapping();
628
+
629
+ var sCurrentHashNoParams = this._oRouter.getHashChanger().getHash().split("?")[0];
630
+
631
+ if (sCurrentHashNoParams && sCurrentHashNoParams.lastIndexOf("/") === sCurrentHashNoParams.length - 1) {
632
+ // Remove trailing '/'
633
+ sCurrentHashNoParams = sCurrentHashNoParams.substring(0, sCurrentHashNoParams.length - 1);
634
+ }
635
+
636
+ var sRootEntityName = sCurrentHashNoParams && sCurrentHashNoParams.substr(0, sCurrentHashNoParams.indexOf("("));
637
+
638
+ if (sRootEntityName.indexOf("/") === 0) {
639
+ sRootEntityName = sRootEntityName.substring(1);
640
+ }
641
+
642
+ var bAllowSemanticBookmark = this._checkPathForSemanticBookmarking(sCurrentHashNoParams, oMetaModel),
643
+ aSemanticKeys = bAllowSemanticBookmark && SemanticKeyHelper.getSemanticKeys(oMetaModel, sRootEntityName);
644
+
645
+ if (!aSemanticKeys) {
646
+ // No semantic keys available --> use the path as is
647
+ return Promise.resolve(sPathToResolve);
648
+ } else if (oLastSemanticMapping && oLastSemanticMapping.semanticPath === sPathToResolve) {
649
+ // This semantic path has been resolved previously
650
+ return Promise.resolve(oLastSemanticMapping.technicalPath);
651
+ } else {
652
+ // We need resolve the semantic path to get the technical keys
653
+ return this._getTechnicalPathFromSemanticPath(sCurrentHashNoParams, oModel, aSemanticKeys).then(function (sTechnicalPath) {
654
+ if (sTechnicalPath && sTechnicalPath !== sPathToResolve) {
655
+ // The semantic path was resolved (otherwise keep the original value for target)
656
+ _this5._oRoutingService.setLastSemanticMapping({
657
+ technicalPath: sTechnicalPath,
658
+ semanticPath: sPathToResolve
659
+ });
660
+
661
+ return sTechnicalPath;
662
+ } else {
663
+ return sPathToResolve;
664
+ }
665
+ });
666
+ }
667
+ }
668
+ /**
669
+ * Sets the binding context of the page from a path.
670
+ *
671
+ * @param {string} sTargetPath The path to build the context. Needs to contain technical keys only.
672
+ * @param {sap.ui.model.odata.v4.ODataModel} oModel The OData model
673
+ * @param {object} oNavigationParameters Navigation parameters
674
+ *
675
+ * @ui5-restricted
676
+ */
677
+ ;
678
+
679
+ _proto._bindPageToPath = function _bindPageToPath(sTargetPath, oModel, oNavigationParameters) {
680
+ var oCurrentContext = this._getBindingContext(),
681
+ sCurrentPath = oCurrentContext && oCurrentContext.getPath(),
682
+ oUseContext = oNavigationParameters.useContext; // We set the binding context only if it's different from the current one
683
+ // or if we have a context already selected
684
+
685
+
686
+ if (sCurrentPath !== sTargetPath || oUseContext && oUseContext.getPath() === sTargetPath) {
687
+ var oTargetContext;
688
+
689
+ if (oUseContext && oUseContext.getPath() === sTargetPath) {
690
+ // We already have the context to be used
691
+ oTargetContext = oUseContext;
692
+ } else {
693
+ // Otherwise we need to create it from sTargetPath
694
+ oTargetContext = this._createBindingContext(sTargetPath, oModel, oNavigationParameters.bNavigateToSiblingEntity);
695
+ }
696
+
697
+ if (oTargetContext !== oCurrentContext) {
698
+ this._bindPageToContext(oTargetContext, oModel, oNavigationParameters);
699
+ }
700
+ } else if (!oNavigationParameters.bReasonIsIappState && EditState.isEditStateDirty()) {
701
+ this._refreshBindingContext(oCurrentContext);
702
+ }
703
+ }
704
+ /**
705
+ * Binds the page to a context.
706
+ *
707
+ * @param {sap.ui.model.odata.v4.Context} oContext Context to be bound
708
+ * @param {sap.ui.model.odata.v4.ODataModel} oModel The OData model
709
+ * @param {object} oNavigationParameters Navigation parameters
710
+ *
711
+ * @ui5-restricted
712
+ */
713
+ ;
714
+
715
+ _proto._bindPageToContext = function _bindPageToContext(oContext, oModel, oNavigationParameters) {
716
+ var _this6 = this;
717
+
718
+ if (!oContext) {
719
+ this.onBeforeBinding(null);
720
+ this.onAfterBinding(null);
721
+ } else {
722
+ var oParentListBinding = oContext.getBinding();
723
+
724
+ if (!oContext.getBinding() || oContext.getBinding().isA("sap.ui.model.odata.v4.ODataListBinding")) {
725
+ // We need to recreate the context otherwise we get errors
726
+ oContext = this._createBindingContext(oContext.getPath(), oModel, oNavigationParameters.bNavigateToSiblingEntity);
727
+
728
+ if (EditState.isEditStateDirty()) {
729
+ // TODO: as a workaround we invalidate the model cache while the app is dirty
730
+ // as the manage model sets the parent in an async task and the request side effects
731
+ // relies on the parent relationship we have to set a timeout 0
732
+ setTimeout(function () {
733
+ _this6._refreshBindingContext(oContext);
734
+ }, 0);
735
+ }
736
+ } // Set the binding context with the proper before/after callbacks
737
+
738
+
739
+ this.onBeforeBinding(oContext, {
740
+ editable: oNavigationParameters.bTargetEditable,
741
+ listBinding: oParentListBinding,
742
+ bPersistOPScroll: oNavigationParameters.bPersistOPScroll,
743
+ bDraftNavigation: oNavigationParameters.bDraftNavigation,
744
+ showPlaceholder: oNavigationParameters.bShowPlaceholder
745
+ });
746
+
747
+ this._setBindingContext(oContext);
748
+
749
+ this.onAfterBinding(oContext);
750
+ }
751
+ }
752
+ /**
753
+ * Creates a binding context from a path.
754
+ *
755
+ * @param {string} sPath The path
756
+ * @param {sap.ui.model.odata.v4.ODataModel} oModel The OData model
757
+ * @returns {sap.ui.model.odata.v4.Context} Created context
758
+ *
759
+ * @ui5-restricted
760
+ */
761
+ ;
762
+
763
+ _proto._createBindingContext = function _createBindingContext(sPath, oModel) {
764
+ var _this7 = this;
765
+
766
+ var navigateToSiblingEntity = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
767
+ var oPageComponent = this._oPageComponent,
768
+ sEntitySet = oPageComponent && oPageComponent.getEntitySet && oPageComponent.getEntitySet(),
769
+ sContextPath = oPageComponent && oPageComponent.getContextPath && oPageComponent.getContextPath() || sEntitySet && "/" + sEntitySet,
770
+ oMetaModel = oModel.getMetaModel(),
771
+ mParameters = {
772
+ $$patchWithoutSideEffects: true,
773
+ $$groupId: "$auto.Heroes",
774
+ $$updateGroupId: "$auto"
775
+ };
776
+
777
+ if (sEntitySet) {
778
+ var sMessagesPath = oMetaModel.getObject(sContextPath + "/@com.sap.vocabularies.Common.v1.Messages/$Path");
779
+
780
+ if (sMessagesPath) {
781
+ mParameters.$select = sMessagesPath;
782
+ }
783
+ } // In case of draft: $select the state flags (HasActiveEntity, HasDraftEntity, and IsActiveEntity)
784
+
785
+
786
+ var oDraftRoot = oMetaModel.getObject(sContextPath + "@com.sap.vocabularies.Common.v1.DraftRoot");
787
+ var oDraftNode = oMetaModel.getObject(sContextPath + "@com.sap.vocabularies.Common.v1.DraftNode");
788
+
789
+ if (oDraftRoot || oDraftNode) {
790
+ if (mParameters.$select === undefined) {
791
+ mParameters.$select = "HasActiveEntity,HasDraftEntity,IsActiveEntity";
792
+ } else {
793
+ mParameters.$select += ",HasActiveEntity,HasDraftEntity,IsActiveEntity";
794
+ }
795
+ }
796
+
797
+ var oHiddenBinding = oModel.bindContext(sPath, undefined, mParameters);
798
+ oHiddenBinding.attachEventOnce("dataRequested", function () {
799
+ BusyLocker.lock(_this7._oView);
800
+ });
801
+ oHiddenBinding.attachEventOnce("dataReceived", this._dataReceivedEventHandler.bind(this, navigateToSiblingEntity));
802
+ return oHiddenBinding.getBoundContext();
803
+ };
804
+
805
+ _proto._dataReceivedEventHandler = function _dataReceivedEventHandler(navigateToSiblingEntity, oEvent) {
806
+ try {
807
+ var _oEvent$getSource, _this9$_oView, _this9$_oView$getCont, _this9$_oView$getCont2;
808
+
809
+ var _exit2 = false;
810
+
811
+ var _this9 = this;
812
+
813
+ function _temp6(_result) {
814
+ if (_exit2) return _result;
815
+
816
+ var _temp2 = function () {
817
+ if (sErrorDescription) {
818
+ var _temp5 = _catch(function () {
819
+ return Promise.resolve(Core.getLibraryResourceBundle("sap.fe.core", true)).then(function (oResourceBundle) {
820
+ var messageHandler = _this9.base.messageHandler;
821
+ var mParams = {};
822
+
823
+ if (sErrorDescription && sErrorDescription.status === 503) {
824
+ mParams = {
825
+ isInitialLoad503Error: true,
826
+ shellBack: true
827
+ };
828
+ } else {
829
+ mParams = {
830
+ title: oResourceBundle.getText("SAPFE_ERROR"),
831
+ description: sErrorDescription,
832
+ isDataReceivedError: true,
833
+ shellBack: true
834
+ };
835
+ }
836
+
837
+ messageHandler.showMessages(mParams);
838
+ });
839
+ }, function (oError) {
840
+ Log.error("Error while getting the core resource bundle", oError);
841
+ });
842
+
843
+ if (_temp5 && _temp5.then) return _temp5.then(function () {});
844
+ }
845
+ }();
846
+
847
+ if (_temp2 && _temp2.then) return _temp2.then(function () {});
848
+ }
849
+
850
+ var context = (oEvent === null || oEvent === void 0 ? void 0 : oEvent.getSource) && (oEvent === null || oEvent === void 0 ? void 0 : (_oEvent$getSource = oEvent.getSource()) === null || _oEvent$getSource === void 0 ? void 0 : _oEvent$getSource.getBoundContext());
851
+ var ProgrammingModel = FELibrary.ProgrammingModel;
852
+ var programmingModel = (_this9$_oView = _this9._oView) === null || _this9$_oView === void 0 ? void 0 : (_this9$_oView$getCont = _this9$_oView.getController()) === null || _this9$_oView$getCont === void 0 ? void 0 : (_this9$_oView$getCont2 = _this9$_oView$getCont._editFlow) === null || _this9$_oView$getCont2 === void 0 ? void 0 : _this9$_oView$getCont2.getProgrammingModel(context);
853
+ var sErrorDescription = oEvent && oEvent.getParameter("error");
854
+ BusyLocker.unlock(_this9._oView);
855
+
856
+ var _temp7 = function () {
857
+ if (programmingModel === ProgrammingModel.Draft && ActivitySync.isCollaborationEnabled(_this9._oView) && navigateToSiblingEntity && context.getProperty("IsActiveEntity") && context.getObject().DraftAdministrativeData) {
858
+ return Promise.resolve(draft.computeSiblingInformation(context, context)).then(function (siblingInfo) {
859
+ if (siblingInfo) {
860
+ _this9.navigateToContext(siblingInfo.targetContext);
861
+
862
+ _exit2 = true;
863
+ }
864
+ });
865
+ }
866
+ }();
867
+
868
+ return Promise.resolve(_temp7 && _temp7.then ? _temp7.then(_temp6) : _temp6(_temp7));
869
+ } catch (e) {
870
+ return Promise.reject(e);
871
+ }
872
+ }
873
+ /**
874
+ * Requests side effects on a binding context to "refresh" it.
875
+ * TODO: get rid of this once provided by the model
876
+ * a refresh on the binding context does not work in case a creation row with a transient context is
877
+ * used. also a requestSideEffects with an empty path would fail due to the transient context
878
+ * therefore we get all dependent bindings (via private model method) to determine all paths and then
879
+ * request them.
880
+ *
881
+ * @param {sap.ui.model.odata.v4.Context} oBindingContext Context to be refreshed
882
+ *
883
+ * @ui5-restricted
884
+ */
885
+ ;
886
+
887
+ _proto._refreshBindingContext = function _refreshBindingContext(oBindingContext) {
888
+ var oPageComponent = this._oPageComponent;
889
+
890
+ var oSideEffectsService = this._oAppComponent.getSideEffectsService();
891
+
892
+ var sRootContextPath = oBindingContext.getPath();
893
+ var sEntitySet = oPageComponent && oPageComponent.getEntitySet && oPageComponent.getEntitySet();
894
+ var sContextPath = oPageComponent && oPageComponent.getContextPath && oPageComponent.getContextPath() || sEntitySet && "/" + sEntitySet;
895
+
896
+ var oMetaModel = this._oView.getModel().getMetaModel();
897
+
898
+ var sMessagesPath;
899
+ var aNavigationPropertyPaths = [];
900
+ var aPropertyPaths = [];
901
+ var oSideEffects = {
902
+ TargetProperties: [],
903
+ TargetEntities: []
904
+ };
905
+
906
+ function getBindingPaths(oBinding) {
907
+ var aDependentBindings;
908
+ var sRelativePath = (oBinding.getContext() && oBinding.getContext().getPath() || "").replace(sRootContextPath, ""); // If no context, this is an absolute binding so no relative path
909
+
910
+ var sPath = (sRelativePath ? sRelativePath.slice(1) + "/" : sRelativePath) + oBinding.getPath();
911
+
912
+ if (oBinding.isA("sap.ui.model.odata.v4.ODataContextBinding")) {
913
+ // if (sPath === "") {
914
+ // now get the dependent bindings
915
+ aDependentBindings = oBinding.getDependentBindings();
916
+
917
+ if (aDependentBindings) {
918
+ // ask the dependent bindings (and only those with the specified groupId
919
+ //if (aDependentBindings.length > 0) {
920
+ for (var _i = 0; _i < aDependentBindings.length; _i++) {
921
+ getBindingPaths(aDependentBindings[_i]);
922
+ }
923
+ } else if (aNavigationPropertyPaths.indexOf(sPath) === -1) {
924
+ aNavigationPropertyPaths.push(sPath);
925
+ }
926
+ } else if (oBinding.isA("sap.ui.model.odata.v4.ODataListBinding")) {
927
+ if (aNavigationPropertyPaths.indexOf(sPath) === -1) {
928
+ aNavigationPropertyPaths.push(sPath);
929
+ }
930
+ } else if (oBinding.isA("sap.ui.model.odata.v4.ODataPropertyBinding")) {
931
+ if (aPropertyPaths.indexOf(sPath) === -1) {
932
+ aPropertyPaths.push(sPath);
933
+ }
934
+ }
935
+ }
936
+
937
+ if (sContextPath) {
938
+ sMessagesPath = oMetaModel.getObject(sContextPath + "/@com.sap.vocabularies.Common.v1.Messages/$Path");
939
+ } // binding of the context must have $$PatchWithoutSideEffects true, this bound context may be needed to be fetched from the dependent binding
940
+
941
+
942
+ getBindingPaths(oBindingContext.getBinding());
943
+ var i;
944
+
945
+ for (i = 0; i < aNavigationPropertyPaths.length; i++) {
946
+ oSideEffects.TargetEntities.push({
947
+ $NavigationPropertyPath: aNavigationPropertyPaths[i]
948
+ });
949
+ }
950
+
951
+ oSideEffects.TargetProperties = aPropertyPaths;
952
+
953
+ if (sMessagesPath) {
954
+ oSideEffects.TargetProperties.push({
955
+ $PropertyPath: sMessagesPath
956
+ });
957
+ }
958
+
959
+ oSideEffectsService.requestSideEffects(oSideEffects.TargetEntities.concat(oSideEffects.TargetProperties), oBindingContext);
960
+ }
961
+ /**
962
+ * Gets the binding context of the page or the component.
963
+ *
964
+ * @returns {sap.ui.model.odata.v4.Context} The binding context
965
+ *
966
+ * @ui5-restricted
967
+ */
968
+ ;
969
+
970
+ _proto._getBindingContext = function _getBindingContext() {
971
+ if (this._oPageComponent) {
972
+ return this._oPageComponent.getBindingContext();
973
+ } else {
974
+ return this._oView.getBindingContext();
975
+ }
976
+ }
977
+ /**
978
+ * Sets the binding context of the page or the component.
979
+ *
980
+ * @param {sap.ui.model.odata.v4.Context} oContext The binding context
981
+ *
982
+ * @ui5-restricted
983
+ */
984
+ ;
985
+
986
+ _proto._setBindingContext = function _setBindingContext(oContext) {
987
+ if (this._oPageComponent) {
988
+ this._oPageComponent.setBindingContext(oContext);
989
+ } else {
990
+ this._oView.setBindingContext(oContext);
991
+ }
992
+ }
993
+ /**
994
+ * Gets the flexible column layout (FCL) level corresponding to the view (-1 if the app is not FCL).
995
+ *
996
+ * @returns {number} The level
997
+ *
998
+ * @ui5-restricted
999
+ */
1000
+ ;
1001
+
1002
+ _proto._getFCLLevel = function _getFCLLevel() {
1003
+ return this._oTargetInformation.FCLLevel;
1004
+ }
1005
+ /**
1006
+ * Switches between column and full-screen mode when FCL is used.
1007
+ *
1008
+ * @ui5-restricted
1009
+ */
1010
+ ;
1011
+
1012
+ _proto.switchFullScreen = function switchFullScreen() {
1013
+ var oSource = this.base.getView();
1014
+
1015
+ var oFCLHelperModel = oSource.getModel("fclhelper"),
1016
+ bIsFullScreen = oFCLHelperModel.getProperty("/actionButtonsInfo/isFullScreen"),
1017
+ sNextLayout = oFCLHelperModel.getProperty(bIsFullScreen ? "/actionButtonsInfo/exitFullScreen" : "/actionButtonsInfo/fullScreen"),
1018
+ oRootViewController = this._oAppComponent.getRootViewController();
1019
+
1020
+ var oContext = oRootViewController.getRightmostContext ? oRootViewController.getRightmostContext() : oSource.getBindingContext();
1021
+
1022
+ this.base._routing.navigateToContext(oContext, {
1023
+ sLayout: sNextLayout
1024
+ }).catch(function () {
1025
+ Log.warning("cannot switch between column and fullscreen");
1026
+ });
1027
+ }
1028
+ /**
1029
+ * Closes the column for the current view in a FCL.
1030
+ *
1031
+ * @ui5-restricted
1032
+ */
1033
+ ;
1034
+
1035
+ _proto.closeColumn = function closeColumn() {
1036
+ var oSource = this.base.getView();
1037
+ var oViewData = oSource.getViewData();
1038
+ var oContext = oSource.getBindingContext();
1039
+ var base = this.base;
1040
+ var oMetaModel = oContext.getModel().getMetaModel();
1041
+
1042
+ if (oViewData && oViewData.viewLevel === 1 && ModelHelper.isDraftSupported(oMetaModel, oContext.getPath())) {
1043
+ CommonUtils.fnProcessDataLossOrDraftDiscardConfirmation(function () {
1044
+ base._routing.navigateBackFromContext(oContext, {
1045
+ noPreservationCache: true
1046
+ });
1047
+ }, Function.prototype, oContext, oSource.getController(), false);
1048
+ } else {
1049
+ base._routing.navigateBackFromContext(oContext, {
1050
+ noPreservationCache: true
1051
+ });
1052
+ }
1053
+ };
1054
+
1055
+ return InternalRouting;
1056
+ }(ControllerExtension), (_applyDecoratedDescriptor(_class2.prototype, "onExit", [_dec2], Object.getOwnPropertyDescriptor(_class2.prototype, "onExit"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "onInit", [_dec3], Object.getOwnPropertyDescriptor(_class2.prototype, "onInit"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "onRouteMatched", [_dec4, _dec5], Object.getOwnPropertyDescriptor(_class2.prototype, "onRouteMatched"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "onRouteMatchedFinished", [_dec6, _dec7], Object.getOwnPropertyDescriptor(_class2.prototype, "onRouteMatchedFinished"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "onBeforeBinding", [_dec8, _dec9], Object.getOwnPropertyDescriptor(_class2.prototype, "onBeforeBinding"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "onAfterBinding", [_dec10, _dec11], Object.getOwnPropertyDescriptor(_class2.prototype, "onAfterBinding"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "navigateToTarget", [_dec12], Object.getOwnPropertyDescriptor(_class2.prototype, "navigateToTarget"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "navigateToRoute", [_dec13], Object.getOwnPropertyDescriptor(_class2.prototype, "navigateToRoute"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "navigateToContext", [_dec14, _dec15], Object.getOwnPropertyDescriptor(_class2.prototype, "navigateToContext"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "navigateBackFromContext", [_dec16, _dec17], Object.getOwnPropertyDescriptor(_class2.prototype, "navigateBackFromContext"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "navigateForwardToContext", [_dec18, _dec19], Object.getOwnPropertyDescriptor(_class2.prototype, "navigateForwardToContext"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "navigateBackFromTransientState", [_dec20, _dec21], Object.getOwnPropertyDescriptor(_class2.prototype, "navigateBackFromTransientState"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "navigateToMessagePage", [_dec22, _dec23], Object.getOwnPropertyDescriptor(_class2.prototype, "navigateToMessagePage"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "isCurrentStateImpactedBy", [_dec24, _dec25], Object.getOwnPropertyDescriptor(_class2.prototype, "isCurrentStateImpactedBy"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "_createBindingContext", [_dec26], Object.getOwnPropertyDescriptor(_class2.prototype, "_createBindingContext"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "switchFullScreen", [_dec27, _dec28], Object.getOwnPropertyDescriptor(_class2.prototype, "switchFullScreen"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "closeColumn", [_dec29, _dec30], Object.getOwnPropertyDescriptor(_class2.prototype, "closeColumn"), _class2.prototype)), _class2)) || _class);
1057
+ return InternalRouting;
1058
+ }, false);
1059
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkludGVybmFsUm91dGluZy50cyJdLCJuYW1lcyI6WyJib2R5IiwicmVjb3ZlciIsInJlc3VsdCIsImUiLCJ0aGVuIiwiSW50ZXJuYWxSb3V0aW5nIiwiZGVmaW5lVUk1Q2xhc3MiLCJtZXRob2RPdmVycmlkZSIsInB1YmxpY0V4dGVuc2lvbiIsImV4dGVuc2libGUiLCJPdmVycmlkZUV4ZWN1dGlvbiIsIkFmdGVyIiwiZmluYWxFeHRlbnNpb24iLCJCZWZvcmUiLCJvbkV4aXQiLCJfb1JvdXRpbmdTZXJ2aWNlIiwiZGV0YWNoUm91dGVNYXRjaGVkIiwiX2ZuUm91dGVNYXRjaGVkQm91bmQiLCJvbkluaXQiLCJfb1ZpZXciLCJiYXNlIiwiZ2V0VmlldyIsIl9vQXBwQ29tcG9uZW50IiwiQ29tbW9uVXRpbHMiLCJnZXRBcHBDb21wb25lbnQiLCJfb1BhZ2VDb21wb25lbnQiLCJDb21wb25lbnQiLCJnZXRPd25lckNvbXBvbmVudEZvciIsIl9vUm91dGVyIiwiZ2V0Um91dGVyIiwiX29Sb3V0ZXJQcm94eSIsImdldFJvdXRlclByb3h5IiwiRXJyb3IiLCJnZXRTZXJ2aWNlIiwib1JvdXRpbmdTZXJ2aWNlIiwiX29uUm91dGVNYXRjaGVkIiwiYmluZCIsImF0dGFjaFJvdXRlTWF0Y2hlZCIsIl9vVGFyZ2V0SW5mb3JtYXRpb24iLCJnZXRUYXJnZXRJbmZvcm1hdGlvbkZvciIsImNhdGNoIiwib25Sb3V0ZU1hdGNoZWQiLCJvblJvdXRlTWF0Y2hlZEZpbmlzaGVkIiwib25CZWZvcmVCaW5kaW5nIiwib0JpbmRpbmdDb250ZXh0IiwibVBhcmFtZXRlcnMiLCJvUm91dGluZyIsImdldENvbnRyb2xsZXIiLCJyb3V0aW5nIiwib25BZnRlckJpbmRpbmciLCJnZXRSb290Vmlld0NvbnRyb2xsZXIiLCJvbkNvbnRleHRCb3VuZFRvVmlldyIsIm5hdmlnYXRlVG9UYXJnZXQiLCJvQ29udGV4dCIsInNOYXZpZ2F0aW9uVGFyZ2V0TmFtZSIsIm9TZW1hbnRpY09iamVjdCIsImJQcmVzZXJ2ZUhpc3RvcnkiLCJvTmF2aWdhdGlvbkNvbmZpZ3VyYXRpb24iLCJnZXROYXZpZ2F0aW9uQ29uZmlndXJhdGlvbiIsIm9EZXRhaWxSb3V0ZSIsImRldGFpbCIsInNSb3V0ZU5hbWUiLCJyb3V0ZSIsIm1QYXJhbWV0ZXJNYXBwaW5nIiwicGFyYW1ldGVycyIsIm5hdmlnYXRlVG8iLCJnZXRWaWV3RGF0YSIsIm5hdmlnYXRlVG9Sb3V0ZSIsInNUYXJnZXRSb3V0ZU5hbWUiLCJvUGFyYW1ldGVycyIsIm5hdmlnYXRlVG9Db250ZXh0Iiwib0NvbnRleHRJbmZvIiwiaXNBIiwiYXN5bmNDb250ZXh0IiwiYWN0aXZhdGVSb3V0ZU1hdGNoU3luY2hyb25pemF0aW9uIiwiY2hlY2tOb0hhc2hDaGFuZ2UiLCJlZGl0YWJsZSIsImJQZXJzaXN0T1BTY3JvbGwiLCJ1cGRhdGVGQ0xMZXZlbCIsImJGb3JjZUZvY3VzIiwiYk5hdmlnYXRlVG9TaWJsaW5nRW50aXR5Iiwib0Vycm9yIiwiTG9nIiwiZXJyb3IiLCJiRGVmZXJyZWRDb250ZXh0IiwiY2FsbEV4dGVuc2lvbiIsIm9JbnRlcm5hbE1vZGVsIiwiZ2V0TW9kZWwiLCJzZXRQcm9wZXJ0eSIsInNvdXJjZUJpbmRpbmdDb250ZXh0IiwiZ2V0T2JqZWN0IiwiYmluZGluZ0NvbnRleHQiLCJvRXZlbnQiLCJiT3ZlcnJpZGVOYXYiLCJvbkJlZm9yZU5hdmlnYXRpb24iLCJQcm9taXNlIiwicmVzb2x2ZSIsIkZDTExldmVsIiwiX2dldEZDTExldmVsIiwibmF2aWdhdGVCYWNrRnJvbUNvbnRleHQiLCJuYXZpZ2F0ZUZvcndhcmRUb0NvbnRleHQiLCJnZXRCaW5kaW5nQ29udGV4dCIsImdldFByb3BlcnR5IiwibmF2aWdhdGVCYWNrRnJvbVRyYW5zaWVudFN0YXRlIiwic0hhc2giLCJnZXRIYXNoIiwiaW5kZXhPZiIsIm5hdkJhY2siLCJuYXZpZ2F0ZVRvTWVzc2FnZVBhZ2UiLCJzRXJyb3JNZXNzYWdlIiwibmF2VG9IYXNoIiwiZ2V0RGVmYXVsdENyZWF0ZUhhc2giLCJkaXNwbGF5TWVzc2FnZVBhZ2UiLCJpc0N1cnJlbnRTdGF0ZUltcGFjdGVkQnkiLCJhVGFyZ2V0cyIsImdldFBhcmFtZXRlciIsInRhcmdldHMiLCJ0YXJnZXROYW1lIiwic1RhcmdldCIsImdldEJpbmRpbmdDb250ZXh0UGF0dGVybiIsImNvbnRleHRQYXR0ZXJuIiwidW5kZWZpbmVkIiwicmVwbGFjZSIsIm1Bcmd1bWVudHMiLCJnZXRQYXJhbWV0ZXJzIiwiYXJndW1lbnRzIiwiYkRlZmVycmVkIiwib05hdmlnYXRpb25QYXJhbWV0ZXJzIiwic0tleSIsInNWYWx1ZSIsImJUYXJnZXRFZGl0YWJsZSIsImhhc093blByb3BlcnR5IiwiYkFjdGlvbkNyZWF0ZSIsIm9Nb2RlbCIsIm9PdXQiLCJfYmluZERlZmVycmVkIiwiX2JpbmRQYWdlIiwiZmluYWxseSIsInVwZGF0ZVVJU3RhdGVGb3JWaWV3Iiwic1RhcmdldFBhdGgiLCJvQXN5bmNDb250ZXh0IiwiY3JlYXRlRGVmZXJyZWRDb250ZXh0IiwidXNlQ29udGV4dCIsIl9nZXRCaW5kaW5nQ29udGV4dCIsImhhc1BlbmRpbmdDaGFuZ2VzIiwiZ2V0QmluZGluZyIsInJlc2V0Q2hhbmdlcyIsIl9zZXRCaW5kaW5nQ29udGV4dCIsIl9iaW5kUGFnZVRvQ29udGV4dCIsIl9yZXNvbHZlU2VtYW50aWNQYXRoIiwic1RlY2huaWNhbFBhdGgiLCJfYmluZFBhZ2VUb1BhdGgiLCJvUmVzb3VyY2VCdW5kbGUiLCJDb3JlIiwiZ2V0TGlicmFyeVJlc291cmNlQnVuZGxlIiwiZ2V0VGV4dCIsInRpdGxlIiwiZGVzY3JpcHRpb24iLCJtZXNzYWdlIiwiX2NyZWF0ZUZpbHRlckZyb21TZW1hbnRpY1BhdGgiLCJzU2VtYW50aWNQYXRoIiwiYVNlbWFudGljS2V5cyIsIm9NZXRhTW9kZWwiLCJmblVucXVvdGVBbmREZWNvZGUiLCJsYXN0SW5kZXhPZiIsImxlbmd0aCIsImRlY29kZVVSSUNvbXBvbmVudCIsInN1YnN0cmluZyIsImFLZXlWYWx1ZXMiLCJzcGxpdCIsImFGaWx0ZXJzIiwiYkZpbHRlcmluZ0Nhc2VTZW5zaXRpdmUiLCJNb2RlbEhlbHBlciIsImlzRmlsdGVyaW5nQ2FzZVNlbnNpdGl2ZSIsInNLZXlWYWx1ZSIsIkZpbHRlciIsInBhdGgiLCIkUHJvcGVydHlQYXRoIiwib3BlcmF0b3IiLCJGaWx0ZXJPcGVyYXRvciIsIkVRIiwidmFsdWUxIiwiY2FzZVNlbnNpdGl2ZSIsIm1LZXlWYWx1ZXMiLCJmb3JFYWNoIiwic0tleUFzc2lnbm1lbnQiLCJhUGFydHMiLCJiRmFpbGVkIiwibWFwIiwib1NlbWFudGljS2V5Iiwib0RyYWZ0RmlsdGVyIiwiZmlsdGVycyIsImFuZCIsInB1c2giLCJvQ29tYmluZWRGaWx0ZXIiLCJfZ2V0VGVjaG5pY2FsUGF0aEZyb21TZW1hbnRpY1BhdGgiLCJnZXRNZXRhTW9kZWwiLCJzRW50aXR5U2V0UGF0aCIsImdldE1ldGFDb250ZXh0IiwiZ2V0UGF0aCIsIm9GaWx0ZXIiLCJzdGFydHNXaXRoIiwib0xpc3RCaW5kaW5nIiwiYmluZExpc3QiLCJyZXF1ZXN0Q29udGV4dHMiLCJvQ29udGV4dHMiLCJfY2hlY2tQYXRoRm9yU2VtYW50aWNCb29rbWFya2luZyIsInNQYXRoIiwiYU1hdGNoZXMiLCJleGVjIiwib0RyYWZ0Um9vdCIsIm9EcmFmdE5vZGUiLCJzUGF0aFRvUmVzb2x2ZSIsIm9MYXN0U2VtYW50aWNNYXBwaW5nIiwiZ2V0TGFzdFNlbWFudGljTWFwcGluZyIsInNDdXJyZW50SGFzaE5vUGFyYW1zIiwiZ2V0SGFzaENoYW5nZXIiLCJzUm9vdEVudGl0eU5hbWUiLCJzdWJzdHIiLCJiQWxsb3dTZW1hbnRpY0Jvb2ttYXJrIiwiU2VtYW50aWNLZXlIZWxwZXIiLCJnZXRTZW1hbnRpY0tleXMiLCJzZW1hbnRpY1BhdGgiLCJ0ZWNobmljYWxQYXRoIiwic2V0TGFzdFNlbWFudGljTWFwcGluZyIsIm9DdXJyZW50Q29udGV4dCIsInNDdXJyZW50UGF0aCIsIm9Vc2VDb250ZXh0Iiwib1RhcmdldENvbnRleHQiLCJfY3JlYXRlQmluZGluZ0NvbnRleHQiLCJiUmVhc29uSXNJYXBwU3RhdGUiLCJFZGl0U3RhdGUiLCJpc0VkaXRTdGF0ZURpcnR5IiwiX3JlZnJlc2hCaW5kaW5nQ29udGV4dCIsIm9QYXJlbnRMaXN0QmluZGluZyIsInNldFRpbWVvdXQiLCJsaXN0QmluZGluZyIsImJEcmFmdE5hdmlnYXRpb24iLCJzaG93UGxhY2Vob2xkZXIiLCJiU2hvd1BsYWNlaG9sZGVyIiwibmF2aWdhdGVUb1NpYmxpbmdFbnRpdHkiLCJvUGFnZUNvbXBvbmVudCIsInNFbnRpdHlTZXQiLCJnZXRFbnRpdHlTZXQiLCJzQ29udGV4dFBhdGgiLCJnZXRDb250ZXh0UGF0aCIsIiQkcGF0Y2hXaXRob3V0U2lkZUVmZmVjdHMiLCIkJGdyb3VwSWQiLCIkJHVwZGF0ZUdyb3VwSWQiLCJzTWVzc2FnZXNQYXRoIiwiJHNlbGVjdCIsIm9IaWRkZW5CaW5kaW5nIiwiYmluZENvbnRleHQiLCJhdHRhY2hFdmVudE9uY2UiLCJCdXN5TG9ja2VyIiwibG9jayIsIl9kYXRhUmVjZWl2ZWRFdmVudEhhbmRsZXIiLCJnZXRCb3VuZENvbnRleHQiLCJzRXJyb3JEZXNjcmlwdGlvbiIsIm1lc3NhZ2VIYW5kbGVyIiwibVBhcmFtcyIsInN0YXR1cyIsImlzSW5pdGlhbExvYWQ1MDNFcnJvciIsInNoZWxsQmFjayIsImlzRGF0YVJlY2VpdmVkRXJyb3IiLCJzaG93TWVzc2FnZXMiLCJjb250ZXh0IiwiZ2V0U291cmNlIiwiUHJvZ3JhbW1pbmdNb2RlbCIsIkZFTGlicmFyeSIsInByb2dyYW1taW5nTW9kZWwiLCJfZWRpdEZsb3ciLCJnZXRQcm9ncmFtbWluZ01vZGVsIiwidW5sb2NrIiwiRHJhZnQiLCJBY3Rpdml0eVN5bmMiLCJpc0NvbGxhYm9yYXRpb25FbmFibGVkIiwiRHJhZnRBZG1pbmlzdHJhdGl2ZURhdGEiLCJkcmFmdCIsImNvbXB1dGVTaWJsaW5nSW5mb3JtYXRpb24iLCJzaWJsaW5nSW5mbyIsInRhcmdldENvbnRleHQiLCJvU2lkZUVmZmVjdHNTZXJ2aWNlIiwiZ2V0U2lkZUVmZmVjdHNTZXJ2aWNlIiwic1Jvb3RDb250ZXh0UGF0aCIsImFOYXZpZ2F0aW9uUHJvcGVydHlQYXRocyIsImFQcm9wZXJ0eVBhdGhzIiwib1NpZGVFZmZlY3RzIiwiVGFyZ2V0UHJvcGVydGllcyIsIlRhcmdldEVudGl0aWVzIiwiZ2V0QmluZGluZ1BhdGhzIiwib0JpbmRpbmciLCJhRGVwZW5kZW50QmluZGluZ3MiLCJzUmVsYXRpdmVQYXRoIiwiZ2V0Q29udGV4dCIsInNsaWNlIiwiZ2V0RGVwZW5kZW50QmluZGluZ3MiLCJpIiwiJE5hdmlnYXRpb25Qcm9wZXJ0eVBhdGgiLCJyZXF1ZXN0U2lkZUVmZmVjdHMiLCJjb25jYXQiLCJzZXRCaW5kaW5nQ29udGV4dCIsInN3aXRjaEZ1bGxTY3JlZW4iLCJvU291cmNlIiwib0ZDTEhlbHBlck1vZGVsIiwiYklzRnVsbFNjcmVlbiIsInNOZXh0TGF5b3V0Iiwib1Jvb3RWaWV3Q29udHJvbGxlciIsImdldFJpZ2h0bW9zdENvbnRleHQiLCJfcm91dGluZyIsInNMYXlvdXQiLCJ3YXJuaW5nIiwiY2xvc2VDb2x1bW4iLCJvVmlld0RhdGEiLCJ2aWV3TGV2ZWwiLCJpc0RyYWZ0U3VwcG9ydGVkIiwiZm5Qcm9jZXNzRGF0YUxvc3NPckRyYWZ0RGlzY2FyZENvbmZpcm1hdGlvbiIsIm5vUHJlc2VydmF0aW9uQ2FjaGUiLCJGdW5jdGlvbiIsInByb3RvdHlwZSIsIkNvbnRyb2xsZXJFeHRlbnNpb24iXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQWdqQk8sa0JBQWdCQSxJQUFoQixFQUFzQkMsT0FBdEIsRUFBK0I7QUFDckMsUUFBSTtBQUNILFVBQUlDLE1BQU0sR0FBR0YsSUFBSSxFQUFqQjtBQUNBLEtBRkQsQ0FFRSxPQUFNRyxDQUFOLEVBQVM7QUFDVixhQUFPRixPQUFPLENBQUNFLENBQUQsQ0FBZDtBQUNBOztBQUNELFFBQUlELE1BQU0sSUFBSUEsTUFBTSxDQUFDRSxJQUFyQixFQUEyQjtB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b20gXCJzYXAvYmFzZS9Mb2dcIjtcbmltcG9ydCBBY3Rpdml0eVN5bmMgZnJvbSBcInNhcC9mZS9jb3JlL2FjdGlvbnMvY29sbGFib3JhdGlvbi9BY3Rpdml0eVN5bmNcIjtcbmltcG9ydCBkcmFmdCBmcm9tIFwic2FwL2ZlL2NvcmUvYWN0aW9ucy9kcmFmdFwiO1xuaW1wb3J0IEFwcENvbXBvbmVudCBmcm9tIFwic2FwL2ZlL2NvcmUvQXBwQ29tcG9uZW50XCI7XG5pbXBvcnQgQnVzeUxvY2tlciBmcm9tIFwic2FwL2ZlL2NvcmUvQnVzeUxvY2tlclwiO1xuaW1wb3J0IENvbW1vblV0aWxzIGZyb20gXCJzYXAvZmUvY29yZS9Db21tb25VdGlsc1wiO1xuaW1wb3J0IHtcblx0ZGVmaW5lVUk1Q2xhc3MsXG5cdEVuaGFuY2VXaXRoVUk1LFxuXHRleHRlbnNpYmxlLFxuXHRmaW5hbEV4dGVuc2lvbixcblx0bWV0aG9kT3ZlcnJpZGUsXG5cdHB1YmxpY0V4dGVuc2lvblxufSBmcm9tIFwic2FwL2ZlL2NvcmUvaGVscGVycy9DbGFzc1N1cHBvcnRcIjtcbmltcG9ydCBFZGl0U3RhdGUgZnJvbSBcInNhcC9mZS9jb3JlL2hlbHBlcnMvRWRpdFN0YXRlXCI7XG5pbXBvcnQgTW9kZWxIZWxwZXIgZnJvbSBcInNhcC9mZS9jb3JlL2hlbHBlcnMvTW9kZWxIZWxwZXJcIjtcbmltcG9ydCBTZW1hbnRpY0tleUhlbHBlciBmcm9tIFwic2FwL2ZlL2NvcmUvaGVscGVycy9TZW1hbnRpY0tleUhlbHBlclwiO1xuaW1wb3J0IEZFTGlicmFyeSBmcm9tIFwic2FwL2ZlL2NvcmUvbGlicmFyeVwiO1xuaW1wb3J0IFBhZ2VDb250cm9sbGVyIGZyb20gXCJzYXAvZmUvY29yZS9QYWdlQ29udHJvbGxlclwiO1xuaW1wb3J0IFJvdXRlclByb3h5IGZyb20gXCJzYXAvZmUvY29yZS9Sb3V0ZXJQcm94eVwiO1xuaW1wb3J0IHsgUm91dGluZ1NlcnZpY2UgfSBmcm9tIFwic2FwL2ZlL2NvcmUvc2VydmljZXMvUm91dGluZ1NlcnZpY2VGYWN0b3J5XCI7XG5pbXBvcnQgVGVtcGxhdGVDb21wb25lbnQgZnJvbSBcInNhcC9mZS9jb3JlL1RlbXBsYXRlQ29tcG9uZW50XCI7XG5pbXBvcnQgRXZlbnQgZnJvbSBcInNhcC91aS9iYXNlL0V2ZW50XCI7XG5pbXBvcnQgQ29tcG9uZW50IGZyb20gXCJzYXAvdWkvY29yZS9Db21wb25lbnRcIjtcbmltcG9ydCBDb3JlIGZyb20gXCJzYXAvdWkvY29yZS9Db3JlXCI7XG5pbXBvcnQgQ29udHJvbGxlckV4dGVuc2lvbiBmcm9tIFwic2FwL3VpL2NvcmUvbXZjL0NvbnRyb2xsZXJFeHRlbnNpb25cIjtcbmltcG9ydCBPdmVycmlkZUV4ZWN1dGlvbiBmcm9tIFwic2FwL3VpL2NvcmUvbXZjL092ZXJyaWRlRXhlY3V0aW9uXCI7XG5pbXBvcnQgVmlldyBmcm9tIFwic2FwL3VpL2NvcmUvbXZjL1ZpZXdcIjtcbmltcG9ydCBSb3V0ZXIgZnJvbSBcInNhcC91aS9jb3JlL3JvdXRpbmcvUm91dGVyXCI7XG5pbXBvcnQgRmlsdGVyIGZyb20gXCJzYXAvdWkvbW9kZWwvRmlsdGVyXCI7XG5pbXBvcnQgRmlsdGVyT3BlcmF0b3IgZnJvbSBcInNhcC91aS9tb2RlbC9GaWx0ZXJPcGVyYXRvclwiO1xuaW1wb3J0IEpTT05Nb2RlbCBmcm9tIFwic2FwL3VpL21vZGVsL2pzb24vSlNPTk1vZGVsXCI7XG5pbXBvcnQgQ29udGV4dCBmcm9tIFwic2FwL3VpL21vZGVsL29kYXRhL3Y0L0NvbnRleHRcIjtcbmltcG9ydCB7IENvcmVFeCB9IGZyb20gXCJ0eXBlcy9leHRlbnNpb25fdHlwZXNcIjtcblxuLyoqXG4gKiB7QGxpbmsgc2FwLnVpLmNvcmUubXZjLkNvbnRyb2xsZXJFeHRlbnNpb24gQ29udHJvbGxlciBleHRlbnNpb259XG4gKlxuICogQG5hbWVzcGFjZVxuICogQGFsaWFzIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkludGVybmFsUm91dGluZ1xuICpcbiAqIEBwcml2YXRlXG4gKiBAc2luY2UgMS43NC4wXG4gKi9cbkBkZWZpbmVVSTVDbGFzcyhcInNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkludGVybmFsUm91dGluZ1wiKVxuY2xhc3MgSW50ZXJuYWxSb3V0aW5nIGV4dGVuZHMgQ29udHJvbGxlckV4dGVuc2lvbiB7XG5cdHByaXZhdGUgYmFzZSE6IFBhZ2VDb250cm9sbGVyO1xuXHRwcml2YXRlIF9vVmlldyE6IFZpZXc7XG5cdHByaXZhdGUgX29BcHBDb21wb25lbnQhOiBBcHBDb21wb25lbnQ7XG5cdHByaXZhdGUgX29QYWdlQ29tcG9uZW50ITogRW5oYW5jZVdpdGhVSTU8VGVtcGxhdGVDb21wb25lbnQ+IHwgbnVsbDtcblx0cHJpdmF0ZSBfb1JvdXRlciE6IFJvdXRlcjtcblx0cHJpdmF0ZSBfb1JvdXRpbmdTZXJ2aWNlITogUm91dGluZ1NlcnZpY2U7XG5cdHByaXZhdGUgX29Sb3V0ZXJQcm94eSE6IFJvdXRlclByb3h5O1xuXHRwcml2YXRlIF9mblJvdXRlTWF0Y2hlZEJvdW5kITogRnVuY3Rpb247XG5cdHByaXZhdGUgX29UYXJnZXRJbmZvcm1hdGlvbjogYW55O1xuXG5cdEBtZXRob2RPdmVycmlkZSgpXG5cdG9uRXhpdCgpIHtcblx0XHR0aGlzLl9vUm91dGluZ1NlcnZpY2UgJiYgdGhpcy5fb1JvdXRpbmdTZXJ2aWNlLmRldGFjaFJvdXRlTWF0Y2hlZCh0aGlzLl9mblJvdXRlTWF0Y2hlZEJvdW5kKTtcblx0fVxuXG5cdEBtZXRob2RPdmVycmlkZSgpXG5cdG9uSW5pdCgpIHtcblx0XHR0aGlzLl9vVmlldyA9IHRoaXMuYmFzZS5nZXRWaWV3KCk7XG5cdFx0dGhpcy5fb0FwcENvbXBvbmVudCA9IENvbW1vblV0aWxzLmdldEFwcENvbXBvbmVudCh0aGlzLl9vVmlldyk7XG5cdFx0dGhpcy5fb1BhZ2VDb21wb25lbnQgPSBDb21wb25lbnQuZ2V0T3duZXJDb21wb25lbnRGb3IodGhpcy5fb1ZpZXcpIGFzIEVuaGFuY2VXaXRoVUk1PFRlbXBsYXRlQ29tcG9uZW50Pjtcblx0XHR0aGlzLl9vUm91dGVyID0gdGhpcy5fb0FwcENvbXBvbmVudC5nZXRSb3V0ZXIoKTtcblx0XHR0aGlzLl9vUm91dGVyUHJveHkgPSAodGhpcy5fb0FwcENvbXBvbmVudCBhcyBhbnkpLmdldFJvdXRlclByb3h5KCk7XG5cblx0XHRpZiAoIXRoaXMuX29BcHBDb21wb25lbnQgfHwgIXRoaXMuX29QYWdlQ29tcG9uZW50KSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gaW5pdGlhbGl6ZSBjb250cm9sZXIgZXh0ZW5zaW9uICdzYXAuZmUuY29yZS5jb250cm9sbGVyZXh0ZXNpb25zLkludGVybmFsUm91dGluZ1wiKTtcblx0XHR9XG5cblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50XG5cdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdGlmICh0aGlzLl9vQXBwQ29tcG9uZW50ID09PSB0aGlzLl9vUGFnZUNvbXBvbmVudCkge1xuXHRcdFx0Ly8gVGhlIHZpZXcgaXNuJ3QgaG9zdGVkIGluIGEgZGVkaWNhdGVkIFVJQ29tcG9uZW50LCBidXQgZGlyZWN0bHkgaW4gdGhlIGFwcFxuXHRcdFx0Ly8gLS0+IGp1c3Qga2VlcCB0aGUgdmlld1xuXHRcdFx0dGhpcy5fb1BhZ2VDb21wb25lbnQgPSBudWxsO1xuXHRcdH1cblxuXHRcdHRoaXMuX29BcHBDb21wb25lbnRcblx0XHRcdC5nZXRTZXJ2aWNlKFwicm91dGluZ1NlcnZpY2VcIilcblx0XHRcdC50aGVuKChvUm91dGluZ1NlcnZpY2U6IFJvdXRpbmdTZXJ2aWNlKSA9PiB7XG5cdFx0XHRcdHRoaXMuX29Sb3V0aW5nU2VydmljZSA9IG9Sb3V0aW5nU2VydmljZTtcblx0XHRcdFx0dGhpcy5fZm5Sb3V0ZU1hdGNoZWRCb3VuZCA9IHRoaXMuX29uUm91dGVNYXRjaGVkLmJpbmQodGhpcyk7XG5cdFx0XHRcdHRoaXMuX29Sb3V0aW5nU2VydmljZS5hdHRhY2hSb3V0ZU1hdGNoZWQodGhpcy5fZm5Sb3V0ZU1hdGNoZWRCb3VuZCk7XG5cdFx0XHRcdHRoaXMuX29UYXJnZXRJbmZvcm1hdGlvbiA9IG9Sb3V0aW5nU2VydmljZS5nZXRUYXJnZXRJbmZvcm1hdGlvbkZvcih0aGlzLl9vUGFnZUNvbXBvbmVudCB8fCB0aGlzLl9vVmlldyk7XG5cdFx0XHR9KVxuXHRcdFx0LmNhdGNoKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiVGhpcyBjb250cm9sbGVyIGV4dGVuc2lvbiBjYW5ub3Qgd29yayB3aXRob3V0IGEgJ3JvdXRpbmdTZXJ2aWNlJyBvbiB0aGUgbWFpbiBBcHBDb21wb25lbnRcIik7XG5cdFx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUcmlnZ2VyZWQgZXZlcnkgdGltZSB0aGlzIGNvbnRyb2xsZXIgaXMgYSBuYXZpZ2F0aW9uIHRhcmdldC5cblx0ICovXG5cdEBwdWJsaWNFeHRlbnNpb24oKVxuXHRAZXh0ZW5zaWJsZShPdmVycmlkZUV4ZWN1dGlvbi5BZnRlcilcblx0b25Sb3V0ZU1hdGNoZWQoKSB7XG5cdFx0LyoqL1xuXHR9XG5cblx0QHB1YmxpY0V4dGVuc2lvbigpXG5cdEBleHRlbnNpYmxlKE92ZXJyaWRlRXhlY3V0aW9uLkFmdGVyKVxuXHRvblJvdXRlTWF0Y2hlZEZpbmlzaGVkKCkge1xuXHRcdC8qKi9cblx0fVxuXG5cdEBwdWJsaWNFeHRlbnNpb24oKVxuXHRAZXh0ZW5zaWJsZShPdmVycmlkZUV4ZWN1dGlvbi5BZnRlcilcblx0b25CZWZvcmVCaW5kaW5nKG9CaW5kaW5nQ29udGV4dDogYW55LCBtUGFyYW1ldGVycz86IGFueSkge1xuXHRcdGNvbnN0IG9Sb3V0aW5nID0gKHRoaXMuYmFzZS5nZXRWaWV3KCkuZ2V0Q29udHJvbGxlcigpIGFzIGFueSkucm91dGluZztcblx0XHRpZiAob1JvdXRpbmcgJiYgb1JvdXRpbmcub25CZWZvcmVCaW5kaW5nKSB7XG5cdFx0XHRvUm91dGluZy5vbkJlZm9yZUJpbmRpbmcob0JpbmRpbmdDb250ZXh0LCBtUGFyYW1ldGVycyk7XG5cdFx0fVxuXHR9XG5cblx0QHB1YmxpY0V4dGVuc2lvbigpXG5cdEBleHRlbnNpYmxlKE92ZXJyaWRlRXhlY3V0aW9uLkFmdGVyKVxuXHRvbkFmdGVyQmluZGluZyhvQmluZGluZ0NvbnRleHQ6IGFueSwgbVBhcmFtZXRlcnM/OiBhbnkpIHtcblx0XHQodGhpcy5fb0FwcENvbXBvbmVudCBhcyBhbnkpLmdldFJvb3RWaWV3Q29udHJvbGxlcigpLm9uQ29udGV4dEJvdW5kVG9WaWV3KG9CaW5kaW5nQ29udGV4dCk7XG5cdFx0Y29uc3Qgb1JvdXRpbmcgPSAodGhpcy5iYXNlLmdldFZpZXcoKS5nZXRDb250cm9sbGVyKCkgYXMgYW55KS5yb3V0aW5nO1xuXHRcdGlmIChvUm91dGluZyAmJiBvUm91dGluZy5vbkFmdGVyQmluZGluZykge1xuXHRcdFx0b1JvdXRpbmcub25BZnRlckJpbmRpbmcob0JpbmRpbmdDb250ZXh0LCBtUGFyYW1ldGVycyk7XG5cdFx0fVxuXHR9XG5cblx0Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0Ly8gTWV0aG9kcyB0cmlnZ2VyaW5nIGEgbmF2aWdhdGlvbiBhZnRlciBhIHVzZXIgYWN0aW9uXG5cdC8vIChlLmcuIGNsaWNrIG9uIGEgdGFibGUgcm93LCBidXR0b24sIGV0Yy4uLilcblx0Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuXHQvKipcblx0ICogTmF2aWdhdGVzIHRvIHRoZSBzcGVjaWZpZWQgbmF2aWdhdGlvbiB0YXJnZXQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHR9IG9Db250ZXh0IENvbnRleHQgaW5zdGFuY2Vcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNOYXZpZ2F0aW9uVGFyZ2V0TmFtZSBOYXZpZ2F0aW9uIHRhcmdldCBuYW1lXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvU2VtYW50aWNPYmplY3QgU2VtYW50aWMgb2JqZWN0XG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gYlByZXNlcnZlSGlzdG9yeSBUcnVlIHRvIGZvcmNlIHRoZSBuZXcgVVJMIHRvIGJlIGFkZGVkIGF0IHRoZSBlbmQgb2YgdGhlIGJyb3dzZXIgaGlzdG9yeSAobm8gcmVwbGFjZSlcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqL1xuXHRAcHVibGljRXh0ZW5zaW9uKClcblx0bmF2aWdhdGVUb1RhcmdldChvQ29udGV4dDogYW55LCBzTmF2aWdhdGlvblRhcmdldE5hbWU6IHN0cmluZywgb1NlbWFudGljT2JqZWN0Pzogb2JqZWN0LCBiUHJlc2VydmVIaXN0b3J5PzogYm9vbGVhbikge1xuXHRcdGNvbnN0IG9OYXZpZ2F0aW9uQ29uZmlndXJhdGlvbiA9XG5cdFx0XHR0aGlzLl9vUGFnZUNvbXBvbmVudCAmJlxuXHRcdFx0dGhpcy5fb1BhZ2VDb21wb25lbnQuZ2V0TmF2aWdhdGlvbkNvbmZpZ3VyYXRpb24gJiZcblx0XHRcdHRoaXMuX29QYWdlQ29tcG9uZW50LmdldE5hdmlnYXRpb25Db25maWd1cmF0aW9uKHNOYXZpZ2F0aW9uVGFyZ2V0TmFtZSk7XG5cdFx0aWYgKG9OYXZpZ2F0aW9uQ29uZmlndXJhdGlvbikge1xuXHRcdFx0Y29uc3Qgb0RldGFpbFJvdXRlID0gb05hdmlnYXRpb25Db25maWd1cmF0aW9uLmRldGFpbDtcblx0XHRcdGNvbnN0IHNSb3V0ZU5hbWUgPSBvRGV0YWlsUm91dGUucm91dGU7XG5cdFx0XHRjb25zdCBtUGFyYW1ldGVyTWFwcGluZyA9IG9EZXRhaWxSb3V0ZS5wYXJhbWV0ZXJzO1xuXHRcdFx0dGhpcy5fb1JvdXRpbmdTZXJ2aWNlLm5hdmlnYXRlVG8ob0NvbnRleHQsIHNSb3V0ZU5hbWUsIG1QYXJhbWV0ZXJNYXBwaW5nLCBiUHJlc2VydmVIaXN0b3J5KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5fb1JvdXRpbmdTZXJ2aWNlLm5hdmlnYXRlVG8ob0NvbnRleHQsIG51bGwsIG51bGwsIGJQcmVzZXJ2ZUhpc3RvcnkpO1xuXHRcdH1cblx0XHR0aGlzLl9vVmlldy5nZXRWaWV3RGF0YSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIE5hdmlnYXRlcyB0byB0aGUgc3BlY2lmaWVkIG5hdmlnYXRpb24gdGFyZ2V0IHJvdXRlLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc1RhcmdldFJvdXRlTmFtZSBOYW1lIG9mIHRoZSB0YXJnZXQgcm91dGVcblx0ICogQHBhcmFtIHtvYmplY3R9IFtvUGFyYW1ldGVyc10gUGFyYW1ldGVycyB0byBiZSB1c2VkIHdpdGggcm91dGUgdG8gY3JlYXRlIHRoZSB0YXJnZXQgaGFzaFxuXHQgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB0aGF0IGlzIHJlc29sdmVkIHdoZW4gdGhlIG5hdmlnYXRpb24gaXMgZmluYWxpemVkXG5cdCAqIEB1aTUtcmVzdHJpY3RlZFxuXHQgKi9cblx0QHB1YmxpY0V4dGVuc2lvbigpXG5cdG5hdmlnYXRlVG9Sb3V0ZShzVGFyZ2V0Um91dGVOYW1lOiBzdHJpbmcsIG9QYXJhbWV0ZXJzPzogb2JqZWN0KSB7XG5cdFx0cmV0dXJuIHRoaXMuX29Sb3V0aW5nU2VydmljZS5uYXZpZ2F0ZVRvUm91dGUoc1RhcmdldFJvdXRlTmFtZSwgb1BhcmFtZXRlcnMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIE5hdmlnYXRlcyB0byBhIHNwZWNpZmljIGNvbnRleHQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHR9IG9Db250ZXh0IFRoZSBjb250ZXh0IHRvIGJlIG5hdmlnYXRlZCB0b1xuXHQgKiBAcGFyYW0ge29iamVjdH0gW21QYXJhbWV0ZXJzXSBPcHRpb25hbCBuYXZpZ2F0aW9uIHBhcmFtZXRlcnNcblx0ICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgcmVzb2x2ZWQgd2hlbiB0aGUgbmF2aWdhdGlvbiBoYXMgYmVlbiB0cmlnZ2VyZWRcblx0ICpcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqL1xuXHRAcHVibGljRXh0ZW5zaW9uKClcblx0QGZpbmFsRXh0ZW5zaW9uKClcblx0bmF2aWdhdGVUb0NvbnRleHQob0NvbnRleHQ6IGFueSwgbVBhcmFtZXRlcnM/OiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRjb25zdCBvQ29udGV4dEluZm86IGFueSA9IHt9O1xuXHRcdG1QYXJhbWV0ZXJzID0gbVBhcmFtZXRlcnMgfHwge307XG5cblx0XHRpZiAob0NvbnRleHQuaXNBKFwic2FwLnVpLm1vZGVsLm9kYXRhLnY0Lk9EYXRhTGlzdEJpbmRpbmdcIikpIHtcblx0XHRcdGlmIChtUGFyYW1ldGVycy5hc3luY0NvbnRleHQpIHtcblx0XHRcdFx0Ly8gdGhlIGNvbnRleHQgaXMgZWl0aGVyIGNyZWF0ZWQgYXN5bmMgKFByb21pc2UpXG5cdFx0XHRcdC8vIFdlIG5lZWQgdG8gYWN0aXZhdGUgdGhlIHJvdXRlTWF0Y2hTeW5jaHJvIG9uIHRoZSBSb3V0ZXJQcm94eSB0byBhdm9pZCB0aGF0XG5cdFx0XHRcdC8vIHRoZSBzdWJzZXF1ZW50IGNhbGwgdG8gbmF2aWdhdGVUb0NvbnRleHQgY29uZmxpY3RzIHdpdGggdGhlIGN1cnJlbnQgb25lXG5cdFx0XHRcdHRoaXMuX29Sb3V0ZXJQcm94eS5hY3RpdmF0ZVJvdXRlTWF0Y2hTeW5jaHJvbml6YXRpb24oKTtcblxuXHRcdFx0XHRtUGFyYW1ldGVycy5hc3luY0NvbnRleHRcblx0XHRcdFx0XHQudGhlbigob0NvbnRleHQ6IGFueSkgPT4ge1xuXHRcdFx0XHRcdFx0Ly8gb25jZSB0aGUgY29udGV4dCBpcyByZXR1cm5lZCB3ZSBuYXZpZ2F0ZSBpbnRvIGl0XG5cdFx0XHRcdFx0XHR0aGlzLm5hdmlnYXRlVG9Db250ZXh0KG9Db250ZXh0LCB7XG5cdFx0XHRcdFx0XHRcdGNoZWNrTm9IYXNoQ2hhbmdlOiBtUGFyYW1ldGVycy5jaGVja05vSGFzaENoYW5nZSxcblx0XHRcdFx0XHRcdFx0ZWRpdGFibGU6IG1QYXJhbWV0ZXJzLmVkaXRhYmxlLFxuXHRcdFx0XHRcdFx0XHRiUGVyc2lzdE9QU2Nyb2xsOiBtUGFyYW1ldGVycy5iUGVyc2lzdE9QU2Nyb2xsLFxuXHRcdFx0XHRcdFx0XHR1cGRhdGVGQ0xMZXZlbDogbVBhcmFtZXRlcnMudXBkYXRlRkNMTGV2ZWwsXG5cdFx0XHRcdFx0XHRcdGJGb3JjZUZvY3VzOiBtUGFyYW1ldGVycy5iRm9yY2VGb2N1cyxcblx0XHRcdFx0XHRcdFx0Yk5hdmlnYXRlVG9TaWJsaW5nRW50aXR5OiBtUGFyYW1ldGVycy5iTmF2aWdhdGVUb1NpYmxpbmdFbnRpdHlcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0LmNhdGNoKGZ1bmN0aW9uIChvRXJyb3I6IGFueSkge1xuXHRcdFx0XHRcdFx0TG9nLmVycm9yKFwiRXJyb3Igd2l0aCB0aGUgYXN5bmMgY29udGV4dFwiLCBvRXJyb3IpO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0fSBlbHNlIGlmICghbVBhcmFtZXRlcnMuYkRlZmVycmVkQ29udGV4dCkge1xuXHRcdFx0XHQvLyBOYXZpZ2F0ZSB0byBhIGxpc3QgYmluZGluZyBub3QgeWV0IHN1cHBvcnRlZFxuXHRcdFx0XHR0aHJvdyBcIm5hdmlnYXRpb24gdG8gYSBsaXN0IGJpbmRpbmcgaXMgbm90IHlldCBzdXBwb3J0ZWRcIjtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAobVBhcmFtZXRlcnMuY2FsbEV4dGVuc2lvbikge1xuXHRcdFx0Y29uc3Qgb0ludGVybmFsTW9kZWwgPSB0aGlzLl9vVmlldy5nZXRNb2RlbChcImludGVybmFsXCIpIGFzIEpTT05Nb2RlbDtcblx0XHRcdG9JbnRlcm5hbE1vZGVsLnNldFByb3BlcnR5KFwiL3BhZ2luYXRvckN1cnJlbnRDb250ZXh0XCIsIG51bGwpO1xuXG5cdFx0XHRvQ29udGV4dEluZm8uc291cmNlQmluZGluZ0NvbnRleHQgPSBvQ29udGV4dC5nZXRPYmplY3QoKTtcblx0XHRcdG9Db250ZXh0SW5mby5iaW5kaW5nQ29udGV4dCA9IG9Db250ZXh0O1xuXHRcdFx0aWYgKG1QYXJhbWV0ZXJzLm9FdmVudCkge1xuXHRcdFx0XHRvQ29udGV4dEluZm8ub0V2ZW50ID0gbVBhcmFtZXRlcnMub0V2ZW50O1xuXHRcdFx0fVxuXHRcdFx0Ly8gU3RvcmluZyB0aGUgc2VsZWN0ZWQgY29udGV4dCB0byB1c2UgaXQgaW4gaW50ZXJuYWwgcm91dGUgbmF2aWdhdGlvbiBpZiBuZWNjZXNzYXJ5LlxuXHRcdFx0Y29uc3QgYk92ZXJyaWRlTmF2ID0gKHRoaXMuYmFzZS5nZXRWaWV3KCkuZ2V0Q29udHJvbGxlcigpIGFzIGFueSkucm91dGluZy5vbkJlZm9yZU5hdmlnYXRpb24ob0NvbnRleHRJbmZvKTtcblx0XHRcdGlmIChiT3ZlcnJpZGVOYXYpIHtcblx0XHRcdFx0b0ludGVybmFsTW9kZWwuc2V0UHJvcGVydHkoXCIvcGFnaW5hdG9yQ3VycmVudENvbnRleHRcIiwgb0NvbnRleHQpO1xuXHRcdFx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdG1QYXJhbWV0ZXJzLkZDTExldmVsID0gdGhpcy5fZ2V0RkNMTGV2ZWwoKTtcblxuXHRcdHJldHVybiB0aGlzLl9vUm91dGluZ1NlcnZpY2UubmF2aWdhdGVUb0NvbnRleHQob0NvbnRleHQsIG1QYXJhbWV0ZXJzLCB0aGlzLl9vVmlldy5nZXRWaWV3RGF0YSgpLCB0aGlzLl9vVGFyZ2V0SW5mb3JtYXRpb24pO1xuXHR9XG5cblx0LyoqXG5cdCAqIE5hdmlnYXRlcyBiYWNrd2FyZHMgZnJvbSBhIGNvbnRleHQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHR9IG9Db250ZXh0IENvbnRleHQgdG8gYmUgbmF2aWdhdGVkIGZyb21cblx0ICogQHBhcmFtIHtvYmplY3R9IFttUGFyYW1ldGVyc10gT3B0aW9uYWwgbmF2aWdhdGlvbiBwYXJhbWV0ZXJzXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHJlc29sdmVkIHdoZW4gdGhlIG5hdmlnYXRpb24gaGFzIGJlZW4gdHJpZ2dlcmVkXG5cdCAqXG5cdCAqIEB1aTUtcmVzdHJpY3RlZFxuXHQgKi9cblx0QHB1YmxpY0V4dGVuc2lvbigpXG5cdEBmaW5hbEV4dGVuc2lvbigpXG5cdG5hdmlnYXRlQmFja0Zyb21Db250ZXh0KG9Db250ZXh0OiBhbnksIG1QYXJhbWV0ZXJzPzogYW55KSB7XG5cdFx0bVBhcmFtZXRlcnMgPSBtUGFyYW1ldGVycyB8fCB7fTtcblx0XHRtUGFyYW1ldGVycy51cGRhdGVGQ0xMZXZlbCA9IC0xO1xuXG5cdFx0cmV0dXJuIHRoaXMubmF2aWdhdGVUb0NvbnRleHQob0NvbnRleHQsIG1QYXJhbWV0ZXJzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBOYXZpZ2F0ZXMgZm9yd2FyZHMgdG8gYSBjb250ZXh0LlxuXHQgKlxuXHQgKiBAcGFyYW0ge3NhcC51aS5tb2RlbC5vZGF0YS52NC5Db250ZXh0fSBvQ29udGV4dCBDb250ZXh0IHRvIGJlIG5hdmlnYXRlZCB0b1xuXHQgKiBAcGFyYW0ge29iamVjdH0gbVBhcmFtZXRlcnMgT3B0aW9uYWwgbmF2aWdhdGlvbiBwYXJhbWV0ZXJzXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHJlc29sdmVkIHdoZW4gdGhlIG5hdmlnYXRpb24gaGFzIGJlZW4gdHJpZ2dlcmVkXG5cdCAqXG5cdCAqIEB1aTUtcmVzdHJpY3RlZFxuXHQgKi9cblx0QHB1YmxpY0V4dGVuc2lvbigpXG5cdEBmaW5hbEV4dGVuc2lvbigpXG5cdG5hdmlnYXRlRm9yd2FyZFRvQ29udGV4dChvQ29udGV4dDogYW55LCBtUGFyYW1ldGVycz86IGFueSkge1xuXHRcdGlmICh0aGlzLl9vVmlldy5nZXRCaW5kaW5nQ29udGV4dChcImludGVybmFsXCIpPy5nZXRQcm9wZXJ0eShcIm1lc3NhZ2VGb290ZXJDb250YWluc0Vycm9yc1wiKSA9PT0gdHJ1ZSkge1xuXHRcdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXHRcdH1cblx0XHRtUGFyYW1ldGVycyA9IG1QYXJhbWV0ZXJzIHx8IHt9O1xuXHRcdG1QYXJhbWV0ZXJzLnVwZGF0ZUZDTExldmVsID0gMTtcblxuXHRcdHJldHVybiB0aGlzLm5hdmlnYXRlVG9Db250ZXh0KG9Db250ZXh0LCBtUGFyYW1ldGVycyk7XG5cdH1cblxuXHQvKipcblx0ICogTmF2aWdhdGVzIGJhY2sgaW4gaGlzdG9yeSBpZiB0aGUgY3VycmVudCBoYXNoIGNvcnJlc3BvbmRzIHRvIGEgdHJhbnNpZW50IHN0YXRlLlxuXHQgKi9cblx0QHB1YmxpY0V4dGVuc2lvbigpXG5cdEBmaW5hbEV4dGVuc2lvbigpXG5cdG5hdmlnYXRlQmFja0Zyb21UcmFuc2llbnRTdGF0ZSgpIHtcblx0XHRjb25zdCBzSGFzaCA9IHRoaXMuX29Sb3V0ZXJQcm94eS5nZXRIYXNoKCk7XG5cblx0XHQvLyBpZiB0cmlnZ2VyZWQgd2hpbGUgbmF2aWdhdGluZyB0byAoLi4uKSwgd2UgbmVlZCB0byBuYXZpZ2F0ZSBiYWNrXG5cdFx0aWYgKHNIYXNoLmluZGV4T2YoXCIoLi4uKVwiKSAhPT0gLTEpIHtcblx0XHRcdHRoaXMuX29Sb3V0ZXJQcm94eS5uYXZCYWNrKCk7XG5cdFx0fVxuXHR9XG5cblx0QHB1YmxpY0V4dGVuc2lvbigpXG5cdEBmaW5hbEV4dGVuc2lvbigpXG5cdG5hdmlnYXRlVG9NZXNzYWdlUGFnZShzRXJyb3JNZXNzYWdlOiBhbnksIG1QYXJhbWV0ZXJzOiBhbnkpIHtcblx0XHRtUGFyYW1ldGVycyA9IG1QYXJhbWV0ZXJzIHx8IHt9O1xuXHRcdGlmICh0aGlzLl9vUm91dGVyUHJveHkuZ2V0SGFzaCgpLmluZGV4T2YoXCJpLWFjdGlvbj1jcmVhdGVcIikgPiAtMSkge1xuXHRcdFx0cmV0dXJuIHRoaXMuX29Sb3V0ZXJQcm94eS5uYXZUb0hhc2godGhpcy5fb1JvdXRpbmdTZXJ2aWNlLmdldERlZmF1bHRDcmVhdGVIYXNoKCkpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRtUGFyYW1ldGVycy5GQ0xMZXZlbCA9IHRoaXMuX2dldEZDTExldmVsKCk7XG5cblx0XHRcdHJldHVybiAodGhpcy5fb0FwcENvbXBvbmVudCBhcyBhbnkpLmdldFJvb3RWaWV3Q29udHJvbGxlcigpLmRpc3BsYXlNZXNzYWdlUGFnZShzRXJyb3JNZXNzYWdlLCBtUGFyYW1ldGVycyk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiBvbmUgb2YgdGhlIGN1cnJlbnQgdmlld3Mgb24gdGhlIHNjcmVlbiBpcyBib3VuZCB0byBhIGdpdmVuIGNvbnRleHQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHR9IG9Db250ZXh0XG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxuXHQgKlxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICovXG5cdEBwdWJsaWNFeHRlbnNpb24oKVxuXHRAZmluYWxFeHRlbnNpb24oKVxuXHRpc0N1cnJlbnRTdGF0ZUltcGFjdGVkQnkob0NvbnRleHQ6IGFueSkge1xuXHRcdHJldHVybiB0aGlzLl9vUm91dGluZ1NlcnZpY2UuaXNDdXJyZW50U3RhdGVJbXBhY3RlZEJ5KG9Db250ZXh0KTtcblx0fVxuXG5cdC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdC8vIE1ldGhvZHMgdG8gYmluZCB0aGUgcGFnZSB3aGVuIGEgcm91dGUgaXMgbWF0Y2hlZFxuXHQvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5cdC8qKlxuXHQgKiBDYWxsZWQgd2hlbiBhIHJvdXRlIGlzIG1hdGNoZWQuXG5cdCAqIEJ1aWxkcyB0aGUgYmluZGluZyBjb250ZXh0IGZyb20gdGhlIG5hdmlnYXRpb24gcGFyYW1ldGVycywgYW5kIGJpbmQgdGhlIHBhZ2UgYWNjb3JkaW5nbHkuXG5cdCAqXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvRXZlbnRcblx0ICpcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqL1xuXHRfb25Sb3V0ZU1hdGNoZWQob0V2ZW50OiBFdmVudCkge1xuXHRcdC8vIENoZWNrIGlmIHRoZSB0YXJnZXQgZm9yIHRoaXMgdmlldyBpcyBwYXJ0IG9mIHRoZSBldmVudCB0YXJnZXRzXG5cdFx0Y29uc3QgYVRhcmdldHMgPSBvRXZlbnQuZ2V0UGFyYW1ldGVyKFwicm91dGVJbmZvcm1hdGlvblwiKSAmJiBvRXZlbnQuZ2V0UGFyYW1ldGVyKFwicm91dGVJbmZvcm1hdGlvblwiKS50YXJnZXRzO1xuXHRcdGlmICghYVRhcmdldHMgfHwgYVRhcmdldHMuaW5kZXhPZih0aGlzLl9vVGFyZ2V0SW5mb3JtYXRpb24udGFyZ2V0TmFtZSkgPT09IC0xKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gUmV0cmlldmUgdGhlIGJpbmRpbmcgY29udGV4dCBwYXR0ZXJuXG5cdFx0bGV0IHNUYXJnZXQ7XG5cdFx0aWYgKHRoaXMuX29QYWdlQ29tcG9uZW50ICYmIHRoaXMuX29QYWdlQ29tcG9uZW50LmdldEJpbmRpbmdDb250ZXh0UGF0dGVybikge1xuXHRcdFx0c1RhcmdldCA9IHRoaXMuX29QYWdlQ29tcG9uZW50LmdldEJpbmRpbmdDb250ZXh0UGF0dGVybigpO1xuXHRcdH1cblx0XHRzVGFyZ2V0ID0gc1RhcmdldCB8fCB0aGlzLl9vVGFyZ2V0SW5mb3JtYXRpb24uY29udGV4dFBhdHRlcm47XG5cblx0XHRpZiAoc1RhcmdldCA9PT0gbnVsbCB8fCBzVGFyZ2V0ID09PSB1bmRlZmluZWQpIHtcblx0XHRcdC8vIERvbid0IGRvIHRoaXMgaWYgd2UgYWxyZWFkeSBnb3Qgc1RhcmdldCA9PSAnJywgd2hpY2ggaXMgYSB2YWxpZCB0YXJnZXQgcGF0dGVyblxuXHRcdFx0c1RhcmdldCA9IG9FdmVudC5nZXRQYXJhbWV0ZXIoXCJyb3V0ZVBhdHRlcm5cIik7XG5cdFx0fVxuXHRcdHNUYXJnZXQgPSBzVGFyZ2V0LnJlcGxhY2UoXCI6P3F1ZXJ5OlwiLCBcIlwiKTtcblxuXHRcdC8vIFJlcGxhY2UgdGhlIHBhcmFtZXRlcnMgYnkgdGhlaXIgdmFsdWVzIGluIHRoZSBiaW5kaW5nIGNvbnRleHQgcGF0dGVyblxuXHRcdGNvbnN0IG1Bcmd1bWVudHMgPSAob0V2ZW50LmdldFBhcmFtZXRlcnMoKSBhcyBhbnkpLmFyZ3VtZW50cztcblx0XHRsZXQgYkRlZmVycmVkID0gZmFsc2U7XG5cdFx0Y29uc3Qgb05hdmlnYXRpb25QYXJhbWV0ZXJzID0gb0V2ZW50LmdldFBhcmFtZXRlcihcIm5hdmlnYXRpb25JbmZvXCIpO1xuXG5cdFx0Zm9yIChjb25zdCBzS2V5IGluIG1Bcmd1bWVudHMpIHtcblx0XHRcdGNvbnN0IHNWYWx1ZSA9IG1Bcmd1bWVudHNbc0tleV07XG5cdFx0XHRpZiAoc1ZhbHVlID09PSBcIi4uLlwiICYmIHNUYXJnZXQuaW5kZXhPZihcIntcIiArIHNLZXkgKyBcIn1cIikgPj0gMCkge1xuXHRcdFx0XHRiRGVmZXJyZWQgPSB0cnVlO1xuXHRcdFx0XHQvLyBTb21ldGltZXMgaW4gcHJlZmVycmVkTW9kZSA9IGNyZWF0ZSwgdGhlIGVkaXQgYnV0dG9uIGlzIHNob3duIGluIGJhY2tncm91bmQgd2hlbiB0aGVcblx0XHRcdFx0Ly8gYWN0aW9uIHBhcmFtZXRlciBkaWFsb2cgc2hvd3MgdXAsIHNldHRpbmcgYlRhcmdldEVkaXRhYmxlIHBhc3NlcyBlZGl0YWJsZSBhcyB0cnVlXG5cdFx0XHRcdC8vIHRvIG9uQmVmb3JlQmluZGluZyBpbiBfYmluZFRhcmdldFBhZ2UgZnVuY3Rpb25cblx0XHRcdFx0b05hdmlnYXRpb25QYXJhbWV0ZXJzLmJUYXJnZXRFZGl0YWJsZSA9IHRydWU7XG5cdFx0XHR9XG5cdFx0XHRzVGFyZ2V0ID0gc1RhcmdldC5yZXBsYWNlKFwie1wiICsgc0tleSArIFwifVwiLCBzVmFsdWUpO1xuXHRcdH1cblx0XHRpZiAobUFyZ3VtZW50c1tcIj9xdWVyeVwiXSAmJiBtQXJndW1lbnRzW1wiP3F1ZXJ5XCJdLmhhc093blByb3BlcnR5KFwiaS1hY3Rpb25cIikpIHtcblx0XHRcdG9OYXZpZ2F0aW9uUGFyYW1ldGVycy5iQWN0aW9uQ3JlYXRlID0gdHJ1ZTtcblx0XHR9XG5cblx0XHQvLyB0aGUgYmluZGluZyB0YXJnZXQgaXMgYWx3YXlzIGFic29sdXRlXG5cdFx0aWYgKHNUYXJnZXQgJiYgc1RhcmdldFswXSAhPT0gXCIvXCIpIHtcblx0XHRcdHNUYXJnZXQgPSBcIi9cIiArIHNUYXJnZXQ7XG5cdFx0fVxuXG5cdFx0dGhpcy5vblJvdXRlTWF0Y2hlZCgpO1xuXG5cdFx0Y29uc3Qgb01vZGVsID0gdGhpcy5fb1ZpZXcuZ2V0TW9kZWwoKTtcblx0XHRsZXQgb091dDtcblx0XHRpZiAoYkRlZmVycmVkKSB7XG5cdFx0XHRvT3V0ID0gdGhpcy5fYmluZERlZmVycmVkKHNUYXJnZXQsIG9OYXZpZ2F0aW9uUGFyYW1ldGVycyk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG9PdXQgPSB0aGlzLl9iaW5kUGFnZShzVGFyZ2V0LCBvTW9kZWwsIG9OYXZpZ2F0aW9uUGFyYW1ldGVycyk7XG5cdFx0fVxuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcm9taXNlL2NhdGNoLW9yLXJldHVyblxuXHRcdG9PdXQuZmluYWxseSgoKSA9PiB7XG5cdFx0XHR0aGlzLm9uUm91dGVNYXRjaGVkRmluaXNoZWQoKTtcblx0XHR9KTtcblxuXHRcdCh0aGlzLl9vQXBwQ29tcG9uZW50IGFzIGFueSkuZ2V0Um9vdFZpZXdDb250cm9sbGVyKCkudXBkYXRlVUlTdGF0ZUZvclZpZXcodGhpcy5fb1ZpZXcsIHRoaXMuX2dldEZDTExldmVsKCkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIERlZmVycmVkIGJpbmRpbmcgKGR1cmluZyBvYmplY3QgY3JlYXRpb24pLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc1RhcmdldFBhdGggVGhlIHBhdGggdG8gdGhlIGRlZmZlcmVkIGNvbnRleHRcblx0ICogQHBhcmFtIHtvYmplY3R9IG9OYXZpZ2F0aW9uUGFyYW1ldGVycyBOYXZpZ2F0aW9uIHBhcmFtZXRlcnNcblx0ICogQHJldHVybnMge1Byb21pc2V9XG5cdCAqIEB1aTUtcmVzdHJpY3RlZFxuXHQgKi9cblx0X2JpbmREZWZlcnJlZChzVGFyZ2V0UGF0aDogc3RyaW5nLCBvTmF2aWdhdGlvblBhcmFtZXRlcnM6IGFueSkge1xuXHRcdHRoaXMub25CZWZvcmVCaW5kaW5nKG51bGwsIHsgZWRpdGFibGU6IG9OYXZpZ2F0aW9uUGFyYW1ldGVycy5iVGFyZ2V0RWRpdGFibGUgfSk7XG5cblx0XHRpZiAob05hdmlnYXRpb25QYXJhbWV0ZXJzLmJEZWZlcnJlZENvbnRleHQgfHwgIW9OYXZpZ2F0aW9uUGFyYW1ldGVycy5vQXN5bmNDb250ZXh0KSB7XG5cdFx0XHQvLyBlaXRoZXIgdGhlIGNvbnRleHQgc2hhbGwgYmUgY3JlYXRlZCBpbiB0aGUgdGFyZ2V0IHBhZ2UgKGRlZmVycmVkIENvbnRleHQpIG9yIGl0IHNoYWxsXG5cdFx0XHQvLyBiZSBjcmVhdGVkIGFzeW5jIGJ1dCB0aGUgdXNlciByZWZyZXNoZWQgdGhlIHBhZ2UgLyBib29rbWFya2VkIHRoaXMgVVJMXG5cdFx0XHQvLyBUT0RPOiBjdXJyZW50bHkgdGhlIHRhcmdldCBjb21wb25lbnQgY3JlYXRlcyB0aGlzIGRvY3VtZW50IGJ1dCB3ZSBzaGFsbCBtb3ZlIHRoaXMgdG9cblx0XHRcdC8vIGEgY2VudHJhbCBwbGFjZVxuXHRcdFx0aWYgKHRoaXMuX29QYWdlQ29tcG9uZW50ICYmIHRoaXMuX29QYWdlQ29tcG9uZW50LmNyZWF0ZURlZmVycmVkQ29udGV4dCkge1xuXHRcdFx0XHR0aGlzLl9vUGFnZUNvbXBvbmVudC5jcmVhdGVEZWZlcnJlZENvbnRleHQoXG5cdFx0XHRcdFx0c1RhcmdldFBhdGgsXG5cdFx0XHRcdFx0b05hdmlnYXRpb25QYXJhbWV0ZXJzLnVzZUNvbnRleHQsXG5cdFx0XHRcdFx0b05hdmlnYXRpb25QYXJhbWV0ZXJzLmJBY3Rpb25DcmVhdGVcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAodGhpcy5fZ2V0QmluZGluZ0NvbnRleHQoKSAmJiB0aGlzLl9nZXRCaW5kaW5nQ29udGV4dCgpLmhhc1BlbmRpbmdDaGFuZ2VzKCkpIHtcblx0XHRcdC8vIEZvciBub3cgcmVtb3ZlIHRoZSBwZW5kaW5nIGNoYW5nZXMgdG8gYXZvaWQgdGhlIG1vZGVsIHJhaXNlcyBlcnJvcnMgYW5kIHRoZSBvYmplY3QgcGFnZSBpcyBhdCBsZWFzdCBib3VuZFxuXHRcdFx0Ly8gSWRlYWxseSB0aGUgdXNlciBzaG91bGQgYmUgYXNrZWQgZm9yXG5cdFx0XHR0aGlzLl9nZXRCaW5kaW5nQ29udGV4dCgpLmdldEJpbmRpbmcoKS5yZXNldENoYW5nZXMoKTtcblx0XHR9XG5cblx0XHQvLyByZW1vdmUgdGhlIGNvbnRleHQgdG8gYXZvaWQgc2hvd2luZyBvbGQgZGF0YVxuXHRcdHRoaXMuX3NldEJpbmRpbmdDb250ZXh0KG51bGwpO1xuXG5cdFx0dGhpcy5vbkFmdGVyQmluZGluZyhudWxsKTtcblx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgYmluZGluZyBjb250ZXh0IG9mIHRoZSBwYWdlIGZyb20gYSBwYXRoLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc1RhcmdldFBhdGggVGhlIHBhdGggdG8gdGhlIGNvbnRleHRcblx0ICogQHBhcmFtIHtzYXAudWkubW9kZWwub2RhdGEudjQuT0RhdGFNb2RlbH0gb01vZGVsIFRoZSBPRGF0YSBtb2RlbFxuXHQgKiBAcGFyYW0ge29iamVjdH0gb05hdmlnYXRpb25QYXJhbWV0ZXJzIE5hdmlnYXRpb24gcGFyYW1ldGVyc1xuXHQgKiBAcmV0dXJucyB7UHJvbWlzZX1cblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqL1xuXHRfYmluZFBhZ2Uoc1RhcmdldFBhdGg6IHN0cmluZywgb01vZGVsOiBhbnksIG9OYXZpZ2F0aW9uUGFyYW1ldGVyczogb2JqZWN0KSB7XG5cdFx0aWYgKHNUYXJnZXRQYXRoID09PSBcIlwiKSB7XG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuX2JpbmRQYWdlVG9Db250ZXh0KG51bGwsIG9Nb2RlbCwgb05hdmlnYXRpb25QYXJhbWV0ZXJzKSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiB0aGlzLl9yZXNvbHZlU2VtYW50aWNQYXRoKHNUYXJnZXRQYXRoLCBvTW9kZWwpXG5cdFx0XHRcdC50aGVuKChzVGVjaG5pY2FsUGF0aDogYW55KSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5fYmluZFBhZ2VUb1BhdGgoc1RlY2huaWNhbFBhdGgsIG9Nb2RlbCwgb05hdmlnYXRpb25QYXJhbWV0ZXJzKTtcblx0XHRcdFx0fSlcblx0XHRcdFx0LmNhdGNoKChvRXJyb3I6IGFueSkgPT4ge1xuXHRcdFx0XHRcdC8vIEVycm9yIGhhbmRsaW5nIGZvciBlcnJvbmVvdXMgbWV0YWRhdGEgcmVxdWVzdFxuXHRcdFx0XHRcdGNvbnN0IG9SZXNvdXJjZUJ1bmRsZSA9IChDb3JlIGFzIENvcmVFeCkuZ2V0TGlicmFyeVJlc291cmNlQnVuZGxlKFwic2FwLmZlLmNvcmVcIik7XG5cblx0XHRcdFx0XHR0aGlzLm5hdmlnYXRlVG9NZXNzYWdlUGFnZShvUmVzb3VyY2VCdW5kbGUuZ2V0VGV4dChcIkNfQ09NTU9OX1NBUEZFX0RBVEFfUkVDRUlWRURfRVJST1JcIiksIHtcblx0XHRcdFx0XHRcdHRpdGxlOiBvUmVzb3VyY2VCdW5kbGUuZ2V0VGV4dChcIkNfQ09NTU9OX1NBUEZFX0VSUk9SXCIpLFxuXHRcdFx0XHRcdFx0ZGVzY3JpcHRpb246IG9FcnJvci5tZXNzYWdlXG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIHRoZSBmaWx0ZXIgdG8gcmV0cmlldmUgYSBjb250ZXh0IGNvcnJlc3BvbmRpbmcgdG8gYSBzZW1hbnRpYyBwYXRoLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc1NlbWFudGljUGF0aCBUaGUgc2VtYW50aWMgcGF0aFxuXHQgKiBAcGFyYW0ge0FycmF5fSBhU2VtYW50aWNLZXlzIFRoZSBzZW1hbnRpYyBrZXlzIGZvciB0aGUgcGF0aFxuXHQgKiBAcGFyYW0ge29iamVjdH0gb01ldGFNb2RlbCBUaGUgaW5zdGFuY2Ugb2YgdGhlIG1ldGEgbW9kZWxcblx0ICogQHJldHVybnMge3NhcC51aS5tb2RlbC5GaWx0ZXJ9IFRoZSBmaWx0ZXJcblx0ICpcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqL1xuXHRfY3JlYXRlRmlsdGVyRnJvbVNlbWFudGljUGF0aChzU2VtYW50aWNQYXRoOiBzdHJpbmcsIGFTZW1hbnRpY0tleXM6IGFueVtdLCBvTWV0YU1vZGVsOiBvYmplY3QpIHtcblx0XHRjb25zdCBmblVucXVvdGVBbmREZWNvZGUgPSBmdW5jdGlvbiAoc1ZhbHVlOiBhbnkpIHtcblx0XHRcdGlmIChzVmFsdWUuaW5kZXhPZihcIidcIikgPT09IDAgJiYgc1ZhbHVlLmxhc3RJbmRleE9mKFwiJ1wiKSA9PT0gc1ZhbHVlLmxlbmd0aCAtIDEpIHtcblx0XHRcdFx0Ly8gUmVtb3ZlIHRoZSBxdW90ZXMgZnJvbSB0aGUgdmFsdWUgYW5kIGRlY29kZSBzcGVjaWFsIGNoYXJzXG5cdFx0XHRcdHNWYWx1ZSA9IGRlY29kZVVSSUNvbXBvbmVudChzVmFsdWUuc3Vic3RyaW5nKDEsIHNWYWx1ZS5sZW5ndGggLSAxKSk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gc1ZhbHVlO1xuXHRcdH07XG5cdFx0Y29uc3QgYUtleVZhbHVlcyA9IHNTZW1hbnRpY1BhdGguc3Vic3RyaW5nKHNTZW1hbnRpY1BhdGguaW5kZXhPZihcIihcIikgKyAxLCBzU2VtYW50aWNQYXRoLmxlbmd0aCAtIDEpLnNwbGl0KFwiLFwiKTtcblx0XHRsZXQgYUZpbHRlcnM6IEZpbHRlcltdO1xuXG5cdFx0aWYgKGFTZW1hbnRpY0tleXMubGVuZ3RoICE9IGFLZXlWYWx1ZXMubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9XG5cblx0XHRjb25zdCBiRmlsdGVyaW5nQ2FzZVNlbnNpdGl2ZSA9IE1vZGVsSGVscGVyLmlzRmlsdGVyaW5nQ2FzZVNlbnNpdGl2ZShvTWV0YU1vZGVsKTtcblxuXHRcdGlmIChhU2VtYW50aWNLZXlzLmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0Ly8gVGFrZSB0aGUgZmlyc3Qga2V5IHZhbHVlXG5cdFx0XHRjb25zdCBzS2V5VmFsdWUgPSBmblVucXVvdGVBbmREZWNvZGUoYUtleVZhbHVlc1swXSk7XG5cdFx0XHRhRmlsdGVycyA9IFtcblx0XHRcdFx0bmV3IEZpbHRlcih7XG5cdFx0XHRcdFx0cGF0aDogYVNlbWFudGljS2V5c1swXS4kUHJvcGVydHlQYXRoLFxuXHRcdFx0XHRcdG9wZXJhdG9yOiBGaWx0ZXJPcGVyYXRvci5FUSxcblx0XHRcdFx0XHR2YWx1ZTE6IHNLZXlWYWx1ZSxcblx0XHRcdFx0XHRjYXNlU2Vuc2l0aXZlOiBiRmlsdGVyaW5nQ2FzZVNlbnNpdGl2ZVxuXHRcdFx0XHR9KVxuXHRcdFx0XTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29uc3QgbUtleVZhbHVlczogYW55ID0ge307XG5cdFx0XHQvLyBDcmVhdGUgYSBtYXAgb2YgYWxsIGtleSB2YWx1ZXNcblx0XHRcdGFLZXlWYWx1ZXMuZm9yRWFjaChmdW5jdGlvbiAoc0tleUFzc2lnbm1lbnQ6IHN0cmluZykge1xuXHRcdFx0XHRjb25zdCBhUGFydHMgPSBzS2V5QXNzaWdubWVudC5zcGxpdChcIj1cIiksXG5cdFx0XHRcdFx0c0tleVZhbHVlID0gZm5VbnF1b3RlQW5kRGVjb2RlKGFQYXJ0c1sxXSk7XG5cblx0XHRcdFx0bUtleVZhbHVlc1thUGFydHNbMF1dID0gc0tleVZhbHVlO1xuXHRcdFx0fSk7XG5cblx0XHRcdGxldCBiRmFpbGVkID0gZmFsc2U7XG5cdFx0XHRhRmlsdGVycyA9IGFTZW1hbnRpY0tleXMubWFwKGZ1bmN0aW9uIChvU2VtYW50aWNLZXk6IGFueSkge1xuXHRcdFx0XHRjb25zdCBzS2V5ID0gb1NlbWFudGljS2V5LiRQcm9wZXJ0eVBhdGgsXG5cdFx0XHRcdFx0c1ZhbHVlID0gbUtleVZhbHVlc1tzS2V5XTtcblxuXHRcdFx0XHRpZiAoc1ZhbHVlICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRyZXR1cm4gbmV3IEZpbHRlcih7XG5cdFx0XHRcdFx0XHRwYXRoOiBzS2V5LFxuXHRcdFx0XHRcdFx0b3BlcmF0b3I6IEZpbHRlck9wZXJhdG9yLkVRLFxuXHRcdFx0XHRcdFx0dmFsdWUxOiBzVmFsdWUsXG5cdFx0XHRcdFx0XHRjYXNlU2Vuc2l0aXZlOiBiRmlsdGVyaW5nQ2FzZVNlbnNpdGl2ZVxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGJGYWlsZWQgPSB0cnVlO1xuXHRcdFx0XHRcdHJldHVybiBuZXcgRmlsdGVyKHtcblx0XHRcdFx0XHRcdHBhdGg6IFwiWFhcIlxuXHRcdFx0XHRcdH0pOyAvLyB3aWxsIGJlIGlnbm9yZSBhbnl3YXkgc2luY2Ugd2UgcmV0dXJuIGFmdGVyXG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHRpZiAoYkZhaWxlZCkge1xuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBBZGQgYSBkcmFmdCBmaWx0ZXIgdG8gbWFrZSBzdXJlIHdlIHRha2UgdGhlIGRyYWZ0IGVudGl0eSBpZiB0aGVyZSBpcyBvbmVcblx0XHQvLyBPciB0aGUgYWN0aXZlIGVudGl0eSBvdGhlcndpc2Vcblx0XHRjb25zdCBvRHJhZnRGaWx0ZXIgPSBuZXcgRmlsdGVyKHtcblx0XHRcdGZpbHRlcnM6IFtuZXcgRmlsdGVyKFwiSXNBY3RpdmVFbnRpdHlcIiwgXCJFUVwiLCBmYWxzZSksIG5ldyBGaWx0ZXIoXCJTaWJsaW5nRW50aXR5L0lzQWN0aXZlRW50aXR5XCIsIFwiRVFcIiwgbnVsbCldLFxuXHRcdFx0YW5kOiBmYWxzZVxuXHRcdH0pO1xuXHRcdGFGaWx0ZXJzLnB1c2gob0RyYWZ0RmlsdGVyKTtcblxuXHRcdGNvbnN0IG9Db21iaW5lZEZpbHRlciA9IG5ldyBGaWx0ZXIoYUZpbHRlcnMsIHRydWUpO1xuXHRcdHJldHVybiBvQ29tYmluZWRGaWx0ZXI7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBwYXRoIHdpdGggc2VtYW50aWMga2V5cyB0byBhIHBhdGggd2l0aCB0ZWNobmljYWwga2V5cy5cblx0ICpcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNTZW1hbnRpY1BhdGggVGhlIHBhdGggd2l0aCBzZW1hbnRpYyBrZXlzXG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0Lk9EYXRhTW9kZWx9IG9Nb2RlbCBUaGUgbW9kZWwgZm9yIHRoZSBwYXRoXG5cdCAqIEBwYXJhbSB7QXJyYXl9IGFTZW1hbnRpY0tleXMgVGhlIHNlbWFudGljIGtleXMgZm9yIHRoZSBwYXRoXG5cdCAqIEByZXR1cm5zIHtQcm9taXNlfSBBIFByb21pc2UgY29udGFpbmluZyB0aGUgcGF0aCB3aXRoIHRlY2huaWNhbCBrZXlzIGlmIHNTZW1hbnRpY1BhdGggY291bGQgYmUgaW50ZXJwcmV0ZWQgYXMgYSBzZW1hbnRpYyBwYXRoLCBudWxsIG90aGVyd2lzZVxuXHQgKlxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICovXG5cdF9nZXRUZWNobmljYWxQYXRoRnJvbVNlbWFudGljUGF0aChzU2VtYW50aWNQYXRoOiBzdHJpbmcsIG9Nb2RlbDogYW55LCBhU2VtYW50aWNLZXlzOiBhbnlbXSkge1xuXHRcdGNvbnN0IG9NZXRhTW9kZWwgPSBvTW9kZWwuZ2V0TWV0YU1vZGVsKCk7XG5cdFx0bGV0IHNFbnRpdHlTZXRQYXRoID0gb01ldGFNb2RlbC5nZXRNZXRhQ29udGV4dChzU2VtYW50aWNQYXRoKS5nZXRQYXRoKCk7XG5cblx0XHRpZiAoIWFTZW1hbnRpY0tleXMgfHwgYVNlbWFudGljS2V5cy5sZW5ndGggPT09IDApIHtcblx0XHRcdC8vIE5vIHNlbWFudGljIGtleXNcblx0XHRcdHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG5cdFx0fVxuXG5cdFx0Ly8gQ3JlYXRlIGEgc2V0IG9mIGZpbHRlcnMgY29ycmVzcG9uZGluZyB0byBhbGwga2V5c1xuXHRcdGNvbnN0IG9GaWx0ZXIgPSB0aGlzLl9jcmVhdGVGaWx0ZXJGcm9tU2VtYW50aWNQYXRoKHNTZW1hbnRpY1BhdGgsIGFTZW1hbnRpY0tleXMsIG9NZXRhTW9kZWwpO1xuXHRcdGlmIChvRmlsdGVyID09PSBudWxsKSB7XG5cdFx0XHQvLyBDb3VsZG4ndCBpbnRlcnByZXQgdGhlIHBhdGggYXMgYSBzZW1hbnRpYyBvbmVcblx0XHRcdHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG5cdFx0fVxuXG5cdFx0Ly8gTG9hZCB0aGUgY29ycmVzcG9uZGluZyBvYmplY3Rcblx0XHRpZiAoIXNFbnRpdHlTZXRQYXRoPy5zdGFydHNXaXRoKFwiL1wiKSkge1xuXHRcdFx0c0VudGl0eVNldFBhdGggPSBcIi9cIiArIHNFbnRpdHlTZXRQYXRoO1xuXHRcdH1cblx0XHRjb25zdCBvTGlzdEJpbmRpbmcgPSBvTW9kZWwuYmluZExpc3Qoc0VudGl0eVNldFBhdGgsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBvRmlsdGVyLCB7XG5cdFx0XHRcIiQkZ3JvdXBJZFwiOiBcIiRhdXRvLkhlcm9lc1wiXG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gb0xpc3RCaW5kaW5nLnJlcXVlc3RDb250ZXh0cygwLCAyKS50aGVuKGZ1bmN0aW9uIChvQ29udGV4dHM6IGFueSkge1xuXHRcdFx0aWYgKG9Db250ZXh0cyAmJiBvQ29udGV4dHMubGVuZ3RoKSB7XG5cdFx0XHRcdHJldHVybiBvQ29udGV4dHNbMF0uZ2V0UGF0aCgpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gTm8gZGF0YSBjb3VsZCBiZSBsb2FkZWRcblx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIGEgcGF0aCBpcyBlbGlnaWJsZSBmb3Igc2VtYW50aWMgYm9va21hcmtpbmcuXG5cdCAqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzUGF0aCBUaGUgcGF0aCB0byB0ZXN0XG5cdCAqIEBwYXJhbSB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0Lk9EYXRhTWV0YU1vZGVsfSBvTWV0YU1vZGVsIFRoZSBhc3NvY2lhdGVkIG1ldGFkYXRhIG1vZGVsXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIHBhdGggaXMgZWxpZ2libGVcblx0ICpcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqL1xuXHRfY2hlY2tQYXRoRm9yU2VtYW50aWNCb29rbWFya2luZyhzUGF0aDogc3RyaW5nLCBvTWV0YU1vZGVsOiBhbnkpIHtcblx0XHQvLyBPbmx5IHBhdGggb24gcm9vdCBvYmplY3RzIGFsbG93IHNlbWFudGljIGJvb2ttYXJraW5nLCBpLmUuIHNQYXRoID0geHh4KHl5eSlcblx0XHRjb25zdCBhTWF0Y2hlcyA9IC9eW1xcL10/KFxcdyspXFwoW15cXC9dK1xcKSQvLmV4ZWMoc1BhdGgpO1xuXHRcdGlmICghYU1hdGNoZXMpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0Ly8gR2V0IHRoZSBlbnRpdHlTZXQgbmFtZVxuXHRcdGNvbnN0IHNFbnRpdHlTZXRQYXRoID0gXCIvXCIgKyBhTWF0Y2hlc1sxXTtcblx0XHQvLyBDaGVjayB0aGUgZW50aXR5IHNldCBzdXBwb3J0cyBkcmFmdCAob3RoZXJ3aXNlIHdlIGRvbid0IHN1cHBvcnQgc2VtYW50aWMgYm9va21hcmtpbmcpXG5cdFx0Y29uc3Qgb0RyYWZ0Um9vdCA9IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNFbnRpdHlTZXRQYXRoICsgXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLkRyYWZ0Um9vdFwiKTtcblx0XHRjb25zdCBvRHJhZnROb2RlID0gb01ldGFNb2RlbC5nZXRPYmplY3Qoc0VudGl0eVNldFBhdGggKyBcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuRHJhZnROb2RlXCIpO1xuXHRcdHJldHVybiBvRHJhZnRSb290IHx8IG9EcmFmdE5vZGUgPyB0cnVlIDogZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQnVpbGRzIGEgcGF0aCB3aXRoIHNlbWFudGljIGtleXMgZnJvbSBhIHBhdGggd2l0aCB0ZWNobmljYWwga2V5cy5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHNQYXRoVG9SZXNvbHZlIFRoZSBwYXRoIHRvIGJlIHRyYW5zZm9ybWVkXG5cdCAqIEBwYXJhbSBvTW9kZWxcblx0ICogQHJldHVybnMge1Byb21pc2V9IFN0cmluZyBwcm9taXNlIGZvciB0aGUgbmV3IHBhdGguIElmIHNQYXRoVG9SZXNvbHZlZCBjb3VsZG4ndCBiZSBpbnRlcnByZXRlZCBhcyBhIHNlbWFudGljIHBhdGgsIGl0IGlzIHJldHVybmVkIGFzIGlzLlxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICovXG5cdF9yZXNvbHZlU2VtYW50aWNQYXRoKHNQYXRoVG9SZXNvbHZlOiBzdHJpbmcsIG9Nb2RlbDogYW55KTogUHJvbWlzZTxzdHJpbmc+IHtcblx0XHRjb25zdCBvTWV0YU1vZGVsID0gb01vZGVsLmdldE1ldGFNb2RlbCgpO1xuXHRcdGNvbnN0IG9MYXN0U2VtYW50aWNNYXBwaW5nID0gdGhpcy5fb1JvdXRpbmdTZXJ2aWNlLmdldExhc3RTZW1hbnRpY01hcHBpbmcoKTtcblx0XHRsZXQgc0N1cnJlbnRIYXNoTm9QYXJhbXMgPSB0aGlzLl9vUm91dGVyLmdldEhhc2hDaGFuZ2VyKCkuZ2V0SGFzaCgpLnNwbGl0KFwiP1wiKVswXTtcblxuXHRcdGlmIChzQ3VycmVudEhhc2hOb1BhcmFtcyAmJiBzQ3VycmVudEhhc2hOb1BhcmFtcy5sYXN0SW5kZXhPZihcIi9cIikgPT09IHNDdXJyZW50SGFzaE5vUGFyYW1zLmxlbmd0aCAtIDEpIHtcblx0XHRcdC8vIFJlbW92ZSB0cmFpbGluZyAnLydcblx0XHRcdHNDdXJyZW50SGFzaE5vUGFyYW1zID0gc0N1cnJlbnRIYXNoTm9QYXJhbXMuc3Vic3RyaW5nKDAsIHNDdXJyZW50SGFzaE5vUGFyYW1zLmxlbmd0aCAtIDEpO1xuXHRcdH1cblxuXHRcdGxldCBzUm9vdEVudGl0eU5hbWUgPSBzQ3VycmVudEhhc2hOb1BhcmFtcyAmJiBzQ3VycmVudEhhc2hOb1BhcmFtcy5zdWJzdHIoMCwgc0N1cnJlbnRIYXNoTm9QYXJhbXMuaW5kZXhPZihcIihcIikpO1xuXHRcdGlmIChzUm9vdEVudGl0eU5hbWUuaW5kZXhPZihcIi9cIikgPT09IDApIHtcblx0XHRcdHNSb290RW50aXR5TmFtZSA9IHNSb290RW50aXR5TmFtZS5zdWJzdHJpbmcoMSk7XG5cdFx0fVxuXHRcdGNvbnN0IGJBbGxvd1NlbWFudGljQm9va21hcmsgPSB0aGlzLl9jaGVja1BhdGhGb3JTZW1hbnRpY0Jvb2ttYXJraW5nKHNDdXJyZW50SGFzaE5vUGFyYW1zLCBvTWV0YU1vZGVsKSxcblx0XHRcdGFTZW1hbnRpY0tleXMgPSBiQWxsb3dTZW1hbnRpY0Jvb2ttYXJrICYmIFNlbWFudGljS2V5SGVscGVyLmdldFNlbWFudGljS2V5cyhvTWV0YU1vZGVsLCBzUm9vdEVudGl0eU5hbWUpO1xuXHRcdGlmICghYVNlbWFudGljS2V5cykge1xuXHRcdFx0Ly8gTm8gc2VtYW50aWMga2V5cyBhdmFpbGFibGUgLS0+IHVzZSB0aGUgcGF0aCBhcyBpc1xuXHRcdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZShzUGF0aFRvUmVzb2x2ZSk7XG5cdFx0fSBlbHNlIGlmIChvTGFzdFNlbWFudGljTWFwcGluZyAmJiBvTGFzdFNlbWFudGljTWFwcGluZy5zZW1hbnRpY1BhdGggPT09IHNQYXRoVG9SZXNvbHZlKSB7XG5cdFx0XHQvLyBUaGlzIHNlbWFudGljIHBhdGggaGFzIGJlZW4gcmVzb2x2ZWQgcHJldmlvdXNseVxuXHRcdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZShvTGFzdFNlbWFudGljTWFwcGluZy50ZWNobmljYWxQYXRoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gV2UgbmVlZCByZXNvbHZlIHRoZSBzZW1hbnRpYyBwYXRoIHRvIGdldCB0aGUgdGVjaG5pY2FsIGtleXNcblx0XHRcdHJldHVybiB0aGlzLl9nZXRUZWNobmljYWxQYXRoRnJvbVNlbWFudGljUGF0aChzQ3VycmVudEhhc2hOb1BhcmFtcywgb01vZGVsLCBhU2VtYW50aWNLZXlzKS50aGVuKChzVGVjaG5pY2FsUGF0aDogYW55KSA9PiB7XG5cdFx0XHRcdGlmIChzVGVjaG5pY2FsUGF0aCAmJiBzVGVjaG5pY2FsUGF0aCAhPT0gc1BhdGhUb1Jlc29sdmUpIHtcblx0XHRcdFx0XHQvLyBUaGUgc2VtYW50aWMgcGF0aCB3YXMgcmVzb2x2ZWQgKG90aGVyd2lzZSBrZWVwIHRoZSBvcmlnaW5hbCB2YWx1ZSBmb3IgdGFyZ2V0KVxuXHRcdFx0XHRcdHRoaXMuX29Sb3V0aW5nU2VydmljZS5zZXRMYXN0U2VtYW50aWNNYXBwaW5nKHtcblx0XHRcdFx0XHRcdHRlY2huaWNhbFBhdGg6IHNUZWNobmljYWxQYXRoLFxuXHRcdFx0XHRcdFx0c2VtYW50aWNQYXRoOiBzUGF0aFRvUmVzb2x2ZVxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdHJldHVybiBzVGVjaG5pY2FsUGF0aDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXR1cm4gc1BhdGhUb1Jlc29sdmU7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBiaW5kaW5nIGNvbnRleHQgb2YgdGhlIHBhZ2UgZnJvbSBhIHBhdGguXG5cdCAqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzVGFyZ2V0UGF0aCBUaGUgcGF0aCB0byBidWlsZCB0aGUgY29udGV4dC4gTmVlZHMgdG8gY29udGFpbiB0ZWNobmljYWwga2V5cyBvbmx5LlxuXHQgKiBAcGFyYW0ge3NhcC51aS5tb2RlbC5vZGF0YS52NC5PRGF0YU1vZGVsfSBvTW9kZWwgVGhlIE9EYXRhIG1vZGVsXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvTmF2aWdhdGlvblBhcmFtZXRlcnMgTmF2aWdhdGlvbiBwYXJhbWV0ZXJzXG5cdCAqXG5cdCAqIEB1aTUtcmVzdHJpY3RlZFxuXHQgKi9cblx0X2JpbmRQYWdlVG9QYXRoKHNUYXJnZXRQYXRoOiBzdHJpbmcsIG9Nb2RlbDogYW55LCBvTmF2aWdhdGlvblBhcmFtZXRlcnM6IGFueSkge1xuXHRcdGNvbnN0IG9DdXJyZW50Q29udGV4dCA9IHRoaXMuX2dldEJpbmRpbmdDb250ZXh0KCksXG5cdFx0XHRzQ3VycmVudFBhdGggPSBvQ3VycmVudENvbnRleHQgJiYgb0N1cnJlbnRDb250ZXh0LmdldFBhdGgoKSxcblx0XHRcdG9Vc2VDb250ZXh0ID0gb05hdmlnYXRpb25QYXJhbWV0ZXJzLnVzZUNvbnRleHQ7XG5cblx0XHQvLyBXZSBzZXQgdGhlIGJpbmRpbmcgY29udGV4dCBvbmx5IGlmIGl0J3MgZGlmZmVyZW50IGZyb20gdGhlIGN1cnJlbnQgb25lXG5cdFx0Ly8gb3IgaWYgd2UgaGF2ZSBhIGNvbnRleHQgYWxyZWFkeSBzZWxlY3RlZFxuXHRcdGlmIChzQ3VycmVudFBhdGggIT09IHNUYXJnZXRQYXRoIHx8IChvVXNlQ29udGV4dCAmJiBvVXNlQ29udGV4dC5nZXRQYXRoKCkgPT09IHNUYXJnZXRQYXRoKSkge1xuXHRcdFx0bGV0IG9UYXJnZXRDb250ZXh0O1xuXHRcdFx0aWYgKG9Vc2VDb250ZXh0ICYmIG9Vc2VDb250ZXh0LmdldFBhdGgoKSA9PT0gc1RhcmdldFBhdGgpIHtcblx0XHRcdFx0Ly8gV2UgYWxyZWFkeSBoYXZlIHRoZSBjb250ZXh0IHRvIGJlIHVzZWRcblx0XHRcdFx0b1RhcmdldENvbnRleHQgPSBvVXNlQ29udGV4dDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIE90aGVyd2lzZSB3ZSBuZWVkIHRvIGNyZWF0ZSBpdCBmcm9tIHNUYXJnZXRQYXRoXG5cdFx0XHRcdG9UYXJnZXRDb250ZXh0ID0gdGhpcy5fY3JlYXRlQmluZGluZ0NvbnRleHQoc1RhcmdldFBhdGgsIG9Nb2RlbCwgb05hdmlnYXRpb25QYXJhbWV0ZXJzLmJOYXZpZ2F0ZVRvU2libGluZ0VudGl0eSk7XG5cdFx0XHR9XG5cdFx0XHRpZiAob1RhcmdldENvbnRleHQgIT09IG9DdXJyZW50Q29udGV4dCkge1xuXHRcdFx0XHR0aGlzLl9iaW5kUGFnZVRvQ29udGV4dChvVGFyZ2V0Q29udGV4dCwgb01vZGVsLCBvTmF2aWdhdGlvblBhcmFtZXRlcnMpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZiAoIW9OYXZpZ2F0aW9uUGFyYW1ldGVycy5iUmVhc29uSXNJYXBwU3RhdGUgJiYgRWRpdFN0YXRlLmlzRWRpdFN0YXRlRGlydHkoKSkge1xuXHRcdFx0dGhpcy5fcmVmcmVzaEJpbmRpbmdDb250ZXh0KG9DdXJyZW50Q29udGV4dCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEJpbmRzIHRoZSBwYWdlIHRvIGEgY29udGV4dC5cblx0ICpcblx0ICogQHBhcmFtIHtzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dH0gb0NvbnRleHQgQ29udGV4dCB0byBiZSBib3VuZFxuXHQgKiBAcGFyYW0ge3NhcC51aS5tb2RlbC5vZGF0YS52NC5PRGF0YU1vZGVsfSBvTW9kZWwgVGhlIE9EYXRhIG1vZGVsXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvTmF2aWdhdGlvblBhcmFtZXRlcnMgTmF2aWdhdGlvbiBwYXJhbWV0ZXJzXG5cdCAqXG5cdCAqIEB1aTUtcmVzdHJpY3RlZFxuXHQgKi9cblx0X2JpbmRQYWdlVG9Db250ZXh0KG9Db250ZXh0OiBhbnksIG9Nb2RlbDogYW55LCBvTmF2aWdhdGlvblBhcmFtZXRlcnM6IGFueSkge1xuXHRcdGlmICghb0NvbnRleHQpIHtcblx0XHRcdHRoaXMub25CZWZvcmVCaW5kaW5nKG51bGwpO1xuXHRcdFx0dGhpcy5vbkFmdGVyQmluZGluZyhudWxsKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29uc3Qgb1BhcmVudExpc3RCaW5kaW5nID0gb0NvbnRleHQuZ2V0QmluZGluZygpO1xuXG5cdFx0XHRpZiAoIW9Db250ZXh0LmdldEJpbmRpbmcoKSB8fCBvQ29udGV4dC5nZXRCaW5kaW5nKCkuaXNBKFwic2FwLnVpLm1vZGVsLm9kYXRhLnY0Lk9EYXRhTGlzdEJpbmRpbmdcIikpIHtcblx0XHRcdFx0Ly8gV2UgbmVlZCB0byByZWNyZWF0ZSB0aGUgY29udGV4dCBvdGhlcndpc2Ugd2UgZ2V0IGVycm9yc1xuXHRcdFx0XHRvQ29udGV4dCA9IHRoaXMuX2NyZWF0ZUJpbmRpbmdDb250ZXh0KG9Db250ZXh0LmdldFBhdGgoKSwgb01vZGVsLCBvTmF2aWdhdGlvblBhcmFtZXRlcnMuYk5hdmlnYXRlVG9TaWJsaW5nRW50aXR5KTtcblx0XHRcdFx0aWYgKEVkaXRTdGF0ZS5pc0VkaXRTdGF0ZURpcnR5KCkpIHtcblx0XHRcdFx0XHQvLyBUT0RPOiBhcyBhIHdvcmthcm91bmQgd2UgaW52YWxpZGF0ZSB0aGUgbW9kZWwgY2FjaGUgd2hpbGUgdGhlIGFwcCBpcyBkaXJ0eVxuXHRcdFx0XHRcdC8vIGFzIHRoZSBtYW5hZ2UgbW9kZWwgc2V0cyB0aGUgcGFyZW50IGluIGFuIGFzeW5jIHRhc2sgYW5kIHRoZSByZXF1ZXN0IHNpZGUgZWZmZWN0c1xuXHRcdFx0XHRcdC8vIHJlbGllcyBvbiB0aGUgcGFyZW50IHJlbGF0aW9uc2hpcCB3ZSBoYXZlIHRvIHNldCBhIHRpbWVvdXQgMFxuXHRcdFx0XHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5fcmVmcmVzaEJpbmRpbmdDb250ZXh0KG9Db250ZXh0KTtcblx0XHRcdFx0XHR9LCAwKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZXQgdGhlIGJpbmRpbmcgY29udGV4dCB3aXRoIHRoZSBwcm9wZXIgYmVmb3JlL2FmdGVyIGNhbGxiYWNrc1xuXHRcdFx0dGhpcy5vbkJlZm9yZUJpbmRpbmcob0NvbnRleHQsIHtcblx0XHRcdFx0ZWRpdGFibGU6IG9OYXZpZ2F0aW9uUGFyYW1ldGVycy5iVGFyZ2V0RWRpdGFibGUsXG5cdFx0XHRcdGxpc3RCaW5kaW5nOiBvUGFyZW50TGlzdEJpbmRpbmcsXG5cdFx0XHRcdGJQZXJzaXN0T1BTY3JvbGw6IG9OYXZpZ2F0aW9uUGFyYW1ldGVycy5iUGVyc2lzdE9QU2Nyb2xsLFxuXHRcdFx0XHRiRHJhZnROYXZpZ2F0aW9uOiBvTmF2aWdhdGlvblBhcmFtZXRlcnMuYkRyYWZ0TmF2aWdhdGlvbixcblx0XHRcdFx0c2hvd1BsYWNlaG9sZGVyOiBvTmF2aWdhdGlvblBhcmFtZXRlcnMuYlNob3dQbGFjZWhvbGRlclxuXHRcdFx0fSk7XG5cblx0XHRcdHRoaXMuX3NldEJpbmRpbmdDb250ZXh0KG9Db250ZXh0KTtcblx0XHRcdHRoaXMub25BZnRlckJpbmRpbmcob0NvbnRleHQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgYmluZGluZyBjb250ZXh0IGZyb20gYSBwYXRoLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc1BhdGggVGhlIHBhdGhcblx0ICogQHBhcmFtIHtzYXAudWkubW9kZWwub2RhdGEudjQuT0RhdGFNb2RlbH0gb01vZGVsIFRoZSBPRGF0YSBtb2RlbFxuXHQgKiBAcmV0dXJucyB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHR9IENyZWF0ZWQgY29udGV4dFxuXHQgKlxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICovXG5cdEBwdWJsaWNFeHRlbnNpb24oKVxuXHRfY3JlYXRlQmluZGluZ0NvbnRleHQoc1BhdGg6IHN0cmluZywgb01vZGVsOiBhbnksIG5hdmlnYXRlVG9TaWJsaW5nRW50aXR5OiBib29sZWFuID0gdHJ1ZSkge1xuXHRcdGNvbnN0IG9QYWdlQ29tcG9uZW50ID0gdGhpcy5fb1BhZ2VDb21wb25lbnQsXG5cdFx0XHRzRW50aXR5U2V0ID0gb1BhZ2VDb21wb25lbnQgJiYgb1BhZ2VDb21wb25lbnQuZ2V0RW50aXR5U2V0ICYmIG9QYWdlQ29tcG9uZW50LmdldEVudGl0eVNldCgpLFxuXHRcdFx0c0NvbnRleHRQYXRoID1cblx0XHRcdFx0KG9QYWdlQ29tcG9uZW50ICYmIG9QYWdlQ29tcG9uZW50LmdldENvbnRleHRQYXRoICYmIG9QYWdlQ29tcG9uZW50LmdldENvbnRleHRQYXRoKCkpIHx8IChzRW50aXR5U2V0ICYmIFwiL1wiICsgc0VudGl0eVNldCksXG5cdFx0XHRvTWV0YU1vZGVsID0gb01vZGVsLmdldE1ldGFNb2RlbCgpLFxuXHRcdFx0bVBhcmFtZXRlcnM6IGFueSA9IHtcblx0XHRcdFx0JCRwYXRjaFdpdGhvdXRTaWRlRWZmZWN0czogdHJ1ZSxcblx0XHRcdFx0JCRncm91cElkOiBcIiRhdXRvLkhlcm9lc1wiLFxuXHRcdFx0XHQkJHVwZGF0ZUdyb3VwSWQ6IFwiJGF1dG9cIlxuXHRcdFx0fTtcblxuXHRcdGlmIChzRW50aXR5U2V0KSB7XG5cdFx0XHRjb25zdCBzTWVzc2FnZXNQYXRoID0gb01ldGFNb2RlbC5nZXRPYmplY3Qoc0NvbnRleHRQYXRoICsgXCIvQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5NZXNzYWdlcy8kUGF0aFwiKTtcblx0XHRcdGlmIChzTWVzc2FnZXNQYXRoKSB7XG5cdFx0XHRcdG1QYXJhbWV0ZXJzLiRzZWxlY3QgPSBzTWVzc2FnZXNQYXRoO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEluIGNhc2Ugb2YgZHJhZnQ6ICRzZWxlY3QgdGhlIHN0YXRlIGZsYWdzIChIYXNBY3RpdmVFbnRpdHksIEhhc0RyYWZ0RW50aXR5LCBhbmQgSXNBY3RpdmVFbnRpdHkpXG5cdFx0Y29uc3Qgb0RyYWZ0Um9vdCA9IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNDb250ZXh0UGF0aCArIFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5EcmFmdFJvb3RcIik7XG5cdFx0Y29uc3Qgb0RyYWZ0Tm9kZSA9IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KHNDb250ZXh0UGF0aCArIFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5EcmFmdE5vZGVcIik7XG5cdFx0aWYgKG9EcmFmdFJvb3QgfHwgb0RyYWZ0Tm9kZSkge1xuXHRcdFx0aWYgKG1QYXJhbWV0ZXJzLiRzZWxlY3QgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRtUGFyYW1ldGVycy4kc2VsZWN0ID0gXCJIYXNBY3RpdmVFbnRpdHksSGFzRHJhZnRFbnRpdHksSXNBY3RpdmVFbnRpdHlcIjtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG1QYXJhbWV0ZXJzLiRzZWxlY3QgKz0gXCIsSGFzQWN0aXZlRW50aXR5LEhhc0RyYWZ0RW50aXR5LElzQWN0aXZlRW50aXR5XCI7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Y29uc3Qgb0hpZGRlbkJpbmRpbmcgPSBvTW9kZWwuYmluZENvbnRleHQoc1BhdGgsIHVuZGVmaW5lZCwgbVBhcmFtZXRlcnMpO1xuXG5cdFx0b0hpZGRlbkJpbmRpbmcuYXR0YWNoRXZlbnRPbmNlKFwiZGF0YVJlcXVlc3RlZFwiLCAoKSA9PiB7XG5cdFx0XHRCdXN5TG9ja2VyLmxvY2sodGhpcy5fb1ZpZXcpO1xuXHRcdH0pO1xuXHRcdG9IaWRkZW5CaW5kaW5nLmF0dGFjaEV2ZW50T25jZShcImRhdGFSZWNlaXZlZFwiLCB0aGlzLl9kYXRhUmVjZWl2ZWRFdmVudEhhbmRsZXIuYmluZCh0aGlzLCBuYXZpZ2F0ZVRvU2libGluZ0VudGl0eSkpO1xuXHRcdHJldHVybiBvSGlkZGVuQmluZGluZy5nZXRCb3VuZENvbnRleHQoKTtcblx0fVxuXG5cdGFzeW5jIF9kYXRhUmVjZWl2ZWRFdmVudEhhbmRsZXIobmF2aWdhdGVUb1NpYmxpbmdFbnRpdHk6IGJvb2xlYW4sIG9FdmVudDogRXZlbnQpIHtcblx0XHRjb25zdCBjb250ZXh0ID0gb0V2ZW50Py5nZXRTb3VyY2UgJiYgKG9FdmVudD8uZ2V0U291cmNlKCkgYXMgYW55KT8uZ2V0Qm91bmRDb250ZXh0KCk7XG5cdFx0Y29uc3QgUHJvZ3JhbW1pbmdNb2RlbCA9IEZFTGlicmFyeS5Qcm9ncmFtbWluZ01vZGVsO1xuXHRcdGNvbnN0IHByb2dyYW1taW5nTW9kZWwgPSAodGhpcy5fb1ZpZXc/LmdldENvbnRyb2xsZXIoKSBhcyBQYWdlQ29udHJvbGxlcik/Ll9lZGl0Rmxvdz8uZ2V0UHJvZ3JhbW1pbmdNb2RlbChjb250ZXh0KTtcblx0XHRjb25zdCBzRXJyb3JEZXNjcmlwdGlvbiA9IG9FdmVudCAmJiBvRXZlbnQuZ2V0UGFyYW1ldGVyKFwiZXJyb3JcIik7XG5cdFx0QnVzeUxvY2tlci51bmxvY2sodGhpcy5fb1ZpZXcpO1xuXHRcdGlmIChcblx0XHRcdHByb2dyYW1taW5nTW9kZWwgPT09IFByb2dyYW1taW5nTW9kZWwuRHJhZnQgJiZcblx0XHRcdEFjdGl2aXR5U3luYy5pc0NvbGxhYm9yYXRpb25FbmFibGVkKHRoaXMuX29WaWV3KSAmJlxuXHRcdFx0bmF2aWdhdGVUb1NpYmxpbmdFbnRpdHkgJiZcblx0XHRcdGNvbnRleHQuZ2V0UHJvcGVydHkoXCJJc0FjdGl2ZUVudGl0eVwiKSAmJlxuXHRcdFx0Y29udGV4dC5nZXRPYmplY3QoKS5EcmFmdEFkbWluaXN0cmF0aXZlRGF0YVxuXHRcdCkge1xuXHRcdFx0Y29uc3Qgc2libGluZ0luZm8gPSBhd2FpdCBkcmFmdC5jb21wdXRlU2libGluZ0luZm9ybWF0aW9uKGNvbnRleHQsIGNvbnRleHQpO1xuXHRcdFx0aWYgKHNpYmxpbmdJbmZvKSB7XG5cdFx0XHRcdHRoaXMubmF2aWdhdGVUb0NvbnRleHQoc2libGluZ0luZm8udGFyZ2V0Q29udGV4dCk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoc0Vycm9yRGVzY3JpcHRpb24pIHtcblx0XHRcdC8vIFRPRE86IGluIGNhc2Ugb2YgNDA0IHRoZSB0ZXh0IHNoYWxsIGJlIGRpZmZlcmVudFxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0Y29uc3Qgb1Jlc291cmNlQnVuZGxlID0gYXdhaXQgKENvcmUgYXMgQ29yZUV4KS5nZXRMaWJyYXJ5UmVzb3VyY2VCdW5kbGUoXCJzYXAuZmUuY29yZVwiLCB0cnVlKTtcblx0XHRcdFx0Y29uc3QgbWVzc2FnZUhhbmRsZXIgPSB0aGlzLmJhc2UubWVzc2FnZUhhbmRsZXI7XG5cdFx0XHRcdGxldCBtUGFyYW1zID0ge307XG5cdFx0XHRcdGlmIChzRXJyb3JEZXNjcmlwdGlvbiAmJiBzRXJyb3JEZXNjcmlwdGlvbi5zdGF0dXMgPT09IDUwMykge1xuXHRcdFx0XHRcdG1QYXJhbXMgPSB7XG5cdFx0XHRcdFx0XHRpc0luaXRpYWxMb2FkNTAzRXJyb3I6IHRydWUsXG5cdFx0XHRcdFx0XHRzaGVsbEJhY2s6IHRydWVcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdG1QYXJhbXMgPSB7XG5cdFx0XHRcdFx0XHR0aXRsZTogb1Jlc291cmNlQnVuZGxlLmdldFRleHQoXCJTQVBGRV9FUlJPUlwiKSxcblx0XHRcdFx0XHRcdGRlc2NyaXB0aW9uOiBzRXJyb3JEZXNjcmlwdGlvbixcblx0XHRcdFx0XHRcdGlzRGF0YVJlY2VpdmVkRXJyb3I6IHRydWUsXG5cdFx0XHRcdFx0XHRzaGVsbEJhY2s6IHRydWVcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9XG5cdFx0XHRcdG1lc3NhZ2VIYW5kbGVyLnNob3dNZXNzYWdlcyhtUGFyYW1zKTtcblx0XHRcdH0gY2F0Y2ggKG9FcnJvcjogYW55KSB7XG5cdFx0XHRcdExvZy5lcnJvcihcIkVycm9yIHdoaWxlIGdldHRpbmcgdGhlIGNvcmUgcmVzb3VyY2UgYnVuZGxlXCIsIG9FcnJvcik7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFJlcXVlc3RzIHNpZGUgZWZmZWN0cyBvbiBhIGJpbmRpbmcgY29udGV4dCB0byBcInJlZnJlc2hcIiBpdC5cblx0ICogVE9ETzogZ2V0IHJpZCBvZiB0aGlzIG9uY2UgcHJvdmlkZWQgYnkgdGhlIG1vZGVsXG5cdCAqIGEgcmVmcmVzaCBvbiB0aGUgYmluZGluZyBjb250ZXh0IGRvZXMgbm90IHdvcmsgaW4gY2FzZSBhIGNyZWF0aW9uIHJvdyB3aXRoIGEgdHJhbnNpZW50IGNvbnRleHQgaXNcblx0ICogdXNlZC4gYWxzbyBhIHJlcXVlc3RTaWRlRWZmZWN0cyB3aXRoIGFuIGVtcHR5IHBhdGggd291bGQgZmFpbCBkdWUgdG8gdGhlIHRyYW5zaWVudCBjb250ZXh0XG5cdCAqIHRoZXJlZm9yZSB3ZSBnZXQgYWxsIGRlcGVuZGVudCBiaW5kaW5ncyAodmlhIHByaXZhdGUgbW9kZWwgbWV0aG9kKSB0byBkZXRlcm1pbmUgYWxsIHBhdGhzIGFuZCB0aGVuXG5cdCAqIHJlcXVlc3QgdGhlbS5cblx0ICpcblx0ICogQHBhcmFtIHtzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dH0gb0JpbmRpbmdDb250ZXh0IENvbnRleHQgdG8gYmUgcmVmcmVzaGVkXG5cdCAqXG5cdCAqIEB1aTUtcmVzdHJpY3RlZFxuXHQgKi9cblx0X3JlZnJlc2hCaW5kaW5nQ29udGV4dChvQmluZGluZ0NvbnRleHQ6IGFueSkge1xuXHRcdGNvbnN0IG9QYWdlQ29tcG9uZW50ID0gdGhpcy5fb1BhZ2VDb21wb25lbnQ7XG5cdFx0Y29uc3Qgb1NpZGVFZmZlY3RzU2VydmljZSA9IHRoaXMuX29BcHBDb21wb25lbnQuZ2V0U2lkZUVmZmVjdHNTZXJ2aWNlKCk7XG5cdFx0Y29uc3Qgc1Jvb3RDb250ZXh0UGF0aCA9IG9CaW5kaW5nQ29udGV4dC5nZXRQYXRoKCk7XG5cdFx0Y29uc3Qgc0VudGl0eVNldCA9IG9QYWdlQ29tcG9uZW50ICYmIG9QYWdlQ29tcG9uZW50LmdldEVudGl0eVNldCAmJiBvUGFnZUNvbXBvbmVudC5nZXRFbnRpdHlTZXQoKTtcblx0XHRjb25zdCBzQ29udGV4dFBhdGggPVxuXHRcdFx0KG9QYWdlQ29tcG9uZW50ICYmIG9QYWdlQ29tcG9uZW50LmdldENvbnRleHRQYXRoICYmIG9QYWdlQ29tcG9uZW50LmdldENvbnRleHRQYXRoKCkpIHx8IChzRW50aXR5U2V0ICYmIFwiL1wiICsgc0VudGl0eVNldCk7XG5cdFx0Y29uc3Qgb01ldGFNb2RlbCA9IHRoaXMuX29WaWV3LmdldE1vZGVsKCkuZ2V0TWV0YU1vZGVsKCk7XG5cdFx0bGV0IHNNZXNzYWdlc1BhdGg7XG5cdFx0Y29uc3QgYU5hdmlnYXRpb25Qcm9wZXJ0eVBhdGhzOiBhbnlbXSA9IFtdO1xuXHRcdGNvbnN0IGFQcm9wZXJ0eVBhdGhzOiBhbnlbXSA9IFtdO1xuXHRcdGNvbnN0IG9TaWRlRWZmZWN0czogYW55ID0ge1xuXHRcdFx0VGFyZ2V0UHJvcGVydGllczogW10sXG5cdFx0XHRUYXJnZXRFbnRpdGllczogW11cblx0XHR9O1xuXG5cdFx0ZnVuY3Rpb24gZ2V0QmluZGluZ1BhdGhzKG9CaW5kaW5nOiBhbnkpIHtcblx0XHRcdGxldCBhRGVwZW5kZW50QmluZGluZ3M7XG5cdFx0XHRjb25zdCBzUmVsYXRpdmVQYXRoID0gKChvQmluZGluZy5nZXRDb250ZXh0KCkgJiYgb0JpbmRpbmcuZ2V0Q29udGV4dCgpLmdldFBhdGgoKSkgfHwgXCJcIikucmVwbGFjZShzUm9vdENvbnRleHRQYXRoLCBcIlwiKTsgLy8gSWYgbm8gY29udGV4dCwgdGhpcyBpcyBhbiBhYnNvbHV0ZSBiaW5kaW5nIHNvIG5vIHJlbGF0aXZlIHBhdGhcblx0XHRcdGNvbnN0IHNQYXRoID0gKHNSZWxhdGl2ZVBhdGggPyBzUmVsYXRpdmVQYXRoLnNsaWNlKDEpICsgXCIvXCIgOiBzUmVsYXRpdmVQYXRoKSArIG9CaW5kaW5nLmdldFBhdGgoKTtcblxuXHRcdFx0aWYgKG9CaW5kaW5nLmlzQShcInNhcC51aS5tb2RlbC5vZGF0YS52NC5PRGF0YUNvbnRleHRCaW5kaW5nXCIpKSB7XG5cdFx0XHRcdC8vIGlmIChzUGF0aCA9PT0gXCJcIikge1xuXHRcdFx0XHQvLyBub3cgZ2V0IHRoZSBkZXBlbmRlbnQgYmluZGluZ3Ncblx0XHRcdFx0YURlcGVuZGVudEJpbmRpbmdzID0gb0JpbmRpbmcuZ2V0RGVwZW5kZW50QmluZGluZ3MoKTtcblx0XHRcdFx0aWYgKGFEZXBlbmRlbnRCaW5kaW5ncykge1xuXHRcdFx0XHRcdC8vIGFzayB0aGUgZGVwZW5kZW50IGJpbmRpbmdzIChhbmQgb25seSB0aG9zZSB3aXRoIHRoZSBzcGVjaWZpZWQgZ3JvdXBJZFxuXHRcdFx0XHRcdC8vaWYgKGFEZXBlbmRlbnRCaW5kaW5ncy5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhRGVwZW5kZW50QmluZGluZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRcdGdldEJpbmRpbmdQYXRocyhhRGVwZW5kZW50QmluZGluZ3NbaV0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIGlmIChhTmF2aWdhdGlvblByb3BlcnR5UGF0aHMuaW5kZXhPZihzUGF0aCkgPT09IC0xKSB7XG5cdFx0XHRcdFx0YU5hdmlnYXRpb25Qcm9wZXJ0eVBhdGhzLnB1c2goc1BhdGgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2UgaWYgKG9CaW5kaW5nLmlzQShcInNhcC51aS5tb2RlbC5vZGF0YS52NC5PRGF0YUxpc3RCaW5kaW5nXCIpKSB7XG5cdFx0XHRcdGlmIChhTmF2aWdhdGlvblByb3BlcnR5UGF0aHMuaW5kZXhPZihzUGF0aCkgPT09IC0xKSB7XG5cdFx0XHRcdFx0YU5hdmlnYXRpb25Qcm9wZXJ0eVBhdGhzLnB1c2goc1BhdGgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2UgaWYgKG9CaW5kaW5nLmlzQShcInNhcC51aS5tb2RlbC5vZGF0YS52NC5PRGF0YVByb3BlcnR5QmluZGluZ1wiKSkge1xuXHRcdFx0XHRpZiAoYVByb3BlcnR5UGF0aHMuaW5kZXhPZihzUGF0aCkgPT09IC0xKSB7XG5cdFx0XHRcdFx0YVByb3BlcnR5UGF0aHMucHVzaChzUGF0aCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoc0NvbnRleHRQYXRoKSB7XG5cdFx0XHRzTWVzc2FnZXNQYXRoID0gb01ldGFNb2RlbC5nZXRPYmplY3Qoc0NvbnRleHRQYXRoICsgXCIvQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5NZXNzYWdlcy8kUGF0aFwiKTtcblx0XHR9XG5cblx0XHQvLyBiaW5kaW5nIG9mIHRoZSBjb250ZXh0IG11c3QgaGF2ZSAkJFBhdGNoV2l0aG91dFNpZGVFZmZlY3RzIHRydWUsIHRoaXMgYm91bmQgY29udGV4dCBtYXkgYmUgbmVlZGVkIHRvIGJlIGZldGNoZWQgZnJvbSB0aGUgZGVwZW5kZW50IGJpbmRpbmdcblx0XHRnZXRCaW5kaW5nUGF0aHMob0JpbmRpbmdDb250ZXh0LmdldEJpbmRpbmcoKSk7XG5cblx0XHRsZXQgaTtcblx0XHRmb3IgKGkgPSAwOyBpIDwgYU5hdmlnYXRpb25Qcm9wZXJ0eVBhdGhzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRvU2lkZUVmZmVjdHMuVGFyZ2V0RW50aXRpZXMucHVzaCh7XG5cdFx0XHRcdCROYXZpZ2F0aW9uUHJvcGVydHlQYXRoOiBhTmF2aWdhdGlvblByb3BlcnR5UGF0aHNbaV1cblx0XHRcdH0pO1xuXHRcdH1cblx0XHRvU2lkZUVmZmVjdHMuVGFyZ2V0UHJvcGVydGllcyA9IGFQcm9wZXJ0eVBhdGhzO1xuXHRcdGlmIChzTWVzc2FnZXNQYXRoKSB7XG5cdFx0XHRvU2lkZUVmZmVjdHMuVGFyZ2V0UHJvcGVydGllcy5wdXNoKHtcblx0XHRcdFx0JFByb3BlcnR5UGF0aDogc01lc3NhZ2VzUGF0aFxuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdG9TaWRlRWZmZWN0c1NlcnZpY2UucmVxdWVzdFNpZGVFZmZlY3RzKG9TaWRlRWZmZWN0cy5UYXJnZXRFbnRpdGllcy5jb25jYXQob1NpZGVFZmZlY3RzLlRhcmdldFByb3BlcnRpZXMpLCBvQmluZGluZ0NvbnRleHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGJpbmRpbmcgY29udGV4dCBvZiB0aGUgcGFnZSBvciB0aGUgY29tcG9uZW50LlxuXHQgKlxuXHQgKiBAcmV0dXJucyB7c2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHR9IFRoZSBiaW5kaW5nIGNvbnRleHRcblx0ICpcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqL1xuXHRfZ2V0QmluZGluZ0NvbnRleHQoKTogQ29udGV4dCB7XG5cdFx0aWYgKHRoaXMuX29QYWdlQ29tcG9uZW50KSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5fb1BhZ2VDb21wb25lbnQuZ2V0QmluZGluZ0NvbnRleHQoKSBhcyBDb250ZXh0O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5fb1ZpZXcuZ2V0QmluZGluZ0NvbnRleHQoKSBhcyBDb250ZXh0O1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBiaW5kaW5nIGNvbnRleHQgb2YgdGhlIHBhZ2Ugb3IgdGhlIGNvbXBvbmVudC5cblx0ICpcblx0ICogQHBhcmFtIHtzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dH0gb0NvbnRleHQgVGhlIGJpbmRpbmcgY29udGV4dFxuXHQgKlxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICovXG5cdF9zZXRCaW5kaW5nQ29udGV4dChvQ29udGV4dDogYW55KSB7XG5cdFx0aWYgKHRoaXMuX29QYWdlQ29tcG9uZW50KSB7XG5cdFx0XHR0aGlzLl9vUGFnZUNvbXBvbmVudC5zZXRCaW5kaW5nQ29udGV4dChvQ29udGV4dCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuX29WaWV3LnNldEJpbmRpbmdDb250ZXh0KG9Db250ZXh0KTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgZmxleGlibGUgY29sdW1uIGxheW91dCAoRkNMKSBsZXZlbCBjb3JyZXNwb25kaW5nIHRvIHRoZSB2aWV3ICgtMSBpZiB0aGUgYXBwIGlzIG5vdCBGQ0wpLlxuXHQgKlxuXHQgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgbGV2ZWxcblx0ICpcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqL1xuXHRfZ2V0RkNMTGV2ZWwoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX29UYXJnZXRJbmZvcm1hdGlvbi5GQ0xMZXZlbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBTd2l0Y2hlcyBiZXR3ZWVuIGNvbHVtbiBhbmQgZnVsbC1zY3JlZW4gbW9kZSB3aGVuIEZDTCBpcyB1c2VkLlxuXHQgKlxuXHQgKiBAdWk1LXJlc3RyaWN0ZWRcblx0ICovXG5cblx0QHB1YmxpY0V4dGVuc2lvbigpXG5cdEBmaW5hbEV4dGVuc2lvbigpXG5cdHN3aXRjaEZ1bGxTY3JlZW4oKSB7XG5cdFx0Y29uc3Qgb1NvdXJjZSA9IHRoaXMuYmFzZS5nZXRWaWV3KCk7XG5cdFx0Y29uc3Qgb0ZDTEhlbHBlck1vZGVsID0gb1NvdXJjZS5nZXRNb2RlbChcImZjbGhlbHBlclwiKSxcblx0XHRcdGJJc0Z1bGxTY3JlZW4gPSBvRkNMSGVscGVyTW9kZWwuZ2V0UHJvcGVydHkoXCIvYWN0aW9uQnV0dG9uc0luZm8vaXNGdWxsU2NyZWVuXCIpLFxuXHRcdFx0c05leHRMYXlvdXQgPSBvRkNMSGVscGVyTW9kZWwuZ2V0UHJvcGVydHkoXG5cdFx0XHRcdGJJc0Z1bGxTY3JlZW4gPyBcIi9hY3Rpb25CdXR0b25zSW5mby9leGl0RnVsbFNjcmVlblwiIDogXCIvYWN0aW9uQnV0dG9uc0luZm8vZnVsbFNjcmVlblwiXG5cdFx0XHQpLFxuXHRcdFx0b1Jvb3RWaWV3Q29udHJvbGxlciA9ICh0aGlzLl9vQXBwQ29tcG9uZW50IGFzIGFueSkuZ2V0Um9vdFZpZXdDb250cm9sbGVyKCk7XG5cblx0XHRjb25zdCBvQ29udGV4dCA9IG9Sb290Vmlld0NvbnRyb2xsZXIuZ2V0UmlnaHRtb3N0Q29udGV4dCA/IG9Sb290Vmlld0NvbnRyb2xsZXIuZ2V0UmlnaHRtb3N0Q29udGV4dCgpIDogb1NvdXJjZS5nZXRCaW5kaW5nQ29udGV4dCgpO1xuXG5cdFx0dGhpcy5iYXNlLl9yb3V0aW5nLm5hdmlnYXRlVG9Db250ZXh0KG9Db250ZXh0LCB7IHNMYXlvdXQ6IHNOZXh0TGF5b3V0IH0pLmNhdGNoKGZ1bmN0aW9uICgpIHtcblx0XHRcdExvZy53YXJuaW5nKFwiY2Fubm90IHN3aXRjaCBiZXR3ZWVuIGNvbHVtbiBhbmQgZnVsbHNjcmVlblwiKTtcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDbG9zZXMgdGhlIGNvbHVtbiBmb3IgdGhlIGN1cnJlbnQgdmlldyBpbiBhIEZDTC5cblx0ICpcblx0ICogQHVpNS1yZXN0cmljdGVkXG5cdCAqL1xuXHRAcHVibGljRXh0ZW5zaW9uKClcblx0QGV4dGVuc2libGUoT3ZlcnJpZGVFeGVjdXRpb24uQmVmb3JlKVxuXHRjbG9zZUNvbHVtbigpIHtcblx0XHRjb25zdCBvU291cmNlID0gdGhpcy5iYXNlLmdldFZpZXcoKTtcblx0XHRjb25zdCBvVmlld0RhdGEgPSBvU291cmNlLmdldFZpZXdEYXRhKCkgYXMgYW55O1xuXHRcdGNvbnN0IG9Db250ZXh0ID0gb1NvdXJjZS5nZXRCaW5kaW5nQ29udGV4dCgpIGFzIENvbnRleHQ7XG5cdFx0Y29uc3QgYmFzZSA9IHRoaXMuYmFzZTtcblx0XHRjb25zdCBvTWV0YU1vZGVsID0gb0NvbnRleHQuZ2V0TW9kZWwoKS5nZXRNZXRhTW9kZWwoKTtcblxuXHRcdGlmIChvVmlld0RhdGEgJiYgb1ZpZXdEYXRhLnZpZXdMZXZlbCA9PT0gMSAmJiBNb2RlbEhlbHBlci5pc0RyYWZ0U3VwcG9ydGVkKG9NZXRhTW9kZWwsIG9Db250ZXh0LmdldFBhdGgoKSkpIHtcblx0XHRcdENvbW1vblV0aWxzLmZuUHJvY2Vzc0RhdGFMb3NzT3JEcmFmdERpc2NhcmRDb25maXJtYXRpb24oXG5cdFx0XHRcdGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRiYXNlLl9yb3V0aW5nLm5hdmlnYXRlQmFja0Zyb21Db250ZXh0KG9Db250ZXh0LCB7IG5vUHJlc2VydmF0aW9uQ2FjaGU6IHRydWUgfSk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdEZ1bmN0aW9uLnByb3RvdHlwZSxcblx0XHRcdFx0b0NvbnRleHQsXG5cdFx0XHRcdG9Tb3VyY2UuZ2V0Q29udHJvbGxlcigpLFxuXHRcdFx0XHRmYWxzZVxuXHRcdFx0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0YmFzZS5fcm91dGluZy5uYXZpZ2F0ZUJhY2tGcm9tQ29udGV4dChvQ29udGV4dCwgeyBub1ByZXNlcnZhdGlvbkNhY2hlOiB0cnVlIH0pO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBJbnRlcm5hbFJvdXRpbmc7XG4iXX0=