@sapui5/sap.fe.core 1.97.0 → 1.100.0

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