@mediusinc/mng-commons 1.0.0-rc.1 → 1.1.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (377) hide show
  1. package/esm2020/lib/api/models/builders/query-param.builder.mjs +58 -58
  2. package/esm2020/lib/api/models/filter-match-type.model.mjs +24 -24
  3. package/esm2020/lib/api/models/filter-param.model.mjs +32 -32
  4. package/esm2020/lib/api/models/index.mjs +8 -8
  5. package/esm2020/lib/api/models/mappers.mjs +12 -12
  6. package/esm2020/lib/api/models/query-mode.model.mjs +17 -17
  7. package/esm2020/lib/api/models/query-param.model.mjs +67 -67
  8. package/esm2020/lib/api/models/query-result.model.mjs +23 -23
  9. package/esm2020/lib/api/models/serialization.model.mjs +1 -1
  10. package/esm2020/lib/api/services/api.abstract.service.mjs +57 -57
  11. package/esm2020/lib/api/services/crud-api.abstract.service.mjs +75 -75
  12. package/esm2020/lib/api/services/get-all-api.abstract.service.mjs +29 -29
  13. package/esm2020/lib/api/services/index.mjs +3 -3
  14. package/esm2020/lib/api/utils/index.mjs +2 -2
  15. package/esm2020/lib/api/utils/medius-rest.util.mjs +212 -212
  16. package/esm2020/lib/api/utils/object-serializer.util.mjs +247 -247
  17. package/esm2020/lib/components/action/action.component.mjs +224 -224
  18. package/esm2020/lib/components/action/editor/action-editor.component.mjs +303 -303
  19. package/esm2020/lib/components/action/index.mjs +4 -4
  20. package/esm2020/lib/components/action/localization/data-language-dropdown.component.mjs +44 -44
  21. package/esm2020/lib/components/action/models/action-component.model.mjs +1 -1
  22. package/esm2020/lib/components/action/models/action-confirmation-service.model.mjs +1 -1
  23. package/esm2020/lib/components/action/models/action-execution.model.mjs +248 -248
  24. package/esm2020/lib/components/action/models/index.mjs +4 -4
  25. package/esm2020/lib/components/action/models/tableview-action-default-categories.model.mjs +10 -10
  26. package/esm2020/lib/components/action/route/action-route.component.mjs +129 -129
  27. package/esm2020/lib/components/form/autocomplete/autocomplete.component.mjs +299 -299
  28. package/esm2020/lib/components/form/date-range/date-range.component.mjs +108 -108
  29. package/esm2020/lib/components/form/dropdown/dropdown.component.mjs +193 -193
  30. package/esm2020/lib/components/form/editor/form-editor.component.mjs +242 -242
  31. package/esm2020/lib/components/form/formly/fields/formly-field-action/formly-field-action.component.mjs +38 -38
  32. package/esm2020/lib/components/form/formly/fields/formly-field-autocomplete/formly-field-autocomplete.component.mjs +49 -49
  33. package/esm2020/lib/components/form/formly/fields/formly-field-dropdown/formly-field-dropdown.component.mjs +44 -44
  34. package/esm2020/lib/components/form/formly/fields/formly-field-fieldset/formly-field-fieldset.component.mjs +25 -25
  35. package/esm2020/lib/components/form/formly/fields/formly-field-input/formly-field-input.component.mjs +149 -149
  36. package/esm2020/lib/components/form/formly/fields/formly-field-label/formly-field-label.component.mjs +23 -23
  37. package/esm2020/lib/components/form/formly/fields/formly-field-lookup-dialog/formly-field-lookup-dialog.component.mjs +180 -180
  38. package/esm2020/lib/components/form/formly/fields/formly-field-table-dialog-form/formly-field-table-dialog-form.component.mjs +177 -177
  39. package/esm2020/lib/components/form/formly/fields/formly-field-table-dialog-multiselect/formly-field-table-dialog-multiselect.component.mjs +148 -148
  40. package/esm2020/lib/components/form/formly/fields/formly-field-tabs/formly-field-tabs.component.mjs +16 -16
  41. package/esm2020/lib/components/form/formly/fields/index.mjs +10 -10
  42. package/esm2020/lib/components/form/formly/formly.config.mjs +211 -211
  43. package/esm2020/lib/components/form/formly/index.mjs +1 -1
  44. package/esm2020/lib/components/form/formly/models/formly-config.model.mjs +1 -1
  45. package/esm2020/lib/components/form/formly/models/formly-field.model.mjs +1 -1
  46. package/esm2020/lib/components/form/formly/models/index.mjs +2 -2
  47. package/esm2020/lib/components/form/formly/wrappers/formly-field-no-label-wrapper/formly-field-no-label-wrapper.component.mjs +14 -14
  48. package/esm2020/lib/components/form/formly/wrappers/formly-field-wrapper/formly-field-wrapper.component.mjs +82 -82
  49. package/esm2020/lib/components/form/formly/wrappers/index.mjs +2 -2
  50. package/esm2020/lib/components/form/index.mjs +4 -4
  51. package/esm2020/lib/components/form/models/field-action-context.model.mjs +1 -1
  52. package/esm2020/lib/components/form/models/form-editor.event.mjs +33 -33
  53. package/esm2020/lib/components/form/models/form-editor.interface.mjs +1 -1
  54. package/esm2020/lib/components/form/models/index.mjs +2 -2
  55. package/esm2020/lib/components/layout/breadcrumb.component.mjs +16 -16
  56. package/esm2020/lib/components/layout/footer.component.mjs +16 -16
  57. package/esm2020/lib/components/layout/index.mjs +7 -7
  58. package/esm2020/lib/components/layout/main-layout.component.mjs +51 -51
  59. package/esm2020/lib/components/layout/menu-item.component.mjs +271 -271
  60. package/esm2020/lib/components/layout/menu.component.mjs +20 -20
  61. package/esm2020/lib/components/layout/services/index.mjs +1 -1
  62. package/esm2020/lib/components/layout/services/main-layout.component.service.mjs +194 -194
  63. package/esm2020/lib/components/layout/topbar.component.mjs +64 -64
  64. package/esm2020/lib/components/layout/version.component.mjs +57 -57
  65. package/esm2020/lib/components/tableview/index.mjs +6 -6
  66. package/esm2020/lib/components/tableview/models/index.mjs +1 -1
  67. package/esm2020/lib/components/tableview/models/table.event.mjs +15 -15
  68. package/esm2020/lib/components/tableview/route/tableview-route.abstract.component.mjs +122 -122
  69. package/esm2020/lib/components/tableview/route/tableview-route.component.mjs +52 -52
  70. package/esm2020/lib/components/tableview/table/column-filter/column-filter.component.mjs +120 -120
  71. package/esm2020/lib/components/tableview/table/column-value/column-value.component.mjs +83 -83
  72. package/esm2020/lib/components/tableview/table/table.component.mjs +593 -593
  73. package/esm2020/lib/components/tableview/tableview.component.mjs +112 -112
  74. package/esm2020/lib/data-providers/base.data-provider.mjs +16 -16
  75. package/esm2020/lib/data-providers/editor.data-provider.mjs +36 -36
  76. package/esm2020/lib/data-providers/index.mjs +6 -6
  77. package/esm2020/lib/data-providers/lookup.data-provider.mjs +15 -15
  78. package/esm2020/lib/data-providers/table.data-provider.mjs +37 -37
  79. package/esm2020/lib/data-providers/tableview-crud.data-provider.mjs +23 -23
  80. package/esm2020/lib/data-providers/tableview.data-provider.mjs +44 -44
  81. package/esm2020/lib/descriptors/action/action-confirmation.descriptor.mjs +76 -76
  82. package/esm2020/lib/descriptors/action-button.descriptor.mjs +59 -59
  83. package/esm2020/lib/descriptors/action.descriptor.mjs +559 -559
  84. package/esm2020/lib/descriptors/column.descriptor.mjs +404 -404
  85. package/esm2020/lib/descriptors/editor.descriptor.mjs +289 -289
  86. package/esm2020/lib/descriptors/field-validation.descriptor.mjs +24 -24
  87. package/esm2020/lib/descriptors/field.descriptor.mjs +987 -979
  88. package/esm2020/lib/descriptors/filter.descriptor.mjs +321 -321
  89. package/esm2020/lib/descriptors/index.mjs +11 -11
  90. package/esm2020/lib/descriptors/interfaces/field-config.interface.mjs +1 -1
  91. package/esm2020/lib/descriptors/interfaces/index.mjs +2 -2
  92. package/esm2020/lib/descriptors/interfaces/lookup-descriptor.interface.mjs +1 -1
  93. package/esm2020/lib/descriptors/model.descriptor.mjs +44 -44
  94. package/esm2020/lib/descriptors/table.descriptor.mjs +481 -481
  95. package/esm2020/lib/descriptors/tableview.descriptor.mjs +343 -343
  96. package/esm2020/lib/descriptors/types/action.type.mjs +25 -25
  97. package/esm2020/lib/descriptors/types/column.type.mjs +20 -20
  98. package/esm2020/lib/descriptors/types/editor.type.mjs +7 -7
  99. package/esm2020/lib/descriptors/types/field.type.mjs +56 -55
  100. package/esm2020/lib/descriptors/types/filter.type.mjs +30 -30
  101. package/esm2020/lib/descriptors/types/index.mjs +6 -6
  102. package/esm2020/lib/descriptors/types/table.type.mjs +26 -26
  103. package/esm2020/lib/directives/component.directive.mjs +43 -43
  104. package/esm2020/lib/directives/index.mjs +2 -2
  105. package/esm2020/lib/directives/template.directive.mjs +27 -27
  106. package/esm2020/lib/mng-commons.module.mjs +475 -472
  107. package/esm2020/lib/models/column-value.model.mjs +1 -1
  108. package/esm2020/lib/models/config.model.mjs +1 -1
  109. package/esm2020/lib/models/enum.model.mjs +1 -1
  110. package/esm2020/lib/models/error.model.mjs +1 -1
  111. package/esm2020/lib/models/index.mjs +9 -9
  112. package/esm2020/lib/models/menu.model.mjs +1 -1
  113. package/esm2020/lib/models/tableview-attr.model.mjs +1 -1
  114. package/esm2020/lib/models/user.model.mjs +1 -1
  115. package/esm2020/lib/models/version.model.mjs +1 -1
  116. package/esm2020/lib/models/view-container.model.mjs +1 -1
  117. package/esm2020/lib/pipes/boolean.pipe.mjs +26 -26
  118. package/esm2020/lib/pipes/class-map.pipe.mjs +21 -21
  119. package/esm2020/lib/pipes/enum.pipe.mjs +24 -24
  120. package/esm2020/lib/pipes/enumerate-async.pipe.mjs +37 -37
  121. package/esm2020/lib/pipes/enumerate.pipe.mjs +54 -54
  122. package/esm2020/lib/pipes/getter.pipe.mjs +19 -19
  123. package/esm2020/lib/pipes/i18n-property.pipe.mjs +17 -17
  124. package/esm2020/lib/pipes/index.mjs +12 -12
  125. package/esm2020/lib/pipes/json-path.pipe.mjs +78 -78
  126. package/esm2020/lib/pipes/{mngLocaleDefaultRowClass.pipe.mjs → locale-default-row-class.pipe.mjs} +26 -26
  127. package/esm2020/lib/pipes/models/internal/enumrate-pipe-i18n.model.mjs +1 -1
  128. package/esm2020/lib/pipes/models/internal/index.mjs +1 -1
  129. package/esm2020/lib/pipes/parametrize.pipe.mjs +84 -84
  130. package/esm2020/lib/pipes/template.pipe.mjs +23 -23
  131. package/esm2020/lib/router/index.mjs +2 -2
  132. package/esm2020/lib/router/models/index.mjs +1 -1
  133. package/esm2020/lib/router/models/router.model.mjs +1 -1
  134. package/esm2020/lib/router/route-builder.mjs +425 -425
  135. package/esm2020/lib/router/tableview-route-builder.mjs +186 -186
  136. package/esm2020/lib/security/authorization.guard.mjs +25 -25
  137. package/esm2020/lib/security/authorization.service.mjs +46 -46
  138. package/esm2020/lib/security/authorization.util.mjs +15 -15
  139. package/esm2020/lib/security/index.mjs +3 -3
  140. package/esm2020/lib/security/model/authorization.type.mjs +7 -7
  141. package/esm2020/lib/security/model/index.mjs +3 -3
  142. package/esm2020/lib/security/model/permission-service.interface.mjs +1 -1
  143. package/esm2020/lib/security/model/permissions.model.mjs +86 -86
  144. package/esm2020/lib/services/action-executor.service.mjs +551 -551
  145. package/esm2020/lib/services/commons.service.mjs +445 -445
  146. package/esm2020/lib/services/configuration.service.mjs +142 -135
  147. package/esm2020/lib/services/error-mapper.service.mjs +13 -13
  148. package/esm2020/lib/services/index.mjs +6 -6
  149. package/esm2020/lib/services/internal/commons-init.provider.mjs +3 -3
  150. package/esm2020/lib/services/internal/commons-init.service.mjs +43 -43
  151. package/esm2020/lib/services/internal/index.mjs +2 -2
  152. package/esm2020/lib/services/navigation.service.mjs +47 -47
  153. package/esm2020/lib/services/providers/config-service.provider.mjs +29 -29
  154. package/esm2020/lib/services/providers/formly-config.provider.mjs +30 -30
  155. package/esm2020/lib/services/providers/index.mjs +2 -2
  156. package/esm2020/lib/services/tokens/browser-storage.token.mjs +5 -5
  157. package/esm2020/lib/services/tokens/commons-init.token.mjs +2 -2
  158. package/esm2020/lib/services/tokens/default-setting.token.mjs +2 -2
  159. package/esm2020/lib/services/tokens/index.mjs +4 -4
  160. package/esm2020/lib/services/tokens/module-config.token.mjs +2 -2
  161. package/esm2020/lib/services/version.service.mjs +38 -38
  162. package/esm2020/lib/services/view-container.component.service.mjs +54 -54
  163. package/esm2020/lib/styles/button-style.builder.mjs +164 -164
  164. package/esm2020/lib/styles/index.mjs +2 -2
  165. package/esm2020/lib/styles/models/index.mjs +2 -2
  166. package/esm2020/lib/styles/models/style-level.enum.mjs +11 -11
  167. package/esm2020/lib/styles/models/style-size.enum.mjs +8 -8
  168. package/esm2020/lib/styles/styles.util.mjs +41 -41
  169. package/esm2020/lib/types/index.mjs +2 -2
  170. package/esm2020/lib/types/type.decorator.mjs +21 -21
  171. package/esm2020/lib/types/type.model.mjs +1 -1
  172. package/esm2020/lib/utils/action-data-provider.util.mjs +144 -144
  173. package/esm2020/lib/utils/date.util.mjs +117 -117
  174. package/esm2020/lib/utils/editor-formly.util.mjs +288 -277
  175. package/esm2020/lib/utils/enum.util.mjs +81 -81
  176. package/esm2020/lib/utils/i18n.util.mjs +232 -232
  177. package/esm2020/lib/utils/index.mjs +9 -9
  178. package/esm2020/lib/utils/model.util.mjs +68 -68
  179. package/esm2020/lib/utils/notification.util.mjs +50 -50
  180. package/esm2020/lib/utils/route.util.mjs +23 -23
  181. package/esm2020/lib/utils/string.util.mjs +26 -26
  182. package/esm2020/lib/utils/tableview.util.mjs +159 -159
  183. package/esm2020/lib/utils/type.util.mjs +92 -92
  184. package/esm2020/mediusinc-mng-commons.mjs +4 -4
  185. package/esm2020/public-api.mjs +54 -54
  186. package/fesm2015/mediusinc-mng-commons.mjs +13635 -13605
  187. package/fesm2015/mediusinc-mng-commons.mjs.map +1 -1
  188. package/fesm2020/mediusinc-mng-commons.mjs +13473 -13443
  189. package/fesm2020/mediusinc-mng-commons.mjs.map +1 -1
  190. package/index.d.ts +5 -5
  191. package/lib/api/models/builders/query-param.builder.d.ts +13 -13
  192. package/lib/api/models/filter-match-type.model.d.ts +23 -23
  193. package/lib/api/models/filter-param.model.d.ts +23 -23
  194. package/lib/api/models/index.d.ts +8 -8
  195. package/lib/api/models/mappers.d.ts +6 -6
  196. package/lib/api/models/query-mode.model.d.ts +16 -16
  197. package/lib/api/models/query-param.model.d.ts +31 -31
  198. package/lib/api/models/query-result.model.d.ts +24 -24
  199. package/lib/api/models/serialization.model.d.ts +8 -8
  200. package/lib/api/services/api.abstract.service.d.ts +24 -24
  201. package/lib/api/services/crud-api.abstract.service.d.ts +22 -22
  202. package/lib/api/services/get-all-api.abstract.service.d.ts +14 -14
  203. package/lib/api/services/index.d.ts +3 -3
  204. package/lib/api/utils/index.d.ts +2 -2
  205. package/lib/api/utils/medius-rest.util.d.ts +16 -16
  206. package/lib/api/utils/object-serializer.util.d.ts +33 -33
  207. package/lib/components/action/action.component.d.ts +74 -74
  208. package/lib/components/action/editor/action-editor.component.d.ts +69 -69
  209. package/lib/components/action/index.d.ts +4 -4
  210. package/lib/components/action/localization/data-language-dropdown.component.d.ts +25 -25
  211. package/lib/components/action/models/action-component.model.d.ts +15 -15
  212. package/lib/components/action/models/action-confirmation-service.model.d.ts +6 -6
  213. package/lib/components/action/models/action-execution.model.d.ts +135 -135
  214. package/lib/components/action/models/index.d.ts +4 -4
  215. package/lib/components/action/models/tableview-action-default-categories.model.d.ts +10 -10
  216. package/lib/components/action/route/action-route.component.d.ts +31 -31
  217. package/lib/components/form/autocomplete/autocomplete.component.d.ts +61 -61
  218. package/lib/components/form/date-range/date-range.component.d.ts +28 -28
  219. package/lib/components/form/dropdown/dropdown.component.d.ts +52 -52
  220. package/lib/components/form/editor/form-editor.component.d.ts +52 -52
  221. package/lib/components/form/formly/fields/formly-field-action/formly-field-action.component.d.ts +13 -13
  222. package/lib/components/form/formly/fields/formly-field-autocomplete/formly-field-autocomplete.component.d.ts +16 -16
  223. package/lib/components/form/formly/fields/formly-field-dropdown/formly-field-dropdown.component.d.ts +15 -15
  224. package/lib/components/form/formly/fields/formly-field-fieldset/formly-field-fieldset.component.d.ts +14 -14
  225. package/lib/components/form/formly/fields/formly-field-input/formly-field-input.component.d.ts +29 -29
  226. package/lib/components/form/formly/fields/formly-field-label/formly-field-label.component.d.ts +11 -11
  227. package/lib/components/form/formly/fields/formly-field-lookup-dialog/formly-field-lookup-dialog.component.d.ts +46 -46
  228. package/lib/components/form/formly/fields/formly-field-table-dialog-form/formly-field-table-dialog-form.component.d.ts +24 -24
  229. package/lib/components/form/formly/fields/formly-field-table-dialog-multiselect/formly-field-table-dialog-multiselect.component.d.ts +37 -37
  230. package/lib/components/form/formly/fields/formly-field-tabs/formly-field-tabs.component.d.ts +7 -7
  231. package/lib/components/form/formly/fields/index.d.ts +10 -10
  232. package/lib/components/form/formly/formly.config.d.ts +14 -14
  233. package/lib/components/form/formly/index.d.ts +1 -1
  234. package/lib/components/form/formly/models/formly-config.model.d.ts +11 -11
  235. package/lib/components/form/formly/models/formly-field.model.d.ts +16 -16
  236. package/lib/components/form/formly/models/index.d.ts +2 -2
  237. package/lib/components/form/formly/wrappers/formly-field-no-label-wrapper/formly-field-no-label-wrapper.component.d.ts +6 -6
  238. package/lib/components/form/formly/wrappers/formly-field-wrapper/formly-field-wrapper.component.d.ts +11 -11
  239. package/lib/components/form/formly/wrappers/index.d.ts +2 -2
  240. package/lib/components/form/index.d.ts +4 -4
  241. package/lib/components/form/models/field-action-context.model.d.ts +17 -17
  242. package/lib/components/form/models/form-editor.event.d.ts +37 -37
  243. package/lib/components/form/models/form-editor.interface.d.ts +10 -10
  244. package/lib/components/form/models/index.d.ts +2 -2
  245. package/lib/components/layout/breadcrumb.component.d.ts +8 -8
  246. package/lib/components/layout/footer.component.d.ts +9 -9
  247. package/lib/components/layout/index.d.ts +7 -7
  248. package/lib/components/layout/main-layout.component.d.ts +20 -20
  249. package/lib/components/layout/menu-item.component.d.ts +52 -52
  250. package/lib/components/layout/menu.component.d.ts +10 -10
  251. package/lib/components/layout/services/index.d.ts +1 -1
  252. package/lib/components/layout/services/main-layout.component.service.d.ts +65 -65
  253. package/lib/components/layout/topbar.component.d.ts +28 -28
  254. package/lib/components/layout/version.component.d.ts +19 -19
  255. package/lib/components/tableview/index.d.ts +6 -6
  256. package/lib/components/tableview/models/index.d.ts +1 -1
  257. package/lib/components/tableview/models/table.event.d.ts +17 -17
  258. package/lib/components/tableview/route/tableview-route.abstract.component.d.ts +29 -29
  259. package/lib/components/tableview/route/tableview-route.component.d.ts +18 -18
  260. package/lib/components/tableview/table/column-filter/column-filter.component.d.ts +38 -38
  261. package/lib/components/tableview/table/column-value/column-value.component.d.ts +35 -35
  262. package/lib/components/tableview/table/table.component.d.ts +115 -115
  263. package/lib/components/tableview/tableview.component.d.ts +48 -48
  264. package/lib/data-providers/base.data-provider.d.ts +14 -14
  265. package/lib/data-providers/editor.data-provider.d.ts +25 -25
  266. package/lib/data-providers/index.d.ts +6 -6
  267. package/lib/data-providers/lookup.data-provider.d.ts +14 -14
  268. package/lib/data-providers/table.data-provider.d.ts +27 -27
  269. package/lib/data-providers/tableview-crud.data-provider.d.ts +8 -8
  270. package/lib/data-providers/tableview.data-provider.d.ts +33 -33
  271. package/lib/descriptors/action/action-confirmation.descriptor.d.ts +36 -36
  272. package/lib/descriptors/action-button.descriptor.d.ts +22 -22
  273. package/lib/descriptors/action.descriptor.d.ts +217 -217
  274. package/lib/descriptors/column.descriptor.d.ts +130 -130
  275. package/lib/descriptors/editor.descriptor.d.ts +116 -116
  276. package/lib/descriptors/field-validation.descriptor.d.ts +19 -19
  277. package/lib/descriptors/field.descriptor.d.ts +345 -342
  278. package/lib/descriptors/filter.descriptor.d.ts +113 -112
  279. package/lib/descriptors/index.d.ts +11 -11
  280. package/lib/descriptors/interfaces/field-config.interface.d.ts +9 -9
  281. package/lib/descriptors/interfaces/index.d.ts +2 -2
  282. package/lib/descriptors/interfaces/lookup-descriptor.interface.d.ts +17 -17
  283. package/lib/descriptors/model.descriptor.d.ts +18 -18
  284. package/lib/descriptors/table.descriptor.d.ts +188 -188
  285. package/lib/descriptors/tableview.descriptor.d.ts +129 -129
  286. package/lib/descriptors/types/action.type.d.ts +21 -21
  287. package/lib/descriptors/types/column.type.d.ts +18 -18
  288. package/lib/descriptors/types/editor.type.d.ts +6 -6
  289. package/lib/descriptors/types/field.type.d.ts +47 -46
  290. package/lib/descriptors/types/filter.type.d.ts +27 -27
  291. package/lib/descriptors/types/index.d.ts +6 -6
  292. package/lib/descriptors/types/table.type.d.ts +22 -22
  293. package/lib/directives/component.directive.d.ts +16 -16
  294. package/lib/directives/index.d.ts +2 -2
  295. package/lib/directives/template.directive.d.ts +13 -13
  296. package/lib/mng-commons.module.d.ts +97 -97
  297. package/lib/models/column-value.model.d.ts +4 -4
  298. package/lib/models/config.model.d.ts +40 -40
  299. package/lib/models/enum.model.d.ts +6 -6
  300. package/lib/models/error.model.d.ts +14 -14
  301. package/lib/models/index.d.ts +9 -9
  302. package/lib/models/menu.model.d.ts +30 -30
  303. package/lib/models/tableview-attr.model.d.ts +10 -10
  304. package/lib/models/user.model.d.ts +8 -8
  305. package/lib/models/version.model.d.ts +18 -18
  306. package/lib/models/view-container.model.d.ts +43 -43
  307. package/lib/pipes/boolean.pipe.d.ts +7 -7
  308. package/lib/pipes/class-map.pipe.d.ts +7 -7
  309. package/lib/pipes/enum.pipe.d.ts +8 -8
  310. package/lib/pipes/enumerate-async.pipe.d.ts +14 -14
  311. package/lib/pipes/enumerate.pipe.d.ts +21 -21
  312. package/lib/pipes/getter.pipe.d.ts +7 -7
  313. package/lib/pipes/i18n-property.pipe.d.ts +8 -8
  314. package/lib/pipes/index.d.ts +11 -11
  315. package/lib/pipes/json-path.pipe.d.ts +13 -13
  316. package/lib/pipes/{mngLocaleDefaultRowClass.pipe.d.ts → locale-default-row-class.pipe.d.ts} +10 -10
  317. package/lib/pipes/models/internal/enumrate-pipe-i18n.model.d.ts +5 -5
  318. package/lib/pipes/models/internal/index.d.ts +1 -1
  319. package/lib/pipes/parametrize.pipe.d.ts +13 -13
  320. package/lib/pipes/template.pipe.d.ts +10 -10
  321. package/lib/router/index.d.ts +2 -2
  322. package/lib/router/models/index.d.ts +1 -1
  323. package/lib/router/models/router.model.d.ts +33 -33
  324. package/lib/router/route-builder.d.ts +98 -98
  325. package/lib/router/tableview-route-builder.d.ts +37 -37
  326. package/lib/security/authorization.guard.d.ts +11 -11
  327. package/lib/security/authorization.service.d.ts +19 -19
  328. package/lib/security/authorization.util.d.ts +5 -5
  329. package/lib/security/index.d.ts +3 -3
  330. package/lib/security/model/authorization.type.d.ts +6 -6
  331. package/lib/security/model/index.d.ts +3 -3
  332. package/lib/security/model/permission-service.interface.d.ts +6 -6
  333. package/lib/security/model/permissions.model.d.ts +37 -37
  334. package/lib/services/action-executor.service.d.ts +149 -149
  335. package/lib/services/commons.service.d.ts +89 -89
  336. package/lib/services/configuration.service.d.ts +57 -52
  337. package/lib/services/error-mapper.service.d.ts +7 -7
  338. package/lib/services/index.d.ts +6 -6
  339. package/lib/services/internal/commons-init.provider.d.ts +3 -3
  340. package/lib/services/internal/commons-init.service.d.ts +16 -16
  341. package/lib/services/internal/index.d.ts +2 -2
  342. package/lib/services/navigation.service.d.ts +14 -14
  343. package/lib/services/providers/config-service.provider.d.ts +6 -6
  344. package/lib/services/providers/formly-config.provider.d.ts +4 -4
  345. package/lib/services/providers/index.d.ts +2 -2
  346. package/lib/services/tokens/browser-storage.token.d.ts +2 -2
  347. package/lib/services/tokens/commons-init.token.d.ts +3 -3
  348. package/lib/services/tokens/default-setting.token.d.ts +2 -2
  349. package/lib/services/tokens/index.d.ts +4 -4
  350. package/lib/services/tokens/module-config.token.d.ts +3 -3
  351. package/lib/services/version.service.d.ts +13 -13
  352. package/lib/services/view-container.component.service.d.ts +31 -31
  353. package/lib/styles/button-style.builder.d.ts +67 -67
  354. package/lib/styles/index.d.ts +2 -2
  355. package/lib/styles/models/index.d.ts +2 -2
  356. package/lib/styles/models/style-level.enum.d.ts +10 -10
  357. package/lib/styles/models/style-size.enum.d.ts +7 -7
  358. package/lib/styles/styles.util.d.ts +14 -14
  359. package/lib/types/index.d.ts +2 -2
  360. package/lib/types/type.decorator.d.ts +4 -4
  361. package/lib/types/type.model.d.ts +23 -23
  362. package/lib/utils/action-data-provider.util.d.ts +20 -20
  363. package/lib/utils/date.util.d.ts +7 -7
  364. package/lib/utils/editor-formly.util.d.ts +12 -12
  365. package/lib/utils/enum.util.d.ts +50 -50
  366. package/lib/utils/i18n.util.d.ts +56 -56
  367. package/lib/utils/index.d.ts +9 -9
  368. package/lib/utils/model.util.d.ts +8 -8
  369. package/lib/utils/notification.util.d.ts +12 -12
  370. package/lib/utils/route.util.d.ts +4 -4
  371. package/lib/utils/string.util.d.ts +4 -4
  372. package/lib/utils/tableview.util.d.ts +40 -40
  373. package/lib/utils/type.util.d.ts +57 -57
  374. package/package.json +1 -1
  375. package/public-api.d.ts +34 -34
  376. package/version-info.json +7 -7
  377. package/mediusinc-mng-commons-1.0.0-rc.1.tgz +0 -0
@@ -1,552 +1,552 @@
1
- import { HttpErrorResponse } from '@angular/common/http';
2
- import { Inject, Injectable } from '@angular/core';
3
- import { from, mergeMap, of, switchMap, throwError } from 'rxjs';
4
- import { catchError, filter, first, map } from 'rxjs/operators';
5
- import { ActionContext, ActionContextValidation, ActionInstance, ActionInstanceStateEnum, ActionParameters } from '../components/action/models';
6
- import { ActionEditorDescriptor } from '../descriptors';
7
- import { ActionActivationTriggerEnum, ActionTypeEnum } from '../descriptors/types';
8
- import { StyleSizeEnum } from '../styles/models';
9
- import { I18nUtils, NotificationUtil, StringUtil } from '../utils';
10
- import { ACTION_EDITOR_DIALOG_COMPONENT_SETTING } from './tokens';
11
- import * as i0 from "@angular/core";
12
- import * as i1 from "@angular/router";
13
- import * as i2 from "primeng/dynamicdialog";
14
- import * as i3 from "primeng/api";
15
- import * as i4 from "@ngx-translate/core";
16
- import * as i5 from "./configuration.service";
17
- import * as i6 from "./navigation.service";
18
- import * as i7 from "./error-mapper.service";
19
- import * as i8 from "../pipes";
20
- export class MngActionExecutorService {
21
- constructor(injector, router, dialogService, confirmationService, translate, configurationService, navigationService, errorMapper, parametrize, defaultEditorDialogComponent) {
22
- this.injector = injector;
23
- this.router = router;
24
- this.dialogService = dialogService;
25
- this.confirmationService = confirmationService;
26
- this.translate = translate;
27
- this.configurationService = configurationService;
28
- this.navigationService = navigationService;
29
- this.errorMapper = errorMapper;
30
- this.parametrize = parametrize;
31
- this.defaultEditorDialogComponent = defaultEditorDialogComponent;
32
- this.debug = false;
33
- // this.debug = true;
34
- }
35
- prepareActionContextValidation(action, parameters, dataProvider) {
36
- const ctxDataProvider = dataProvider ?? action.dataProvider ?? parameters.viewContainer?.getDataProvider();
37
- const ctx = new ActionContextValidation(action, parameters, ctxDataProvider, this.getDataProviderService(ctxDataProvider) ?? undefined);
38
- return ctx;
39
- }
40
- prepareActionContext(instance, parameters, dataProvider, previousActionInstance) {
41
- const ctxDataProvider = dataProvider ?? instance.action.dataProvider ?? parameters.viewContainer?.getDataProvider();
42
- const ctx = new ActionContext(instance, parameters, 'run', ctxDataProvider, this.getDataProviderService(ctxDataProvider) ?? undefined);
43
- ctx.previousActionInstance = previousActionInstance;
44
- instance.newContext(ctx);
45
- return ctx;
46
- }
47
- /**
48
- * Prepares action exec context for action of type editor.
49
- *
50
- * @param item Item instance (if exists).
51
- * @param itemId Item id (if exists).
52
- * @param dataProvider Data provider.
53
- * @param sourceComponent Source component from where the context preparation was called.
54
- * @param viewContainer View container/service.
55
- * @param actionData Additional action data.
56
- */
57
- prepareContextForEditor(instance, parameters, functionName, dataProvider, previousActionInstance) {
58
- const editorAction = instance.action;
59
- let ctxDataProvider = dataProvider;
60
- if (!ctxDataProvider && editorAction.dataProvider) {
61
- ctxDataProvider = editorAction.dataProvider;
62
- }
63
- if (!ctxDataProvider) {
64
- const viewContainerDataProvider = parameters.viewContainer?.getDataProvider();
65
- if (viewContainerDataProvider) {
66
- ctxDataProvider = viewContainerDataProvider;
67
- }
68
- }
69
- const ctx = new ActionContext(instance, parameters, functionName, ctxDataProvider, this.getDataProviderService(ctxDataProvider) ?? undefined);
70
- ctx.previousActionInstance = previousActionInstance;
71
- instance.newContext(ctx);
72
- return ctx;
73
- }
74
- /**
75
- * Runs action context by submitting execution results/errors to context, watching over instance results/errors, displaying notifications,
76
- * running next/error action and triggering dismiss of action.
77
- *
78
- * @param action Action descriptor.
79
- * @param parameters Action parameters for context.
80
- * @param dataProvider Editor data provider for context.
81
- * @param instance Optional existing action instance (if non provided, new will be created).
82
- * @param previousActionInstance Optional previous action instance to link in next instance.
83
- *
84
- * @return Action context for submit (=run) function.
85
- */
86
- runActionContext(ctx) {
87
- const isMainRunFn = ctx.functionName === 'submit' || ctx.functionName === 'run';
88
- let actionEditor;
89
- let fnObs;
90
- switch (ctx.functionName) {
91
- case 'submit':
92
- actionEditor = ctx.instance.action;
93
- if (typeof actionEditor.submitFunction !== 'function') {
94
- return throwError(() => new Error(`Submit function for action ${actionEditor.actionNameLong} cannot be invoked.`));
95
- }
96
- fnObs = actionEditor.submitFunction;
97
- break;
98
- case 'fetch':
99
- actionEditor = ctx.instance.action;
100
- fnObs = actionEditor.fetchFunction;
101
- break;
102
- case 'run':
103
- default:
104
- fnObs = ctx.instance.action.runFunction;
105
- break;
106
- }
107
- const retObs = of(void 0).pipe(first(), switchMap(() => {
108
- if (isMainRunFn) {
109
- // if main run function, also set loading to true
110
- ctx.instance.state = ActionInstanceStateEnum.RunStart;
111
- ctx.instance.isRunLoadingSubject.next(true);
112
- }
113
- else {
114
- ctx.instance.state = ActionInstanceStateEnum.FetchStart;
115
- }
116
- // start context execution to mark execution loading
117
- ctx.executionStart();
118
- return fnObs(ctx);
119
- }), mergeMap(runResult => {
120
- // set next state depending on run
121
- ctx.instance.state = isMainRunFn ? ActionInstanceStateEnum.RunEnd : ActionInstanceStateEnum.FetchEnd;
122
- // set execution result
123
- ctx.executionNext(runResult, isMainRunFn);
124
- if (isMainRunFn) {
125
- // set instance final result on main run execution
126
- ctx.instance.result = runResult;
127
- ctx.instance.isRunLoadingSubject.next(false);
128
- // handle notification
129
- if (ctx.instance.action.hasRunNotificationSuccess) {
130
- ctx.notification = NotificationUtil.actionNotificationSuccess(this.translate, ctx.instance.action, ctx.functionName, ctx.instance.action.runNotificationSuccessTitle, ctx.instance.action.runNotificationSuccessMessage, ctx.parameters.viewContainer ?? undefined, ctx.parameters?.item);
131
- }
132
- // handle possible after run action
133
- if (ctx.instance.action.afterRunAction) {
134
- // mark new state for next action start
135
- ctx.instance.state = ActionInstanceStateEnum.NextActionStart;
136
- const nextActionInstance = this.activateAction(ctx.instance.action.afterRunAction, new ActionParameters(ctx.parameters.itemId, runResult)
137
- .withActionData(ctx.parameters.actionData)
138
- .withRoute(ctx.parameters.route)
139
- .withSourceComponent(ctx.parameters.sourceComponent)
140
- .withViewContainer(ctx.parameters.viewContainer), undefined, ctx.instance);
141
- ctx.instance.nextActionInstance = nextActionInstance;
142
- // finish current action when next action finishes
143
- return nextActionInstance.state$.pipe(filter(state => state >= ActionInstanceStateEnum.FinishSuccess), map(() => {
144
- ctx.instance.state = ActionInstanceStateEnum.NextActionEnd;
145
- return runResult;
146
- }));
147
- }
148
- }
149
- return of(runResult);
150
- }), map(runResult => {
151
- if (isMainRunFn) {
152
- // deactivate action
153
- this.deactivateAction(ctx.instance);
154
- }
155
- return runResult;
156
- }), catchError(err => {
157
- // transform error to mng action error
158
- const actionError = this.toMngActionError(err);
159
- // set instance state to error
160
- ctx.instance.state = isMainRunFn ? ActionInstanceStateEnum.RunError : ActionInstanceStateEnum.FetchError;
161
- // mark execution error on context
162
- ctx.executionError(actionError);
163
- let errorObs = of(void 0);
164
- if (isMainRunFn) {
165
- ctx.instance.error = err;
166
- ctx.instance.isRunLoadingSubject.next(false);
167
- // handle error notification
168
- if (ctx.instance.action.hasRunNotificationError) {
169
- actionError.notification = NotificationUtil.actionNotificationError(this.translate, ctx.instance.action, actionError, ctx.functionName, ctx.parameters.viewContainer ?? undefined, ctx.parameters.item);
170
- }
171
- // handle possible error action if run
172
- if (isMainRunFn && ctx.instance.action.onRunErrorAction) {
173
- // cannot start with trigger, because routing might be problematic (lousing previous results etc.)
174
- const errorActionInstance = this.activateAction(ctx.instance.action.onRunErrorAction, new ActionParameters(ctx.parameters.itemId, ctx.parameters.item)
175
- .withActionData(ctx.parameters.actionData)
176
- .withRoute(ctx.parameters.route)
177
- .withSourceComponent(ctx.parameters.sourceComponent)
178
- .withViewContainer(ctx.parameters.viewContainer));
179
- ctx.instance.errorActionInstance = errorActionInstance;
180
- errorObs = errorActionInstance.state$.pipe(filter(state => state >= ActionInstanceStateEnum.FinishSuccess), map(() => void 0));
181
- }
182
- }
183
- // liste and map only to mark instance state as finished error state
184
- return errorObs.pipe(map(() => {
185
- // deactivate action
186
- this.deactivateAction(ctx.instance);
187
- // rethrow error to propagate furher
188
- throw actionError;
189
- }));
190
- }));
191
- retObs.subscribe({
192
- next: res => {
193
- if (this.debug) {
194
- console.debug(`ActionContext ${ctx.contextLongName} execution next event`, res);
195
- }
196
- },
197
- error: err => {
198
- if (this.debug) {
199
- console.debug(`ActionContext ${ctx.contextLongName} execution error event`, err);
200
- }
201
- }
202
- });
203
- return retObs;
204
- }
205
- /**
206
- * Runs editor action's submit (=main run) function by creating new action context for action instance.
207
- *
208
- * @param action Action descriptor.
209
- * @param parameters Action parameters for context.
210
- * @param dataProvider Editor data provider for context.
211
- * @param instance Optional existing action instance (if non provided, new will be created).
212
- * @param previousActionInstance Optional previous action instance to link in next instance.
213
- *
214
- * @return Action context for submit (=run) function.
215
- */
216
- runEditorSave(action, parameters, dataProvider, instance, previousActionInstance) {
217
- if (!instance) {
218
- // create new instance if non provided
219
- instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationEnd, this.debug);
220
- }
221
- const context = this.prepareContextForEditor(instance, parameters, 'submit', dataProvider, previousActionInstance);
222
- this.runActionContext(context);
223
- return context;
224
- }
225
- /**
226
- * Gets service instance of data provider.
227
- *
228
- * @param dataProvider Data provider instance.
229
- */
230
- getDataProviderService(dataProvider) {
231
- if (dataProvider?.serviceType) {
232
- return this.injector.get(dataProvider.serviceType);
233
- }
234
- else {
235
- return null;
236
- }
237
- }
238
- /**
239
- * Runs editor action's fetch function by creating new action context for action instance.
240
- *
241
- * @param action Action descriptor.
242
- * @param parameters Action parameters for context.
243
- * @param dataProvider Editor data provider for context.
244
- * @param instance Optional existing action instance (if non provided, new will be created).
245
- * @param previousActionInstance Optional previous action instance to link in next instance.
246
- *
247
- * @return Action context for fetch function.
248
- */
249
- runEditorFetch(action, parameters, dataProvider, instance, previousActionInstance) {
250
- if (!instance) {
251
- // create new instance if non provided
252
- instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationEnd, this.debug);
253
- }
254
- const context = this.prepareContextForEditor(instance, parameters, 'fetch', dataProvider, previousActionInstance);
255
- this.runActionContext(context);
256
- return context;
257
- }
258
- /**
259
- * Runs action's main run function by creating new action context for action instance.
260
- *
261
- * @param action Action descriptor.
262
- * @param parameters Action parameters for context run.
263
- * @param dataProvider Data provider for context run.
264
- * @param instance Optional existing action instance (if non provided, new will be created).
265
- * @param previousActionInstance Optional previous action instance to link in next instance.
266
- *
267
- * @return Action context for run function.
268
- */
269
- runAction(action, parameters, dataProvider, instance, previousActionInstance) {
270
- if (!instance) {
271
- // create new instance if non provided
272
- instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationEnd, this.debug);
273
- }
274
- const context = this.prepareActionContext(instance, parameters, dataProvider, previousActionInstance);
275
- if (action.hasRunConfirmation) {
276
- const sourceComponent = parameters?.sourceComponent;
277
- const confirmationDescriptor = action.runConfirmationDialogDescriptor;
278
- if (typeof sourceComponent?.getConfirmationService !== 'function' || typeof sourceComponent?.getConfirmationServiceInstanceKey !== 'function') {
279
- throw new Error(`Source component ${sourceComponent} should be implementing IConfirmationService interface to be able to provide confirmation functionality.`);
280
- }
281
- const item = parameters.item;
282
- const srcConfirmComponent = sourceComponent;
283
- let confirmParams = {
284
- key: srcConfirmComponent.getConfirmationServiceInstanceKey(action),
285
- icon: confirmationDescriptor.icon,
286
- acceptVisible: true,
287
- acceptIcon: confirmationDescriptor.acceptButton.icon ?? undefined,
288
- acceptButtonStyleClass: confirmationDescriptor.acceptButton.styleClass.build(),
289
- rejectVisible: true,
290
- rejectIcon: confirmationDescriptor.rejectButton?.icon ?? undefined,
291
- rejectButtonStyleClass: confirmationDescriptor.rejectButton?.styleClass.build(),
292
- closeOnEscape: confirmationDescriptor.closeOnEscape
293
- };
294
- if (confirmationDescriptor.title !== null) {
295
- confirmParams.header = I18nUtils.Action.get(this.translate, action, 'confirm.title', confirmationDescriptor.title, item, 'general.confirmation') ?? undefined;
296
- }
297
- if (confirmationDescriptor.message !== null) {
298
- confirmParams.message =
299
- I18nUtils.Action.get(this.translate, action, 'confirm.message', confirmationDescriptor.message, StringUtil.escapeHtmlAny(item), 'general.confirmation') ??
300
- undefined;
301
- }
302
- if (confirmationDescriptor.acceptButton.label !== null) {
303
- confirmParams.acceptLabel =
304
- I18nUtils.Action.get(this.translate, action, 'confirm.accept', confirmationDescriptor.acceptButton.label, item, 'general.yes') ?? undefined;
305
- }
306
- if (confirmationDescriptor.acceptButton.icon !== null) {
307
- confirmParams.acceptIcon = confirmationDescriptor.acceptButton.icon;
308
- }
309
- if (confirmationDescriptor.rejectButton?.icon !== null) {
310
- confirmParams.rejectIcon = confirmationDescriptor.rejectButton?.icon;
311
- }
312
- if (confirmationDescriptor.rejectButton?.label !== null) {
313
- confirmParams.rejectLabel =
314
- I18nUtils.Action.get(this.translate, action, 'confirm.reject', confirmationDescriptor.rejectButton?.label, item, 'general.no') ?? undefined;
315
- }
316
- if (confirmationDescriptor.rejectButton == null || (confirmationDescriptor.rejectButton.label === null && confirmationDescriptor.rejectButton.icon === null)) {
317
- confirmParams.rejectVisible = false;
318
- }
319
- confirmParams.accept = () => {
320
- instance.state = ActionInstanceStateEnum.RunConfirmationEndAccept;
321
- this.runActionContext(context);
322
- };
323
- confirmParams.reject = () => {
324
- instance.state = ActionInstanceStateEnum.RunConfirmationEndReject;
325
- this.deactivateAction(instance);
326
- };
327
- if (confirmationDescriptor.runConfirmationConfigMapFn) {
328
- confirmParams = confirmationDescriptor.runConfirmationConfigMapFn(context, confirmParams);
329
- }
330
- context.confirmation = confirmParams;
331
- instance.state = ActionInstanceStateEnum.RunConfirmationStart;
332
- srcConfirmComponent.getConfirmationService().confirm(confirmParams);
333
- }
334
- else {
335
- this.runActionContext(context);
336
- }
337
- return context;
338
- }
339
- /**
340
- * Activates action (in case of dialog, dialog will be opened).
341
- *
342
- * @param action Action descriptor.
343
- * @param parameters Action parameters for activation of action instance.
344
- * @param instance Optional existing action instance (if non provided, new will be created).
345
- * @param previousActionInstance Optional previous action instance to link in next instance.
346
- *
347
- * @return Action instance - if non provided in parameters, the newly created will be returned.
348
- */
349
- activateAction(action, parameters, instance, previousActionInstance) {
350
- if (!instance) {
351
- // create new instance if non provided
352
- instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationStart, this.debug);
353
- }
354
- instance.activationParameters = parameters;
355
- // start activation instance
356
- instance.state = ActionInstanceStateEnum.ActivationStart;
357
- if (action.type === ActionTypeEnum.Editor) {
358
- let dialogComponent = this.defaultEditorDialogComponent;
359
- const dialogClassNames = ['mng-dialog'];
360
- if (action instanceof ActionEditorDescriptor) {
361
- dialogClassNames.push(action.dialogClassName ?? 'mng-action-editor-dialog');
362
- switch (action.dialogSize) {
363
- case StyleSizeEnum.ExtraSmall:
364
- dialogClassNames.push('mng-dialog-xs');
365
- break;
366
- case StyleSizeEnum.Small:
367
- dialogClassNames.push('mng-dialog-sm');
368
- break;
369
- case StyleSizeEnum.Large:
370
- dialogClassNames.push('mng-dialog-lg');
371
- break;
372
- case StyleSizeEnum.ExtraLarge:
373
- dialogClassNames.push('mng-dialog-xl');
374
- break;
375
- case StyleSizeEnum.Normal:
376
- default:
377
- break;
378
- }
379
- if (action.editorComponent) {
380
- dialogComponent = action.editorComponent;
381
- }
382
- }
383
- const dialogConfig = {
384
- data: {},
385
- styleClass: dialogClassNames.join(' ')
386
- };
387
- dialogConfig.data.actionInstance = instance;
388
- dialogConfig.data.previousActionInstance = previousActionInstance;
389
- const dialogRef = this.dialogService.open(dialogComponent, dialogConfig);
390
- dialogRef.onClose.pipe(first()).subscribe(() => {
391
- this.deactivateAction(instance, true);
392
- });
393
- instance.activationDialogRef = dialogRef;
394
- return instance;
395
- }
396
- else {
397
- // directly execute action
398
- instance.state = ActionInstanceStateEnum.ActivationEnd;
399
- const context = this.runAction(action, parameters, undefined, instance, previousActionInstance);
400
- return context.instance;
401
- }
402
- }
403
- /**
404
- * Deactivates action by choosing final state, closing dialog and completing all subjects in instance and contexts.
405
- *
406
- * @param instance Action instance.
407
- * @param fromDialogListener Deactivation called from dialog listener, in this case deactivation happens only if true.
408
- */
409
- deactivateAction(instance, fromDialogListener = false) {
410
- if (!fromDialogListener && instance.state >= ActionInstanceStateEnum.FinishSuccess) {
411
- if (this.debug) {
412
- console.debug(`ActionInstance ${instance.instanceLongName} already finished`);
413
- }
414
- return;
415
- }
416
- let finalState;
417
- if (typeof instance.result !== 'undefined') {
418
- finalState = ActionInstanceStateEnum.FinishSuccess;
419
- }
420
- else if (typeof instance.error !== 'undefined') {
421
- finalState = ActionInstanceStateEnum.FinishError;
422
- }
423
- else {
424
- finalState = ActionInstanceStateEnum.FinishDismissed;
425
- }
426
- if (instance.action.type === ActionTypeEnum.Editor) {
427
- const hasDialog = typeof instance.activationDialogRef !== 'undefined';
428
- if (hasDialog && !fromDialogListener) {
429
- if (finalState === ActionInstanceStateEnum.FinishSuccess) {
430
- // if state is finish and not called from dialog listener, close the dialog first which will retrigger this function, then finish it
431
- instance.activationDialogRef.close(instance.result);
432
- }
433
- // error and dismissed must both have fromDialogListener to be able to finish
434
- return;
435
- }
436
- }
437
- // set final state on instance
438
- instance.state = finalState;
439
- // complete all subjects
440
- instance.finish();
441
- }
442
- /**
443
- * Triggers action from table row click position.
444
- *
445
- * @param action Action descriptor.
446
- * @param event Target table click event.
447
- * @param route Currently activate route.
448
- * @param tableDescriptor Table descriptor.
449
- * @param dataKeyProperty Data key property.
450
- */
451
- triggerRowClickAction(action, event, route, tableDescriptor, dataKeyProperty) {
452
- const idProperty = dataKeyProperty ?? tableDescriptor?.dataKeyProperty ?? action?.model?.idPropertyName ?? dataKeyProperty;
453
- if (!idProperty) {
454
- throw new Error(`Row click action ${action.actionNameLong} can not be triggered, because id property could not be found.`);
455
- }
456
- const rowItem = event?.rowItem;
457
- return this.triggerAction(action, new ActionParameters(rowItem[idProperty], event.rowItem).withRoute(route));
458
- }
459
- /**
460
- * Triggers action with parameters.
461
- *
462
- * @param action Action descriptor.
463
- * @param parameters Action parameters for action execution to construct new route.
464
- *
465
- * @return Action instance - if non provided in parameters, the newly created will be returned.
466
- */
467
- triggerAction(action, parameters) {
468
- const instance = new ActionInstance(action, undefined, this.debug);
469
- instance.triggerParameters = parameters;
470
- if (action.activationTrigger === ActionActivationTriggerEnum.OnRoute) {
471
- const baseUrl = this.router.url.split('?')[0];
472
- const parsedUrl = this.router.parseUrl(this.router.url);
473
- let actionUrl = action.routeUrl ?? '';
474
- // TODO: dont strip '/', but use it accordingly with Angular's router patterns (/, ./, ../)
475
- if (actionUrl.startsWith('/')) {
476
- actionUrl = actionUrl.substring(1);
477
- }
478
- const actionUrlSegments = this.parametrize.transform(actionUrl, parameters.itemId, parameters.item, parameters.actionData).split('/');
479
- instance.triggerRouteNavigation = from(this.router.navigate([baseUrl, ...actionUrlSegments], { relativeTo: parameters.route, queryParams: parsedUrl.queryParams }));
480
- return instance;
481
- }
482
- else {
483
- instance.state = ActionInstanceStateEnum.TriggerEnd;
484
- return this.activateAction(action, parameters);
485
- }
486
- }
487
- /**
488
- * Deactivates on route triggered action by trying to reroute back to location where action was triggered.
489
- * @param instance Action instance.
490
- */
491
- deactivateOnRouteTriggeredAction(instance) {
492
- if (instance.action.activationTrigger !== ActionActivationTriggerEnum.OnRoute) {
493
- return;
494
- }
495
- // for now, deactivation always means going back to tableview root
496
- // if (this.navigationService.getPreviousLocation()) {
497
- // // there are internal history records, so back can be normally called
498
- // this.navigationService.back();
499
- // } else {
500
- // // there is no internal history records, figure out the base url by eliminating action specific url
501
- let url = this.navigationService.getCurrentLocation();
502
- // let previousUrl = this.navigationService.getPreviousLocation();
503
- // console.log(url, previousUrl);
504
- if (!url) {
505
- this.navigationService.back();
506
- }
507
- else {
508
- if (url.startsWith('/')) {
509
- url = url.substring(1);
510
- }
511
- const urlPathSegments = url.split('?')[0].split('#')[0].split('/');
512
- let actionUrl = instance.action?.routeUrl ?? '';
513
- if (actionUrl.startsWith('/')) {
514
- actionUrl = actionUrl.substring(1);
515
- }
516
- const actionUrlSegments = actionUrl.split('/');
517
- const redirectUrl = '/' + urlPathSegments.slice(0, urlPathSegments.length - actionUrlSegments.length).join('/');
518
- // const replaceUrl = previousUrl !== null && previousUrl.split('?')[0].split('#')[0] === redirectUrl;
519
- // No URL replaces, probably ok, to allow going back
520
- this.router.navigateByUrl(redirectUrl);
521
- }
522
- // }
523
- }
524
- /**
525
- * Transform error of any type to mng error by using error mapper that could be provided by final project.
526
- * @param error error of any type.
527
- *
528
- * @return mapped MngError.
529
- */
530
- toMngActionError(error) {
531
- const actionError = {
532
- name: error?.name ?? 'UnknownError',
533
- message: error?.message ?? 'Unknown error',
534
- cause: error
535
- };
536
- if (error instanceof HttpErrorResponse) {
537
- actionError.status = error.status;
538
- actionError.statusDescription = error.statusText;
539
- actionError.url = error.url ?? undefined;
540
- }
541
- return this.errorMapper.toMngError(error, actionError);
542
- }
543
- }
544
- MngActionExecutorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: MngActionExecutorService, deps: [{ token: i0.Injector }, { token: i1.Router }, { token: i2.DialogService }, { token: i3.ConfirmationService }, { token: i4.TranslateService }, { token: i5.MngConfigurationService }, { token: i6.MngNavigationService }, { token: i7.MngErrorMapperService }, { token: i8.MngParametrizePipe }, { token: ACTION_EDITOR_DIALOG_COMPONENT_SETTING }], target: i0.ɵɵFactoryTarget.Injectable });
545
- MngActionExecutorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: MngActionExecutorService });
546
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: MngActionExecutorService, decorators: [{
547
- type: Injectable
548
- }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.Router }, { type: i2.DialogService }, { type: i3.ConfirmationService }, { type: i4.TranslateService }, { type: i5.MngConfigurationService }, { type: i6.MngNavigationService }, { type: i7.MngErrorMapperService }, { type: i8.MngParametrizePipe }, { type: i0.Type, decorators: [{
549
- type: Inject,
550
- args: [ACTION_EDITOR_DIALOG_COMPONENT_SETTING]
551
- }] }]; } });
1
+ import { HttpErrorResponse } from '@angular/common/http';
2
+ import { Inject, Injectable } from '@angular/core';
3
+ import { from, mergeMap, of, switchMap, throwError } from 'rxjs';
4
+ import { catchError, filter, first, map } from 'rxjs/operators';
5
+ import { ActionContext, ActionContextValidation, ActionInstance, ActionInstanceStateEnum, ActionParameters } from '../components/action/models';
6
+ import { ActionEditorDescriptor } from '../descriptors';
7
+ import { ActionActivationTriggerEnum, ActionTypeEnum } from '../descriptors/types';
8
+ import { StyleSizeEnum } from '../styles/models';
9
+ import { I18nUtils, NotificationUtil, StringUtil } from '../utils';
10
+ import { ACTION_EDITOR_DIALOG_COMPONENT_SETTING } from './tokens';
11
+ import * as i0 from "@angular/core";
12
+ import * as i1 from "@angular/router";
13
+ import * as i2 from "primeng/dynamicdialog";
14
+ import * as i3 from "primeng/api";
15
+ import * as i4 from "@ngx-translate/core";
16
+ import * as i5 from "./configuration.service";
17
+ import * as i6 from "./navigation.service";
18
+ import * as i7 from "./error-mapper.service";
19
+ import * as i8 from "../pipes";
20
+ export class MngActionExecutorService {
21
+ constructor(injector, router, dialogService, confirmationService, translate, configurationService, navigationService, errorMapper, parametrize, defaultEditorDialogComponent) {
22
+ this.injector = injector;
23
+ this.router = router;
24
+ this.dialogService = dialogService;
25
+ this.confirmationService = confirmationService;
26
+ this.translate = translate;
27
+ this.configurationService = configurationService;
28
+ this.navigationService = navigationService;
29
+ this.errorMapper = errorMapper;
30
+ this.parametrize = parametrize;
31
+ this.defaultEditorDialogComponent = defaultEditorDialogComponent;
32
+ this.debug = false;
33
+ // this.debug = true;
34
+ }
35
+ prepareActionContextValidation(action, parameters, dataProvider) {
36
+ const ctxDataProvider = dataProvider ?? action.dataProvider ?? parameters.viewContainer?.getDataProvider();
37
+ const ctx = new ActionContextValidation(action, parameters, ctxDataProvider, this.getDataProviderService(ctxDataProvider) ?? undefined);
38
+ return ctx;
39
+ }
40
+ prepareActionContext(instance, parameters, dataProvider, previousActionInstance) {
41
+ const ctxDataProvider = dataProvider ?? instance.action.dataProvider ?? parameters.viewContainer?.getDataProvider();
42
+ const ctx = new ActionContext(instance, parameters, 'run', ctxDataProvider, this.getDataProviderService(ctxDataProvider) ?? undefined);
43
+ ctx.previousActionInstance = previousActionInstance;
44
+ instance.newContext(ctx);
45
+ return ctx;
46
+ }
47
+ /**
48
+ * Prepares action exec context for action of type editor.
49
+ *
50
+ * @param item Item instance (if exists).
51
+ * @param itemId Item id (if exists).
52
+ * @param dataProvider Data provider.
53
+ * @param sourceComponent Source component from where the context preparation was called.
54
+ * @param viewContainer View container/service.
55
+ * @param actionData Additional action data.
56
+ */
57
+ prepareContextForEditor(instance, parameters, functionName, dataProvider, previousActionInstance) {
58
+ const editorAction = instance.action;
59
+ let ctxDataProvider = dataProvider;
60
+ if (!ctxDataProvider && editorAction.dataProvider) {
61
+ ctxDataProvider = editorAction.dataProvider;
62
+ }
63
+ if (!ctxDataProvider) {
64
+ const viewContainerDataProvider = parameters.viewContainer?.getDataProvider();
65
+ if (viewContainerDataProvider) {
66
+ ctxDataProvider = viewContainerDataProvider;
67
+ }
68
+ }
69
+ const ctx = new ActionContext(instance, parameters, functionName, ctxDataProvider, this.getDataProviderService(ctxDataProvider) ?? undefined);
70
+ ctx.previousActionInstance = previousActionInstance;
71
+ instance.newContext(ctx);
72
+ return ctx;
73
+ }
74
+ /**
75
+ * Runs action context by submitting execution results/errors to context, watching over instance results/errors, displaying notifications,
76
+ * running next/error action and triggering dismiss of action.
77
+ *
78
+ * @param action Action descriptor.
79
+ * @param parameters Action parameters for context.
80
+ * @param dataProvider Editor data provider for context.
81
+ * @param instance Optional existing action instance (if non provided, new will be created).
82
+ * @param previousActionInstance Optional previous action instance to link in next instance.
83
+ *
84
+ * @return Action context for submit (=run) function.
85
+ */
86
+ runActionContext(ctx) {
87
+ const isMainRunFn = ctx.functionName === 'submit' || ctx.functionName === 'run';
88
+ let actionEditor;
89
+ let fnObs;
90
+ switch (ctx.functionName) {
91
+ case 'submit':
92
+ actionEditor = ctx.instance.action;
93
+ if (typeof actionEditor.submitFunction !== 'function') {
94
+ return throwError(() => new Error(`Submit function for action ${actionEditor.actionNameLong} cannot be invoked.`));
95
+ }
96
+ fnObs = actionEditor.submitFunction;
97
+ break;
98
+ case 'fetch':
99
+ actionEditor = ctx.instance.action;
100
+ fnObs = actionEditor.fetchFunction;
101
+ break;
102
+ case 'run':
103
+ default:
104
+ fnObs = ctx.instance.action.runFunction;
105
+ break;
106
+ }
107
+ const retObs = of(void 0).pipe(first(), switchMap(() => {
108
+ if (isMainRunFn) {
109
+ // if main run function, also set loading to true
110
+ ctx.instance.state = ActionInstanceStateEnum.RunStart;
111
+ ctx.instance.isRunLoadingSubject.next(true);
112
+ }
113
+ else {
114
+ ctx.instance.state = ActionInstanceStateEnum.FetchStart;
115
+ }
116
+ // start context execution to mark execution loading
117
+ ctx.executionStart();
118
+ return fnObs(ctx);
119
+ }), mergeMap(runResult => {
120
+ // set next state depending on run
121
+ ctx.instance.state = isMainRunFn ? ActionInstanceStateEnum.RunEnd : ActionInstanceStateEnum.FetchEnd;
122
+ // set execution result
123
+ ctx.executionNext(runResult, isMainRunFn);
124
+ if (isMainRunFn) {
125
+ // set instance final result on main run execution
126
+ ctx.instance.result = runResult;
127
+ ctx.instance.isRunLoadingSubject.next(false);
128
+ // handle notification
129
+ if (ctx.instance.action.hasRunNotificationSuccess) {
130
+ ctx.notification = NotificationUtil.actionNotificationSuccess(this.translate, ctx.instance.action, ctx.functionName, ctx.instance.action.runNotificationSuccessTitle, ctx.instance.action.runNotificationSuccessMessage, ctx.parameters.viewContainer ?? undefined, ctx.parameters?.item);
131
+ }
132
+ // handle possible after run action
133
+ if (ctx.instance.action.afterRunAction) {
134
+ // mark new state for next action start
135
+ ctx.instance.state = ActionInstanceStateEnum.NextActionStart;
136
+ const nextActionInstance = this.activateAction(ctx.instance.action.afterRunAction, new ActionParameters(ctx.parameters.itemId, runResult)
137
+ .withActionData(ctx.parameters.actionData)
138
+ .withRoute(ctx.parameters.route)
139
+ .withSourceComponent(ctx.parameters.sourceComponent)
140
+ .withViewContainer(ctx.parameters.viewContainer), undefined, ctx.instance);
141
+ ctx.instance.nextActionInstance = nextActionInstance;
142
+ // finish current action when next action finishes
143
+ return nextActionInstance.state$.pipe(filter(state => state >= ActionInstanceStateEnum.FinishSuccess), map(() => {
144
+ ctx.instance.state = ActionInstanceStateEnum.NextActionEnd;
145
+ return runResult;
146
+ }));
147
+ }
148
+ }
149
+ return of(runResult);
150
+ }), map(runResult => {
151
+ if (isMainRunFn) {
152
+ // deactivate action
153
+ this.deactivateAction(ctx.instance);
154
+ }
155
+ return runResult;
156
+ }), catchError(err => {
157
+ // transform error to mng action error
158
+ const actionError = this.toMngActionError(err);
159
+ // set instance state to error
160
+ ctx.instance.state = isMainRunFn ? ActionInstanceStateEnum.RunError : ActionInstanceStateEnum.FetchError;
161
+ // mark execution error on context
162
+ ctx.executionError(actionError);
163
+ let errorObs = of(void 0);
164
+ if (isMainRunFn) {
165
+ ctx.instance.error = err;
166
+ ctx.instance.isRunLoadingSubject.next(false);
167
+ // handle error notification
168
+ if (ctx.instance.action.hasRunNotificationError) {
169
+ actionError.notification = NotificationUtil.actionNotificationError(this.translate, ctx.instance.action, actionError, ctx.functionName, ctx.parameters.viewContainer ?? undefined, ctx.parameters.item);
170
+ }
171
+ // handle possible error action if run
172
+ if (isMainRunFn && ctx.instance.action.onRunErrorAction) {
173
+ // cannot start with trigger, because routing might be problematic (lousing previous results etc.)
174
+ const errorActionInstance = this.activateAction(ctx.instance.action.onRunErrorAction, new ActionParameters(ctx.parameters.itemId, ctx.parameters.item)
175
+ .withActionData(ctx.parameters.actionData)
176
+ .withRoute(ctx.parameters.route)
177
+ .withSourceComponent(ctx.parameters.sourceComponent)
178
+ .withViewContainer(ctx.parameters.viewContainer));
179
+ ctx.instance.errorActionInstance = errorActionInstance;
180
+ errorObs = errorActionInstance.state$.pipe(filter(state => state >= ActionInstanceStateEnum.FinishSuccess), map(() => void 0));
181
+ }
182
+ }
183
+ // liste and map only to mark instance state as finished error state
184
+ return errorObs.pipe(map(() => {
185
+ // deactivate action
186
+ this.deactivateAction(ctx.instance);
187
+ // rethrow error to propagate furher
188
+ throw actionError;
189
+ }));
190
+ }));
191
+ retObs.subscribe({
192
+ next: res => {
193
+ if (this.debug) {
194
+ console.debug(`ActionContext ${ctx.contextLongName} execution next event`, res);
195
+ }
196
+ },
197
+ error: err => {
198
+ if (this.debug) {
199
+ console.debug(`ActionContext ${ctx.contextLongName} execution error event`, err);
200
+ }
201
+ }
202
+ });
203
+ return retObs;
204
+ }
205
+ /**
206
+ * Runs editor action's submit (=main run) function by creating new action context for action instance.
207
+ *
208
+ * @param action Action descriptor.
209
+ * @param parameters Action parameters for context.
210
+ * @param dataProvider Editor data provider for context.
211
+ * @param instance Optional existing action instance (if non provided, new will be created).
212
+ * @param previousActionInstance Optional previous action instance to link in next instance.
213
+ *
214
+ * @return Action context for submit (=run) function.
215
+ */
216
+ runEditorSave(action, parameters, dataProvider, instance, previousActionInstance) {
217
+ if (!instance) {
218
+ // create new instance if non provided
219
+ instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationEnd, this.debug);
220
+ }
221
+ const context = this.prepareContextForEditor(instance, parameters, 'submit', dataProvider, previousActionInstance);
222
+ this.runActionContext(context);
223
+ return context;
224
+ }
225
+ /**
226
+ * Gets service instance of data provider.
227
+ *
228
+ * @param dataProvider Data provider instance.
229
+ */
230
+ getDataProviderService(dataProvider) {
231
+ if (dataProvider?.serviceType) {
232
+ return this.injector.get(dataProvider.serviceType);
233
+ }
234
+ else {
235
+ return null;
236
+ }
237
+ }
238
+ /**
239
+ * Runs editor action's fetch function by creating new action context for action instance.
240
+ *
241
+ * @param action Action descriptor.
242
+ * @param parameters Action parameters for context.
243
+ * @param dataProvider Editor data provider for context.
244
+ * @param instance Optional existing action instance (if non provided, new will be created).
245
+ * @param previousActionInstance Optional previous action instance to link in next instance.
246
+ *
247
+ * @return Action context for fetch function.
248
+ */
249
+ runEditorFetch(action, parameters, dataProvider, instance, previousActionInstance) {
250
+ if (!instance) {
251
+ // create new instance if non provided
252
+ instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationEnd, this.debug);
253
+ }
254
+ const context = this.prepareContextForEditor(instance, parameters, 'fetch', dataProvider, previousActionInstance);
255
+ this.runActionContext(context);
256
+ return context;
257
+ }
258
+ /**
259
+ * Runs action's main run function by creating new action context for action instance.
260
+ *
261
+ * @param action Action descriptor.
262
+ * @param parameters Action parameters for context run.
263
+ * @param dataProvider Data provider for context run.
264
+ * @param instance Optional existing action instance (if non provided, new will be created).
265
+ * @param previousActionInstance Optional previous action instance to link in next instance.
266
+ *
267
+ * @return Action context for run function.
268
+ */
269
+ runAction(action, parameters, dataProvider, instance, previousActionInstance) {
270
+ if (!instance) {
271
+ // create new instance if non provided
272
+ instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationEnd, this.debug);
273
+ }
274
+ const context = this.prepareActionContext(instance, parameters, dataProvider, previousActionInstance);
275
+ if (action.hasRunConfirmation) {
276
+ const sourceComponent = parameters?.sourceComponent;
277
+ const confirmationDescriptor = action.runConfirmationDialogDescriptor;
278
+ if (typeof sourceComponent?.getConfirmationService !== 'function' || typeof sourceComponent?.getConfirmationServiceInstanceKey !== 'function') {
279
+ throw new Error(`Source component ${sourceComponent} should be implementing IConfirmationService interface to be able to provide confirmation functionality.`);
280
+ }
281
+ const item = parameters.item;
282
+ const srcConfirmComponent = sourceComponent;
283
+ let confirmParams = {
284
+ key: srcConfirmComponent.getConfirmationServiceInstanceKey(action),
285
+ icon: confirmationDescriptor.icon,
286
+ acceptVisible: true,
287
+ acceptIcon: confirmationDescriptor.acceptButton.icon ?? undefined,
288
+ acceptButtonStyleClass: confirmationDescriptor.acceptButton.styleClass.build(),
289
+ rejectVisible: true,
290
+ rejectIcon: confirmationDescriptor.rejectButton?.icon ?? undefined,
291
+ rejectButtonStyleClass: confirmationDescriptor.rejectButton?.styleClass.build(),
292
+ closeOnEscape: confirmationDescriptor.closeOnEscape
293
+ };
294
+ if (confirmationDescriptor.title !== null) {
295
+ confirmParams.header = I18nUtils.Action.get(this.translate, action, 'confirm.title', confirmationDescriptor.title, item, 'general.confirmation') ?? undefined;
296
+ }
297
+ if (confirmationDescriptor.message !== null) {
298
+ confirmParams.message =
299
+ I18nUtils.Action.get(this.translate, action, 'confirm.message', confirmationDescriptor.message, StringUtil.escapeHtmlAny(item), 'general.confirmation') ??
300
+ undefined;
301
+ }
302
+ if (confirmationDescriptor.acceptButton.label !== null) {
303
+ confirmParams.acceptLabel =
304
+ I18nUtils.Action.get(this.translate, action, 'confirm.accept', confirmationDescriptor.acceptButton.label, item, 'general.yes') ?? undefined;
305
+ }
306
+ if (confirmationDescriptor.acceptButton.icon !== null) {
307
+ confirmParams.acceptIcon = confirmationDescriptor.acceptButton.icon;
308
+ }
309
+ if (confirmationDescriptor.rejectButton?.icon !== null) {
310
+ confirmParams.rejectIcon = confirmationDescriptor.rejectButton?.icon;
311
+ }
312
+ if (confirmationDescriptor.rejectButton?.label !== null) {
313
+ confirmParams.rejectLabel =
314
+ I18nUtils.Action.get(this.translate, action, 'confirm.reject', confirmationDescriptor.rejectButton?.label, item, 'general.no') ?? undefined;
315
+ }
316
+ if (confirmationDescriptor.rejectButton == null || (confirmationDescriptor.rejectButton.label === null && confirmationDescriptor.rejectButton.icon === null)) {
317
+ confirmParams.rejectVisible = false;
318
+ }
319
+ confirmParams.accept = () => {
320
+ instance.state = ActionInstanceStateEnum.RunConfirmationEndAccept;
321
+ this.runActionContext(context);
322
+ };
323
+ confirmParams.reject = () => {
324
+ instance.state = ActionInstanceStateEnum.RunConfirmationEndReject;
325
+ this.deactivateAction(instance);
326
+ };
327
+ if (confirmationDescriptor.runConfirmationConfigMapFn) {
328
+ confirmParams = confirmationDescriptor.runConfirmationConfigMapFn(context, confirmParams);
329
+ }
330
+ context.confirmation = confirmParams;
331
+ instance.state = ActionInstanceStateEnum.RunConfirmationStart;
332
+ srcConfirmComponent.getConfirmationService().confirm(confirmParams);
333
+ }
334
+ else {
335
+ this.runActionContext(context);
336
+ }
337
+ return context;
338
+ }
339
+ /**
340
+ * Activates action (in case of dialog, dialog will be opened).
341
+ *
342
+ * @param action Action descriptor.
343
+ * @param parameters Action parameters for activation of action instance.
344
+ * @param instance Optional existing action instance (if non provided, new will be created).
345
+ * @param previousActionInstance Optional previous action instance to link in next instance.
346
+ *
347
+ * @return Action instance - if non provided in parameters, the newly created will be returned.
348
+ */
349
+ activateAction(action, parameters, instance, previousActionInstance) {
350
+ if (!instance) {
351
+ // create new instance if non provided
352
+ instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationStart, this.debug);
353
+ }
354
+ instance.activationParameters = parameters;
355
+ // start activation instance
356
+ instance.state = ActionInstanceStateEnum.ActivationStart;
357
+ if (action.type === ActionTypeEnum.Editor) {
358
+ let dialogComponent = this.defaultEditorDialogComponent;
359
+ const dialogClassNames = ['mng-dialog'];
360
+ if (action instanceof ActionEditorDescriptor) {
361
+ dialogClassNames.push(action.dialogClassName ?? 'mng-action-editor-dialog');
362
+ switch (action.dialogSize) {
363
+ case StyleSizeEnum.ExtraSmall:
364
+ dialogClassNames.push('mng-dialog-xs');
365
+ break;
366
+ case StyleSizeEnum.Small:
367
+ dialogClassNames.push('mng-dialog-sm');
368
+ break;
369
+ case StyleSizeEnum.Large:
370
+ dialogClassNames.push('mng-dialog-lg');
371
+ break;
372
+ case StyleSizeEnum.ExtraLarge:
373
+ dialogClassNames.push('mng-dialog-xl');
374
+ break;
375
+ case StyleSizeEnum.Normal:
376
+ default:
377
+ break;
378
+ }
379
+ if (action.editorComponent) {
380
+ dialogComponent = action.editorComponent;
381
+ }
382
+ }
383
+ const dialogConfig = {
384
+ data: {},
385
+ styleClass: dialogClassNames.join(' ')
386
+ };
387
+ dialogConfig.data.actionInstance = instance;
388
+ dialogConfig.data.previousActionInstance = previousActionInstance;
389
+ const dialogRef = this.dialogService.open(dialogComponent, dialogConfig);
390
+ dialogRef.onClose.pipe(first()).subscribe(() => {
391
+ this.deactivateAction(instance, true);
392
+ });
393
+ instance.activationDialogRef = dialogRef;
394
+ return instance;
395
+ }
396
+ else {
397
+ // directly execute action
398
+ instance.state = ActionInstanceStateEnum.ActivationEnd;
399
+ const context = this.runAction(action, parameters, undefined, instance, previousActionInstance);
400
+ return context.instance;
401
+ }
402
+ }
403
+ /**
404
+ * Deactivates action by choosing final state, closing dialog and completing all subjects in instance and contexts.
405
+ *
406
+ * @param instance Action instance.
407
+ * @param fromDialogListener Deactivation called from dialog listener, in this case deactivation happens only if true.
408
+ */
409
+ deactivateAction(instance, fromDialogListener = false) {
410
+ if (!fromDialogListener && instance.state >= ActionInstanceStateEnum.FinishSuccess) {
411
+ if (this.debug) {
412
+ console.debug(`ActionInstance ${instance.instanceLongName} already finished`);
413
+ }
414
+ return;
415
+ }
416
+ let finalState;
417
+ if (typeof instance.result !== 'undefined') {
418
+ finalState = ActionInstanceStateEnum.FinishSuccess;
419
+ }
420
+ else if (typeof instance.error !== 'undefined') {
421
+ finalState = ActionInstanceStateEnum.FinishError;
422
+ }
423
+ else {
424
+ finalState = ActionInstanceStateEnum.FinishDismissed;
425
+ }
426
+ if (instance.action.type === ActionTypeEnum.Editor) {
427
+ const hasDialog = typeof instance.activationDialogRef !== 'undefined';
428
+ if (hasDialog && !fromDialogListener) {
429
+ if (finalState === ActionInstanceStateEnum.FinishSuccess) {
430
+ // if state is finish and not called from dialog listener, close the dialog first which will retrigger this function, then finish it
431
+ instance.activationDialogRef.close(instance.result);
432
+ }
433
+ // error and dismissed must both have fromDialogListener to be able to finish
434
+ return;
435
+ }
436
+ }
437
+ // set final state on instance
438
+ instance.state = finalState;
439
+ // complete all subjects
440
+ instance.finish();
441
+ }
442
+ /**
443
+ * Triggers action from table row click position.
444
+ *
445
+ * @param action Action descriptor.
446
+ * @param event Target table click event.
447
+ * @param route Currently activate route.
448
+ * @param tableDescriptor Table descriptor.
449
+ * @param dataKeyProperty Data key property.
450
+ */
451
+ triggerRowClickAction(action, event, route, tableDescriptor, dataKeyProperty) {
452
+ const idProperty = dataKeyProperty ?? tableDescriptor?.dataKeyProperty ?? action?.model?.idPropertyName ?? dataKeyProperty;
453
+ if (!idProperty) {
454
+ throw new Error(`Row click action ${action.actionNameLong} can not be triggered, because id property could not be found.`);
455
+ }
456
+ const rowItem = event?.rowItem;
457
+ return this.triggerAction(action, new ActionParameters(rowItem[idProperty], event.rowItem).withRoute(route));
458
+ }
459
+ /**
460
+ * Triggers action with parameters.
461
+ *
462
+ * @param action Action descriptor.
463
+ * @param parameters Action parameters for action execution to construct new route.
464
+ *
465
+ * @return Action instance - if non provided in parameters, the newly created will be returned.
466
+ */
467
+ triggerAction(action, parameters) {
468
+ const instance = new ActionInstance(action, undefined, this.debug);
469
+ instance.triggerParameters = parameters;
470
+ if (action.activationTrigger === ActionActivationTriggerEnum.OnRoute) {
471
+ const baseUrl = this.router.url.split('?')[0];
472
+ const parsedUrl = this.router.parseUrl(this.router.url);
473
+ let actionUrl = action.routeUrl ?? '';
474
+ // TODO: dont strip '/', but use it accordingly with Angular's router patterns (/, ./, ../)
475
+ if (actionUrl.startsWith('/')) {
476
+ actionUrl = actionUrl.substring(1);
477
+ }
478
+ const actionUrlSegments = this.parametrize.transform(actionUrl, parameters.itemId, parameters.item, parameters.actionData).split('/');
479
+ instance.triggerRouteNavigation = from(this.router.navigate([baseUrl, ...actionUrlSegments], { relativeTo: parameters.route, queryParams: parsedUrl.queryParams }));
480
+ return instance;
481
+ }
482
+ else {
483
+ instance.state = ActionInstanceStateEnum.TriggerEnd;
484
+ return this.activateAction(action, parameters);
485
+ }
486
+ }
487
+ /**
488
+ * Deactivates on route triggered action by trying to reroute back to location where action was triggered.
489
+ * @param instance Action instance.
490
+ */
491
+ deactivateOnRouteTriggeredAction(instance) {
492
+ if (instance.action.activationTrigger !== ActionActivationTriggerEnum.OnRoute) {
493
+ return;
494
+ }
495
+ // for now, deactivation always means going back to tableview root
496
+ // if (this.navigationService.getPreviousLocation()) {
497
+ // // there are internal history records, so back can be normally called
498
+ // this.navigationService.back();
499
+ // } else {
500
+ // // there is no internal history records, figure out the base url by eliminating action specific url
501
+ let url = this.navigationService.getCurrentLocation();
502
+ // let previousUrl = this.navigationService.getPreviousLocation();
503
+ // console.log(url, previousUrl);
504
+ if (!url) {
505
+ this.navigationService.back();
506
+ }
507
+ else {
508
+ if (url.startsWith('/')) {
509
+ url = url.substring(1);
510
+ }
511
+ const urlPathSegments = url.split('?')[0].split('#')[0].split('/');
512
+ let actionUrl = instance.action?.routeUrl ?? '';
513
+ if (actionUrl.startsWith('/')) {
514
+ actionUrl = actionUrl.substring(1);
515
+ }
516
+ const actionUrlSegments = actionUrl.split('/');
517
+ const redirectUrl = '/' + urlPathSegments.slice(0, urlPathSegments.length - actionUrlSegments.length).join('/');
518
+ // const replaceUrl = previousUrl !== null && previousUrl.split('?')[0].split('#')[0] === redirectUrl;
519
+ // No URL replaces, probably ok, to allow going back
520
+ this.router.navigateByUrl(redirectUrl);
521
+ }
522
+ // }
523
+ }
524
+ /**
525
+ * Transform error of any type to mng error by using error mapper that could be provided by final project.
526
+ * @param error error of any type.
527
+ *
528
+ * @return mapped MngError.
529
+ */
530
+ toMngActionError(error) {
531
+ const actionError = {
532
+ name: error?.name ?? 'UnknownError',
533
+ message: error?.message ?? 'Unknown error',
534
+ cause: error
535
+ };
536
+ if (error instanceof HttpErrorResponse) {
537
+ actionError.status = error.status;
538
+ actionError.statusDescription = error.statusText;
539
+ actionError.url = error.url ?? undefined;
540
+ }
541
+ return this.errorMapper.toMngError(error, actionError);
542
+ }
543
+ }
544
+ MngActionExecutorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: MngActionExecutorService, deps: [{ token: i0.Injector }, { token: i1.Router }, { token: i2.DialogService }, { token: i3.ConfirmationService }, { token: i4.TranslateService }, { token: i5.MngConfigurationService }, { token: i6.MngNavigationService }, { token: i7.MngErrorMapperService }, { token: i8.MngParametrizePipe }, { token: ACTION_EDITOR_DIALOG_COMPONENT_SETTING }], target: i0.ɵɵFactoryTarget.Injectable });
545
+ MngActionExecutorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: MngActionExecutorService });
546
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: MngActionExecutorService, decorators: [{
547
+ type: Injectable
548
+ }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.Router }, { type: i2.DialogService }, { type: i3.ConfirmationService }, { type: i4.TranslateService }, { type: i5.MngConfigurationService }, { type: i6.MngNavigationService }, { type: i7.MngErrorMapperService }, { type: i8.MngParametrizePipe }, { type: i0.Type, decorators: [{
549
+ type: Inject,
550
+ args: [ACTION_EDITOR_DIALOG_COMPONENT_SETTING]
551
+ }] }]; } });
552
552
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWV4ZWN1dG9yLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2FjdGlvbi1leGVjdXRvci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBQ3ZELE9BQU8sRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFpQixNQUFNLGVBQWUsQ0FBQztBQU1qRSxPQUFPLEVBQWEsSUFBSSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUMzRSxPQUFPLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFFOUQsT0FBTyxFQUFDLGFBQWEsRUFBRSx1QkFBdUIsRUFBRSxjQUFjLEVBQUUsdUJBQXVCLEVBQUUsZ0JBQWdCLEVBQTZCLE1BQU0sNkJBQTZCLENBQUM7QUFHMUssT0FBTyxFQUFtQixzQkFBc0IsRUFBa0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUV6RixPQUFPLEVBQUMsMkJBQTJCLEVBQUUsY0FBYyxFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFHakYsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBQy9DLE9BQU8sRUFBQyxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsVUFBVSxFQUFDLE1BQU0sVUFBVSxDQUFDO0FBSWpFLE9BQU8sRUFBQyxzQ0FBc0MsRUFBQyxNQUFNLFVBQVUsQ0FBQzs7Ozs7Ozs7OztBQUdoRSxNQUFNLE9BQU8sd0JBQXdCO0lBR2pDLFlBQ1ksUUFBa0IsRUFDbEIsTUFBYyxFQUNkLGFBQTRCLEVBQzVCLG1CQUF3QyxFQUN4QyxTQUEyQixFQUMzQixvQkFBNkMsRUFDN0MsaUJBQXVDLEVBQ3ZDLFdBQWtDLEVBQ2xDLFdBQStCLEVBQ2lC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LHdCQUF3QixrVEFhckIsc0NBQXNDO3lIQWJ6Qyx3QkFBd0I7MkZBQXhCLHdCQUF3QjtrQkFEcEMsVUFBVTs7MEJBY0YsTUFBTTsyQkFBQyxzQ0FBc0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0h0dHBFcnJvclJlc3BvbnNlfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQge0luamVjdCwgSW5qZWN0YWJsZSwgSW5qZWN0b3IsIFR5cGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtBY3RpdmF0ZWRSb3V0ZSwgUm91dGVyLCBVcmxUcmVlfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuXG5pbXBvcnQge1RyYW5zbGF0ZVNlcnZpY2V9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtDb25maXJtYXRpb24sIENvbmZpcm1hdGlvblNlcnZpY2V9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7RGlhbG9nU2VydmljZSwgRHluYW1pY0RpYWxvZ0NvbmZpZ30gZnJvbSAncHJpbWVuZy9keW5hbWljZGlhbG9nJztcbmltcG9ydCB7T2JzZXJ2YWJsZSwgZnJvbSwgbWVyZ2VNYXAsIG9mLCBzd2l0Y2hNYXAsIHRocm93RXJyb3J9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtjYXRjaEVycm9yLCBmaWx0ZXIsIGZpcnN0LCBtYXB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtBY3Rpb25Db250ZXh0LCBBY3Rpb25Db250ZXh0VmFsaWRhdGlvbiwgQWN0aW9uSW5zdGFuY2UsIEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLCBBY3Rpb25QYXJhbWV0ZXJzLCBJQWN0aW9uQ29uZmlybWF0aW9uU2VydmljZX0gZnJvbSAnLi4vY29tcG9uZW50cy9hY3Rpb24vbW9kZWxzJztcbmltcG9ydCB7TW5nVGFibGVDZWxsQ2xpY2tFdmVudH0gZnJvbSAnLi4vY29tcG9uZW50cy90YWJsZXZpZXcvbW9kZWxzJztcbmltcG9ydCB7SURhdGFQcm92aWRlciwgSUVkaXRvckRhdGFQcm92aWRlcn0gZnJvbSAnLi4vZGF0YS1wcm92aWRlcnMnO1xuaW1wb3J0IHtBY3Rpb25EZXNjcmlwdG9yLCBBY3Rpb25FZGl0b3JEZXNjcmlwdG9yLCBUYWJsZURlc2NyaXB0b3J9IGZyb20gJy4uL2Rlc2NyaXB0b3JzJztcbmltcG9ydCB7QWN0aW9uQ29uZmlybWF0aW9uRGlhbG9nRGVzY3JpcHRvcn0gZnJvbSAnLi4vZGVzY3JpcHRvcnMvYWN0aW9uL2FjdGlvbi1jb25maXJtYXRpb24uZGVzY3JpcHRvcic7XG5pbXBvcnQge0FjdGlvbkFjdGl2YXRpb25UcmlnZ2VyRW51bSwgQWN0aW9uVHlwZUVudW19IGZyb20gJy4uL2Rlc2NyaXB0b3JzL3R5cGVzJztcbmltcG9ydCB7SVZpZXdDb250YWluZXIsIE1uZ0Vycm9yfSBmcm9tICcuLi9tb2RlbHMnO1xuaW1wb3J0IHtNbmdQYXJhbWV0cml6ZVBpcGV9IGZyb20gJy4uL3BpcGVzJztcbmltcG9ydCB7U3R5bGVTaXplRW51bX0gZnJvbSAnLi4vc3R5bGVzL21vZGVscyc7XG5pbXBvcnQge0kxOG5VdGlscywgTm90aWZpY2F0aW9uVXRpbCwgU3RyaW5nVXRpbH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHtNbmdDb25maWd1cmF0aW9uU2VydmljZX0gZnJvbSAnLi9jb25maWd1cmF0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHtNbmdFcnJvck1hcHBlclNlcnZpY2V9IGZyb20gJy4vZXJyb3ItbWFwcGVyLnNlcnZpY2UnO1xuaW1wb3J0IHtNbmdOYXZpZ2F0aW9uU2VydmljZX0gZnJvbSAnLi9uYXZpZ2F0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHtBQ1RJT05fRURJVE9SX0RJQUxPR19DT01QT05FTlRfU0VUVElOR30gZnJvbSAnLi90b2tlbnMnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTW5nQWN0aW9uRXhlY3V0b3JTZXJ2aWNlIHtcbiAgICBwcml2YXRlIGRlYnVnID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgICAgIHByaXZhdGUgZGlhbG9nU2VydmljZTogRGlhbG9nU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBjb25maXJtYXRpb25TZXJ2aWNlOiBDb25maXJtYXRpb25TZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBjb25maWd1cmF0aW9uU2VydmljZTogTW5nQ29uZmlndXJhdGlvblNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbmF2aWdhdGlvblNlcnZpY2U6IE1uZ05hdmlnYXRpb25TZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIGVycm9yTWFwcGVyOiBNbmdFcnJvck1hcHBlclNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgcGFyYW1ldHJpemU6IE1uZ1BhcmFtZXRyaXplUGlwZSxcbiAgICAgICAgQEluamVjdChBQ1RJT05fRURJVE9SX0RJQUxPR19DT01QT05FTlRfU0VUVElORykgcHJpdmF0ZSBkZWZhdWx0RWRpdG9yRGlhbG9nQ29tcG9uZW50OiBUeXBlPGFueT5cbiAgICApIHtcbiAgICAgICAgLy8gdGhpcy5kZWJ1ZyA9IHRydWU7XG4gICAgfVxuXG4gICAgcHVibGljIHByZXBhcmVBY3Rpb25Db250ZXh0VmFsaWRhdGlvbjxULCBTPihhY3Rpb246IEFjdGlvbkRlc2NyaXB0b3I8VD4sIHBhcmFtZXRlcnM6IEFjdGlvblBhcmFtZXRlcnM8VD4sIGRhdGFQcm92aWRlcj86IElEYXRhUHJvdmlkZXI8VCwgUz4pOiBBY3Rpb25Db250ZXh0VmFsaWRhdGlvbjxULCBTPiB7XG4gICAgICAgIGNvbnN0IGN0eERhdGFQcm92aWRlciA9IGRhdGFQcm92aWRlciA/PyBhY3Rpb24uZGF0YVByb3ZpZGVyID8/IHBhcmFtZXRlcnMudmlld0NvbnRhaW5lcj8uZ2V0RGF0YVByb3ZpZGVyKCk7XG4gICAgICAgIGNvbnN0IGN0eCA9IG5ldyBBY3Rpb25Db250ZXh0VmFsaWRhdGlvbjxULCBTPihhY3Rpb24sIHBhcmFtZXRlcnMsIGN0eERhdGFQcm92aWRlciwgdGhpcy5nZXREYXRhUHJvdmlkZXJTZXJ2aWNlKGN0eERhdGFQcm92aWRlcikgPz8gdW5kZWZpbmVkKTtcbiAgICAgICAgcmV0dXJuIGN0eDtcbiAgICB9XG5cbiAgICBwdWJsaWMgcHJlcGFyZUFjdGlvbkNvbnRleHQ8VCwgUz4oXG4gICAgICAgIGluc3RhbmNlOiBBY3Rpb25JbnN0YW5jZTxULCBTPixcbiAgICAgICAgcGFyYW1ldGVyczogQWN0aW9uUGFyYW1ldGVyczxUPixcbiAgICAgICAgZGF0YVByb3ZpZGVyPzogSURhdGFQcm92aWRlcjxULCBTPixcbiAgICAgICAgcHJldmlvdXNBY3Rpb25JbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPHVua25vd24sIHVua25vd24+XG4gICAgKTogQWN0aW9uQ29udGV4dDxULCBTPiB7XG4gICAgICAgIGNvbnN0IGN0eERhdGFQcm92aWRlciA9IGRhdGFQcm92aWRlciA/PyBpbnN0YW5jZS5hY3Rpb24uZGF0YVByb3ZpZGVyID8/IHBhcmFtZXRlcnMudmlld0NvbnRhaW5lcj8uZ2V0RGF0YVByb3ZpZGVyKCk7XG4gICAgICAgIGNvbnN0IGN0eCA9IG5ldyBBY3Rpb25Db250ZXh0PFQsIFM+KGluc3RhbmNlLCBwYXJhbWV0ZXJzLCAncnVuJywgY3R4RGF0YVByb3ZpZGVyLCB0aGlzLmdldERhdGFQcm92aWRlclNlcnZpY2UoY3R4RGF0YVByb3ZpZGVyKSA/PyB1bmRlZmluZWQpO1xuICAgICAgICBjdHgucHJldmlvdXNBY3Rpb25JbnN0YW5jZSA9IHByZXZpb3VzQWN0aW9uSW5zdGFuY2U7XG4gICAgICAgIGluc3RhbmNlLm5ld0NvbnRleHQoY3R4KTtcbiAgICAgICAgcmV0dXJuIGN0eDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmVwYXJlcyBhY3Rpb24gZXhlYyBjb250ZXh0IGZvciBhY3Rpb24gb2YgdHlwZSBlZGl0b3IuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaXRlbSBJdGVtIGluc3RhbmNlIChpZiBleGlzdHMpLlxuICAgICAqIEBwYXJhbSBpdGVtSWQgSXRlbSBpZCAoaWYgZXhpc3RzKS5cbiAgICAgKiBAcGFyYW0gZGF0YVByb3ZpZGVyIERhdGEgcHJvdmlkZXIuXG4gICAgICogQHBhcmFtIHNvdXJjZUNvbXBvbmVudCBTb3VyY2UgY29tcG9uZW50IGZyb20gd2hlcmUgdGhlIGNvbnRleHQgcHJlcGFyYXRpb24gd2FzIGNhbGxlZC5cbiAgICAgKiBAcGFyYW0gdmlld0NvbnRhaW5lciBWaWV3IGNvbnRhaW5lci9zZXJ2aWNlLlxuICAgICAqIEBwYXJhbSBhY3Rpb25EYXRhIEFkZGl0aW9uYWwgYWN0aW9uIGRhdGEuXG4gICAgICovXG4gICAgcHJpdmF0ZSBwcmVwYXJlQ29udGV4dEZvckVkaXRvcjxULCBTPihcbiAgICAgICAgaW5zdGFuY2U6IEFjdGlvbkluc3RhbmNlPFQsIFM+LFxuICAgICAgICBwYXJhbWV0ZXJzOiBBY3Rpb25QYXJhbWV0ZXJzPFQ+LFxuICAgICAgICBmdW5jdGlvbk5hbWU6ICdzdWJtaXQnIHwgJ2ZldGNoJyxcbiAgICAgICAgZGF0YVByb3ZpZGVyPzogSUVkaXRvckRhdGFQcm92aWRlcjxULCBTPixcbiAgICAgICAgcHJldmlvdXNBY3Rpb25JbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPHVua25vd24sIHVua25vd24+XG4gICAgKTogQWN0aW9uQ29udGV4dDxULCBTPiB7XG4gICAgICAgIGNvbnN0IGVkaXRvckFjdGlvbiA9IGluc3RhbmNlLmFjdGlvbiBhcyBBY3Rpb25FZGl0b3JEZXNjcmlwdG9yPFQ+O1xuICAgICAgICBsZXQgY3R4RGF0YVByb3ZpZGVyID0gZGF0YVByb3ZpZGVyO1xuICAgICAgICBpZiAoIWN0eERhdGFQcm92aWRlciAmJiBlZGl0b3JBY3Rpb24uZGF0YVByb3ZpZGVyKSB7XG4gICAgICAgICAgICBjdHhEYXRhUHJvdmlkZXIgPSBlZGl0b3JBY3Rpb24uZGF0YVByb3ZpZGVyO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY3R4RGF0YVByb3ZpZGVyKSB7XG4gICAgICAgICAgICBjb25zdCB2aWV3Q29udGFpbmVyRGF0YVByb3ZpZGVyID0gcGFyYW1ldGVycy52aWV3Q29udGFpbmVyPy5nZXREYXRhUHJvdmlkZXIoKTtcbiAgICAgICAgICAgIGlmICh2aWV3Q29udGFpbmVyRGF0YVByb3ZpZGVyKSB7XG4gICAgICAgICAgICAgICAgY3R4RGF0YVByb3ZpZGVyID0gdmlld0NvbnRhaW5lckRhdGFQcm92aWRlciBhcyBJRWRpdG9yRGF0YVByb3ZpZGVyPFQsIFM+O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGN0eCA9IG5ldyBBY3Rpb25Db250ZXh0PFQsIFM+KGluc3RhbmNlLCBwYXJhbWV0ZXJzLCBmdW5jdGlvbk5hbWUsIGN0eERhdGFQcm92aWRlciwgdGhpcy5nZXREYXRhUHJvdmlkZXJTZXJ2aWNlKGN0eERhdGFQcm92aWRlcikgPz8gdW5kZWZpbmVkKTtcbiAgICAgICAgY3R4LnByZXZpb3VzQWN0aW9uSW5zdGFuY2UgPSBwcmV2aW91c0FjdGlvbkluc3RhbmNlO1xuICAgICAgICBpbnN0YW5jZS5uZXdDb250ZXh0KGN0eCk7XG4gICAgICAgIHJldHVybiBjdHg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUnVucyBhY3Rpb24gY29udGV4dCBieSBzdWJtaXR0aW5nIGV4ZWN1dGlvbiByZXN1bHRzL2Vycm9ycyB0byBjb250ZXh0LCB3YXRjaGluZyBvdmVyIGluc3RhbmNlIHJlc3VsdHMvZXJyb3JzLCBkaXNwbGF5aW5nIG5vdGlmaWNhdGlvbnMsXG4gICAgICogcnVubmluZyBuZXh0L2Vycm9yIGFjdGlvbiBhbmQgdHJpZ2dlcmluZyBkaXNtaXNzIG9mIGFjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBhY3Rpb24gQWN0aW9uIGRlc2NyaXB0b3IuXG4gICAgICogQHBhcmFtIHBhcmFtZXRlcnMgQWN0aW9uIHBhcmFtZXRlcnMgZm9yIGNvbnRleHQuXG4gICAgICogQHBhcmFtIGRhdGFQcm92aWRlciBFZGl0b3IgZGF0YSBwcm92aWRlciBmb3IgY29udGV4dC5cbiAgICAgKiBAcGFyYW0gaW5zdGFuY2UgT3B0aW9uYWwgZXhpc3RpbmcgYWN0aW9uIGluc3RhbmNlIChpZiBub24gcHJvdmlkZWQsIG5ldyB3aWxsIGJlIGNyZWF0ZWQpLlxuICAgICAqIEBwYXJhbSBwcmV2aW91c0FjdGlvbkluc3RhbmNlIE9wdGlvbmFsIHByZXZpb3VzIGFjdGlvbiBpbnN0YW5jZSB0byBsaW5rIGluIG5leHQgaW5zdGFuY2UuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIEFjdGlvbiBjb250ZXh0IGZvciBzdWJtaXQgKD1ydW4pIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBydW5BY3Rpb25Db250ZXh0PFQsIFM+KGN0eDogQWN0aW9uQ29udGV4dDxULCBTPik6IE9ic2VydmFibGU8VCB8IG51bGwgfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgY29uc3QgaXNNYWluUnVuRm4gPSBjdHguZnVuY3Rpb25OYW1lID09PSAnc3VibWl0JyB8fCBjdHguZnVuY3Rpb25OYW1lID09PSAncnVuJztcbiAgICAgICAgbGV0IGFjdGlvbkVkaXRvcjogQWN0aW9uRWRpdG9yRGVzY3JpcHRvcjxUPjtcblxuICAgICAgICBsZXQgZm5PYnM6IChjdHg6IEFjdGlvbkNvbnRleHQ8VCwgUz4pID0+IE9ic2VydmFibGU8VCB8IG51bGwgfCB1bmRlZmluZWQ+O1xuICAgICAgICBzd2l0Y2ggKGN0eC5mdW5jdGlvbk5hbWUpIHtcbiAgICAgICAgICAgIGNhc2UgJ3N1Ym1pdCc6XG4gICAgICAgICAgICAgICAgYWN0aW9uRWRpdG9yID0gY3R4Lmluc3RhbmNlLmFjdGlvbiBhcyBBY3Rpb25FZGl0b3JEZXNjcmlwdG9yPFQ+O1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYWN0aW9uRWRpdG9yLnN1Ym1pdEZ1bmN0aW9uICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IG5ldyBFcnJvcihgU3VibWl0IGZ1bmN0aW9uIGZvciBhY3Rpb24gJHthY3Rpb25FZGl0b3IuYWN0aW9uTmFtZUxvbmd9IGNhbm5vdCBiZSBpbnZva2VkLmApKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZm5PYnMgPSBhY3Rpb25FZGl0b3Iuc3VibWl0RnVuY3Rpb247XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdmZXRjaCc6XG4gICAgICAgICAgICAgICAgYWN0aW9uRWRpdG9yID0gY3R4Lmluc3RhbmNlLmFjdGlvbiBhcyBBY3Rpb25FZGl0b3JEZXNjcmlwdG9yPFQ+O1xuICAgICAgICAgICAgICAgIGZuT2JzID0gYWN0aW9uRWRpdG9yLmZldGNoRnVuY3Rpb247XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdydW4nOlxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBmbk9icyA9IGN0eC5pbnN0YW5jZS5hY3Rpb24ucnVuRnVuY3Rpb247XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXRPYnMgPSBvZih2b2lkIDApLnBpcGUoXG4gICAgICAgICAgICBmaXJzdCgpLFxuICAgICAgICAgICAgc3dpdGNoTWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoaXNNYWluUnVuRm4pIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgbWFpbiBydW4gZnVuY3Rpb24sIGFsc28gc2V0IGxvYWRpbmcgdG8gdHJ1ZVxuICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2Uuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5SdW5TdGFydDtcbiAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLmlzUnVuTG9hZGluZ1N1YmplY3QubmV4dCh0cnVlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2Uuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5GZXRjaFN0YXJ0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBzdGFydCBjb250ZXh0IGV4ZWN1dGlvbiB0byBtYXJrIGV4ZWN1dGlvbiBsb2FkaW5nXG4gICAgICAgICAgICAgICAgY3R4LmV4ZWN1dGlvblN0YXJ0KCk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gZm5PYnMoY3R4KTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgbWVyZ2VNYXAocnVuUmVzdWx0ID0+IHtcbiAgICAgICAgICAgICAgICAvLyBzZXQgbmV4dCBzdGF0ZSBkZXBlbmRpbmcgb24gcnVuXG4gICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLnN0YXRlID0gaXNNYWluUnVuRm4gPyBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5SdW5FbmQgOiBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5GZXRjaEVuZDtcbiAgICAgICAgICAgICAgICAvLyBzZXQgZXhlY3V0aW9uIHJlc3VsdFxuICAgICAgICAgICAgICAgIGN0eC5leGVjdXRpb25OZXh0KHJ1blJlc3VsdCwgaXNNYWluUnVuRm4pO1xuXG4gICAgICAgICAgICAgICAgaWYgKGlzTWFpblJ1bkZuKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHNldCBpbnN0YW5jZSBmaW5hbCByZXN1bHQgb24gbWFpbiBydW4gZXhlY3V0aW9uXG4gICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5yZXN1bHQgPSBydW5SZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5pc1J1bkxvYWRpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBub3RpZmljYXRpb25cbiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eC5pbnN0YW5jZS5hY3Rpb24uaGFzUnVuTm90aWZpY2F0aW9uU3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lm5vdGlmaWNhdGlvbiA9IE5vdGlmaWNhdGlvblV0aWwuYWN0aW9uTm90aWZpY2F0aW9uU3VjY2VzcyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyYW5zbGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2UuYWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5mdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLmFjdGlvbi5ydW5Ob3RpZmljYXRpb25TdWNjZXNzVGl0bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLmFjdGlvbi5ydW5Ob3RpZmljYXRpb25TdWNjZXNzTWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgucGFyYW1ldGVycy52aWV3Q29udGFpbmVyID8/IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgucGFyYW1ldGVycz8uaXRlbVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBwb3NzaWJsZSBhZnRlciBydW4gYWN0aW9uXG4gICAgICAgICAgICAgICAgICAgIGlmIChjdHguaW5zdGFuY2UuYWN0aW9uLmFmdGVyUnVuQWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBtYXJrIG5ldyBzdGF0ZSBmb3IgbmV4dCBhY3Rpb24gc3RhcnRcbiAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5zdGF0ZSA9IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLk5leHRBY3Rpb25TdGFydDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5leHRBY3Rpb25JbnN0YW5jZSA9IHRoaXMuYWN0aXZhdGVBY3Rpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLmFjdGlvbi5hZnRlclJ1bkFjdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQWN0aW9uUGFyYW1ldGVyczx1bmtub3duPihjdHgucGFyYW1ldGVycy5pdGVtSWQsIHJ1blJlc3VsdClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndpdGhBY3Rpb25EYXRhKGN0eC5wYXJhbWV0ZXJzLmFjdGlvbkRhdGEpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC53aXRoUm91dGUoY3R4LnBhcmFtZXRlcnMucm91dGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC53aXRoU291cmNlQ29tcG9uZW50KGN0eC5wYXJhbWV0ZXJzLnNvdXJjZUNvbXBvbmVudClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndpdGhWaWV3Q29udGFpbmVyKGN0eC5wYXJhbWV0ZXJzLnZpZXdDb250YWluZXIgYXMgSVZpZXdDb250YWluZXI8dW5rbm93biwgdW5rbm93bj4pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2UgYXMgQWN0aW9uSW5zdGFuY2U8dW5rbm93biwgdW5rbm93bj5cbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2UubmV4dEFjdGlvbkluc3RhbmNlID0gbmV4dEFjdGlvbkluc3RhbmNlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBmaW5pc2ggY3VycmVudCBhY3Rpb24gd2hlbiBuZXh0IGFjdGlvbiBmaW5pc2hlc1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5leHRBY3Rpb25JbnN0YW5jZS5zdGF0ZSQucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoc3RhdGUgPT4gc3RhdGUgPj0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uRmluaXNoU3VjY2VzcyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLnN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uTmV4dEFjdGlvbkVuZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJ1blJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBvZihydW5SZXN1bHQpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBtYXAocnVuUmVzdWx0ID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoaXNNYWluUnVuRm4pIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZGVhY3RpdmF0ZSBhY3Rpb25cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWFjdGl2YXRlQWN0aW9uKGN0eC5pbnN0YW5jZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBydW5SZXN1bHQ7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGNhdGNoRXJyb3IoZXJyID0+IHtcbiAgICAgICAgICAgICAgICAvLyB0cmFuc2Zvcm0gZXJyb3IgdG8gbW5nIGFjdGlvbiBlcnJvclxuICAgICAgICAgICAgICAgIGNvbnN0IGFjdGlvbkVycm9yID0gdGhpcy50b01uZ0FjdGlvbkVycm9yKGVycik7XG5cbiAgICAgICAgICAgICAgICAvLyBzZXQgaW5zdGFuY2Ugc3RhdGUgdG8gZXJyb3JcbiAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2Uuc3RhdGUgPSBpc01haW5SdW5GbiA/IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLlJ1bkVycm9yIDogQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uRmV0Y2hFcnJvcjtcbiAgICAgICAgICAgICAgICAvLyBtYXJrIGV4ZWN1dGlvbiBlcnJvciBvbiBjb250ZXh0XG4gICAgICAgICAgICAgICAgY3R4LmV4ZWN1dGlvbkVycm9yKGFjdGlvbkVycm9yKTtcblxuICAgICAgICAgICAgICAgIGxldCBlcnJvck9icyA9IG9mKHZvaWQgMCk7XG4gICAgICAgICAgICAgICAgaWYgKGlzTWFpblJ1bkZuKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5lcnJvciA9IGVycjtcbiAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLmlzUnVuTG9hZGluZ1N1YmplY3QubmV4dChmYWxzZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxlIGVycm9yIG5vdGlmaWNhdGlvblxuICAgICAgICAgICAgICAgICAgICBpZiAoY3R4Lmluc3RhbmNlLmFjdGlvbi5oYXNSdW5Ob3RpZmljYXRpb25FcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uRXJyb3Iubm90aWZpY2F0aW9uID0gTm90aWZpY2F0aW9uVXRpbC5hY3Rpb25Ob3RpZmljYXRpb25FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyYW5zbGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2UuYWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbkVycm9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5mdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LnBhcmFtZXRlcnMudmlld0NvbnRhaW5lciA/PyB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LnBhcmFtZXRlcnMuaXRlbVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBwb3NzaWJsZSBlcnJvciBhY3Rpb24gaWYgcnVuXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc01haW5SdW5GbiAmJiBjdHguaW5zdGFuY2UuYWN0aW9uLm9uUnVuRXJyb3JBY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbm5vdCBzdGFydCB3aXRoIHRyaWdnZXIsIGJlY2F1c2Ugcm91dGluZyBtaWdodCBiZSBwcm9ibGVtYXRpYyAobG91c2luZyBwcmV2aW91cyByZXN1bHRzIGV0Yy4pXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvckFjdGlvbkluc3RhbmNlID0gdGhpcy5hY3RpdmF0ZUFjdGlvbihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2UuYWN0aW9uLm9uUnVuRXJyb3JBY3Rpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEFjdGlvblBhcmFtZXRlcnM8VD4oY3R4LnBhcmFtZXRlcnMuaXRlbUlkLCBjdHgucGFyYW1ldGVycy5pdGVtKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAud2l0aEFjdGlvbkRhdGEoY3R4LnBhcmFtZXRlcnMuYWN0aW9uRGF0YSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndpdGhSb3V0ZShjdHgucGFyYW1ldGVycy5yb3V0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndpdGhTb3VyY2VDb21wb25lbnQoY3R4LnBhcmFtZXRlcnMuc291cmNlQ29tcG9uZW50KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAud2l0aFZpZXdDb250YWluZXIoY3R4LnBhcmFtZXRlcnMudmlld0NvbnRhaW5lcilcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2UuZXJyb3JBY3Rpb25JbnN0YW5jZSA9IGVycm9yQWN0aW9uSW5zdGFuY2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck9icyA9IGVycm9yQWN0aW9uSW5zdGFuY2Uuc3RhdGUkLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHN0YXRlID0+IHN0YXRlID49IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkZpbmlzaFN1Y2Nlc3MpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcCgoKSA9PiB2b2lkIDApXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gbGlzdGUgYW5kIG1hcCBvbmx5IHRvIG1hcmsgaW5zdGFuY2Ugc3RhdGUgYXMgZmluaXNoZWQgZXJyb3Igc3RhdGVcbiAgICAgICAgICAgICAgICByZXR1cm4gZXJyb3JPYnMucGlwZShcbiAgICAgICAgICAgICAgICAgICAgbWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlYWN0aXZhdGUgYWN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlYWN0aXZhdGVBY3Rpb24oY3R4Lmluc3RhbmNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJldGhyb3cgZXJyb3IgdG8gcHJvcGFnYXRlIGZ1cmhlclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgYWN0aW9uRXJyb3I7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0T2JzLnN1YnNjcmliZSh7XG4gICAgICAgICAgICBuZXh0OiByZXMgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoYEFjdGlvbkNvbnRleHQgJHtjdHguY29udGV4dExvbmdOYW1lfSBleGVjdXRpb24gbmV4dCBldmVudGAsIHJlcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVycm9yOiBlcnIgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoYEFjdGlvbkNvbnRleHQgJHtjdHguY29udGV4dExvbmdOYW1lfSBleGVjdXRpb24gZXJyb3IgZXZlbnRgLCBlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHJldE9icztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSdW5zIGVkaXRvciBhY3Rpb24ncyBzdWJtaXQgKD1tYWluIHJ1bikgZnVuY3Rpb24gYnkgY3JlYXRpbmcgbmV3IGFjdGlvbiBjb250ZXh0IGZvciBhY3Rpb24gaW5zdGFuY2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uIEFjdGlvbiBkZXNjcmlwdG9yLlxuICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJzIEFjdGlvbiBwYXJhbWV0ZXJzIGZvciBjb250ZXh0LlxuICAgICAqIEBwYXJhbSBkYXRhUHJvdmlkZXIgRWRpdG9yIGRhdGEgcHJvdmlkZXIgZm9yIGNvbnRleHQuXG4gICAgICogQHBhcmFtIGluc3RhbmNlIE9wdGlvbmFsIGV4aXN0aW5nIGFjdGlvbiBpbnN0YW5jZSAoaWYgbm9uIHByb3ZpZGVkLCBuZXcgd2lsbCBiZSBjcmVhdGVkKS5cbiAgICAgKiBAcGFyYW0gcHJldmlvdXNBY3Rpb25JbnN0YW5jZSBPcHRpb25hbCBwcmV2aW91cyBhY3Rpb24gaW5zdGFuY2UgdG8gbGluayBpbiBuZXh0IGluc3RhbmNlLlxuICAgICAqXG4gICAgICogQHJldHVybiBBY3Rpb24gY29udGV4dCBmb3Igc3VibWl0ICg9cnVuKSBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgcnVuRWRpdG9yU2F2ZTxULCBTPihcbiAgICAgICAgYWN0aW9uOiBBY3Rpb25FZGl0b3JEZXNjcmlwdG9yPFQ+LFxuICAgICAgICBwYXJhbWV0ZXJzOiBBY3Rpb25QYXJhbWV0ZXJzPFQ+LFxuICAgICAgICBkYXRhUHJvdmlkZXI/OiBJRWRpdG9yRGF0YVByb3ZpZGVyPFQsIFM+LFxuICAgICAgICBpbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPFQsIFM+LFxuICAgICAgICBwcmV2aW91c0FjdGlvbkluc3RhbmNlPzogQWN0aW9uSW5zdGFuY2U8dW5rbm93biwgdW5rbm93bj5cbiAgICApOiBBY3Rpb25Db250ZXh0PFQsIFM+IHtcbiAgICAgICAgaWYgKCFpbnN0YW5jZSkge1xuICAgICAgICAgICAgLy8gY3JlYXRlIG5ldyBpbnN0YW5jZSBpZiBub24gcHJvdmlkZWRcbiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IEFjdGlvbkluc3RhbmNlPFQsIFM+KGFjdGlvbiwgQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uQWN0aXZhdGlvbkVuZCwgdGhpcy5kZWJ1Zyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMucHJlcGFyZUNvbnRleHRGb3JFZGl0b3IoaW5zdGFuY2UsIHBhcmFtZXRlcnMsICdzdWJtaXQnLCBkYXRhUHJvdmlkZXIsIHByZXZpb3VzQWN0aW9uSW5zdGFuY2UpO1xuICAgICAgICB0aGlzLnJ1bkFjdGlvbkNvbnRleHQoY29udGV4dCk7XG4gICAgICAgIHJldHVybiBjb250ZXh0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgc2VydmljZSBpbnN0YW5jZSBvZiBkYXRhIHByb3ZpZGVyLlxuICAgICAqXG4gICAgICogQHBhcmFtIGRhdGFQcm92aWRlciBEYXRhIHByb3ZpZGVyIGluc3RhbmNlLlxuICAgICAqL1xuICAgIHByaXZhdGUgZ2V0RGF0YVByb3ZpZGVyU2VydmljZTxULCBTPihkYXRhUHJvdmlkZXI/OiBJRGF0YVByb3ZpZGVyPFQsIFM+KTogUyB8IG51bGwge1xuICAgICAgICBpZiAoZGF0YVByb3ZpZGVyPy5zZXJ2aWNlVHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5qZWN0b3IuZ2V0PFM+KGRhdGFQcm92aWRlci5zZXJ2aWNlVHlwZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJ1bnMgZWRpdG9yIGFjdGlvbidzIGZldGNoIGZ1bmN0aW9uIGJ5IGNyZWF0aW5nIG5ldyBhY3Rpb24gY29udGV4dCBmb3IgYWN0aW9uIGluc3RhbmNlLlxuICAgICAqXG4gICAgICogQHBhcmFtIGFjdGlvbiBBY3Rpb24gZGVzY3JpcHRvci5cbiAgICAgKiBAcGFyYW0gcGFyYW1ldGVycyBBY3Rpb24gcGFyYW1ldGVycyBmb3IgY29udGV4dC5cbiAgICAgKiBAcGFyYW0gZGF0YVByb3ZpZGVyIEVkaXRvciBkYXRhIHByb3ZpZGVyIGZvciBjb250ZXh0LlxuICAgICAqIEBwYXJhbSBpbnN0YW5jZSBPcHRpb25hbCBleGlzdGluZyBhY3Rpb24gaW5zdGFuY2UgKGlmIG5vbiBwcm92aWRlZCwgbmV3IHdpbGwgYmUgY3JlYXRlZCkuXG4gICAgICogQHBhcmFtIHByZXZpb3VzQWN0aW9uSW5zdGFuY2UgT3B0aW9uYWwgcHJldmlvdXMgYWN0aW9uIGluc3RhbmNlIHRvIGxpbmsgaW4gbmV4dCBpbnN0YW5jZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm4gQWN0aW9uIGNvbnRleHQgZm9yIGZldGNoIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBydW5FZGl0b3JGZXRjaDxULCBTPihcbiAgICAgICAgYWN0aW9uOiBBY3Rpb25FZGl0b3JEZXNjcmlwdG9yPFQ+LFxuICAgICAgICBwYXJhbWV0ZXJzOiBBY3Rpb25QYXJhbWV0ZXJzPFQ+LFxuICAgICAgICBkYXRhUHJvdmlkZXI/OiBJRWRpdG9yRGF0YVByb3ZpZGVyPFQsIFM+LFxuICAgICAgICBpbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPFQsIFM+LFxuICAgICAgICBwcmV2aW91c0FjdGlvbkluc3RhbmNlPzogQWN0aW9uSW5zdGFuY2U8dW5rbm93biwgdW5rbm93bj5cbiAgICApOiBBY3Rpb25Db250ZXh0PFQsIFM+IHtcbiAgICAgICAgaWYgKCFpbnN0YW5jZSkge1xuICAgICAgICAgICAgLy8gY3JlYXRlIG5ldyBpbnN0YW5jZSBpZiBub24gcHJvdmlkZWRcbiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IEFjdGlvbkluc3RhbmNlPFQsIFM+KGFjdGlvbiwgQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uQWN0aXZhdGlvbkVuZCwgdGhpcy5kZWJ1Zyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMucHJlcGFyZUNvbnRleHRGb3JFZGl0b3IoaW5zdGFuY2UsIHBhcmFtZXRlcnMsICdmZXRjaCcsIGRhdGFQcm92aWRlciwgcHJldmlvdXNBY3Rpb25JbnN0YW5jZSk7XG4gICAgICAgIHRoaXMucnVuQWN0aW9uQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUnVucyBhY3Rpb24ncyBtYWluIHJ1biBmdW5jdGlvbiBieSBjcmVhdGluZyBuZXcgYWN0aW9uIGNvbnRleHQgZm9yIGFjdGlvbiBpbnN0YW5jZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBhY3Rpb24gQWN0aW9uIGRlc2NyaXB0b3IuXG4gICAgICogQHBhcmFtIHBhcmFtZXRlcnMgQWN0aW9uIHBhcmFtZXRlcnMgZm9yIGNvbnRleHQgcnVuLlxuICAgICAqIEBwYXJhbSBkYXRhUHJvdmlkZXIgRGF0YSBwcm92aWRlciBmb3IgY29udGV4dCBydW4uXG4gICAgICogQHBhcmFtIGluc3RhbmNlIE9wdGlvbmFsIGV4aXN0aW5nIGFjdGlvbiBpbnN0YW5jZSAoaWYgbm9uIHByb3ZpZGVkLCBuZXcgd2lsbCBiZSBjcmVhdGVkKS5cbiAgICAgKiBAcGFyYW0gcHJldmlvdXNBY3Rpb25JbnN0YW5jZSBPcHRpb25hbCBwcmV2aW91cyBhY3Rpb24gaW5zdGFuY2UgdG8gbGluayBpbiBuZXh0IGluc3RhbmNlLlxuICAgICAqXG4gICAgICogQHJldHVybiBBY3Rpb24gY29udGV4dCBmb3IgcnVuIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBydW5BY3Rpb248VCwgUz4oXG4gICAgICAgIGFjdGlvbjogQWN0aW9uRGVzY3JpcHRvcjxUPixcbiAgICAgICAgcGFyYW1ldGVyczogQWN0aW9uUGFyYW1ldGVyczxUPixcbiAgICAgICAgZGF0YVByb3ZpZGVyPzogSURhdGFQcm92aWRlcjxULCBTPixcbiAgICAgICAgaW5zdGFuY2U/OiBBY3Rpb25JbnN0YW5jZTxULCBTPixcbiAgICAgICAgcHJldmlvdXNBY3Rpb25JbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPHVua25vd24sIHVua25vd24+XG4gICAgKTogQWN0aW9uQ29udGV4dDxULCBTPiB7XG4gICAgICAgIGlmICghaW5zdGFuY2UpIHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBuZXcgaW5zdGFuY2UgaWYgbm9uIHByb3ZpZGVkXG4gICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBBY3Rpb25JbnN0YW5jZTxULCBTPihhY3Rpb24sIEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkFjdGl2YXRpb25FbmQsIHRoaXMuZGVidWcpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLnByZXBhcmVBY3Rpb25Db250ZXh0KGluc3RhbmNlLCBwYXJhbWV0ZXJzLCBkYXRhUHJvdmlkZXIsIHByZXZpb3VzQWN0aW9uSW5zdGFuY2UpO1xuICAgICAgICBpZiAoYWN0aW9uLmhhc1J1bkNvbmZpcm1hdGlvbikge1xuICAgICAgICAgICAgY29uc3Qgc291cmNlQ29tcG9uZW50ID0gcGFyYW1ldGVycz8uc291cmNlQ29tcG9uZW50O1xuICAgICAgICAgICAgY29uc3QgY29uZmlybWF0aW9uRGVzY3JpcHRvciA9IGFjdGlvbi5ydW5Db25maXJtYXRpb25EaWFsb2dEZXNjcmlwdG9yIGFzIEFjdGlvbkNvbmZpcm1hdGlvbkRpYWxvZ0Rlc2NyaXB0b3I8VD47XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc291cmNlQ29tcG9uZW50Py5nZXRDb25maXJtYXRpb25TZXJ2aWNlICE9PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBzb3VyY2VDb21wb25lbnQ/LmdldENvbmZpcm1hdGlvblNlcnZpY2VJbnN0YW5jZUtleSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU291cmNlIGNvbXBvbmVudCAke3NvdXJjZUNvbXBvbmVudH0gc2hvdWxkIGJlIGltcGxlbWVudGluZyBJQ29uZmlybWF0aW9uU2VydmljZSBpbnRlcmZhY2UgdG8gYmUgYWJsZSB0byBwcm92aWRlIGNvbmZpcm1hdGlvbiBmdW5jdGlvbmFsaXR5LmApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBpdGVtID0gcGFyYW1ldGVycy5pdGVtO1xuXG4gICAgICAgICAgICBjb25zdCBzcmNDb25maXJtQ29tcG9uZW50ID0gc291cmNlQ29tcG9uZW50IGFzIElBY3Rpb25Db25maXJtYXRpb25TZXJ2aWNlO1xuICAgICAgICAgICAgbGV0IGNvbmZpcm1QYXJhbXM6IENvbmZpcm1hdGlvbiA9IHtcbiAgICAgICAgICAgICAgICBrZXk6IHNyY0NvbmZpcm1Db21wb25lbnQuZ2V0Q29uZmlybWF0aW9uU2VydmljZUluc3RhbmNlS2V5KGFjdGlvbiksXG4gICAgICAgICAgICAgICAgaWNvbjogY29uZmlybWF0aW9uRGVzY3JpcHRvci5pY29uLFxuICAgICAgICAgICAgICAgIGFjY2VwdFZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgYWNjZXB0SWNvbjogY29uZmlybWF0aW9uRGVzY3JpcHRvci5hY2NlcHRCdXR0b24uaWNvbiA/PyB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgYWNjZXB0QnV0dG9uU3R5bGVDbGFzczogY29uZmlybWF0aW9uRGVzY3JpcHRvci5hY2NlcHRCdXR0b24uc3R5bGVDbGFzcy5idWlsZCgpLFxuICAgICAgICAgICAgICAgIHJlamVjdFZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgcmVqZWN0SWNvbjogY29uZmlybWF0aW9uRGVzY3JpcHRvci5yZWplY3RCdXR0b24/Lmljb24gPz8gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIHJlamVjdEJ1dHRvblN0eWxlQ2xhc3M6IGNvbmZpcm1hdGlvbkRlc2NyaXB0b3IucmVqZWN0QnV0dG9uPy5zdHlsZUNsYXNzLmJ1aWxkKCksXG4gICAgICAgICAgICAgICAgY2xvc2VPbkVzY2FwZTogY29uZmlybWF0aW9uRGVzY3JpcHRvci5jbG9zZU9uRXNjYXBlXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAoY29uZmlybWF0aW9uRGVzY3JpcHRvci50aXRsZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbmZpcm1QYXJhbXMuaGVhZGVyID0gSTE4blV0aWxzLkFjdGlvbi5nZXQodGhpcy50cmFuc2xhdGUsIGFjdGlvbiwgJ2NvbmZpcm0udGl0bGUnLCBjb25maXJtYXRpb25EZXNjcmlwdG9yLnRpdGxlLCBpdGVtLCAnZ2VuZXJhbC5jb25maXJtYXRpb24nKSA/PyB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb25maXJtYXRpb25EZXNjcmlwdG9yLm1lc3NhZ2UgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25maXJtUGFyYW1zLm1lc3NhZ2UgPVxuICAgICAgICAgICAgICAgICAgICBJMThuVXRpbHMuQWN0aW9uLmdldCh0aGlzLnRyYW5zbGF0ZSwgYWN0aW9uLCAnY29uZmlybS5tZXNzYWdlJywgY29uZmlybWF0aW9uRGVzY3JpcHRvci5tZXNzYWdlLCBTdHJpbmdVdGlsLmVzY2FwZUh0bWxBbnkoaXRlbSksICdnZW5lcmFsLmNvbmZpcm1hdGlvbicpID8/XG4gICAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbmZpcm1hdGlvbkRlc2NyaXB0b3IuYWNjZXB0QnV0dG9uLmxhYmVsICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uZmlybVBhcmFtcy5hY2NlcHRMYWJlbCA9XG4gICAgICAgICAgICAgICAgICAgIEkxOG5VdGlscy5BY3Rpb24uZ2V0KHRoaXMudHJhbnNsYXRlLCBhY3Rpb24sICdjb25maXJtLmFjY2VwdCcsIGNvbmZpcm1hdGlvbkRlc2NyaXB0b3IuYWNjZXB0QnV0dG9uLmxhYmVsLCBpdGVtLCAnZ2VuZXJhbC55ZXMnKSA/PyB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb25maXJtYXRpb25EZXNjcmlwdG9yLmFjY2VwdEJ1dHRvbi5pY29uICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uZmlybVBhcmFtcy5hY2NlcHRJY29uID0gY29uZmlybWF0aW9uRGVzY3JpcHRvci5hY2NlcHRCdXR0b24uaWNvbjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbmZpcm1hdGlvbkRlc2NyaXB0b3IucmVqZWN0QnV0dG9uPy5pY29uICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uZmlybVBhcmFtcy5yZWplY3RJY29uID0gY29uZmlybWF0aW9uRGVzY3JpcHRvci5yZWplY3RCdXR0b24/Lmljb247XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb25maXJtYXRpb25EZXNjcmlwdG9yLnJlamVjdEJ1dHRvbj8ubGFiZWwgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25maXJtUGFyYW1zLnJlamVjdExhYmVsID1cbiAgICAgICAgICAgICAgICAgICAgSTE4blV0aWxzLkFjdGlvbi5nZXQodGhpcy50cmFuc2xhdGUsIGFjdGlvbiwgJ2NvbmZpcm0ucmVqZWN0JywgY29uZmlybWF0aW9uRGVzY3JpcHRvci5yZWplY3RCdXR0b24/LmxhYmVsLCBpdGVtLCAnZ2VuZXJhbC5ubycpID8/IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbmZpcm1hdGlvbkRlc2NyaXB0b3IucmVqZWN0QnV0dG9uID09IG51bGwgfHwgKGNvbmZpcm1hdGlvbkRlc2NyaXB0b3IucmVqZWN0QnV0dG9uLmxhYmVsID09PSBudWxsICYmIGNvbmZpcm1hdGlvbkRlc2NyaXB0b3IucmVqZWN0QnV0dG9uLmljb24gPT09IG51bGwpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlybVBhcmFtcy5yZWplY3RWaXNpYmxlID0gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbmZpcm1QYXJhbXMuYWNjZXB0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGluc3RhbmNlIS5zdGF0ZSA9IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLlJ1bkNvbmZpcm1hdGlvbkVuZEFjY2VwdDtcbiAgICAgICAgICAgICAgICB0aGlzLnJ1bkFjdGlvbkNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25maXJtUGFyYW1zLnJlamVjdCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZSEuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5SdW5Db25maXJtYXRpb25FbmRSZWplY3Q7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWFjdGl2YXRlQWN0aW9uKGluc3RhbmNlISk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAoY29uZmlybWF0aW9uRGVzY3JpcHRvci5ydW5Db25maXJtYXRpb25Db25maWdNYXBGbikge1xuICAgICAgICAgICAgICAgIGNvbmZpcm1QYXJhbXMgPSBjb25maXJtYXRpb25EZXNjcmlwdG9yLnJ1bkNvbmZpcm1hdGlvbkNvbmZpZ01hcEZuKGNvbnRleHQsIGNvbmZpcm1QYXJhbXMpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb250ZXh0LmNvbmZpcm1hdGlvbiA9IGNvbmZpcm1QYXJhbXM7XG4gICAgICAgICAgICBpbnN0YW5jZS5zdGF0ZSA9IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLlJ1bkNvbmZpcm1hdGlvblN0YXJ0O1xuXG4gICAgICAgICAgICBzcmNDb25maXJtQ29tcG9uZW50LmdldENvbmZpcm1hdGlvblNlcnZpY2UoKS5jb25maXJtKGNvbmZpcm1QYXJhbXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5ydW5BY3Rpb25Db250ZXh0KGNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb250ZXh0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFjdGl2YXRlcyBhY3Rpb24gKGluIGNhc2Ugb2YgZGlhbG9nLCBkaWFsb2cgd2lsbCBiZSBvcGVuZWQpLlxuICAgICAqXG4gICAgICogQHBhcmFtIGFjdGlvbiBBY3Rpb24gZGVzY3JpcHRvci5cbiAgICAgKiBAcGFyYW0gcGFyYW1ldGVycyBBY3Rpb24gcGFyYW1ldGVycyBmb3IgYWN0aXZhdGlvbiBvZiBhY3Rpb24gaW5zdGFuY2UuXG4gICAgICogQHBhcmFtIGluc3RhbmNlIE9wdGlvbmFsIGV4aXN0aW5nIGFjdGlvbiBpbnN0YW5jZSAoaWYgbm9uIHByb3ZpZGVkLCBuZXcgd2lsbCBiZSBjcmVhdGVkKS5cbiAgICAgKiBAcGFyYW0gcHJldmlvdXNBY3Rpb25JbnN0YW5jZSBPcHRpb25hbCBwcmV2aW91cyBhY3Rpb24gaW5zdGFuY2UgdG8gbGluayBpbiBuZXh0IGluc3RhbmNlLlxuICAgICAqXG4gICAgICogQHJldHVybiBBY3Rpb24gaW5zdGFuY2UgLSBpZiBub24gcHJvdmlkZWQgaW4gcGFyYW1ldGVycywgdGhlIG5ld2x5IGNyZWF0ZWQgd2lsbCBiZSByZXR1cm5lZC5cbiAgICAgKi9cbiAgICBwdWJsaWMgYWN0aXZhdGVBY3Rpb248VCwgUz4oXG4gICAgICAgIGFjdGlvbjogQWN0aW9uRGVzY3JpcHRvcjxUPixcbiAgICAgICAgcGFyYW1ldGVyczogQWN0aW9uUGFyYW1ldGVyczxUPixcbiAgICAgICAgaW5zdGFuY2U/OiBBY3Rpb25JbnN0YW5jZTxULCBTPixcbiAgICAgICAgcHJldmlvdXNBY3Rpb25JbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPHVua25vd24sIHVua25vd24+XG4gICAgKTogQWN0aW9uSW5zdGFuY2U8VCwgUz4ge1xuICAgICAgICBpZiAoIWluc3RhbmNlKSB7XG4gICAgICAgICAgICAvLyBjcmVhdGUgbmV3IGluc3RhbmNlIGlmIG5vbiBwcm92aWRlZFxuICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgQWN0aW9uSW5zdGFuY2U8VCwgUz4oYWN0aW9uLCBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5BY3RpdmF0aW9uU3RhcnQsIHRoaXMuZGVidWcpO1xuICAgICAgICB9XG4gICAgICAgIGluc3RhbmNlLmFjdGl2YXRpb25QYXJhbWV0ZXJzID0gcGFyYW1ldGVycztcbiAgICAgICAgLy8gc3RhcnQgYWN0aXZhdGlvbiBpbnN0YW5jZVxuICAgICAgICBpbnN0YW5jZS5zdGF0ZSA9IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkFjdGl2YXRpb25TdGFydDtcbiAgICAgICAgaWYgKGFjdGlvbi50eXBlID09PSBBY3Rpb25UeXBlRW51bS5FZGl0b3IpIHtcbiAgICAgICAgICAgIGxldCBkaWFsb2dDb21wb25lbnQgPSB0aGlzLmRlZmF1bHRFZGl0b3JEaWFsb2dDb21wb25lbnQ7XG4gICAgICAgICAgICBjb25zdCBkaWFsb2dDbGFzc05hbWVzID0gWydtbmctZGlhbG9nJ107XG4gICAgICAgICAgICBpZiAoYWN0aW9uIGluc3RhbmNlb2YgQWN0aW9uRWRpdG9yRGVzY3JpcHRvcikge1xuICAgICAgICAgICAgICAgIGRpYWxvZ0NsYXNzTmFtZXMucHVzaChhY3Rpb24uZGlhbG9nQ2xhc3NOYW1lID8/ICdtbmctYWN0aW9uLWVkaXRvci1kaWFsb2cnKTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGFjdGlvbi5kaWFsb2dTaXplKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgU3R5bGVTaXplRW51bS5FeHRyYVNtYWxsOlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nQ2xhc3NOYW1lcy5wdXNoKCdtbmctZGlhbG9nLXhzJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBTdHlsZVNpemVFbnVtLlNtYWxsOlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nQ2xhc3NOYW1lcy5wdXNoKCdtbmctZGlhbG9nLXNtJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBTdHlsZVNpemVFbnVtLkxhcmdlOlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nQ2xhc3NOYW1lcy5wdXNoKCdtbmctZGlhbG9nLWxnJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBTdHlsZVNpemVFbnVtLkV4dHJhTGFyZ2U6XG4gICAgICAgICAgICAgICAgICAgICAgICBkaWFsb2dDbGFzc05hbWVzLnB1c2goJ21uZy1kaWFsb2cteGwnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFN0eWxlU2l6ZUVudW0uTm9ybWFsOlxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChhY3Rpb24uZWRpdG9yQ29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGRpYWxvZ0NvbXBvbmVudCA9IGFjdGlvbi5lZGl0b3JDb21wb25lbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgZGlhbG9nQ29uZmlnOiBEeW5hbWljRGlhbG9nQ29uZmlnID0ge1xuICAgICAgICAgICAgICAgIGRhdGE6IHt9LFxuICAgICAgICAgICAgICAgIHN0eWxlQ2xhc3M6IGRpYWxvZ0NsYXNzTmFtZXMuam9pbignICcpXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZGlhbG9nQ29uZmlnLmRhdGEuYWN0aW9uSW5zdGFuY2UgPSBpbnN0YW5jZTtcbiAgICAgICAgICAgIGRpYWxvZ0NvbmZpZy5kYXRhLnByZXZpb3VzQWN0aW9uSW5zdGFuY2UgPSBwcmV2aW91c0FjdGlvbkluc3RhbmNlO1xuICAgICAgICAgICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2dTZXJ2aWNlLm9wZW4oZGlhbG9nQ29tcG9uZW50LCBkaWFsb2dDb25maWcpO1xuICAgICAgICAgICAgZGlhbG9nUmVmLm9uQ2xvc2UucGlwZShmaXJzdCgpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVhY3RpdmF0ZUFjdGlvbihpbnN0YW5jZSEsIHRydWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpbnN0YW5jZS5hY3RpdmF0aW9uRGlhbG9nUmVmID0gZGlhbG9nUmVmO1xuICAgICAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gZGlyZWN0bHkgZXhlY3V0ZSBhY3Rpb25cbiAgICAgICAgICAgIGluc3RhbmNlLnN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uQWN0aXZhdGlvbkVuZDtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLnJ1bkFjdGlvbjxULCBTPihhY3Rpb24sIHBhcmFtZXRlcnMsIHVuZGVmaW5lZCwgaW5zdGFuY2UsIHByZXZpb3VzQWN0aW9uSW5zdGFuY2UpO1xuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuaW5zdGFuY2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWFjdGl2YXRlcyBhY3Rpb24gYnkgY2hvb3NpbmcgZmluYWwgc3RhdGUsIGNsb3NpbmcgZGlhbG9nIGFuZCBjb21wbGV0aW5nIGFsbCBzdWJqZWN0cyBpbiBpbnN0YW5jZSBhbmQgY29udGV4dHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zdGFuY2UgQWN0aW9uIGluc3RhbmNlLlxuICAgICAqIEBwYXJhbSBmcm9tRGlhbG9nTGlzdGVuZXIgRGVhY3RpdmF0aW9uIGNhbGxlZCBmcm9tIGRpYWxvZyBsaXN0ZW5lciwgaW4gdGhpcyBjYXNlIGRlYWN0aXZhdGlvbiBoYXBwZW5zIG9ubHkgaWYgdHJ1ZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgZGVhY3RpdmF0ZUFjdGlvbjxULCBTPihpbnN0YW5jZTogQWN0aW9uSW5zdGFuY2U8VCwgUz4sIGZyb21EaWFsb2dMaXN0ZW5lciA9IGZhbHNlKSB7XG4gICAgICAgIGlmICghZnJvbURpYWxvZ0xpc3RlbmVyICYmIGluc3RhbmNlLnN0YXRlID49IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkZpbmlzaFN1Y2Nlc3MpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhgQWN0aW9uSW5zdGFuY2UgJHtpbnN0YW5jZS5pbnN0YW5jZUxvbmdOYW1lfSBhbHJlYWR5IGZpbmlzaGVkYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgZmluYWxTdGF0ZTogQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW07XG4gICAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UucmVzdWx0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgZmluYWxTdGF0ZSA9IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkZpbmlzaFN1Y2Nlc3M7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmVycm9yICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgZmluYWxTdGF0ZSA9IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkZpbmlzaEVycm9yO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmluYWxTdGF0ZSA9IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkZpbmlzaERpc21pc3NlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbnN0YW5jZS5hY3Rpb24udHlwZSA9PT0gQWN0aW9uVHlwZUVudW0uRWRpdG9yKSB7XG4gICAgICAgICAgICBjb25zdCBoYXNEaWFsb2cgPSB0eXBlb2YgaW5zdGFuY2UuYWN0aXZhdGlvbkRpYWxvZ1JlZiAhPT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgICAgICBpZiAoaGFzRGlhbG9nICYmICFmcm9tRGlhbG9nTGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZmluYWxTdGF0ZSA9PT0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uRmluaXNoU3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICAvLyBpZiBzdGF0ZSBpcyBmaW5pc2ggYW5kIG5vdCBjYWxsZWQgZnJvbSBkaWFsb2cgbGlzdGVuZXIsIGNsb3NlIHRoZSBkaWFsb2cgZmlyc3Qgd2hpY2ggd2lsbCByZXRyaWdnZXIgdGhpcyBmdW5jdGlvbiwgdGhlbiBmaW5pc2ggaXRcbiAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UuYWN0aXZhdGlvbkRpYWxvZ1JlZiEuY2xvc2UoaW5zdGFuY2UucmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gZXJyb3IgYW5kIGRpc21pc3NlZCBtdXN0IGJvdGggaGF2ZSBmcm9tRGlhbG9nTGlzdGVuZXIgdG8gYmUgYWJsZSB0byBmaW5pc2hcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzZXQgZmluYWwgc3RhdGUgb24gaW5zdGFuY2VcbiAgICAgICAgaW5zdGFuY2Uuc3RhdGUgPSBmaW5hbFN0YXRlO1xuICAgICAgICAvLyBjb21wbGV0ZSBhbGwgc3ViamVjdHNcbiAgICAgICAgaW5zdGFuY2UuZmluaXNoKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJpZ2dlcnMgYWN0aW9uIGZyb20gdGFibGUgcm93IGNsaWNrIHBvc2l0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIGFjdGlvbiBBY3Rpb24gZGVzY3JpcHRvci5cbiAgICAgKiBAcGFyYW0gZXZlbnQgVGFyZ2V0IHRhYmxlIGNsaWNrIGV2ZW50LlxuICAgICAqIEBwYXJhbSByb3V0ZSBDdXJyZW50bHkgYWN0aXZhdGUgcm91dGUuXG4gICAgICogQHBhcmFtIHRhYmxlRGVzY3JpcHRvciBUYWJsZSBkZXNjcmlwdG9yLlxuICAgICAqIEBwYXJhbSBkYXRhS2V5UHJvcGVydHkgRGF0YSBrZXkgcHJvcGVydHkuXG4gICAgICovXG4gICAgcHVibGljIHRyaWdnZXJSb3dDbGlja0FjdGlvbjxUPihcbiAgICAgICAgYWN0aW9uOiBBY3Rpb25EZXNjcmlwdG9yPFQ+LFxuICAgICAgICBldmVudDogTW5nVGFibGVDZWxsQ2xpY2tFdmVudDxUPixcbiAgICAgICAgcm91dGU/OiBBY3RpdmF0ZWRSb3V0ZSxcbiAgICAgICAgdGFibGVEZXNjcmlwdG9yPzogVGFibGVEZXNjcmlwdG9yPFQ+LFxuICAgICAgICBkYXRhS2V5UHJvcGVydHk/OiBzdHJpbmdcbiAgICApIHtcbiAgICAgICAgY29uc3QgaWRQcm9wZXJ0eSA9IGRhdGFLZXlQcm9wZXJ0eSA/PyB0YWJsZURlc2NyaXB0b3I/LmRhdGFLZXlQcm9wZXJ0eSA/PyBhY3Rpb24/Lm1vZGVsPy5pZFByb3BlcnR5TmFtZSA/PyBkYXRhS2V5UHJvcGVydHk7XG4gICAgICAgIGlmICghaWRQcm9wZXJ0eSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBSb3cgY2xpY2sgYWN0aW9uICR7YWN0aW9uLmFjdGlvbk5hbWVMb25nfSBjYW4gbm90IGJlIHRyaWdnZXJlZCwgYmVjYXVzZSBpZCBwcm9wZXJ0eSBjb3VsZCBub3QgYmUgZm91bmQuYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgcm93SXRlbSA9IGV2ZW50Py5yb3dJdGVtIGFzIGFueTtcbiAgICAgICAgcmV0dXJuIHRoaXMudHJpZ2dlckFjdGlvbihhY3Rpb24sIG5ldyBBY3Rpb25QYXJhbWV0ZXJzPFQ+KHJvd0l0ZW1baWRQcm9wZXJ0eV0sIGV2ZW50LnJvd0l0ZW0pLndpdGhSb3V0ZShyb3V0ZSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJzIGFjdGlvbiB3aXRoIHBhcmFtZXRlcnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uIEFjdGlvbiBkZXNjcmlwdG9yLlxuICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJzIEFjdGlvbiBwYXJhbWV0ZXJzIGZvciBhY3Rpb24gZXhlY3V0aW9uIHRvIGNvbnN0cnVjdCBuZXcgcm91dGUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIEFjdGlvbiBpbnN0YW5jZSAtIGlmIG5vbiBwcm92aWRlZCBpbiBwYXJhbWV0ZXJzLCB0aGUgbmV3bHkgY3JlYXRlZCB3aWxsIGJlIHJldHVybmVkLlxuICAgICAqL1xuICAgIHB1YmxpYyB0cmlnZ2VyQWN0aW9uPFQsIFM+KGFjdGlvbjogQWN0aW9uRGVzY3JpcHRvcjxUPiwgcGFyYW1ldGVyczogQWN0aW9uUGFyYW1ldGVyczxUPik6IEFjdGlvbkluc3RhbmNlPFQsIFM+IHtcbiAgICAgICAgY29uc3QgaW5zdGFuY2UgPSBuZXcgQWN0aW9uSW5zdGFuY2U8VCwgUz4oYWN0aW9uLCB1bmRlZmluZWQsIHRoaXMuZGVidWcpO1xuICAgICAgICBpbnN0YW5jZS50cmlnZ2VyUGFyYW1ldGVycyA9IHBhcmFtZXRlcnM7XG4gICAgICAgIGlmIChhY3Rpb24uYWN0aXZhdGlvblRyaWdnZXIgPT09IEFjdGlvbkFjdGl2YXRpb25UcmlnZ2VyRW51bS5PblJvdXRlKSB7XG4gICAgICAgICAgICBjb25zdCBiYXNlVXJsID0gdGhpcy5yb3V0ZXIudXJsLnNwbGl0KCc/JylbMF07XG4gICAgICAgICAgICBjb25zdCBwYXJzZWRVcmw6IFVybFRyZWUgPSB0aGlzLnJvdXRlci5wYXJzZVVybCh0aGlzLnJvdXRlci51cmwpO1xuICAgICAgICAgICAgbGV0IGFjdGlvblVybCA9IGFjdGlvbi5yb3V0ZVVybCA/PyAnJztcbiAgICAgICAgICAgIC8vIFRPRE86IGRvbnQgc3RyaXAgJy8nLCBidXQgdXNlIGl0IGFjY29yZGluZ2x5IHdpdGggQW5ndWxhcidzIHJvdXRlciBwYXR0ZXJucyAoLywgLi8sIC4uLylcbiAgICAgICAgICAgIGlmIChhY3Rpb25Vcmwuc3RhcnRzV2l0aCgnLycpKSB7XG4gICAgICAgICAgICAgICAgYWN0aW9uVXJsID0gYWN0aW9uVXJsLnN1YnN0cmluZygxKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgYWN0aW9uVXJsU2VnbWVudHMgPSB0aGlzLnBhcmFtZXRyaXplLnRyYW5zZm9ybShhY3Rpb25VcmwsIHBhcmFtZXRlcnMuaXRlbUlkLCBwYXJhbWV0ZXJzLml0ZW0sIHBhcmFtZXRlcnMuYWN0aW9uRGF0YSkuc3BsaXQoJy8nKTtcblxuICAgICAgICAgICAgaW5zdGFuY2UudHJpZ2dlclJvdXRlTmF2aWdhdGlvbiA9IGZyb20odGhpcy5yb3V0ZXIubmF2aWdhdGUoW2Jhc2VVcmwsIC4uLmFjdGlvblVybFNlZ21lbnRzXSwge3JlbGF0aXZlVG86IHBhcmFtZXRlcnMucm91dGUsIHF1ZXJ5UGFyYW1zOiBwYXJzZWRVcmwucXVlcnlQYXJhbXN9KSk7XG5cbiAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluc3RhbmNlLnN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uVHJpZ2dlckVuZDtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFjdGl2YXRlQWN0aW9uKGFjdGlvbiwgcGFyYW1ldGVycyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWFjdGl2YXRlcyBvbiByb3V0ZSB0cmlnZ2VyZWQgYWN0aW9uIGJ5IHRyeWluZyB0byByZXJvdXRlIGJhY2sgdG8gbG9jYXRpb24gd2hlcmUgYWN0aW9uIHdhcyB0cmlnZ2VyZWQuXG4gICAgICogQHBhcmFtIGluc3RhbmNlIEFjdGlvbiBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgZGVhY3RpdmF0ZU9uUm91dGVUcmlnZ2VyZWRBY3Rpb248VCwgUz4oaW5zdGFuY2U6IEFjdGlvbkluc3RhbmNlPFQsIFM+KSB7XG4gICAgICAgIGlmIChpbnN0YW5jZS5hY3Rpb24uYWN0aXZhdGlvblRyaWdnZXIgIT09IEFjdGlvbkFjdGl2YXRpb25UcmlnZ2VyRW51bS5PblJvdXRlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gZm9yIG5vdywgZGVhY3RpdmF0aW9uIGFsd2F5cyBtZWFucyBnb2luZyBiYWNrIHRvIHRhYmxldmlldyByb290XG4gICAgICAgIC8vIGlmICh0aGlzLm5hdmlnYXRpb25TZXJ2aWNlLmdldFByZXZpb3VzTG9jYXRpb24oKSkge1xuICAgICAgICAvLyAgICAgLy8gdGhlcmUgYXJlIGludGVybmFsIGhpc3RvcnkgcmVjb3Jkcywgc28gYmFjayBjYW4gYmUgbm9ybWFsbHkgY2FsbGVkXG4gICAgICAgIC8vICAgICB0aGlzLm5hdmlnYXRpb25TZXJ2aWNlLmJhY2soKTtcbiAgICAgICAgLy8gfSBlbHNlIHtcbiAgICAgICAgLy8gICAgIC8vIHRoZXJlIGlzIG5vIGludGVybmFsIGhpc3RvcnkgcmVjb3JkcywgZmlndXJlIG91dCB0aGUgYmFzZSB1cmwgYnkgZWxpbWluYXRpbmcgYWN0aW9uIHNwZWNpZmljIHVybFxuICAgICAgICBsZXQgdXJsID0gdGhpcy5uYXZpZ2F0aW9uU2VydmljZS5nZXRDdXJyZW50TG9jYXRpb24oKTtcbiAgICAgICAgLy8gbGV0IHByZXZpb3VzVXJsID0gdGhpcy5uYXZpZ2F0aW9uU2VydmljZS5nZXRQcmV2aW91c0xvY2F0aW9uKCk7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHVybCwgcHJldmlvdXNVcmwpO1xuICAgICAgICBpZiAoIXVybCkge1xuICAgICAgICAgICAgdGhpcy5uYXZpZ2F0aW9uU2VydmljZS5iYWNrKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodXJsLnN0YXJ0c1dpdGgoJy8nKSkge1xuICAgICAgICAgICAgICAgIHVybCA9IHVybC5zdWJzdHJpbmcoMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB1cmxQYXRoU2VnbWVudHMgPSB1cmwuc3BsaXQoJz8nKVswXS5zcGxpdCgnIycpWzBdLnNwbGl0KCcvJyk7XG4gICAgICAgICAgICBsZXQgYWN0aW9uVXJsID0gaW5zdGFuY2UuYWN0aW9uPy5yb3V0ZVVybCA/PyAnJztcbiAgICAgICAgICAgIGlmIChhY3Rpb25Vcmwuc3RhcnRzV2l0aCgnLycpKSB7XG4gICAgICAgICAgICAgICAgYWN0aW9uVXJsID0gYWN0aW9uVXJsLnN1YnN0cmluZygxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGFjdGlvblVybFNlZ21lbnRzID0gYWN0aW9uVXJsLnNwbGl0KCcvJyk7XG4gICAgICAgICAgICBjb25zdCByZWRpcmVjdFVybCA9ICcvJyArIHVybFBhdGhTZWdtZW50cy5zbGljZSgwLCB1cmxQYXRoU2VnbWVudHMubGVuZ3RoIC0gYWN0aW9uVXJsU2VnbWVudHMubGVuZ3RoKS5qb2luKCcvJyk7XG4gICAgICAgICAgICAvLyBjb25zdCByZXBsYWNlVXJsID0gcHJldmlvdXNVcmwgIT09IG51bGwgJiYgcHJldmlvdXNVcmwuc3BsaXQoJz8nKVswXS5zcGxpdCgnIycpWzBdID09PSByZWRpcmVjdFVybDtcbiAgICAgICAgICAgIC8vIE5vIFVSTCByZXBsYWNlcywgcHJvYmFibHkgb2ssIHRvIGFsbG93IGdvaW5nIGJhY2tcbiAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlQnlVcmwocmVkaXJlY3RVcmwpO1xuICAgICAgICB9XG4gICAgICAgIC8vIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmFuc2Zvcm0gZXJyb3Igb2YgYW55IHR5cGUgdG8gbW5nIGVycm9yIGJ5IHVzaW5nIGVycm9yIG1hcHBlciB0aGF0IGNvdWxkIGJlIHByb3ZpZGVkIGJ5IGZpbmFsIHByb2plY3QuXG4gICAgICogQHBhcmFtIGVycm9yIGVycm9yIG9mIGFueSB0eXBlLlxuICAgICAqXG4gICAgICogQHJldHVybiBtYXBwZWQgTW5nRXJyb3IuXG4gICAgICovXG4gICAgcHVibGljIHRvTW5nQWN0aW9uRXJyb3IoZXJyb3I/OiBhbnkpOiBNbmdFcnJvciB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkVycm9yOiBNbmdFcnJvciA9IHtcbiAgICAgICAgICAgIG5hbWU6IGVycm9yPy5uYW1lID8/ICdVbmtub3duRXJyb3InLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3I/Lm1lc3NhZ2UgPz8gJ1Vua25vd24gZXJyb3InLFxuICAgICAgICAgICAgY2F1c2U6IGVycm9yXG4gICAgICAgIH07XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEh0dHBFcnJvclJlc3BvbnNlKSB7XG4gICAgICAgICAgICBhY3Rpb25FcnJvci5zdGF0dXMgPSBlcnJvci5zdGF0dXM7XG4gICAgICAgICAgICBhY3Rpb25FcnJvci5zdGF0dXNEZXNjcmlwdGlvbiA9IGVycm9yLnN0YXR1c1RleHQ7XG4gICAgICAgICAgICBhY3Rpb25FcnJvci51cmwgPSBlcnJvci51cmwgPz8gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmVycm9yTWFwcGVyLnRvTW5nRXJyb3IoZXJyb3IsIGFjdGlvbkVycm9yKTtcbiAgICB9XG59XG4iXX0=