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