@mediusinc/mng-commons 2.6.0-rc.2 → 3.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. package/README.md +15 -4
  2. package/dev-scripts/version-info.js +1 -0
  3. package/esm2022/lib/api/models/filter-param.model.mjs +33 -0
  4. package/esm2022/lib/api/models/query-param.model.mjs +68 -0
  5. package/esm2022/lib/api/models/query-result.model.mjs +24 -0
  6. package/esm2022/lib/api/utils/medius-rest.util.mjs +255 -0
  7. package/esm2022/lib/api/utils/object-serializer.util.mjs +258 -0
  8. package/esm2022/lib/components/action/action.component.mjs +304 -0
  9. package/esm2022/lib/components/action/editor/action-editor.component.mjs +386 -0
  10. package/esm2022/lib/components/action/localization/data-language-dropdown.component.mjs +54 -0
  11. package/{esm2020 → esm2022}/lib/components/action/models/action-execution.model.mjs +1 -1
  12. package/esm2022/lib/components/action/models/tableview-action-default-categories.model.mjs +11 -0
  13. package/{esm2020 → esm2022}/lib/components/action/route/action-route.component.mjs +4 -4
  14. package/esm2022/lib/components/form/autocomplete/autocomplete.component.mjs +300 -0
  15. package/{esm2020 → esm2022}/lib/components/form/date-range/date-range.component.mjs +5 -5
  16. package/esm2022/lib/components/form/dropdown/dropdown.component.mjs +212 -0
  17. package/esm2022/lib/components/form/editor/form-editor.component.mjs +288 -0
  18. package/{esm2020 → esm2022}/lib/components/form/formly/fields/formly-field-action/formly-field-action.component.mjs +4 -4
  19. package/{esm2020 → esm2022}/lib/components/form/formly/fields/formly-field-autocomplete/formly-field-autocomplete.component.mjs +5 -5
  20. package/{esm2020 → esm2022}/lib/components/form/formly/fields/formly-field-custom/formly-custom-field-base.model.mjs +4 -4
  21. package/{esm2020 → esm2022}/lib/components/form/formly/fields/formly-field-custom/formly-field-custom.component.mjs +6 -6
  22. package/{esm2020 → esm2022}/lib/components/form/formly/fields/formly-field-dropdown/formly-field-dropdown.component.mjs +4 -4
  23. package/{esm2020 → esm2022}/lib/components/form/formly/fields/formly-field-fieldset/formly-field-fieldset.component.mjs +4 -4
  24. package/{esm2020 → esm2022}/lib/components/form/formly/fields/formly-field-input/formly-field-input.component.mjs +5 -5
  25. package/{esm2020 → esm2022}/lib/components/form/formly/fields/formly-field-label/formly-field-label.component.mjs +4 -4
  26. package/{esm2020 → esm2022}/lib/components/form/formly/fields/formly-field-lookup-dialog/formly-field-lookup-dialog.component.mjs +7 -7
  27. package/{esm2020 → esm2022}/lib/components/form/formly/fields/formly-field-table-dialog-form/formly-field-table-dialog-form.component.mjs +4 -4
  28. package/{esm2020 → esm2022}/lib/components/form/formly/fields/formly-field-table-dialog-multiselect/formly-field-table-dialog-multiselect.component.mjs +4 -4
  29. package/esm2022/lib/components/form/formly/fields/formly-field-tabs/formly-field-tabs.component.mjs +19 -0
  30. package/{esm2020 → esm2022}/lib/components/form/formly/wrappers/formly-field-no-label-wrapper/formly-field-no-label-wrapper.component.mjs +4 -4
  31. package/{esm2020 → esm2022}/lib/components/form/formly/wrappers/formly-field-wrapper/formly-field-wrapper.component.mjs +4 -4
  32. package/esm2022/lib/components/form/models/form-editor.event.mjs +49 -0
  33. package/esm2022/lib/components/layout/breadcrumb.component.mjs +34 -0
  34. package/{esm2020 → esm2022}/lib/components/layout/footer.component.mjs +4 -4
  35. package/{esm2020 → esm2022}/lib/components/layout/main-layout.component.mjs +4 -4
  36. package/esm2022/lib/components/layout/menu-item.component.mjs +297 -0
  37. package/{esm2020 → esm2022}/lib/components/layout/menu.component.mjs +4 -4
  38. package/{esm2020 → esm2022}/lib/components/layout/services/main-layout.component.service.mjs +4 -4
  39. package/{esm2020 → esm2022}/lib/components/layout/topbar-user.component.mjs +4 -4
  40. package/{esm2020 → esm2022}/lib/components/layout/topbar.component.mjs +4 -4
  41. package/{esm2020 → esm2022}/lib/components/layout/version.component.mjs +4 -4
  42. package/{esm2020 → esm2022}/lib/components/pages/error/error-page.component.mjs +4 -4
  43. package/{esm2020 → esm2022}/lib/components/pages/not-found/not-found-page.component.mjs +4 -4
  44. package/{esm2020 → esm2022}/lib/components/tableview/models/table.event.mjs +1 -1
  45. package/{esm2020 → esm2022}/lib/components/tableview/route/tableview-route.abstract.component.mjs +5 -5
  46. package/{esm2020 → esm2022}/lib/components/tableview/route/tableview-route.component.mjs +4 -4
  47. package/esm2022/lib/components/tableview/table/column-filter/column-filter.component.mjs +124 -0
  48. package/esm2022/lib/components/tableview/table/column-value/column-value.component.mjs +110 -0
  49. package/esm2022/lib/components/tableview/table/table.component.mjs +747 -0
  50. package/esm2022/lib/components/tableview/tableview.component.mjs +147 -0
  51. package/esm2022/lib/descriptors/action/action.descriptor.mjs +634 -0
  52. package/esm2022/lib/descriptors/editor/editor.descriptor.mjs +304 -0
  53. package/esm2022/lib/descriptors/table/table.descriptor.mjs +542 -0
  54. package/esm2022/lib/descriptors/tableview/tableview.descriptor.mjs +352 -0
  55. package/{esm2020 → esm2022}/lib/descriptors/types/table.type.mjs +1 -5
  56. package/{esm2020 → esm2022}/lib/directives/component.directive.mjs +5 -5
  57. package/{esm2020 → esm2022}/lib/directives/template.directive.mjs +5 -5
  58. package/esm2022/lib/mng-commons.module.mjs +465 -0
  59. package/{esm2020 → esm2022}/lib/pipes/boolean.pipe.mjs +4 -4
  60. package/{esm2020 → esm2022}/lib/pipes/class-map.pipe.mjs +4 -4
  61. package/{esm2020 → esm2022}/lib/pipes/enum.pipe.mjs +4 -4
  62. package/{esm2020 → esm2022}/lib/pipes/enumerate-async.pipe.mjs +4 -4
  63. package/{esm2020 → esm2022}/lib/pipes/enumerate.pipe.mjs +4 -4
  64. package/{esm2020 → esm2022}/lib/pipes/getter.pipe.mjs +4 -4
  65. package/{esm2020 → esm2022}/lib/pipes/i18n-property.pipe.mjs +4 -4
  66. package/{esm2020 → esm2022}/lib/pipes/json-path.pipe.mjs +4 -4
  67. package/{esm2020 → esm2022}/lib/pipes/locale-default-row-class.pipe.mjs +4 -4
  68. package/{esm2020 → esm2022}/lib/pipes/parametrize.pipe.mjs +4 -4
  69. package/{esm2020 → esm2022}/lib/pipes/template.pipe.mjs +4 -4
  70. package/esm2022/lib/router/route-builder.mjs +308 -0
  71. package/esm2022/lib/router/routes-builder.mjs +61 -0
  72. package/esm2022/lib/security/authorization.guard.mjs +15 -0
  73. package/{esm2020 → esm2022}/lib/security/authorization.service.mjs +4 -4
  74. package/esm2022/lib/services/action-executor.service.mjs +703 -0
  75. package/{esm2020 → esm2022}/lib/services/commons.service.mjs +4 -4
  76. package/esm2022/lib/services/configuration.service.mjs +150 -0
  77. package/{esm2020 → esm2022}/lib/services/internal/commons-init.service.mjs +4 -4
  78. package/{esm2020 → esm2022}/lib/services/mng-localstorage-config.service.mjs +4 -4
  79. package/{esm2020 → esm2022}/lib/services/navigation.service.mjs +4 -4
  80. package/{esm2020 → esm2022}/lib/services/router.service.mjs +4 -4
  81. package/{esm2020 → esm2022}/lib/services/version.service.mjs +4 -4
  82. package/{esm2020 → esm2022}/lib/services/view-container.component.service.mjs +4 -4
  83. package/esm2022/lib/styles/styles.util.mjs +42 -0
  84. package/esm2022/lib/types/type.model.mjs +2 -0
  85. package/esm2022/lib/utils/date.util.mjs +120 -0
  86. package/esm2022/lib/utils/tableview.util.mjs +193 -0
  87. package/esm2022/lib/utils/type.util.mjs +94 -0
  88. package/{fesm2020 → fesm2022}/mediusinc-mng-commons.mjs +930 -908
  89. package/fesm2022/mediusinc-mng-commons.mjs.map +1 -0
  90. package/lib/api/utils/medius-rest.util.d.ts +4 -3
  91. package/lib/components/action/action.component.d.ts +1 -1
  92. package/lib/components/action/editor/action-editor.component.d.ts +6 -9
  93. package/lib/components/action/localization/data-language-dropdown.component.d.ts +1 -1
  94. package/lib/components/form/autocomplete/autocomplete.component.d.ts +4 -4
  95. package/lib/components/form/date-range/date-range.component.d.ts +1 -1
  96. package/lib/components/form/dropdown/dropdown.component.d.ts +3 -3
  97. package/lib/components/form/editor/form-editor.component.d.ts +1 -1
  98. package/lib/components/form/formly/fields/formly-field-custom/formly-custom-field-base.model.d.ts +1 -1
  99. package/lib/components/layout/breadcrumb.component.d.ts +5 -0
  100. package/lib/components/layout/menu-item.component.d.ts +1 -1
  101. package/lib/components/layout/version.component.d.ts +1 -1
  102. package/lib/components/tableview/models/table.event.d.ts +2 -2
  103. package/lib/components/tableview/route/tableview-route.component.d.ts +1 -1
  104. package/lib/components/tableview/table/column-filter/column-filter.component.d.ts +2 -2
  105. package/lib/components/tableview/table/column-value/column-value.component.d.ts +1 -1
  106. package/lib/components/tableview/table/table.component.d.ts +6 -7
  107. package/lib/components/tableview/tableview.component.d.ts +7 -11
  108. package/lib/descriptors/editor/editor.descriptor.d.ts +1 -1
  109. package/lib/descriptors/table/table.descriptor.d.ts +7 -1
  110. package/lib/descriptors/tableview/tableview.descriptor.d.ts +4 -4
  111. package/lib/descriptors/types/table.type.d.ts +1 -5
  112. package/lib/directives/component.directive.d.ts +1 -1
  113. package/lib/directives/template.directive.d.ts +1 -1
  114. package/lib/router/route-builder.d.ts +6 -10
  115. package/lib/router/routes-builder.d.ts +0 -5
  116. package/lib/security/authorization.guard.d.ts +2 -11
  117. package/lib/services/action-executor.service.d.ts +1 -15
  118. package/lib/utils/route.util.d.ts +8 -19
  119. package/lib/utils/tableview.util.d.ts +5 -0
  120. package/package.json +13 -20
  121. package/esm2020/lib/api/models/filter-param.model.mjs +0 -33
  122. package/esm2020/lib/api/models/query-param.model.mjs +0 -68
  123. package/esm2020/lib/api/models/query-result.model.mjs +0 -24
  124. package/esm2020/lib/api/utils/medius-rest.util.mjs +0 -246
  125. package/esm2020/lib/api/utils/object-serializer.util.mjs +0 -258
  126. package/esm2020/lib/components/action/action.component.mjs +0 -303
  127. package/esm2020/lib/components/action/editor/action-editor.component.mjs +0 -390
  128. package/esm2020/lib/components/action/localization/data-language-dropdown.component.mjs +0 -47
  129. package/esm2020/lib/components/action/models/tableview-action-default-categories.model.mjs +0 -11
  130. package/esm2020/lib/components/form/autocomplete/autocomplete.component.mjs +0 -303
  131. package/esm2020/lib/components/form/dropdown/dropdown.component.mjs +0 -214
  132. package/esm2020/lib/components/form/editor/form-editor.component.mjs +0 -288
  133. package/esm2020/lib/components/form/formly/fields/formly-field-tabs/formly-field-tabs.component.mjs +0 -19
  134. package/esm2020/lib/components/form/models/form-editor.event.mjs +0 -49
  135. package/esm2020/lib/components/layout/breadcrumb.component.mjs +0 -19
  136. package/esm2020/lib/components/layout/menu-item.component.mjs +0 -294
  137. package/esm2020/lib/components/tableview/table/column-filter/column-filter.component.mjs +0 -126
  138. package/esm2020/lib/components/tableview/table/column-value/column-value.component.mjs +0 -108
  139. package/esm2020/lib/components/tableview/table/table.component.mjs +0 -749
  140. package/esm2020/lib/components/tableview/tableview.component.mjs +0 -146
  141. package/esm2020/lib/descriptors/action/action.descriptor.mjs +0 -634
  142. package/esm2020/lib/descriptors/editor/editor.descriptor.mjs +0 -304
  143. package/esm2020/lib/descriptors/table/table.descriptor.mjs +0 -521
  144. package/esm2020/lib/descriptors/tableview/tableview.descriptor.mjs +0 -347
  145. package/esm2020/lib/mng-commons.module.mjs +0 -469
  146. package/esm2020/lib/router/route-builder.mjs +0 -312
  147. package/esm2020/lib/router/routes-builder.mjs +0 -68
  148. package/esm2020/lib/security/authorization.guard.mjs +0 -30
  149. package/esm2020/lib/services/action-executor.service.mjs +0 -722
  150. package/esm2020/lib/services/configuration.service.mjs +0 -150
  151. package/esm2020/lib/styles/styles.util.mjs +0 -42
  152. package/esm2020/lib/types/type.model.mjs +0 -2
  153. package/esm2020/lib/utils/date.util.mjs +0 -120
  154. package/esm2020/lib/utils/tableview.util.mjs +0 -171
  155. package/esm2020/lib/utils/type.util.mjs +0 -94
  156. package/fesm2015/mediusinc-mng-commons.mjs +0 -15900
  157. package/fesm2015/mediusinc-mng-commons.mjs.map +0 -1
  158. package/fesm2020/mediusinc-mng-commons.mjs.map +0 -1
  159. /package/{esm2020 → esm2022}/index.mjs +0 -0
  160. /package/{esm2020 → esm2022}/lib/api/models/builders/query-param.builder.mjs +0 -0
  161. /package/{esm2020 → esm2022}/lib/api/models/filter-match-type.model.mjs +0 -0
  162. /package/{esm2020 → esm2022}/lib/api/models/index.mjs +0 -0
  163. /package/{esm2020 → esm2022}/lib/api/models/mappers.mjs +0 -0
  164. /package/{esm2020 → esm2022}/lib/api/models/query-mode.model.mjs +0 -0
  165. /package/{esm2020 → esm2022}/lib/api/models/serialization.model.mjs +0 -0
  166. /package/{esm2020 → esm2022}/lib/api/services/api.abstract.service.mjs +0 -0
  167. /package/{esm2020 → esm2022}/lib/api/services/crud-api.abstract.service.mjs +0 -0
  168. /package/{esm2020 → esm2022}/lib/api/services/get-all-api.abstract.service.mjs +0 -0
  169. /package/{esm2020 → esm2022}/lib/api/services/index.mjs +0 -0
  170. /package/{esm2020 → esm2022}/lib/api/utils/index.mjs +0 -0
  171. /package/{esm2020 → esm2022}/lib/components/action/index.mjs +0 -0
  172. /package/{esm2020 → esm2022}/lib/components/action/models/action-component.model.mjs +0 -0
  173. /package/{esm2020 → esm2022}/lib/components/action/models/action-confirmation-service.model.mjs +0 -0
  174. /package/{esm2020 → esm2022}/lib/components/action/models/index.mjs +0 -0
  175. /package/{esm2020 → esm2022}/lib/components/form/formly/fields/index.mjs +0 -0
  176. /package/{esm2020 → esm2022}/lib/components/form/formly/formly.config.mjs +0 -0
  177. /package/{esm2020 → esm2022}/lib/components/form/formly/index.mjs +0 -0
  178. /package/{esm2020 → esm2022}/lib/components/form/formly/models/formly-config.model.mjs +0 -0
  179. /package/{esm2020 → esm2022}/lib/components/form/formly/models/formly-field.model.mjs +0 -0
  180. /package/{esm2020 → esm2022}/lib/components/form/formly/models/index.mjs +0 -0
  181. /package/{esm2020 → esm2022}/lib/components/form/formly/wrappers/index.mjs +0 -0
  182. /package/{esm2020 → esm2022}/lib/components/form/index.mjs +0 -0
  183. /package/{esm2020 → esm2022}/lib/components/form/models/field-action-context.model.mjs +0 -0
  184. /package/{esm2020 → esm2022}/lib/components/form/models/form-editor.interface.mjs +0 -0
  185. /package/{esm2020 → esm2022}/lib/components/form/models/index.mjs +0 -0
  186. /package/{esm2020 → esm2022}/lib/components/layout/index.mjs +0 -0
  187. /package/{esm2020 → esm2022}/lib/components/layout/services/index.mjs +0 -0
  188. /package/{esm2020 → esm2022}/lib/components/pages/index.mjs +0 -0
  189. /package/{esm2020 → esm2022}/lib/components/tableview/index.mjs +0 -0
  190. /package/{esm2020 → esm2022}/lib/components/tableview/models/index.mjs +0 -0
  191. /package/{esm2020 → esm2022}/lib/components/tableview/table/models/index.mjs +0 -0
  192. /package/{esm2020 → esm2022}/lib/components/tableview/table/models/table.interface.mjs +0 -0
  193. /package/{esm2020 → esm2022}/lib/data-providers/base.data-provider.mjs +0 -0
  194. /package/{esm2020 → esm2022}/lib/data-providers/editor.data-provider.mjs +0 -0
  195. /package/{esm2020 → esm2022}/lib/data-providers/index.mjs +0 -0
  196. /package/{esm2020 → esm2022}/lib/data-providers/lookup.data-provider.mjs +0 -0
  197. /package/{esm2020 → esm2022}/lib/data-providers/table.data-provider.mjs +0 -0
  198. /package/{esm2020 → esm2022}/lib/data-providers/tableview-crud.data-provider.mjs +0 -0
  199. /package/{esm2020 → esm2022}/lib/data-providers/tableview.data-provider.mjs +0 -0
  200. /package/{esm2020 → esm2022}/lib/descriptors/action/action-button.descriptor.mjs +0 -0
  201. /package/{esm2020 → esm2022}/lib/descriptors/action/action-confirmation.descriptor.mjs +0 -0
  202. /package/{esm2020 → esm2022}/lib/descriptors/action/index.mjs +0 -0
  203. /package/{esm2020 → esm2022}/lib/descriptors/editor/field-validation.descriptor.mjs +0 -0
  204. /package/{esm2020 → esm2022}/lib/descriptors/editor/field.descriptor.mjs +0 -0
  205. /package/{esm2020 → esm2022}/lib/descriptors/editor/index.mjs +0 -0
  206. /package/{esm2020 → esm2022}/lib/descriptors/filter/filter.descriptor.mjs +0 -0
  207. /package/{esm2020 → esm2022}/lib/descriptors/filter/index.mjs +0 -0
  208. /package/{esm2020 → esm2022}/lib/descriptors/index.mjs +0 -0
  209. /package/{esm2020 → esm2022}/lib/descriptors/interfaces/field-config.interface.mjs +0 -0
  210. /package/{esm2020 → esm2022}/lib/descriptors/interfaces/index.mjs +0 -0
  211. /package/{esm2020 → esm2022}/lib/descriptors/interfaces/lookup-descriptor.interface.mjs +0 -0
  212. /package/{esm2020 → esm2022}/lib/descriptors/model.descriptor.mjs +0 -0
  213. /package/{esm2020 → esm2022}/lib/descriptors/table/column.descriptor.mjs +0 -0
  214. /package/{esm2020 → esm2022}/lib/descriptors/table/index.mjs +0 -0
  215. /package/{esm2020 → esm2022}/lib/descriptors/tableview/index.mjs +0 -0
  216. /package/{esm2020 → esm2022}/lib/descriptors/types/action.type.mjs +0 -0
  217. /package/{esm2020 → esm2022}/lib/descriptors/types/column.type.mjs +0 -0
  218. /package/{esm2020 → esm2022}/lib/descriptors/types/editor.type.mjs +0 -0
  219. /package/{esm2020 → esm2022}/lib/descriptors/types/field.type.mjs +0 -0
  220. /package/{esm2020 → esm2022}/lib/descriptors/types/filter.type.mjs +0 -0
  221. /package/{esm2020 → esm2022}/lib/descriptors/types/index.mjs +0 -0
  222. /package/{esm2020 → esm2022}/lib/directives/index.mjs +0 -0
  223. /package/{esm2020 → esm2022}/lib/models/column-value.model.mjs +0 -0
  224. /package/{esm2020 → esm2022}/lib/models/config.model.mjs +0 -0
  225. /package/{esm2020 → esm2022}/lib/models/enum.model.mjs +0 -0
  226. /package/{esm2020 → esm2022}/lib/models/error-internal.model.mjs +0 -0
  227. /package/{esm2020 → esm2022}/lib/models/error.model.mjs +0 -0
  228. /package/{esm2020 → esm2022}/lib/models/index.mjs +0 -0
  229. /package/{esm2020 → esm2022}/lib/models/menu.model.mjs +0 -0
  230. /package/{esm2020 → esm2022}/lib/models/tableview-attr.model.mjs +0 -0
  231. /package/{esm2020 → esm2022}/lib/models/user.model.mjs +0 -0
  232. /package/{esm2020 → esm2022}/lib/models/version.model.mjs +0 -0
  233. /package/{esm2020 → esm2022}/lib/models/view-container.model.mjs +0 -0
  234. /package/{esm2020 → esm2022}/lib/pipes/index.mjs +0 -0
  235. /package/{esm2020 → esm2022}/lib/pipes/models/internal/enumrate-pipe-i18n.model.mjs +0 -0
  236. /package/{esm2020 → esm2022}/lib/pipes/models/internal/index.mjs +0 -0
  237. /package/{esm2020 → esm2022}/lib/provide-commons.mjs +0 -0
  238. /package/{esm2020 → esm2022}/lib/router/index.mjs +0 -0
  239. /package/{esm2020 → esm2022}/lib/router/models/index.mjs +0 -0
  240. /package/{esm2020 → esm2022}/lib/router/models/router.model.mjs +0 -0
  241. /package/{esm2020 → esm2022}/lib/router/tableview-route-builder.mjs +0 -0
  242. /package/{esm2020 → esm2022}/lib/security/authorization.util.mjs +0 -0
  243. /package/{esm2020 → esm2022}/lib/security/index.mjs +0 -0
  244. /package/{esm2020 → esm2022}/lib/security/model/authorization.type.mjs +0 -0
  245. /package/{esm2020 → esm2022}/lib/security/model/index.mjs +0 -0
  246. /package/{esm2020 → esm2022}/lib/security/model/permission-service.interface.mjs +0 -0
  247. /package/{esm2020 → esm2022}/lib/security/model/permissions.model.mjs +0 -0
  248. /package/{esm2020 → esm2022}/lib/services/error-mapper.service.mjs +0 -0
  249. /package/{esm2020 → esm2022}/lib/services/index.mjs +0 -0
  250. /package/{esm2020 → esm2022}/lib/services/internal/commons-init.provider.mjs +0 -0
  251. /package/{esm2020 → esm2022}/lib/services/internal/index.mjs +0 -0
  252. /package/{esm2020 → esm2022}/lib/services/providers/config-service.provider.mjs +0 -0
  253. /package/{esm2020 → esm2022}/lib/services/providers/formly-config.provider.mjs +0 -0
  254. /package/{esm2020 → esm2022}/lib/services/providers/index.mjs +0 -0
  255. /package/{esm2020 → esm2022}/lib/services/tokens/browser-storage.token.mjs +0 -0
  256. /package/{esm2020 → esm2022}/lib/services/tokens/commons-init.token.mjs +0 -0
  257. /package/{esm2020 → esm2022}/lib/services/tokens/default-setting.token.mjs +0 -0
  258. /package/{esm2020 → esm2022}/lib/services/tokens/index.mjs +0 -0
  259. /package/{esm2020 → esm2022}/lib/services/tokens/module-config.token.mjs +0 -0
  260. /package/{esm2020 → esm2022}/lib/styles/button-style.builder.mjs +0 -0
  261. /package/{esm2020 → esm2022}/lib/styles/index.mjs +0 -0
  262. /package/{esm2020 → esm2022}/lib/styles/models/index.mjs +0 -0
  263. /package/{esm2020 → esm2022}/lib/styles/models/style-level.enum.mjs +0 -0
  264. /package/{esm2020 → esm2022}/lib/styles/models/style-size.enum.mjs +0 -0
  265. /package/{esm2020 → esm2022}/lib/types/i18n.type.mjs +0 -0
  266. /package/{esm2020 → esm2022}/lib/types/index.mjs +0 -0
  267. /package/{esm2020 → esm2022}/lib/types/mng-localstorage-config-value.type.mjs +0 -0
  268. /package/{esm2020 → esm2022}/lib/types/type.decorator.mjs +0 -0
  269. /package/{esm2020 → esm2022}/lib/utils/action-data-provider.util.mjs +0 -0
  270. /package/{esm2020 → esm2022}/lib/utils/editor-formly.util.mjs +0 -0
  271. /package/{esm2020 → esm2022}/lib/utils/enum.util.mjs +0 -0
  272. /package/{esm2020 → esm2022}/lib/utils/export.util.mjs +0 -0
  273. /package/{esm2020 → esm2022}/lib/utils/file.util.mjs +0 -0
  274. /package/{esm2020 → esm2022}/lib/utils/i18n.util.mjs +0 -0
  275. /package/{esm2020 → esm2022}/lib/utils/index.mjs +0 -0
  276. /package/{esm2020 → esm2022}/lib/utils/model.util.mjs +0 -0
  277. /package/{esm2020 → esm2022}/lib/utils/notification.util.mjs +0 -0
  278. /package/{esm2020 → esm2022}/lib/utils/object.util.mjs +0 -0
  279. /package/{esm2020 → esm2022}/lib/utils/route.util.mjs +0 -0
  280. /package/{esm2020 → esm2022}/lib/utils/string.util.mjs +0 -0
  281. /package/{esm2020 → esm2022}/lib/validators/field.validator.mjs +0 -0
  282. /package/{esm2020 → esm2022}/lib/validators/index.mjs +0 -0
  283. /package/{esm2020 → esm2022}/mediusinc-mng-commons.mjs +0 -0
@@ -0,0 +1,703 @@
1
+ import { HttpErrorResponse } from '@angular/common/http';
2
+ import { Inject, Injectable, Injector, Type } from '@angular/core';
3
+ import { Router } from '@angular/router';
4
+ import { TranslateService } from '@ngx-translate/core';
5
+ import { DialogService } from 'primeng/dynamicdialog';
6
+ import { from, mergeMap, of, switchMap, take, timeout } from 'rxjs';
7
+ import { catchError, filter, first, map } from 'rxjs/operators';
8
+ import { ActionContext, ActionContextValidation, ActionInstance, ActionInstanceStateEnum, ActionParameters } from '../components/action/models';
9
+ import { ActionEditorDescriptor } from '../descriptors/action';
10
+ import { ActionActivationTriggerEnum, ActionTypeEnum } from '../descriptors/types';
11
+ import { MngErrorInternal } from '../models';
12
+ import { MngParametrizePipe } from '../pipes';
13
+ import { StyleSizeEnum } from '../styles/models';
14
+ import { ActionDataProviderUtil, I18nUtils, NotificationUtil, StringUtil } from '../utils';
15
+ import { MngCommonsService } from './commons.service';
16
+ import { MngErrorMapperService } from './error-mapper.service';
17
+ import { MngNavigationService } from './navigation.service';
18
+ import { ACTION_EDITOR_DIALOG_COMPONENT_SETTING } from './tokens';
19
+ import * as i0 from "@angular/core";
20
+ import * as i1 from "@angular/router";
21
+ import * as i2 from "primeng/dynamicdialog";
22
+ import * as i3 from "@ngx-translate/core";
23
+ import * as i4 from "./commons.service";
24
+ import * as i5 from "./navigation.service";
25
+ import * as i6 from "./error-mapper.service";
26
+ import * as i7 from "../pipes";
27
+ export class MngActionExecutorService {
28
+ constructor(injector, router, dialogService, translate, mngCommons, navigationService, errorMapper, parametrize, defaultEditorDialogComponent) {
29
+ this.injector = injector;
30
+ this.router = router;
31
+ this.dialogService = dialogService;
32
+ this.translate = translate;
33
+ this.mngCommons = mngCommons;
34
+ this.navigationService = navigationService;
35
+ this.errorMapper = errorMapper;
36
+ this.parametrize = parametrize;
37
+ this.defaultEditorDialogComponent = defaultEditorDialogComponent;
38
+ this.instancesBufferMax = 100;
39
+ this._instances = [];
40
+ this.debugLog = this.mngCommons.actionsDebugLog;
41
+ }
42
+ get instances() {
43
+ return [...this._instances];
44
+ }
45
+ /**
46
+ * Prepares action context for usage in validation.
47
+ * @param action Action descriptor.
48
+ * @param parameters Action parameters.
49
+ * @param dataProvider Data provider.
50
+ */
51
+ prepareActionContextValidation(action, parameters, dataProvider) {
52
+ const ctxDataProvider = dataProvider ?? action.dataProvider ?? parameters.viewContainer?.getDataProvider();
53
+ return new ActionContextValidation(action, parameters, ctxDataProvider, ActionDataProviderUtil.getDataProviderService(this.injector, ctxDataProvider) ?? undefined);
54
+ }
55
+ /**
56
+ * Runs action context by submitting execution results/errors to context, watching over instance results/errors, displaying notifications,
57
+ * running next/error action and triggering dismiss of action. Confirmation is also processed here.
58
+ *
59
+ * @param ctx Action context to run.
60
+ */
61
+ run(ctx) {
62
+ const isMainRunFn = ctx.functionName === 'submit' || ctx.functionName === 'run';
63
+ // if (ctx.instance.action.type === ActionTypeEnum.Direct && ctx.instance.action.hasRunConfirmation) {
64
+ if (isMainRunFn && ctx.instance.action.hasRunConfirmation) {
65
+ // only direct action can be configured with run confirmation
66
+ // if editor, then run confirmation is mapped to submit action and ignored as editor run
67
+ const sourceComponent = ctx.parameters?.sourceComponent;
68
+ const confirmationDescriptor = ctx.instance.action.runConfirmationDialogDescriptor;
69
+ if (typeof sourceComponent?.getConfirmationService !== 'function' || typeof sourceComponent?.getConfirmationServiceInstanceKey !== 'function') {
70
+ throw new MngErrorInternal(`Source component ${sourceComponent} should be implementing IConfirmationService interface to be able to provide confirmation functionality.`, 'ActionExecutorService error').consoleError();
71
+ }
72
+ const item = ctx.parameters.item;
73
+ const srcConfirmComponent = sourceComponent;
74
+ let confirmParams = {
75
+ key: srcConfirmComponent.getConfirmationServiceInstanceKey(ctx.instance.action),
76
+ icon: confirmationDescriptor.icon,
77
+ acceptVisible: true,
78
+ acceptIcon: confirmationDescriptor.acceptButton.icon ?? undefined,
79
+ acceptButtonStyleClass: confirmationDescriptor.acceptButton.styleClass.build(),
80
+ rejectVisible: true,
81
+ rejectIcon: confirmationDescriptor.rejectButton?.icon ?? undefined,
82
+ rejectButtonStyleClass: confirmationDescriptor.rejectButton?.styleClass.build(),
83
+ closeOnEscape: confirmationDescriptor.closeOnEscape
84
+ };
85
+ if (confirmationDescriptor.title !== null) {
86
+ confirmParams.header =
87
+ I18nUtils.Action.get(this.translate, ctx.instance.action, 'confirm.title', confirmationDescriptor.title, item, 'general.confirmation') ?? undefined;
88
+ }
89
+ if (confirmationDescriptor.message !== null) {
90
+ confirmParams.message =
91
+ I18nUtils.Action.get(this.translate, ctx.instance.action, 'confirm.message', confirmationDescriptor.message, StringUtil.escapeHtmlAny(item), 'general.confirmation') ?? undefined;
92
+ }
93
+ if (confirmationDescriptor.acceptButton.label !== null) {
94
+ confirmParams.acceptLabel =
95
+ I18nUtils.Action.get(this.translate, ctx.instance.action, 'confirm.accept', confirmationDescriptor.acceptButton.label, item, 'general.yes') ?? undefined;
96
+ }
97
+ if (confirmationDescriptor.acceptButton.icon !== null) {
98
+ confirmParams.acceptIcon = confirmationDescriptor.acceptButton.icon;
99
+ }
100
+ if (confirmationDescriptor.rejectButton?.icon !== null) {
101
+ confirmParams.rejectIcon = confirmationDescriptor.rejectButton?.icon;
102
+ }
103
+ if (confirmationDescriptor.rejectButton?.label !== null) {
104
+ confirmParams.rejectLabel =
105
+ I18nUtils.Action.get(this.translate, ctx.instance.action, 'confirm.reject', confirmationDescriptor.rejectButton?.label, item, 'general.no') ?? undefined;
106
+ }
107
+ if (confirmationDescriptor.rejectButton == null || (confirmationDescriptor.rejectButton.label === null && confirmationDescriptor.rejectButton.icon === null)) {
108
+ confirmParams.rejectVisible = false;
109
+ }
110
+ confirmParams.accept = () => {
111
+ ctx.instance.state = ActionInstanceStateEnum.RunConfirmationEndAccept;
112
+ this.runWithoutConfirmation(ctx);
113
+ };
114
+ confirmParams.reject = () => {
115
+ ctx.instance.state = ActionInstanceStateEnum.RunConfirmationEndReject;
116
+ if (ctx.instance.action.type !== ActionTypeEnum.Editor) {
117
+ // if not editor, the it can be closed
118
+ this.finishAction(ctx.instance);
119
+ }
120
+ };
121
+ if (confirmationDescriptor.runConfirmationConfigMapFn) {
122
+ confirmParams = confirmationDescriptor.runConfirmationConfigMapFn(ctx, confirmParams);
123
+ }
124
+ ctx.confirmation = confirmParams;
125
+ ctx.instance.state = ActionInstanceStateEnum.RunConfirmationStart;
126
+ srcConfirmComponent.getConfirmationService().confirm(confirmParams);
127
+ }
128
+ else {
129
+ this.runWithoutConfirmation(ctx);
130
+ }
131
+ }
132
+ /**
133
+ * Runs action context by submitting execution results/errors to context, watching over instance results/errors, displaying notifications,
134
+ * running next/error action and triggering dismiss of action. Confirmation
135
+ *
136
+ * @param ctx Action context to run.
137
+ * @param parameters Action parameters for context.
138
+ * @param dataProvider Editor data provider for context.
139
+ * @param instance Optional existing action instance (if non provided, new will be created).
140
+ * @param previousActionInstance Optional previous action instance to link in next instance.
141
+ *
142
+ * @return Action context for submit (=run) function.
143
+ */
144
+ runWithoutConfirmation(ctx) {
145
+ const isMainRunFn = ctx.functionName === 'submit' || ctx.functionName === 'run';
146
+ const isErrorCriticalRunFn = ctx.functionName === 'run';
147
+ let actionEditor;
148
+ let fnObs;
149
+ switch (ctx.functionName) {
150
+ case 'submit':
151
+ actionEditor = ctx.instance.action;
152
+ if (typeof actionEditor.submitFunction !== 'function') {
153
+ const defaultSubmit = of(ctx.parameters?.item ? ctx.parameters.item : undefined);
154
+ fnObs = ctx => {
155
+ if (ctx.parameters.itemId) {
156
+ return ActionDataProviderUtil.runUpdate(ctx, defaultSubmit);
157
+ }
158
+ else {
159
+ return ActionDataProviderUtil.runCreate(ctx, defaultSubmit);
160
+ }
161
+ };
162
+ }
163
+ else {
164
+ fnObs = actionEditor.submitFunction;
165
+ }
166
+ break;
167
+ case 'fetch':
168
+ actionEditor = ctx.instance.action;
169
+ if (typeof actionEditor.fetchFunction !== 'function') {
170
+ const defaultFetch = of(ctx.parameters?.item ? ctx.parameters.item : undefined);
171
+ fnObs = ctx => {
172
+ if (ctx.parameters.itemId || typeof ctx.parameters.item === 'object') {
173
+ return ActionDataProviderUtil.runFetch(ctx, defaultFetch);
174
+ }
175
+ return defaultFetch;
176
+ };
177
+ }
178
+ else {
179
+ fnObs = actionEditor.fetchFunction;
180
+ }
181
+ break;
182
+ case 'run':
183
+ default:
184
+ fnObs = ctx.instance.action.runFunction;
185
+ break;
186
+ }
187
+ const retObs = of(void 0).pipe(take(1), switchMap(() => {
188
+ if (isMainRunFn) {
189
+ // if main run function, also set loading to true
190
+ ctx.instance.state = ActionInstanceStateEnum.RunStart;
191
+ ctx.instance.isRunLoadingSubject.next(true);
192
+ }
193
+ else {
194
+ ctx.instance.state = ActionInstanceStateEnum.FetchStart;
195
+ }
196
+ // start context execution to mark execution loading
197
+ ctx.executionStart();
198
+ return fnObs(ctx);
199
+ }), mergeMap(runResult => {
200
+ // set next state depending on run
201
+ ctx.instance.state = isMainRunFn ? ActionInstanceStateEnum.RunEnd : ActionInstanceStateEnum.FetchEnd;
202
+ // set execution result
203
+ ctx.executionNext(runResult, isMainRunFn);
204
+ if (isMainRunFn) {
205
+ // set instance final result on main run execution
206
+ ctx.instance.result = runResult;
207
+ ctx.instance.isRunLoadingSubject.next(false);
208
+ // handle notification
209
+ if (ctx.instance.action.hasRunNotificationSuccess) {
210
+ ctx.notification = NotificationUtil.actionNotificationSuccess(this.translate, ctx.instance.action, ctx.functionName, ctx.instance.action.runNotificationSuccessTitle, ctx.instance.action.runNotificationSuccessMessage, ctx.parameters.viewContainer ?? undefined, {
211
+ ...ctx.parameters?.item,
212
+ ...runResult
213
+ });
214
+ }
215
+ // handle possible after run action
216
+ if (ctx.instance.action.afterRunAction) {
217
+ // mark new state for next action start
218
+ ctx.instance.state = ActionInstanceStateEnum.NextActionStart;
219
+ const nextActionInstance = this.activateAction(ctx.instance.action.afterRunAction, new ActionParameters(ctx.parameters.itemId, runResult)
220
+ .withActionData(ctx.parameters.actionData)
221
+ .withRoute(ctx.parameters.route)
222
+ .withSourceComponent(ctx.parameters.sourceComponent)
223
+ .withViewContainer(ctx.parameters.viewContainer), undefined, ctx.instance);
224
+ ctx.instance.nextActionInstance = nextActionInstance;
225
+ // finish current action when next action finishes
226
+ return nextActionInstance.state$.pipe(filter(state => state >= ActionInstanceStateEnum.FinishSuccessFinal), map(() => {
227
+ ctx.instance.state = ActionInstanceStateEnum.NextActionEnd;
228
+ return runResult;
229
+ }));
230
+ }
231
+ }
232
+ else {
233
+ if (actionEditor.hasFetchNotificationSuccess) {
234
+ NotificationUtil.actionNotificationSuccess(this.translate, actionEditor, 'fetch', actionEditor.fetchNotificationSuccessTitle, actionEditor.fetchNotificationSuccessMessage, ctx.parameters.viewContainer, ctx.parameters.item);
235
+ }
236
+ }
237
+ return of(runResult);
238
+ }), map(runResult => {
239
+ if (isMainRunFn) {
240
+ // deactivate action
241
+ this.finishAction(ctx.instance);
242
+ }
243
+ return runResult;
244
+ }), catchError(err => {
245
+ // transform error to mng action error
246
+ const actionError = this.toMngActionError(err);
247
+ // set instance state to error
248
+ ctx.instance.state = isMainRunFn ? ActionInstanceStateEnum.RunError : ActionInstanceStateEnum.FetchError;
249
+ // mark execution error on context
250
+ ctx.executionError(actionError);
251
+ let errorObs = of(void 0);
252
+ if (isMainRunFn) {
253
+ ctx.instance.error = err;
254
+ ctx.instance.isRunLoadingSubject.next(false);
255
+ // handle error notification
256
+ if (ctx.instance.action.hasRunNotificationError) {
257
+ actionError.notification = NotificationUtil.actionNotificationError(this.translate, ctx.instance.action, actionError, ctx.functionName, ctx.parameters.viewContainer ?? undefined, ctx.parameters.item);
258
+ }
259
+ // handle possible error action if run
260
+ if (isMainRunFn && ctx.instance.action.onRunErrorAction) {
261
+ // cannot start with trigger, because routing might be problematic (lousing previous results etc.)
262
+ const errorActionInstance = this.activateAction(ctx.instance.action.onRunErrorAction, new ActionParameters(ctx.parameters.itemId, ctx.parameters.item)
263
+ .withActionData(ctx.parameters.actionData)
264
+ .withRoute(ctx.parameters.route)
265
+ .withSourceComponent(ctx.parameters.sourceComponent)
266
+ .withViewContainer(ctx.parameters.viewContainer));
267
+ ctx.instance.errorActionInstance = errorActionInstance;
268
+ errorObs = errorActionInstance.state$.pipe(filter(state => state >= ActionInstanceStateEnum.FinishSuccessFinal), map(() => void 0));
269
+ }
270
+ }
271
+ else {
272
+ if (ctx.instance.action.hasRunNotificationError) {
273
+ NotificationUtil.actionNotificationError(this.translate, ctx.instance.action, actionError, 'fetch', ctx.parameters.viewContainer, ctx.parameters.item);
274
+ }
275
+ }
276
+ // liste and map only to mark instance state as finished error state
277
+ return errorObs.pipe(map(() => {
278
+ // deactivate action only if critical (fetch on editor or run on button actions)
279
+ if (isErrorCriticalRunFn) {
280
+ this.finishAction(ctx.instance);
281
+ }
282
+ // rethrow error to propagate furher
283
+ throw actionError;
284
+ }));
285
+ }));
286
+ ctx.runSubscription = retObs.subscribe({
287
+ next: res => {
288
+ if (this.debugLog) {
289
+ // eslint-disable-next-line no-console, no-restricted-syntax
290
+ console.debug(`ActionContext ${ctx.contextLongName} execution next event`, res);
291
+ }
292
+ },
293
+ error: err => {
294
+ if (this.debugLog) {
295
+ // eslint-disable-next-line no-console, no-restricted-syntax
296
+ console.debug(`ActionContext ${ctx.contextLongName} execution error event`, err);
297
+ }
298
+ }
299
+ });
300
+ return retObs;
301
+ }
302
+ /**
303
+ * Prepares editor action's fetch function by creating new action context for action instance.
304
+ *
305
+ * @param action Action descriptor.
306
+ * @param parameters Action parameters for context.
307
+ * @param dataProvider Editor data provider for context.
308
+ * @param instance Optional existing action instance (if non provided, new will be created).
309
+ * @param previousActionInstance Optional previous action instance to link in next instance.
310
+ *
311
+ * @return Action context for fetch function.
312
+ */
313
+ prepareContextForEditorFetch(action, parameters, dataProvider, instance, previousActionInstance) {
314
+ instance = this.getOrCreateInstance(instance, action, parameters, ActionInstanceStateEnum.ActivationEnd);
315
+ return this.prepareContextForEditor(instance, parameters, 'fetch', dataProvider, previousActionInstance);
316
+ }
317
+ /**
318
+ * Runs editor action's submit (=main run) function by creating new action context for action instance.
319
+ *
320
+ * @param action Action descriptor.
321
+ * @param parameters Action parameters for context.
322
+ * @param dataProvider Editor data provider for context.
323
+ * @param instance Optional existing action instance (if non provided, new will be created).
324
+ * @param previousActionInstance Optional previous action instance to link in next instance.
325
+ *
326
+ * @return Action context for submit (=run) function.
327
+ */
328
+ prepareContextForEditorSubmit(action, parameters, dataProvider, instance, previousActionInstance) {
329
+ instance = this.getOrCreateInstance(instance, action, parameters, ActionInstanceStateEnum.ActivationEnd);
330
+ return this.prepareContextForEditor(instance, parameters, 'submit', dataProvider, previousActionInstance);
331
+ }
332
+ /**
333
+ * Prepares action exec context for action of type editor.
334
+ *
335
+ * @param item Item instance (if exists).
336
+ * @param itemId Item id (if exists).
337
+ * @param dataProvider Data provider.
338
+ * @param sourceComponent Source component from where the context preparation was called.
339
+ * @param viewContainer View container/service.
340
+ * @param actionData Additional action data.
341
+ */
342
+ prepareContextForEditor(instance, parameters, functionName, dataProvider, previousActionInstance) {
343
+ if (instance.action.type !== ActionTypeEnum.Editor) {
344
+ throw new MngErrorInternal(`Cannot create editor context for action ${instance.action.actionNameLong} of type ${instance.action.type}.`);
345
+ }
346
+ const editorAction = instance.action;
347
+ let ctxDataProvider = dataProvider;
348
+ if (!ctxDataProvider && editorAction.dataProvider) {
349
+ ctxDataProvider = editorAction.dataProvider;
350
+ }
351
+ if (!ctxDataProvider) {
352
+ const viewContainerDataProvider = parameters.viewContainer?.getDataProvider();
353
+ if (viewContainerDataProvider) {
354
+ ctxDataProvider = viewContainerDataProvider;
355
+ }
356
+ }
357
+ const ctx = new ActionContext(instance, parameters, functionName, ctxDataProvider, ActionDataProviderUtil.getDataProviderService(this.injector, ctxDataProvider) ?? undefined);
358
+ ctx.previousActionInstance = previousActionInstance;
359
+ instance.newContext(ctx);
360
+ return ctx;
361
+ }
362
+ /**
363
+ * Runs action's main run function by creating new action context for action instance.
364
+ *
365
+ * @param action Action descriptor.
366
+ * @param parameters Action parameters for context run.
367
+ * @param dataProvider Data provider for context run.
368
+ * @param instance Optional existing action instance (if non provided, new will be created).
369
+ * @param previousActionInstance Optional previous action instance to link in next instance.
370
+ *
371
+ * @return Action context for run function.
372
+ */
373
+ prepareContext(action, parameters, dataProvider, instance, previousActionInstance) {
374
+ instance = this.getOrCreateInstance(instance, action, parameters, ActionInstanceStateEnum.ActivationEnd);
375
+ const ctxDataProvider = dataProvider ?? instance.action.dataProvider ?? parameters.viewContainer?.getDataProvider();
376
+ const ctx = new ActionContext(instance, parameters, 'run', ctxDataProvider, ActionDataProviderUtil.getDataProviderService(this.injector, ctxDataProvider) ?? undefined);
377
+ ctx.previousActionInstance = previousActionInstance;
378
+ instance.newContext(ctx);
379
+ return ctx;
380
+ }
381
+ /**
382
+ * Activates action (in case of dialog, dialog will be opened).
383
+ *
384
+ * @param action Action descriptor.
385
+ * @param parameters Action parameters for activation of action instance.
386
+ * @param instance Optional existing action instance (if non provided, new will be created).
387
+ * @param previousActionInstance Optional previous action instance to link in next instance.
388
+ * @param runContext Marks if context should be run.
389
+ *
390
+ * @return Action instance - if non provided in parameters, the newly created will be returned.
391
+ */
392
+ activateAction(action, parameters, instance, previousActionInstance, runContext = false) {
393
+ instance = this.getOrCreateInstance(instance, action, parameters, ActionInstanceStateEnum.ActivationStart);
394
+ instance.state = ActionInstanceStateEnum.ActivationStart;
395
+ instance.activationParameters = parameters;
396
+ // start activation instance
397
+ if (action.type === ActionTypeEnum.Editor) {
398
+ let dialogComponent = this.defaultEditorDialogComponent;
399
+ const dialogClassNames = ['mng-dialog'];
400
+ if (action instanceof ActionEditorDescriptor) {
401
+ dialogClassNames.push(action.dialogClassName ?? 'mng-action-editor-dialog');
402
+ switch (action.dialogSize) {
403
+ case StyleSizeEnum.ExtraSmall:
404
+ dialogClassNames.push('mng-dialog-xs');
405
+ break;
406
+ case StyleSizeEnum.Small:
407
+ dialogClassNames.push('mng-dialog-sm');
408
+ break;
409
+ case StyleSizeEnum.Large:
410
+ dialogClassNames.push('mng-dialog-lg');
411
+ break;
412
+ case StyleSizeEnum.ExtraLarge:
413
+ dialogClassNames.push('mng-dialog-xl');
414
+ break;
415
+ case StyleSizeEnum.Normal:
416
+ default:
417
+ break;
418
+ }
419
+ if (action.editorComponent) {
420
+ dialogComponent = action.editorComponent;
421
+ }
422
+ }
423
+ const dialogConfig = {
424
+ data: {},
425
+ styleClass: dialogClassNames.join(' ')
426
+ };
427
+ dialogConfig.data.actionInstance = instance;
428
+ dialogConfig.data.previousActionInstance = previousActionInstance;
429
+ const dialogRef = this.dialogService.open(dialogComponent, dialogConfig);
430
+ dialogRef.onClose.pipe(take(1)).subscribe(() => {
431
+ // to close dialog on 'X' click or esc button
432
+ this.finishAction(instance);
433
+ });
434
+ instance.activationDialogRef = dialogRef;
435
+ return instance;
436
+ }
437
+ else {
438
+ // directly execute action
439
+ instance.state = ActionInstanceStateEnum.ActivationEnd;
440
+ const context = this.prepareContext(action, parameters, undefined, instance, previousActionInstance);
441
+ if (runContext) {
442
+ this.run(context);
443
+ }
444
+ return context.instance;
445
+ }
446
+ }
447
+ /**
448
+ * To be called when action editor is initialized to correctly activate action.
449
+ * @param action Action descriptor.
450
+ * @param instance Action instance (if available).
451
+ */
452
+ onActionEditorInit(action, instance) {
453
+ if (action.type !== ActionTypeEnum.Editor) {
454
+ throw new Error(`Action ${action.actionName} is not of type editor, cannot be activated through "onActionEditorOnInit"`);
455
+ }
456
+ if (instance && action.activationTrigger === ActionActivationTriggerEnum.OnRoute) {
457
+ const triggeredInstance = instance.activationParameters?.viewContainer?.getActionRouteTriggeredInstance?.();
458
+ const activationInstance = instance.activationParameters?.viewContainer?.getActionRouteTriggeredInstance?.();
459
+ if (triggeredInstance && triggeredInstance.instanceLongName !== instance.instanceLongName) {
460
+ console.warn(`Found triggered parameters view container instance ${triggeredInstance.instanceLongName} and it does not match instance ${instance.instanceLongName} retrieved on editor init.`);
461
+ }
462
+ if (activationInstance && activationInstance.instanceLongName !== instance.instanceLongName) {
463
+ console.warn(`Found triggered parameters view container instance ${activationInstance.instanceLongName} and it does not match instance ${instance.instanceLongName} retrieved on editor init.`);
464
+ }
465
+ }
466
+ instance = this.getOrCreateInstance(instance, action, undefined, ActionInstanceStateEnum.ActivationStart);
467
+ instance.state = ActionInstanceStateEnum.ActivationEnd;
468
+ return instance;
469
+ }
470
+ /**
471
+ * To be called when action editor cmp is being destroyed to correctly finish action.
472
+ * @param instance Action instance.
473
+ */
474
+ onActionEditorDestroy(instance) {
475
+ if (!instance) {
476
+ return;
477
+ }
478
+ instance = this.getOrCreateInstance(instance);
479
+ if (instance.action.type !== ActionTypeEnum.Editor) {
480
+ throw new Error(`Action instance ${instance.instanceLongName} is not of type editor, cannot be deactivated through "onActionEditorOnDestroy"`);
481
+ }
482
+ if (instance.action.activationTrigger !== ActionActivationTriggerEnum.OnRoute) {
483
+ this.finishAction(instance, true);
484
+ }
485
+ }
486
+ /**
487
+ * To be called when action route cmp is being destroyed to correctly finish action.
488
+ * @param instance Action instance.
489
+ */
490
+ onActionRouteDestroy(instance) {
491
+ if (!instance) {
492
+ return;
493
+ }
494
+ instance = this.getOrCreateInstance(instance);
495
+ if (instance.action.activationTrigger !== ActionActivationTriggerEnum.OnRoute) {
496
+ throw new Error(`Action instance ${instance.instanceLongName} is not triggered on route, cannot be deactivated through "onActionRouteOnDestroy"`);
497
+ }
498
+ this.finishAction(instance, true);
499
+ }
500
+ /**
501
+ * Deactivates action by choosing final state, closing dialog and completing all subjects in instance and contexts.
502
+ *
503
+ * @param instance Action instance.
504
+ * @param onDestroy Marks if finish is called on component destroy lifecycle hook.
505
+ */
506
+ finishAction(instance, onDestroy = false) {
507
+ instance = this.getOrCreateInstance(instance);
508
+ if (instance.state >= ActionInstanceStateEnum.FinishSuccessFinal) {
509
+ if (this.debugLog) {
510
+ // eslint-disable-next-line no-console, no-restricted-syntax
511
+ console.debug(`ActionInstance ${instance.instanceLongName} already finished`);
512
+ }
513
+ return;
514
+ }
515
+ let finalState;
516
+ if (typeof instance.result !== 'undefined') {
517
+ finalState = ActionInstanceStateEnum.FinishSuccessFinal;
518
+ }
519
+ else if (typeof instance.error !== 'undefined') {
520
+ finalState = ActionInstanceStateEnum.FinishErrorFinal;
521
+ }
522
+ else if (onDestroy) {
523
+ finalState = ActionInstanceStateEnum.FinishComponentDestroyFinal;
524
+ }
525
+ else {
526
+ finalState = ActionInstanceStateEnum.FinishDismissedFinal;
527
+ }
528
+ if (instance.action.type === ActionTypeEnum.Editor) {
529
+ const hasDialog = typeof instance.activationDialogRef !== 'undefined';
530
+ const resubmitEnabled = instance.action.resubmitEnabled;
531
+ if (finalState === ActionInstanceStateEnum.FinishSuccessFinal) {
532
+ if ((hasDialog && resubmitEnabled === true) || (!hasDialog && resubmitEnabled !== false)) {
533
+ finalState = ActionInstanceStateEnum.FinishSuccessReactivateFinal;
534
+ }
535
+ }
536
+ if (hasDialog && finalState !== ActionInstanceStateEnum.FinishSuccessReactivateFinal) {
537
+ // if state is finish and not called from dialog listener, close the dialog first which will retrigger this function, then finish it
538
+ instance.activationDialogRef.close(instance.result);
539
+ }
540
+ }
541
+ // unset instance in view container
542
+ instance.context?.parameters.viewContainer?.unsetActionRouteTriggeredInstance?.();
543
+ // set final state on instance
544
+ instance.state = finalState;
545
+ if (finalState === ActionInstanceStateEnum.FinishSuccessReactivateFinal) {
546
+ // prepare reactivation instance
547
+ const newInstanceStatus = instance.action.resubmitRefetch ? ActionInstanceStateEnum.ActivationEnd : ActionInstanceStateEnum.FetchEnd;
548
+ // must skip initialization from view container, because it would only get old instance.
549
+ // we need new instance before we can set new one on the view container.
550
+ const newInstance = this.getOrCreateInstance(undefined, instance.action, undefined, newInstanceStatus, true);
551
+ newInstance.previousInstance = instance;
552
+ // copy some additional settings
553
+ newInstance.activationDialogRef = instance.activationDialogRef;
554
+ newInstance.triggerParameters = instance.triggerParameters;
555
+ newInstance.activationParameters = instance.activationParameters;
556
+ instance.context?.parameters.viewContainer?.setActionRouteTriggeredInstance?.(newInstance);
557
+ instance.reactivationInstance = newInstance;
558
+ }
559
+ }
560
+ /**
561
+ * Triggers action with parameters.
562
+ *
563
+ * @param action Action descriptor.
564
+ * @param parameters Action parameters for action execution to construct new route.
565
+ * @param runContext Marks if context should be run.
566
+ *
567
+ * @return Action instance - if non provided in parameters, the newly created will be returned.
568
+ */
569
+ triggerAction(action, parameters, runContext = false) {
570
+ const instance = this.getOrCreateInstance(undefined, action, parameters);
571
+ instance.triggerParameters = parameters;
572
+ instance.state = ActionInstanceStateEnum.TriggerStart;
573
+ if (action.activationTrigger === ActionActivationTriggerEnum.OnRoute) {
574
+ const baseUrl = this.router.url.split('?')[0];
575
+ const parsedUrl = this.router.parseUrl(this.router.url);
576
+ let actionUrl = action.routeUrl ?? '';
577
+ // TODO: dont strip '/', but use it accordingly with Angular's router patterns (/, ./, ../)
578
+ if (actionUrl.startsWith('/')) {
579
+ actionUrl = actionUrl.substring(1);
580
+ }
581
+ const actionUrlSegments = this.parametrize.transform(actionUrl, parameters.itemId, parameters.item, parameters.actionData).split('/');
582
+ // set instance in view container
583
+ parameters.viewContainer?.setActionRouteTriggeredInstance?.(instance);
584
+ from(this.router.navigate([baseUrl, ...actionUrlSegments], { relativeTo: parameters.route, queryParams: parsedUrl.queryParams }))
585
+ .pipe(take(1))
586
+ .subscribe(() => (instance.state = ActionInstanceStateEnum.TriggerEnd));
587
+ return instance;
588
+ }
589
+ else {
590
+ instance.state = ActionInstanceStateEnum.TriggerEnd;
591
+ this.activateAction(action, parameters, instance);
592
+ if (runContext) {
593
+ const context = instance.context;
594
+ if (context) {
595
+ this.run(context);
596
+ }
597
+ }
598
+ return instance;
599
+ }
600
+ }
601
+ /**
602
+ * Deactivates on route triggered action by trying to reroute back to location where action was triggered.
603
+ * @param instance Action instance.
604
+ */
605
+ finishActionRouteUntrigger(instance) {
606
+ if (instance.action.activationTrigger !== ActionActivationTriggerEnum.OnRoute) {
607
+ return;
608
+ }
609
+ instance = this.getOrCreateInstance(instance);
610
+ instance.state = ActionInstanceStateEnum.FinishRouteUntriggerStart;
611
+ let url = this.navigationService.getCurrentLocationFromHistory() ?? this.navigationService.getCurrentLocationFromUrl();
612
+ if (!url) {
613
+ this.navigationService.back();
614
+ }
615
+ else {
616
+ if (url.startsWith('/')) {
617
+ url = url.substring(1);
618
+ }
619
+ const splitUrlQueryParam = url.split('?');
620
+ const urlPathSegments = splitUrlQueryParam[0].split('#')[0].split('/');
621
+ const queryParam = splitUrlQueryParam[1]?.split('#')[0];
622
+ let actionUrl = instance.action?.routeUrl ?? '';
623
+ if (actionUrl.startsWith('/')) {
624
+ actionUrl = actionUrl.substring(1);
625
+ }
626
+ const actionUrlSegments = actionUrl.split('/');
627
+ let redirectUrl = '/' + urlPathSegments.slice(0, urlPathSegments.length - actionUrlSegments.length).join('/');
628
+ if (typeof queryParam !== 'undefined') {
629
+ redirectUrl = `${redirectUrl}?${queryParam}`;
630
+ }
631
+ // No URL replaces, probably ok, to allow going back
632
+ from(this.router.navigateByUrl(redirectUrl))
633
+ .pipe(first(), timeout(1000))
634
+ .subscribe({
635
+ next: () => (instance.state = ActionInstanceStateEnum.FinishRouteUntriggerEndFinal),
636
+ error: () => (instance.state = ActionInstanceStateEnum.FinishRouteUntriggerTimeoutFinal)
637
+ });
638
+ }
639
+ }
640
+ /**
641
+ * Transform error of any type to mng error by using error mapper that could be provided by final project.
642
+ * @param error error of any type.
643
+ *
644
+ * @return mapped MngError.
645
+ */
646
+ toMngActionError(error) {
647
+ const actionError = {
648
+ name: error?.name ?? 'UnknownError',
649
+ message: error?.message ?? 'Unknown error',
650
+ cause: error
651
+ };
652
+ if (error instanceof HttpErrorResponse) {
653
+ actionError.status = error.status;
654
+ actionError.statusDescription = error.statusText;
655
+ actionError.url = error.url ?? undefined;
656
+ }
657
+ return this.errorMapper.toMngError(error, actionError);
658
+ }
659
+ /**
660
+ * Creates or gets existing action instance.
661
+ * @param instance Action instance.
662
+ * @param action Action descriptor.
663
+ * @param parameters Action parameters.
664
+ * @param instanceInitialStatus Action instance initial status.
665
+ * @param skipInitializationFromViewContainer If initialization of instance from view container should be skipped.
666
+ * @private
667
+ */
668
+ getOrCreateInstance(instance, action, parameters, instanceInitialStatus, skipInitializationFromViewContainer = false) {
669
+ if (!skipInitializationFromViewContainer && !instance && action?.activationTrigger === ActionActivationTriggerEnum.OnRoute && parameters) {
670
+ instance = parameters.viewContainer?.getActionRouteTriggeredInstance?.();
671
+ }
672
+ if (!instance) {
673
+ if (!action) {
674
+ throw new MngErrorInternal('Action descriptor is not provided, instance cannot be created.', 'ActionExecutorService error').consoleError();
675
+ }
676
+ // create new instance if non provided
677
+ instance = new ActionInstance(action, instanceInitialStatus, this.debugLog);
678
+ }
679
+ if (this.mngCommons.actionsDebugInstances && !this._instances.some(i => i.instanceLongName === instance.instanceLongName)) {
680
+ if (this._instances.length >= this.instancesBufferMax) {
681
+ const lastInstance = this._instances.shift();
682
+ if (this.debugLog && lastInstance.state < ActionInstanceStateEnum.FinishSuccessFinal) {
683
+ console.error(`Not all instances are finished! Finishing instance ${instance.instanceLongName} with dismissal.`);
684
+ lastInstance.forceFinish();
685
+ }
686
+ }
687
+ this._instances.push(instance);
688
+ }
689
+ return instance;
690
+ }
691
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MngActionExecutorService, deps: [{ token: i0.Injector }, { token: i1.Router }, { token: i2.DialogService }, { token: i3.TranslateService }, { token: i4.MngCommonsService }, { token: i5.MngNavigationService }, { token: i6.MngErrorMapperService }, { token: i7.MngParametrizePipe }, { token: ACTION_EDITOR_DIALOG_COMPONENT_SETTING }], target: i0.ɵɵFactoryTarget.Injectable }); }
692
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MngActionExecutorService, providedIn: 'root' }); }
693
+ }
694
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MngActionExecutorService, decorators: [{
695
+ type: Injectable,
696
+ args: [{
697
+ providedIn: 'root'
698
+ }]
699
+ }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.Router }, { type: i2.DialogService }, { type: i3.TranslateService }, { type: i4.MngCommonsService }, { type: i5.MngNavigationService }, { type: i6.MngErrorMapperService }, { type: i7.MngParametrizePipe }, { type: i0.Type, decorators: [{
700
+ type: Inject,
701
+ args: [ACTION_EDITOR_DIALOG_COMPONENT_SETTING]
702
+ }] }]; } });
703
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWV4ZWN1dG9yLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2FjdGlvbi1leGVjdXRvci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBQ3ZELE9BQU8sRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDakUsT0FBTyxFQUFDLE1BQU0sRUFBVSxNQUFNLGlCQUFpQixDQUFDO0FBRWhELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBRXJELE9BQU8sRUFBQyxhQUFhLEVBQXNCLE1BQU0sdUJBQXVCLENBQUM7QUFDekUsT0FBTyxFQUFhLElBQUksRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzlFLE9BQU8sRUFBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUU5RCxPQUFPLEVBQUMsYUFBYSxFQUFFLHVCQUF1QixFQUFFLGNBQWMsRUFBRSx1QkFBdUIsRUFBRSxnQkFBZ0IsRUFBNkIsTUFBTSw2QkFBNkIsQ0FBQztBQUUxSyxPQUFPLEVBQXVELHNCQUFzQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDbkgsT0FBTyxFQUFDLDJCQUEyQixFQUFFLGNBQWMsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBQ2pGLE9BQU8sRUFBK0QsZ0JBQWdCLEVBQUMsTUFBTSxXQUFXLENBQUM7QUFDekcsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sVUFBVSxDQUFDO0FBQzVDLE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQztBQUMvQyxPQUFP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O2FBQzlJO1lBQ0Qsc0NBQXNDO1lBQ3RDLFFBQVEsR0FBRyxJQUFJLGNBQWMsQ0FBTyxNQUFNLEVBQUUscUJBQXFCLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1NBQ3JGO1FBRUQsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLHFCQUFxQixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLEtBQUssUUFBUyxDQUFDLGdCQUFnQixDQUFDLEVBQUU7WUFDeEgsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUU7Z0JBQ25ELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBRTdDLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxZQUFhLENBQUMsS0FBSyxHQUFHLHVCQUF1QixDQUFDLGtCQUFrQixFQUFFO29CQUNuRixPQUFPLENBQUMsS0FBSyxDQUFDLHNEQUFzRCxRQUFRLENBQUMsZ0JBQWdCLGtCQUFrQixDQUFDLENBQUM7b0JBQ2pILFlBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztpQkFDL0I7YUFDSjtZQUVELElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1NBQ2xDO1FBRUQsT0FBTyxRQUFRLENBQUM7SUFDcEIsQ0FBQzs4R0FwMEJRLHdCQUF3Qix5UUFjckIsc0NBQXNDO2tIQWR6Qyx3QkFBd0IsY0FGckIsTUFBTTs7MkZBRVQsd0JBQXdCO2tCQUhwQyxVQUFVO21CQUFDO29CQUNSLFVBQVUsRUFBRSxNQUFNO2lCQUNyQjs7MEJBZVEsTUFBTTsyQkFBQyxzQ0FBc0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0h0dHBFcnJvclJlc3BvbnNlfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQge0luamVjdCwgSW5qZWN0YWJsZSwgSW5qZWN0b3IsIFR5cGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtSb3V0ZXIsIFVybFRyZWV9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5cbmltcG9ydCB7VHJhbnNsYXRlU2VydmljZX0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQge0NvbmZpcm1hdGlvbn0gZnJvbSAncHJpbWVuZy9hcGknO1xuaW1wb3J0IHtEaWFsb2dTZXJ2aWNlLCBEeW5hbWljRGlhbG9nQ29uZmlnfSBmcm9tICdwcmltZW5nL2R5bmFtaWNkaWFsb2cnO1xuaW1wb3J0IHtPYnNlcnZhYmxlLCBmcm9tLCBtZXJnZU1hcCwgb2YsIHN3aXRjaE1hcCwgdGFrZSwgdGltZW91dH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge2NhdGNoRXJyb3IsIGZpbHRlciwgZmlyc3QsIG1hcH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQge0FjdGlvbkNvbnRleHQsIEFjdGlvbkNvbnRleHRWYWxpZGF0aW9uLCBBY3Rpb25JbnN0YW5jZSwgQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0sIEFjdGlvblBhcmFtZXRlcnMsIElBY3Rpb25Db25maXJtYXRpb25TZXJ2aWNlfSBmcm9tICcuLi9jb21wb25lbnRzL2FjdGlvbi9tb2RlbHMnO1xuaW1wb3J0IHtJRGF0YVByb3ZpZGVyLCBJRWRpdG9yRGF0YVByb3ZpZGVyfSBmcm9tICcuLi9kYXRhLXByb3ZpZGVycyc7XG5pbXBvcnQge0FjdGlvbkNvbmZpcm1hdGlvbkRpYWxvZ0Rlc2NyaXB0b3IsIEFjdGlvbkRlc2NyaXB0b3IsIEFjdGlvbkVkaXRvckRlc2NyaXB0b3J9IGZyb20gJy4uL2Rlc2NyaXB0b3JzL2FjdGlvbic7XG5pbXBvcnQge0FjdGlvbkFjdGl2YXRpb25UcmlnZ2VyRW51bSwgQWN0aW9uVHlwZUVudW19IGZyb20gJy4uL2Rlc2NyaXB0b3JzL3R5cGVzJztcbmltcG9ydCB7SVZpZXdBY3Rpb25Sb3V0ZVRyaWdnZXJlZENvbnRhaW5lciwgSVZpZXdDb250YWluZXIsIE1uZ0Vycm9yLCBNbmdFcnJvckludGVybmFsfSBmcm9tICcuLi9tb2RlbHMnO1xuaW1wb3J0IHtNbmdQYXJhbWV0cml6ZVBpcGV9IGZyb20gJy4uL3BpcGVzJztcbmltcG9ydCB7U3R5bGVTaXplRW51bX0gZnJvbSAnLi4vc3R5bGVzL21vZGVscyc7XG5pbXBvcnQge0FjdGlvbkRhdGFQcm92aWRlclV0aWwsIEkxOG5VdGlscywgTm90aWZpY2F0aW9uVXRpbCwgU3RyaW5nVXRpbH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHtNbmdDb21tb25zU2VydmljZX0gZnJvbSAnLi9jb21tb25zLnNlcnZpY2UnO1xuaW1wb3J0IHtNbmdFcnJvck1hcHBlclNlcnZpY2V9IGZyb20gJy4vZXJyb3ItbWFwcGVyLnNlcnZpY2UnO1xuaW1wb3J0IHtNbmdOYXZpZ2F0aW9uU2VydmljZX0gZnJvbSAnLi9uYXZpZ2F0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHtBQ1RJT05fRURJVE9SX0RJQUxPR19DT01QT05FTlRfU0VUVElOR30gZnJvbSAnLi90b2tlbnMnO1xuXG5ASW5qZWN0YWJsZSh7XG4gICAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIE1uZ0FjdGlvbkV4ZWN1dG9yU2VydmljZSB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBkZWJ1Z0xvZzogYm9vbGVhbjtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGluc3RhbmNlc0J1ZmZlck1heCA9IDEwMDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9pbnN0YW5jZXM6IEFjdGlvbkluc3RhbmNlPGFueSwgYW55PltdID0gW107XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgICAgIHByaXZhdGUgZGlhbG9nU2VydmljZTogRGlhbG9nU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbW5nQ29tbW9uczogTW5nQ29tbW9uc1NlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbmF2aWdhdGlvblNlcnZpY2U6IE1uZ05hdmlnYXRpb25TZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIGVycm9yTWFwcGVyOiBNbmdFcnJvck1hcHBlclNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgcGFyYW1ldHJpemU6IE1uZ1BhcmFtZXRyaXplUGlwZSxcbiAgICAgICAgQEluamVjdChBQ1RJT05fRURJVE9SX0RJQUxPR19DT01QT05FTlRfU0VUVElORykgcHJpdmF0ZSBkZWZhdWx0RWRpdG9yRGlhbG9nQ29tcG9uZW50OiBUeXBlPGFueT5cbiAgICApIHtcbiAgICAgICAgdGhpcy5kZWJ1Z0xvZyA9IHRoaXMubW5nQ29tbW9ucy5hY3Rpb25zRGVidWdMb2c7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBpbnN0YW5jZXMoKSB7XG4gICAgICAgIHJldHVybiBbLi4udGhpcy5faW5zdGFuY2VzXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmVwYXJlcyBhY3Rpb24gY29udGV4dCBmb3IgdXNhZ2UgaW4gdmFsaWRhdGlvbi5cbiAgICAgKiBAcGFyYW0gYWN0aW9uIEFjdGlvbiBkZXNjcmlwdG9yLlxuICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJzIEFjdGlvbiBwYXJhbWV0ZXJzLlxuICAgICAqIEBwYXJhbSBkYXRhUHJvdmlkZXIgRGF0YSBwcm92aWRlci5cbiAgICAgKi9cbiAgICBwdWJsaWMgcHJlcGFyZUFjdGlvbkNvbnRleHRWYWxpZGF0aW9uPFQsIFM+KGFjdGlvbjogQWN0aW9uRGVzY3JpcHRvcjxUPiwgcGFyYW1ldGVyczogQWN0aW9uUGFyYW1ldGVyczxUPiwgZGF0YVByb3ZpZGVyPzogSURhdGFQcm92aWRlcjxULCBTPik6IEFjdGlvbkNvbnRleHRWYWxpZGF0aW9uPFQsIFM+IHtcbiAgICAgICAgY29uc3QgY3R4RGF0YVByb3ZpZGVyID0gZGF0YVByb3ZpZGVyID8/IGFjdGlvbi5kYXRhUHJvdmlkZXIgPz8gcGFyYW1ldGVycy52aWV3Q29udGFpbmVyPy5nZXREYXRhUHJvdmlkZXIoKTtcbiAgICAgICAgcmV0dXJuIG5ldyBBY3Rpb25Db250ZXh0VmFsaWRhdGlvbjxULCBTPihhY3Rpb24sIHBhcmFtZXRlcnMsIGN0eERhdGFQcm92aWRlciwgQWN0aW9uRGF0YVByb3ZpZGVyVXRpbC5nZXREYXRhUHJvdmlkZXJTZXJ2aWNlKHRoaXMuaW5qZWN0b3IsIGN0eERhdGFQcm92aWRlcikgPz8gdW5kZWZpbmVkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSdW5zIGFjdGlvbiBjb250ZXh0IGJ5IHN1Ym1pdHRpbmcgZXhlY3V0aW9uIHJlc3VsdHMvZXJyb3JzIHRvIGNvbnRleHQsIHdhdGNoaW5nIG92ZXIgaW5zdGFuY2UgcmVzdWx0cy9lcnJvcnMsIGRpc3BsYXlpbmcgbm90aWZpY2F0aW9ucyxcbiAgICAgKiBydW5uaW5nIG5leHQvZXJyb3IgYWN0aW9uIGFuZCB0cmlnZ2VyaW5nIGRpc21pc3Mgb2YgYWN0aW9uLiBDb25maXJtYXRpb24gaXMgYWxzbyBwcm9jZXNzZWQgaGVyZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBjdHggQWN0aW9uIGNvbnRleHQgdG8gcnVuLlxuICAgICAqL1xuICAgIHB1YmxpYyBydW48VCwgUz4oY3R4OiBBY3Rpb25Db250ZXh0PFQsIFM+KSB7XG4gICAgICAgIGNvbnN0IGlzTWFpblJ1bkZuID0gY3R4LmZ1bmN0aW9uTmFtZSA9PT0gJ3N1Ym1pdCcgfHwgY3R4LmZ1bmN0aW9uTmFtZSA9PT0gJ3J1bic7XG5cbiAgICAgICAgLy8gaWYgKGN0eC5pbnN0YW5jZS5hY3Rpb24udHlwZSA9PT0gQWN0aW9uVHlwZUVudW0uRGlyZWN0ICYmIGN0eC5pbnN0YW5jZS5hY3Rpb24uaGFzUnVuQ29uZmlybWF0aW9uKSB7XG4gICAgICAgIGlmIChpc01haW5SdW5GbiAmJiBjdHguaW5zdGFuY2UuYWN0aW9uLmhhc1J1bkNvbmZpcm1hdGlvbikge1xuICAgICAgICAgICAgLy8gb25seSBkaXJlY3QgYWN0aW9uIGNhbiBiZSBjb25maWd1cmVkIHdpdGggcnVuIGNvbmZpcm1hdGlvblxuICAgICAgICAgICAgLy8gaWYgZWRpdG9yLCB0aGVuIHJ1biBjb25maXJtYXRpb24gaXMgbWFwcGVkIHRvIHN1Ym1pdCBhY3Rpb24gYW5kIGlnbm9yZWQgYXMgZWRpdG9yIHJ1blxuICAgICAgICAgICAgY29uc3Qgc291cmNlQ29tcG9uZW50ID0gY3R4LnBhcmFtZXRlcnM/LnNvdXJjZUNvbXBvbmVudDtcbiAgICAgICAgICAgIGNvbnN0IGNvbmZpcm1hdGlvbkRlc2NyaXB0b3IgPSBjdHguaW5zdGFuY2UuYWN0aW9uLnJ1bkNvbmZpcm1hdGlvbkRpYWxvZ0Rlc2NyaXB0b3IgYXMgQWN0aW9uQ29uZmlybWF0aW9uRGlhbG9nRGVzY3JpcHRvcjxUPjtcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzb3VyY2VDb21wb25lbnQ/LmdldENvbmZpcm1hdGlvblNlcnZpY2UgIT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIHNvdXJjZUNvbXBvbmVudD8uZ2V0Q29uZmlybWF0aW9uU2VydmljZUluc3RhbmNlS2V5ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1uZ0Vycm9ySW50ZXJuYWwoXG4gICAgICAgICAgICAgICAgICAgIGBTb3VyY2UgY29tcG9uZW50ICR7c291cmNlQ29tcG9uZW50fSBzaG91bGQgYmUgaW1wbGVtZW50aW5nIElDb25maXJtYXRpb25TZXJ2aWNlIGludGVyZmFjZSB0byBiZSBhYmxlIHRvIHByb3ZpZGUgY29uZmlybWF0aW9uIGZ1bmN0aW9uYWxpdHkuYCxcbiAgICAgICAgICAgICAgICAgICAgJ0FjdGlvbkV4ZWN1dG9yU2VydmljZSBlcnJvcidcbiAgICAgICAgICAgICAgICApLmNvbnNvbGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBpdGVtID0gY3R4LnBhcmFtZXRlcnMuaXRlbTtcblxuICAgICAgICAgICAgY29uc3Qgc3JjQ29uZmlybUNvbXBvbmVudCA9IHNvdXJjZUNvbXBvbmVudCBhcyBJQWN0aW9uQ29uZmlybWF0aW9uU2VydmljZTtcbiAgICAgICAgICAgIGxldCBjb25maXJtUGFyYW1zOiBDb25maXJtYXRpb24gPSB7XG4gICAgICAgICAgICAgICAga2V5OiBzcmNDb25maXJtQ29tcG9uZW50LmdldENvbmZpcm1hdGlvblNlcnZpY2VJbnN0YW5jZUtleShjdHguaW5zdGFuY2UuYWN0aW9uKSxcbiAgICAgICAgICAgICAgICBpY29uOiBjb25maXJtYXRpb25EZXNjcmlwdG9yLmljb24sXG4gICAgICAgICAgICAgICAgYWNjZXB0VmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBhY2NlcHRJY29uOiBjb25maXJtYXRpb25EZXNjcmlwdG9yLmFjY2VwdEJ1dHRvbi5pY29uID8/IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBhY2NlcHRCdXR0b25TdHlsZUNsYXNzOiBjb25maXJtYXRpb25EZXNjcmlwdG9yLmFjY2VwdEJ1dHRvbi5zdHlsZUNsYXNzLmJ1aWxkKCksXG4gICAgICAgICAgICAgICAgcmVqZWN0VmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICByZWplY3RJY29uOiBjb25maXJtYXRpb25EZXNjcmlwdG9yLnJlamVjdEJ1dHRvbj8uaWNvbiA/PyB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgcmVqZWN0QnV0dG9uU3R5bGVDbGFzczogY29uZmlybWF0aW9uRGVzY3JpcHRvci5yZWplY3RCdXR0b24/LnN0eWxlQ2xhc3MuYnVpbGQoKSxcbiAgICAgICAgICAgICAgICBjbG9zZU9uRXNjYXBlOiBjb25maXJtYXRpb25EZXNjcmlwdG9yLmNsb3NlT25Fc2NhcGVcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmIChjb25maXJtYXRpb25EZXNjcmlwdG9yLnRpdGxlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uZmlybVBhcmFtcy5oZWFkZXIgPVxuICAgICAgICAgICAgICAgICAgICBJMThuVXRpbHMuQWN0aW9uLmdldCh0aGlzLnRyYW5zbGF0ZSwgY3R4Lmluc3RhbmNlLmFjdGlvbiwgJ2NvbmZpcm0udGl0bGUnLCBjb25maXJtYXRpb25EZXNjcmlwdG9yLnRpdGxlLCBpdGVtLCAnZ2VuZXJhbC5jb25maXJtYXRpb24nKSA/PyB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb25maXJtYXRpb25EZXNjcmlwdG9yLm1lc3NhZ2UgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25maXJtUGFyYW1zLm1lc3NhZ2UgPVxuICAgICAgICAgICAgICAgICAgICBJMThuVXRpbHMuQWN0aW9uLmdldChcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJhbnNsYXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLmFjdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICdjb25maXJtLm1lc3NhZ2UnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlybWF0aW9uRGVzY3JpcHRvci5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nVXRpbC5lc2NhcGVIdG1sQW55KGl0ZW0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbmVyYWwuY29uZmlybWF0aW9uJ1xuICAgICAgICAgICAgICAgICAgICApID8/IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbmZpcm1hdGlvbkRlc2NyaXB0b3IuYWNjZXB0QnV0dG9uLmxhYmVsICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uZmlybVBhcmFtcy5hY2NlcHRMYWJlbCA9XG4gICAgICAgICAgICAgICAgICAgIEkxOG5VdGlscy5BY3Rpb24uZ2V0KHRoaXMudHJhbnNsYXRlLCBjdHguaW5zdGFuY2UuYWN0aW9uLCAnY29uZmlybS5hY2NlcHQnLCBjb25maXJtYXRpb25EZXNjcmlwdG9yLmFjY2VwdEJ1dHRvbi5sYWJlbCwgaXRlbSwgJ2dlbmVyYWwueWVzJykgPz8gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY29uZmlybWF0aW9uRGVzY3JpcHRvci5hY2NlcHRCdXR0b24uaWNvbiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbmZpcm1QYXJhbXMuYWNjZXB0SWNvbiA9IGNvbmZpcm1hdGlvbkRlc2NyaXB0b3IuYWNjZXB0QnV0dG9uLmljb247XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb25maXJtYXRpb25EZXNjcmlwdG9yLnJlamVjdEJ1dHRvbj8uaWNvbiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbmZpcm1QYXJhbXMucmVqZWN0SWNvbiA9IGNvbmZpcm1hdGlvbkRlc2NyaXB0b3IucmVqZWN0QnV0dG9uPy5pY29uO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY29uZmlybWF0aW9uRGVzY3JpcHRvci5yZWplY3RCdXR0b24/LmxhYmVsICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uZmlybVBhcmFtcy5yZWplY3RMYWJlbCA9XG4gICAgICAgICAgICAgICAgICAgIEkxOG5VdGlscy5BY3Rpb24uZ2V0KHRoaXMudHJhbnNsYXRlLCBjdHguaW5zdGFuY2UuYWN0aW9uLCAnY29uZmlybS5yZWplY3QnLCBjb25maXJtYXRpb25EZXNjcmlwdG9yLnJlamVjdEJ1dHRvbj8ubGFiZWwsIGl0ZW0sICdnZW5lcmFsLm5vJykgPz8gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY29uZmlybWF0aW9uRGVzY3JpcHRvci5yZWplY3RCdXR0b24gPT0gbnVsbCB8fCAoY29uZmlybWF0aW9uRGVzY3JpcHRvci5yZWplY3RCdXR0b24ubGFiZWwgPT09IG51bGwgJiYgY29uZmlybWF0aW9uRGVzY3JpcHRvci5yZWplY3RCdXR0b24uaWNvbiA9PT0gbnVsbCkpIHtcbiAgICAgICAgICAgICAgICBjb25maXJtUGFyYW1zLnJlamVjdFZpc2libGUgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uZmlybVBhcmFtcy5hY2NlcHQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLnN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uUnVuQ29uZmlybWF0aW9uRW5kQWNjZXB0O1xuICAgICAgICAgICAgICAgIHRoaXMucnVuV2l0aG91dENvbmZpcm1hdGlvbihjdHgpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uZmlybVBhcmFtcy5yZWplY3QgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLnN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uUnVuQ29uZmlybWF0aW9uRW5kUmVqZWN0O1xuICAgICAgICAgICAgICAgIGlmIChjdHguaW5zdGFuY2UuYWN0aW9uLnR5cGUgIT09IEFjdGlvblR5cGVFbnVtLkVkaXRvcikge1xuICAgICAgICAgICAgICAgICAgICAvLyBpZiBub3QgZWRpdG9yLCB0aGUgaXQgY2FuIGJlIGNsb3NlZFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbmlzaEFjdGlvbihjdHguaW5zdGFuY2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmIChjb25maXJtYXRpb25EZXNjcmlwdG9yLnJ1bkNvbmZpcm1hdGlvbkNvbmZpZ01hcEZuKSB7XG4gICAgICAgICAgICAgICAgY29uZmlybVBhcmFtcyA9IGNvbmZpcm1hdGlvbkRlc2NyaXB0b3IucnVuQ29uZmlybWF0aW9uQ29uZmlnTWFwRm4oY3R4LCBjb25maXJtUGFyYW1zKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY3R4LmNvbmZpcm1hdGlvbiA9IGNvbmZpcm1QYXJhbXM7XG4gICAgICAgICAgICBjdHguaW5zdGFuY2Uuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5SdW5Db25maXJtYXRpb25TdGFydDtcblxuICAgICAgICAgICAgc3JjQ29uZmlybUNvbXBvbmVudC5nZXRDb25maXJtYXRpb25TZXJ2aWNlKCkuY29uZmlybShjb25maXJtUGFyYW1zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucnVuV2l0aG91dENvbmZpcm1hdGlvbihjdHgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUnVucyBhY3Rpb24gY29udGV4dCBieSBzdWJtaXR0aW5nIGV4ZWN1dGlvbiByZXN1bHRzL2Vycm9ycyB0byBjb250ZXh0LCB3YXRjaGluZyBvdmVyIGluc3RhbmNlIHJlc3VsdHMvZXJyb3JzLCBkaXNwbGF5aW5nIG5vdGlmaWNhdGlvbnMsXG4gICAgICogcnVubmluZyBuZXh0L2Vycm9yIGFjdGlvbiBhbmQgdHJpZ2dlcmluZyBkaXNtaXNzIG9mIGFjdGlvbi4gQ29uZmlybWF0aW9uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY3R4IEFjdGlvbiBjb250ZXh0IHRvIHJ1bi5cbiAgICAgKiBAcGFyYW0gcGFyYW1ldGVycyBBY3Rpb24gcGFyYW1ldGVycyBmb3IgY29udGV4dC5cbiAgICAgKiBAcGFyYW0gZGF0YVByb3ZpZGVyIEVkaXRvciBkYXRhIHByb3ZpZGVyIGZvciBjb250ZXh0LlxuICAgICAqIEBwYXJhbSBpbnN0YW5jZSBPcHRpb25hbCBleGlzdGluZyBhY3Rpb24gaW5zdGFuY2UgKGlmIG5vbiBwcm92aWRlZCwgbmV3IHdpbGwgYmUgY3JlYXRlZCkuXG4gICAgICogQHBhcmFtIHByZXZpb3VzQWN0aW9uSW5zdGFuY2UgT3B0aW9uYWwgcHJldmlvdXMgYWN0aW9uIGluc3RhbmNlIHRvIGxpbmsgaW4gbmV4dCBpbnN0YW5jZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm4gQWN0aW9uIGNvbnRleHQgZm9yIHN1Ym1pdCAoPXJ1bikgZnVuY3Rpb24uXG4gICAgICovXG4gICAgcHJpdmF0ZSBydW5XaXRob3V0Q29uZmlybWF0aW9uPFQsIFM+KGN0eDogQWN0aW9uQ29udGV4dDxULCBTPik6IE9ic2VydmFibGU8VCB8IG51bGwgfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgY29uc3QgaXNNYWluUnVuRm4gPSBjdHguZnVuY3Rpb25OYW1lID09PSAnc3VibWl0JyB8fCBjdHguZnVuY3Rpb25OYW1lID09PSAncnVuJztcbiAgICAgICAgY29uc3QgaXNFcnJvckNyaXRpY2FsUnVuRm4gPSBjdHguZnVuY3Rpb25OYW1lID09PSAncnVuJztcbiAgICAgICAgbGV0IGFjdGlvbkVkaXRvcjogQWN0aW9uRWRpdG9yRGVzY3JpcHRvcjxUPjtcblxuICAgICAgICBsZXQgZm5PYnM6IChjdHg6IEFjdGlvbkNvbnRleHQ8VCwgUz4pID0+IE9ic2VydmFibGU8VCB8IG51bGwgfCB1bmRlZmluZWQ+O1xuICAgICAgICBzd2l0Y2ggKGN0eC5mdW5jdGlvbk5hbWUpIHtcbiAgICAgICAgICAgIGNhc2UgJ3N1Ym1pdCc6XG4gICAgICAgICAgICAgICAgYWN0aW9uRWRpdG9yID0gY3R4Lmluc3RhbmNlLmFjdGlvbiBhcyBBY3Rpb25FZGl0b3JEZXNjcmlwdG9yPFQ+O1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYWN0aW9uRWRpdG9yLnN1Ym1pdEZ1bmN0aW9uICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRlZmF1bHRTdWJtaXQgPSBvZihjdHgucGFyYW1ldGVycz8uaXRlbSA/IGN0eC5wYXJhbWV0ZXJzLml0ZW0gOiB1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgICAgICBmbk9icyA9IGN0eCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3R4LnBhcmFtZXRlcnMuaXRlbUlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEFjdGlvbkRhdGFQcm92aWRlclV0aWwucnVuVXBkYXRlKGN0eCwgZGVmYXVsdFN1Ym1pdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBBY3Rpb25EYXRhUHJvdmlkZXJVdGlsLnJ1bkNyZWF0ZShjdHgsIGRlZmF1bHRTdWJtaXQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZuT2JzID0gYWN0aW9uRWRpdG9yLnN1Ym1pdEZ1bmN0aW9uO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2ZldGNoJzpcbiAgICAgICAgICAgICAgICBhY3Rpb25FZGl0b3IgPSBjdHguaW5zdGFuY2UuYWN0aW9uIGFzIEFjdGlvbkVkaXRvckRlc2NyaXB0b3I8VD47XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhY3Rpb25FZGl0b3IuZmV0Y2hGdW5jdGlvbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZhdWx0RmV0Y2ggPSBvZihjdHgucGFyYW1ldGVycz8uaXRlbSA/IGN0eC5wYXJhbWV0ZXJzLml0ZW0gOiB1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgICAgICBmbk9icyA9IGN0eCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3R4LnBhcmFtZXRlcnMuaXRlbUlkIHx8IHR5cGVvZiBjdHgucGFyYW1ldGVycy5pdGVtID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBBY3Rpb25EYXRhUHJvdmlkZXJVdGlsLnJ1bkZldGNoKGN0eCwgZGVmYXVsdEZldGNoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0RmV0Y2g7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZm5PYnMgPSBhY3Rpb25FZGl0b3IuZmV0Y2hGdW5jdGlvbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdydW4nOlxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBmbk9icyA9IGN0eC5pbnN0YW5jZS5hY3Rpb24ucnVuRnVuY3Rpb247XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXRPYnMgPSBvZih2b2lkIDApLnBpcGUoXG4gICAgICAgICAgICB0YWtlKDEpLFxuICAgICAgICAgICAgc3dpdGNoTWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoaXNNYWluUnVuRm4pIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgbWFpbiBydW4gZnVuY3Rpb24sIGFsc28gc2V0IGxvYWRpbmcgdG8gdHJ1ZVxuICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2Uuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5SdW5TdGFydDtcbiAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLmlzUnVuTG9hZGluZ1N1YmplY3QubmV4dCh0cnVlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2Uuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5GZXRjaFN0YXJ0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBzdGFydCBjb250ZXh0IGV4ZWN1dGlvbiB0byBtYXJrIGV4ZWN1dGlvbiBsb2FkaW5nXG4gICAgICAgICAgICAgICAgY3R4LmV4ZWN1dGlvblN0YXJ0KCk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gZm5PYnMoY3R4KTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgbWVyZ2VNYXAocnVuUmVzdWx0ID0+IHtcbiAgICAgICAgICAgICAgICAvLyBzZXQgbmV4dCBzdGF0ZSBkZXBlbmRpbmcgb24gcnVuXG4gICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLnN0YXRlID0gaXNNYWluUnVuRm4gPyBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5SdW5FbmQgOiBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5GZXRjaEVuZDtcbiAgICAgICAgICAgICAgICAvLyBzZXQgZXhlY3V0aW9uIHJlc3VsdFxuICAgICAgICAgICAgICAgIGN0eC5leGVjdXRpb25OZXh0KHJ1blJlc3VsdCwgaXNNYWluUnVuRm4pO1xuXG4gICAgICAgICAgICAgICAgaWYgKGlzTWFpblJ1bkZuKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHNldCBpbnN0YW5jZSBmaW5hbCByZXN1bHQgb24gbWFpbiBydW4gZXhlY3V0aW9uXG4gICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5yZXN1bHQgPSBydW5SZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5pc1J1bkxvYWRpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBub3RpZmljYXRpb25cbiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eC5pbnN0YW5jZS5hY3Rpb24uaGFzUnVuTm90aWZpY2F0aW9uU3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lm5vdGlmaWNhdGlvbiA9IE5vdGlmaWNhdGlvblV0aWwuYWN0aW9uTm90aWZpY2F0aW9uU3VjY2VzcyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyYW5zbGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2UuYWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5mdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLmFjdGlvbi5ydW5Ob3RpZmljYXRpb25TdWNjZXNzVGl0bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLmFjdGlvbi5ydW5Ob3RpZmljYXRpb25TdWNjZXNzTWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgucGFyYW1ldGVycy52aWV3Q29udGFpbmVyID8/IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLmN0eC5wYXJhbWV0ZXJzPy5pdGVtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5ydW5SZXN1bHRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxlIHBvc3NpYmxlIGFmdGVyIHJ1biBhY3Rpb25cbiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eC5pbnN0YW5jZS5hY3Rpb24uYWZ0ZXJSdW5BY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1hcmsgbmV3IHN0YXRlIGZvciBuZXh0IGFjdGlvbiBzdGFydFxuICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLnN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uTmV4dEFjdGlvblN0YXJ0O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV4dEFjdGlvbkluc3RhbmNlID0gdGhpcy5hY3RpdmF0ZUFjdGlvbihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2UuYWN0aW9uLmFmdGVyUnVuQWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBBY3Rpb25QYXJhbWV0ZXJzPHVua25vd24+KGN0eC5wYXJhbWV0ZXJzLml0ZW1JZCwgcnVuUmVzdWx0KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAud2l0aEFjdGlvbkRhdGEoY3R4LnBhcmFtZXRlcnMuYWN0aW9uRGF0YSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndpdGhSb3V0ZShjdHgucGFyYW1ldGVycy5yb3V0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndpdGhTb3VyY2VDb21wb25lbnQoY3R4LnBhcmFtZXRlcnMuc291cmNlQ29tcG9uZW50KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAud2l0aFZpZXdDb250YWluZXIoY3R4LnBhcmFtZXRlcnMudmlld0NvbnRhaW5lciBhcyBJVmlld0NvbnRhaW5lcjx1bmtub3duLCB1bmtub3duPiksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZSBhcyBBY3Rpb25JbnN0YW5jZTx1bmtub3duLCB1bmtub3duPlxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5uZXh0QWN0aW9uSW5zdGFuY2UgPSBuZXh0QWN0aW9uSW5zdGFuY2U7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbmlzaCBjdXJyZW50IGFjdGlvbiB3aGVuIG5leHQgYWN0aW9uIGZpbmlzaGVzXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV4dEFjdGlvbkluc3RhbmNlLnN0YXRlJC5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihzdGF0ZSA9PiBzdGF0ZSA+PSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5GaW5pc2hTdWNjZXNzRmluYWwpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5zdGF0ZSA9IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLk5leHRBY3Rpb25FbmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBydW5SZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYWN0aW9uRWRpdG9yLmhhc0ZldGNoTm90aWZpY2F0aW9uU3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgTm90aWZpY2F0aW9uVXRpbC5hY3Rpb25Ob3RpZmljYXRpb25TdWNjZXNzKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJhbnNsYXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbkVkaXRvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZmV0Y2gnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbkVkaXRvci5mZXRjaE5vdGlmaWNhdGlvblN1Y2Nlc3NUaXRsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb25FZGl0b3IuZmV0Y2hOb3RpZmljYXRpb25TdWNjZXNzTWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgucGFyYW1ldGVycy52aWV3Q29udGFpbmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5wYXJhbWV0ZXJzLml0ZW1cbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gb2YocnVuUmVzdWx0KTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgbWFwKHJ1blJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGlzTWFpblJ1bkZuKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGRlYWN0aXZhdGUgYWN0aW9uXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmluaXNoQWN0aW9uKGN0eC5pbnN0YW5jZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBydW5SZXN1bHQ7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGNhdGNoRXJyb3IoZXJyID0+IHtcbiAgICAgICAgICAgICAgICAvLyB0cmFuc2Zvcm0gZXJyb3IgdG8gbW5nIGFjdGlvbiBlcnJvclxuICAgICAgICAgICAgICAgIGNvbnN0IGFjdGlvbkVycm9yID0gdGhpcy50b01uZ0FjdGlvbkVycm9yKGVycik7XG5cbiAgICAgICAgICAgICAgICAvLyBzZXQgaW5zdGFuY2Ugc3RhdGUgdG8gZXJyb3JcbiAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2Uuc3RhdGUgPSBpc01haW5SdW5GbiA/IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLlJ1bkVycm9yIDogQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uRmV0Y2hFcnJvcjtcbiAgICAgICAgICAgICAgICAvLyBtYXJrIGV4ZWN1dGlvbiBlcnJvciBvbiBjb250ZXh0XG4gICAgICAgICAgICAgICAgY3R4LmV4ZWN1dGlvbkVycm9yKGFjdGlvbkVycm9yKTtcblxuICAgICAgICAgICAgICAgIGxldCBlcnJvck9icyA9IG9mKHZvaWQgMCk7XG4gICAgICAgICAgICAgICAgaWYgKGlzTWFpblJ1bkZuKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5lcnJvciA9IGVycjtcbiAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLmlzUnVuTG9hZGluZ1N1YmplY3QubmV4dChmYWxzZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxlIGVycm9yIG5vdGlmaWNhdGlvblxuICAgICAgICAgICAgICAgICAgICBpZiAoY3R4Lmluc3RhbmNlLmFjdGlvbi5oYXNSdW5Ob3RpZmljYXRpb25FcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uRXJyb3Iubm90aWZpY2F0aW9uID0gTm90aWZpY2F0aW9uVXRpbC5hY3Rpb25Ob3RpZmljYXRpb25FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyYW5zbGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2UuYWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbkVycm9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5mdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LnBhcmFtZXRlcnMudmlld0NvbnRhaW5lciA/PyB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LnBhcmFtZXRlcnMuaXRlbVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBwb3NzaWJsZSBlcnJvciBhY3Rpb24gaWYgcnVuXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc01haW5SdW5GbiAmJiBjdHguaW5zdGFuY2UuYWN0aW9uLm9uUnVuRXJyb3JBY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbm5vdCBzdGFydCB3aXRoIHRyaWdnZXIsIGJlY2F1c2Ugcm91dGluZyBtaWdodCBiZSBwcm9ibGVtYXRpYyAobG91c2luZyBwcmV2aW91cyByZXN1bHRzIGV0Yy4pXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvckFjdGlvbkluc3RhbmNlID0gdGhpcy5hY3RpdmF0ZUFjdGlvbjxULCBTPihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2UuYWN0aW9uLm9uUnVuRXJyb3JBY3Rpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEFjdGlvblBhcmFtZXRlcnM8VD4oY3R4LnBhcmFtZXRlcnMuaXRlbUlkLCBjdHgucGFyYW1ldGVycy5pdGVtKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAud2l0aEFjdGlvbkRhdGEoY3R4LnBhcmFtZXRlcnMuYWN0aW9uRGF0YSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndpdGhSb3V0ZShjdHgucGFyYW1ldGVycy5yb3V0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndpdGhTb3VyY2VDb21wb25lbnQoY3R4LnBhcmFtZXRlcnMuc291cmNlQ29tcG9uZW50KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAud2l0aFZpZXdDb250YWluZXIoY3R4LnBhcmFtZXRlcnMudmlld0NvbnRhaW5lcilcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2UuZXJyb3JBY3Rpb25JbnN0YW5jZSA9IGVycm9yQWN0aW9uSW5zdGFuY2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck9icyA9IGVycm9yQWN0aW9uSW5zdGFuY2Uuc3RhdGUkLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHN0YXRlID0+IHN0YXRlID49IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkZpbmlzaFN1Y2Nlc3NGaW5hbCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwKCgpID0+IHZvaWQgMClcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY3R4Lmluc3RhbmNlLmFjdGlvbi5oYXNSdW5Ob3RpZmljYXRpb25FcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgTm90aWZpY2F0aW9uVXRpbC5hY3Rpb25Ob3RpZmljYXRpb25FcnJvcih0aGlzLnRyYW5zbGF0ZSwgY3R4Lmluc3RhbmNlLmFjdGlvbiwgYWN0aW9uRXJyb3IsICdmZXRjaCcsIGN0eC5wYXJhbWV0ZXJzLnZpZXdDb250YWluZXIsIGN0eC5wYXJhbWV0ZXJzLml0ZW0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gbGlzdGUgYW5kIG1hcCBvbmx5IHRvIG1hcmsgaW5zdGFuY2Ugc3RhdGUgYXMgZmluaXNoZWQgZXJyb3Igc3RhdGVcbiAgICAgICAgICAgICAgICByZXR1cm4gZXJyb3JPYnMucGlwZShcbiAgICAgICAgICAgICAgICAgICAgbWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlYWN0aXZhdGUgYWN0aW9uIG9ubHkgaWYgY3JpdGljYWwgKGZldGNoIG9uIGVkaXRvciBvciBydW4gb24gYnV0dG9uIGFjdGlvbnMpXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNFcnJvckNyaXRpY2FsUnVuRm4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbmlzaEFjdGlvbihjdHguaW5zdGFuY2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmV0aHJvdyBlcnJvciB0byBwcm9wYWdhdGUgZnVyaGVyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBhY3Rpb25FcnJvcjtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcblxuICAgICAgICBjdHgucnVuU3Vic2NyaXB0aW9uID0gcmV0T2JzLnN1YnNjcmliZSh7XG4gICAgICAgICAgICBuZXh0OiByZXMgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnTG9nKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlLCBuby1yZXN0cmljdGVkLXN5bnRheFxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKGBBY3Rpb25Db250ZXh0ICR7Y3R4LmNvbnRleHRMb25nTmFtZX0gZXhlY3V0aW9uIG5leHQgZXZlbnRgLCByZXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogZXJyID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1Z0xvZykge1xuICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZSwgbm8tcmVzdHJpY3RlZC1zeW50YXhcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhgQWN0aW9uQ29udGV4dCAke2N0eC5jb250ZXh0TG9uZ05hbWV9IGV4ZWN1dGlvbiBlcnJvciBldmVudGAsIGVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcmV0T2JzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByZXBhcmVzIGVkaXRvciBhY3Rpb24ncyBmZXRjaCBmdW5jdGlvbiBieSBjcmVhdGluZyBuZXcgYWN0aW9uIGNvbnRleHQgZm9yIGFjdGlvbiBpbnN0YW5jZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBhY3Rpb24gQWN0aW9uIGRlc2NyaXB0b3IuXG4gICAgICogQHBhcmFtIHBhcmFtZXRlcnMgQWN0aW9uIHBhcmFtZXRlcnMgZm9yIGNvbnRleHQuXG4gICAgICogQHBhcmFtIGRhdGFQcm92aWRlciBFZGl0b3IgZGF0YSBwcm92aWRlciBmb3IgY29udGV4dC5cbiAgICAgKiBAcGFyYW0gaW5zdGFuY2UgT3B0aW9uYWwgZXhpc3RpbmcgYWN0aW9uIGluc3RhbmNlIChpZiBub24gcHJvdmlkZWQsIG5ldyB3aWxsIGJlIGNyZWF0ZWQpLlxuICAgICAqIEBwYXJhbSBwcmV2aW91c0FjdGlvbkluc3RhbmNlIE9wdGlvbmFsIHByZXZpb3VzIGFjdGlvbiBpbnN0YW5jZSB0byBsaW5rIGluIG5leHQgaW5zdGFuY2UuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIEFjdGlvbiBjb250ZXh0IGZvciBmZXRjaCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgcHJlcGFyZUNvbnRleHRGb3JFZGl0b3JGZXRjaDxULCBTPihcbiAgICAgICAgYWN0aW9uOiBBY3Rpb25FZGl0b3JEZXNjcmlwdG9yPFQ+LFxuICAgICAgICBwYXJhbWV0ZXJzOiBBY3Rpb25QYXJhbWV0ZXJzPFQ+LFxuICAgICAgICBkYXRhUHJvdmlkZXI/OiBJRWRpdG9yRGF0YVByb3ZpZGVyPFQsIFM+LFxuICAgICAgICBpbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPFQsIFM+LFxuICAgICAgICBwcmV2aW91c0FjdGlvbkluc3RhbmNlPzogQWN0aW9uSW5zdGFuY2U8dW5rbm93biwgdW5rbm93bj5cbiAgICApOiBBY3Rpb25Db250ZXh0PFQsIFM+IHtcbiAgICAgICAgaW5zdGFuY2UgPSB0aGlzLmdldE9yQ3JlYXRlSW5zdGFuY2UoaW5zdGFuY2UsIGFjdGlvbiwgcGFyYW1ldGVycywgQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uQWN0aXZhdGlvbkVuZCk7XG4gICAgICAgIHJldHVybiB0aGlzLnByZXBhcmVDb250ZXh0Rm9yRWRpdG9yKGluc3RhbmNlLCBwYXJhbWV0ZXJzLCAnZmV0Y2gnLCBkYXRhUHJvdmlkZXIsIHByZXZpb3VzQWN0aW9uSW5zdGFuY2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJ1bnMgZWRpdG9yIGFjdGlvbidzIHN1Ym1pdCAoPW1haW4gcnVuKSBmdW5jdGlvbiBieSBjcmVhdGluZyBuZXcgYWN0aW9uIGNvbnRleHQgZm9yIGFjdGlvbiBpbnN0YW5jZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBhY3Rpb24gQWN0aW9uIGRlc2NyaXB0b3IuXG4gICAgICogQHBhcmFtIHBhcmFtZXRlcnMgQWN0aW9uIHBhcmFtZXRlcnMgZm9yIGNvbnRleHQuXG4gICAgICogQHBhcmFtIGRhdGFQcm92aWRlciBFZGl0b3IgZGF0YSBwcm92aWRlciBmb3IgY29udGV4dC5cbiAgICAgKiBAcGFyYW0gaW5zdGFuY2UgT3B0aW9uYWwgZXhpc3RpbmcgYWN0aW9uIGluc3RhbmNlIChpZiBub24gcHJvdmlkZWQsIG5ldyB3aWxsIGJlIGNyZWF0ZWQpLlxuICAgICAqIEBwYXJhbSBwcmV2aW91c0FjdGlvbkluc3RhbmNlIE9wdGlvbmFsIHByZXZpb3VzIGFjdGlvbiBpbnN0YW5jZSB0byBsaW5rIGluIG5leHQgaW5zdGFuY2UuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIEFjdGlvbiBjb250ZXh0IGZvciBzdWJtaXQgKD1ydW4pIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBwcmVwYXJlQ29udGV4dEZvckVkaXRvclN1Ym1pdDxULCBTPihcbiAgICAgICAgYWN0aW9uOiBBY3Rpb25FZGl0b3JEZXNjcmlwdG9yPFQ+LFxuICAgICAgICBwYXJhbWV0ZXJzOiBBY3Rpb25QYXJhbWV0ZXJzPFQ+LFxuICAgICAgICBkYXRhUHJvdmlkZXI/OiBJRWRpdG9yRGF0YVByb3ZpZGVyPFQsIFM+LFxuICAgICAgICBpbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPFQsIFM+LFxuICAgICAgICBwcmV2aW91c0FjdGlvbkluc3RhbmNlPzogQWN0aW9uSW5zdGFuY2U8dW5rbm93biwgdW5rbm93bj5cbiAgICApOiBBY3Rpb25Db250ZXh0PFQsIFM+IHtcbiAgICAgICAgaW5zdGFuY2UgPSB0aGlzLmdldE9yQ3JlYXRlSW5zdGFuY2UoaW5zdGFuY2UsIGFjdGlvbiwgcGFyYW1ldGVycywgQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uQWN0aXZhdGlvbkVuZCk7XG4gICAgICAgIHJldHVybiB0aGlzLnByZXBhcmVDb250ZXh0Rm9yRWRpdG9yKGluc3RhbmNlLCBwYXJhbWV0ZXJzLCAnc3VibWl0JywgZGF0YVByb3ZpZGVyLCBwcmV2aW91c0FjdGlvbkluc3RhbmNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmVwYXJlcyBhY3Rpb24gZXhlYyBjb250ZXh0IGZvciBhY3Rpb24gb2YgdHlwZSBlZGl0b3IuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaXRlbSBJdGVtIGluc3RhbmNlIChpZiBleGlzdHMpLlxuICAgICAqIEBwYXJhbSBpdGVtSWQgSXRlbSBpZCAoaWYgZXhpc3RzKS5cbiAgICAgKiBAcGFyYW0gZGF0YVByb3ZpZGVyIERhdGEgcHJvdmlkZXIuXG4gICAgICogQHBhcmFtIHNvdXJjZUNvbXBvbmVudCBTb3VyY2UgY29tcG9uZW50IGZyb20gd2hlcmUgdGhlIGNvbnRleHQgcHJlcGFyYXRpb24gd2FzIGNhbGxlZC5cbiAgICAgKiBAcGFyYW0gdmlld0NvbnRhaW5lciBWaWV3IGNvbnRhaW5lci9zZXJ2aWNlLlxuICAgICAqIEBwYXJhbSBhY3Rpb25EYXRhIEFkZGl0aW9uYWwgYWN0aW9uIGRhdGEuXG4gICAgICovXG4gICAgcHJpdmF0ZSBwcmVwYXJlQ29udGV4dEZvckVkaXRvcjxULCBTPihcbiAgICAgICAgaW5zdGFuY2U6IEFjdGlvbkluc3RhbmNlPFQsIFM+LFxuICAgICAgICBwYXJhbWV0ZXJzOiBBY3Rpb25QYXJhbWV0ZXJzPFQ+LFxuICAgICAgICBmdW5jdGlvbk5hbWU6ICdzdWJtaXQnIHwgJ2ZldGNoJyxcbiAgICAgICAgZGF0YVByb3ZpZGVyPzogSUVkaXRvckRhdGFQcm92aWRlcjxULCBTPixcbiAgICAgICAgcHJldmlvdXNBY3Rpb25JbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPHVua25vd24sIHVua25vd24+XG4gICAgKTogQWN0aW9uQ29udGV4dDxULCBTPiB7XG4gICAgICAgIGlmIChpbnN0YW5jZS5hY3Rpb24udHlwZSAhPT0gQWN0aW9uVHlwZUVudW0uRWRpdG9yKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgTW5nRXJyb3JJbnRlcm5hbChgQ2Fubm90IGNyZWF0ZSBlZGl0b3IgY29udGV4dCBmb3IgYWN0aW9uICR7aW5zdGFuY2UuYWN0aW9uLmFjdGlvbk5hbWVMb25nfSBvZiB0eXBlICR7aW5zdGFuY2UuYWN0aW9uLnR5cGV9LmApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGVkaXRvckFjdGlvbiA9IGluc3RhbmNlLmFjdGlvbiBhcyBBY3Rpb25FZGl0b3JEZXNjcmlwdG9yPFQ+O1xuICAgICAgICBsZXQgY3R4RGF0YVByb3ZpZGVyID0gZGF0YVByb3ZpZGVyO1xuICAgICAgICBpZiAoIWN0eERhdGFQcm92aWRlciAmJiBlZGl0b3JBY3Rpb24uZGF0YVByb3ZpZGVyKSB7XG4gICAgICAgICAgICBjdHhEYXRhUHJvdmlkZXIgPSBlZGl0b3JBY3Rpb24uZGF0YVByb3ZpZGVyO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY3R4RGF0YVByb3ZpZGVyKSB7XG4gICAgICAgICAgICBjb25zdCB2aWV3Q29udGFpbmVyRGF0YVByb3ZpZGVyID0gcGFyYW1ldGVycy52aWV3Q29udGFpbmVyPy5nZXREYXRhUHJvdmlkZXIoKTtcbiAgICAgICAgICAgIGlmICh2aWV3Q29udGFpbmVyRGF0YVByb3ZpZGVyKSB7XG4gICAgICAgICAgICAgICAgY3R4RGF0YVByb3ZpZGVyID0gdmlld0NvbnRhaW5lckRhdGFQcm92aWRlciBhcyBJRWRpdG9yRGF0YVByb3ZpZGVyPFQsIFM+O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGN0eCA9IG5ldyBBY3Rpb25Db250ZXh0PFQsIFM+KFxuICAgICAgICAgICAgaW5zdGFuY2UsXG4gICAgICAgICAgICBwYXJhbWV0ZXJzLFxuICAgICAgICAgICAgZnVuY3Rpb25OYW1lLFxuICAgICAgICAgICAgY3R4RGF0YVByb3ZpZGVyLFxuICAgICAgICAgICAgQWN0aW9uRGF0YVByb3ZpZGVyVXRpbC5nZXREYXRhUHJvdmlkZXJTZXJ2aWNlKHRoaXMuaW5qZWN0b3IsIGN0eERhdGFQcm92aWRlcikgPz8gdW5kZWZpbmVkXG4gICAgICAgICk7XG4gICAgICAgIGN0eC5wcmV2aW91c0FjdGlvbkluc3RhbmNlID0gcHJldmlvdXNBY3Rpb25JbnN0YW5jZTtcbiAgICAgICAgaW5zdGFuY2UubmV3Q29udGV4dChjdHgpO1xuICAgICAgICByZXR1cm4gY3R4O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJ1bnMgYWN0aW9uJ3MgbWFpbiBydW4gZnVuY3Rpb24gYnkgY3JlYXRpbmcgbmV3IGFjdGlvbiBjb250ZXh0IGZvciBhY3Rpb24gaW5zdGFuY2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uIEFjdGlvbiBkZXNjcmlwdG9yLlxuICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJzIEFjdGlvbiBwYXJhbWV0ZXJzIGZvciBjb250ZXh0IHJ1bi5cbiAgICAgKiBAcGFyYW0gZGF0YVByb3ZpZGVyIERhdGEgcHJvdmlkZXIgZm9yIGNvbnRleHQgcnVuLlxuICAgICAqIEBwYXJhbSBpbnN0YW5jZSBPcHRpb25hbCBleGlzdGluZyBhY3Rpb24gaW5zdGFuY2UgKGlmIG5vbiBwcm92aWRlZCwgbmV3IHdpbGwgYmUgY3JlYXRlZCkuXG4gICAgICogQHBhcmFtIHByZXZpb3VzQWN0aW9uSW5zdGFuY2UgT3B0aW9uYWwgcHJldmlvdXMgYWN0aW9uIGluc3RhbmNlIHRvIGxpbmsgaW4gbmV4dCBpbnN0YW5jZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm4gQWN0aW9uIGNvbnRleHQgZm9yIHJ1biBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBwcml2YXRlIHByZXBhcmVDb250ZXh0PFQsIFM+KFxuICAgICAgICBhY3Rpb246IEFjdGlvbkRlc2NyaXB0b3I8VD4sXG4gICAgICAgIHBhcmFtZXRlcnM6IEFjdGlvblBhcmFtZXRlcnM8VD4sXG4gICAgICAgIGRhdGFQcm92aWRlcj86IElEYXRhUHJvdmlkZXI8VCwgUz4sXG4gICAgICAgIGluc3RhbmNlPzogQWN0aW9uSW5zdGFuY2U8VCwgUz4sXG4gICAgICAgIHByZXZpb3VzQWN0aW9uSW5zdGFuY2U/OiBBY3Rpb25JbnN0YW5jZTx1bmtub3duLCB1bmtub3duPlxuICAgICk6IEFjdGlvbkNvbnRleHQ8VCwgUz4ge1xuICAgICAgICBpbnN0YW5jZSA9IHRoaXMuZ2V0T3JDcmVhdGVJbnN0YW5jZShpbnN0YW5jZSwgYWN0aW9uLCBwYXJhbWV0ZXJzLCBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5BY3RpdmF0aW9uRW5kKTtcblxuICAgICAgICBjb25zdCBjdHhEYXRhUHJvdmlkZXIgPSBkYXRhUHJvdmlkZXIgPz8gaW5zdGFuY2UuYWN0aW9uLmRhdGFQcm92aWRlciA/PyBwYXJhbWV0ZXJzLnZpZXdDb250YWluZXI/LmdldERhdGFQcm92aWRlcigpO1xuICAgICAgICBjb25zdCBjdHggPSBuZXcgQWN0aW9uQ29udGV4dDxULCBTPihcbiAgICAgICAgICAgIGluc3RhbmNlLFxuICAgICAgICAgICAgcGFyYW1ldGVycyxcbiAgICAgICAgICAgICdydW4nLFxuICAgICAgICAgICAgY3R4RGF0YVByb3ZpZGVyLFxuICAgICAgICAgICAgQWN0aW9uRGF0YVByb3ZpZGVyVXRpbC5nZXREYXRhUHJvdmlkZXJTZXJ2aWNlKHRoaXMuaW5qZWN0b3IsIGN0eERhdGFQcm92aWRlcikgPz8gdW5kZWZpbmVkXG4gICAgICAgICk7XG4gICAgICAgIGN0eC5wcmV2aW91c0FjdGlvbkluc3RhbmNlID0gcHJldmlvdXNBY3Rpb25JbnN0YW5jZTtcbiAgICAgICAgaW5zdGFuY2UubmV3Q29udGV4dChjdHgpO1xuXG4gICAgICAgIHJldHVybiBjdHg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWN0aXZhdGVzIGFjdGlvbiAoaW4gY2FzZSBvZiBkaWFsb2csIGRpYWxvZyB3aWxsIGJlIG9wZW5lZCkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uIEFjdGlvbiBkZXNjcmlwdG9yLlxuICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJzIEFjdGlvbiBwYXJhbWV0ZXJzIGZvciBhY3RpdmF0aW9uIG9mIGFjdGlvbiBpbnN0YW5jZS5cbiAgICAgKiBAcGFyYW0gaW5zdGFuY2UgT3B0aW9uYWwgZXhpc3RpbmcgYWN0aW9uIGluc3RhbmNlIChpZiBub24gcHJvdmlkZWQsIG5ldyB3aWxsIGJlIGNyZWF0ZWQpLlxuICAgICAqIEBwYXJhbSBwcmV2aW91c0FjdGlvbkluc3RhbmNlIE9wdGlvbmFsIHByZXZpb3VzIGFjdGlvbiBpbnN0YW5jZSB0byBsaW5rIGluIG5leHQgaW5zdGFuY2UuXG4gICAgICogQHBhcmFtIHJ1bkNvbnRleHQgTWFya3MgaWYgY29udGV4dCBzaG91bGQgYmUgcnVuLlxuICAgICAqXG4gICAgICogQHJldHVybiBBY3Rpb24gaW5zdGFuY2UgLSBpZiBub24gcHJvdmlkZWQgaW4gcGFyYW1ldGVycywgdGhlIG5ld2x5IGNyZWF0ZWQgd2lsbCBiZSByZXR1cm5lZC5cbiAgICAgKi9cbiAgICBwdWJsaWMgYWN0aXZhdGVBY3Rpb248VCwgUz4oXG4gICAgICAgIGFjdGlvbjogQWN0aW9uRGVzY3JpcHRvcjxUPixcbiAgICAgICAgcGFyYW1ldGVyczogQWN0aW9uUGFyYW1ldGVyczxUPixcbiAgICAgICAgaW5zdGFuY2U/OiBBY3Rpb25JbnN0YW5jZTxULCBTPixcbiAgICAgICAgcHJldmlvdXNBY3Rpb25JbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPHVua25vd24sIHVua25vd24+LFxuICAgICAgICBydW5Db250ZXh0ID0gZmFsc2VcbiAgICApOiBBY3Rpb25JbnN0YW5jZTxULCBTPiB7XG4gICAgICAgIGluc3RhbmNlID0gdGhpcy5nZXRPckNyZWF0ZUluc3RhbmNlKGluc3RhbmNlLCBhY3Rpb24sIHBhcmFtZXRlcnMsIEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkFjdGl2YXRpb25TdGFydCk7XG4gICAgICAgIGluc3RhbmNlLnN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uQWN0aXZhdGlvblN0YXJ0O1xuICAgICAgICBpbnN0YW5jZS5hY3RpdmF0aW9uUGFyYW1ldGVycyA9IHBhcmFtZXRlcnM7XG4gICAgICAgIC8vIHN0YXJ0IGFjdGl2YXRpb24gaW5zdGFuY2VcbiAgICAgICAgaWYgKGFjdGlvbi50eXBlID09PSBBY3Rpb25UeXBlRW51bS5FZGl0b3IpIHtcbiAgICAgICAgICAgIGxldCBkaWFsb2dDb21wb25lbnQgPSB0aGlzLmRlZmF1bHRFZGl0b3JEaWFsb2dDb21wb25lbnQ7XG4gICAgICAgICAgICBjb25zdCBkaWFsb2dDbGFzc05hbWVzID0gWydtbmctZGlhbG9nJ107XG4gICAgICAgICAgICBpZiAoYWN0aW9uIGluc3RhbmNlb2YgQWN0aW9uRWRpdG9yRGVzY3JpcHRvcikge1xuICAgICAgICAgICAgICAgIGRpYWxvZ0NsYXNzTmFtZXMucHVzaChhY3Rpb24uZGlhbG9nQ2xhc3NOYW1lID8/ICdtbmctYWN0aW9uLWVkaXRvci1kaWFsb2cnKTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGFjdGlvbi5kaWFsb2dTaXplKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgU3R5bGVTaXplRW51bS5FeHRyYVNtYWxsOlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nQ2xhc3NOYW1lcy5wdXNoKCdtbmctZGlhbG9nLXhzJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBTdHlsZVNpemVFbnVtLlNtYWxsOlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nQ2xhc3NOYW1lcy5wdXNoKCdtbmctZGlhbG9nLXNtJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBTdHlsZVNpemVFbnVtLkxhcmdlOlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nQ2xhc3NOYW1lcy5wdXNoKCdtbmctZGlhbG9nLWxnJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBTdHlsZVNpemVFbnVtLkV4dHJhTGFyZ2U6XG4gICAgICAgICAgICAgICAgICAgICAgICBkaWFsb2dDbGFzc05hbWVzLnB1c2goJ21uZy1kaWFsb2cteGwnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFN0eWxlU2l6ZUVudW0uTm9ybWFsOlxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChhY3Rpb24uZWRpdG9yQ29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGRpYWxvZ0NvbXBvbmVudCA9IGFjdGlvbi5lZGl0b3JDb21wb25lbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgZGlhbG9nQ29uZmlnOiBEeW5hbWljRGlhbG9nQ29uZmlnID0ge1xuICAgICAgICAgICAgICAgIGRhdGE6IHt9LFxuICAgICAgICAgICAgICAgIHN0eWxlQ2xhc3M6IGRpYWxvZ0NsYXNzTmFtZXMuam9pbignICcpXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZGlhbG9nQ29uZmlnLmRhdGEuYWN0aW9uSW5zdGFuY2UgPSBpbnN0YW5jZTtcbiAgICAgICAgICAgIGRpYWxvZ0NvbmZpZy5kYXRhLnByZXZpb3VzQWN0aW9uSW5zdGFuY2UgPSBwcmV2aW91c0FjdGlvbkluc3RhbmNlO1xuICAgICAgICAgICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2dTZXJ2aWNlLm9wZW4oZGlhbG9nQ29tcG9uZW50LCBkaWFsb2dDb25maWcpO1xuICAgICAgICAgICAgZGlhbG9nUmVmLm9uQ2xvc2UucGlwZSh0YWtlKDEpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIHRvIGNsb3NlIGRpYWxvZyBvbiAnWCcgY2xpY2sgb3IgZXNjIGJ1dHRvblxuICAgICAgICAgICAgICAgIHRoaXMuZmluaXNoQWN0aW9uKGluc3RhbmNlISk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGluc3RhbmNlLmFjdGl2YXRpb25EaWFsb2dSZWYgPSBkaWFsb2dSZWY7XG4gICAgICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBkaXJlY3RseSBleGVjdXRlIGFjdGlvblxuICAgICAgICAgICAgaW5zdGFuY2Uuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5BY3RpdmF0aW9uRW5kO1xuICAgICAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMucHJlcGFyZUNvbnRleHQ8VCwgUz4oYWN0aW9uLCBwYXJhbWV0ZXJzLCB1bmRlZmluZWQsIGluc3RhbmNlLCBwcmV2aW91c0FjdGlvbkluc3RhbmNlKTtcblxuICAgICAgICAgICAgaWYgKHJ1bkNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJ1bihjb250ZXh0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuaW5zdGFuY2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUbyBiZSBjYWxsZWQgd2hlbiBhY3Rpb24gZWRpdG9yIGlzIGluaXRpYWxpemVkIHRvIGNvcnJlY3RseSBhY3RpdmF0ZSBhY3Rpb24uXG4gICAgICogQHBhcmFtIGFjdGlvbiBBY3Rpb24gZGVzY3JpcHRvci5cbiAgICAgKiBAcGFyYW0gaW5zdGFuY2UgQWN0aW9uIGluc3RhbmNlIChpZiBhdmFpbGFibGUpLlxuICAgICAqL1xuICAgIHB1YmxpYyBvbkFjdGlvbkVkaXRvckluaXQ8VCwgUz4oYWN0aW9uOiBBY3Rpb25EZXNjcmlwdG9yPFQ+LCBpbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPFQsIFM+KTogQWN0aW9uSW5zdGFuY2U8VCwgUz4ge1xuICAgICAgICBpZiAoYWN0aW9uLnR5cGUgIT09IEFjdGlvblR5cGVFbnVtLkVkaXRvcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBBY3Rpb24gJHthY3Rpb24uYWN0aW9uTmFtZX0gaXMgbm90IG9mIHR5cGUgZWRpdG9yLCBjYW5ub3QgYmUgYWN0aXZhdGVkIHRocm91Z2ggXCJvbkFjdGlvbkVkaXRvck9uSW5pdFwiYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGluc3RhbmNlICYmIGFjdGlvbi5hY3RpdmF0aW9uVHJpZ2dlciA9PT0gQWN0aW9uQWN0aXZhdGlvblRyaWdnZXJFbnVtLk9uUm91dGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHRyaWdnZXJlZEluc3RhbmNlID0gKGluc3RhbmNlLmFjdGl2YXRpb25QYXJhbWV0ZXJzPy52aWV3Q29udGFpbmVyIGFzIElWaWV3QWN0aW9uUm91dGVUcmlnZ2VyZWRDb250YWluZXI8VCwgUz4gfCB1bmRlZmluZWQpPy5nZXRBY3Rpb25Sb3V0ZVRyaWdnZXJlZEluc3RhbmNlPy4oKTtcbiAgICAgICAgICAgIGNvbnN0IGFjdGl2YXRpb25JbnN0YW5jZSA9IChpbnN0YW5jZS5hY3RpdmF0aW9uUGFyYW1ldGVycz8udmlld0NvbnRhaW5lciBhcyBJVmlld0FjdGlvblJvdXRlVHJpZ2dlcmVkQ29udGFpbmVyPFQsIFM+IHwgdW5kZWZpbmVkKT8uZ2V0QWN0aW9uUm91dGVUcmlnZ2VyZWRJbnN0YW5jZT8uKCk7XG4gICAgICAgICAgICBpZiAodHJpZ2dlcmVkSW5zdGFuY2UgJiYgdHJpZ2dlcmVkSW5zdGFuY2UuaW5zdGFuY2VMb25nTmFtZSAhPT0gaW5zdGFuY2UuaW5zdGFuY2VMb25nTmFtZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgYEZvdW5kIHRyaWdnZXJlZCBwYXJhbWV0ZXJzIHZpZXcgY29udGFpbmVyIGluc3RhbmNlICR7dHJpZ2dlcmVkSW5zdGFuY2UuaW5zdGFuY2VMb25nTmFtZX0gYW5kIGl0IGRvZXMgbm90IG1hdGNoIGluc3RhbmNlICR7aW5zdGFuY2UuaW5zdGFuY2VMb25nTmFtZX0gcmV0cmlldmVkIG9uIGVkaXRvciBpbml0LmBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGFjdGl2YXRpb25JbnN0YW5jZSAmJiBhY3RpdmF0aW9uSW5zdGFuY2UuaW5zdGFuY2VMb25nTmFtZSAhPT0gaW5zdGFuY2UuaW5zdGFuY2VMb25nTmFtZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgYEZvdW5kIHRyaWdnZXJlZCBwYXJhbWV0ZXJzIHZpZXcgY29udGFpbmVyIGluc3RhbmNlICR7YWN0aXZhdGlvbkluc3RhbmNlLmluc3RhbmNlTG9uZ05hbWV9IGFuZCBpdCBkb2VzIG5vdCBtYXRjaCBpbnN0YW5jZSAke2luc3RhbmNlLmluc3RhbmNlTG9uZ05hbWV9IHJldHJpZXZlZCBvbiBlZGl0b3IgaW5pdC5gXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpbnN0YW5jZSA9IHRoaXMuZ2V0T3JDcmVhdGVJbnN0YW5jZShpbnN0YW5jZSwgYWN0aW9uLCB1bmRlZmluZWQsIEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkFjdGl2YXRpb25TdGFydCk7XG4gICAgICAgIGluc3RhbmNlLnN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uQWN0aXZhdGlvbkVuZDtcbiAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRvIGJlIGNhbGxlZCB3aGVuIGFjdGlvbiBlZGl0b3IgY21wIGlzIGJlaW5nIGRlc3Ryb3llZCB0byBjb3JyZWN0bHkgZmluaXNoIGFjdGlvbi5cbiAgICAgKiBAcGFyYW0gaW5zdGFuY2UgQWN0aW9uIGluc3RhbmNlLlxuICAgICAqL1xuICAgIHB1YmxpYyBvbkFjdGlvbkVkaXRvckRlc3Ryb3k8VCwgUz4oaW5zdGFuY2U/OiBBY3Rpb25JbnN0YW5jZTxULCBTPik6IHZvaWQge1xuICAgICAgICBpZiAoIWluc3RhbmNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaW5zdGFuY2UgPSB0aGlzLmdldE9yQ3JlYXRlSW5zdGFuY2UoaW5zdGFuY2UpO1xuICAgICAgICBpZiAoaW5zdGFuY2UuYWN0aW9uLnR5cGUgIT09IEFjdGlvblR5cGVFbnVtLkVkaXRvcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBBY3Rpb24gaW5zdGFuY2UgJHtpbnN0YW5jZS5pbnN0YW5jZUxvbmdOYW1lfSBpcyBub3Qgb2YgdHlwZSBlZGl0b3IsIGNhbm5vdCBiZSBkZWFjdGl2YXRlZCB0aHJvdWdoIFwib25BY3Rpb25FZGl0b3JPbkRlc3Ryb3lcImApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpbnN0YW5jZS5hY3Rpb24uYWN0aXZhdGlvblRyaWdnZXIgIT09IEFjdGlvbkFjdGl2YXRpb25UcmlnZ2VyRW51bS5PblJvdXRlKSB7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaEFjdGlvbihpbnN0YW5jZSwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUbyBiZSBjYWxsZWQgd2hlbiBhY3Rpb24gcm91dGUgY21wIGlzIGJlaW5nIGRlc3Ryb3llZCB0byBjb3JyZWN0bHkgZmluaXNoIGFjdGlvbi5cbiAgICAgKiBAcGFyYW0gaW5zdGFuY2UgQWN0aW9uIGluc3RhbmNlLlxuICAgICAqL1xuICAgIHB1YmxpYyBvbkFjdGlvblJvdXRlRGVzdHJveTxULCBTPihpbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPFQsIFM+KTogdm9pZCB7XG4gICAgICAgIGlmICghaW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpbnN0YW5jZSA9IHRoaXMuZ2V0T3JDcmVhdGVJbnN0YW5jZShpbnN0YW5jZSk7XG4gICAgICAgIGlmIChpbnN0YW5jZS5hY3Rpb24uYWN0aXZhdGlvblRyaWdnZXIgIT09IEFjdGlvbkFjdGl2YXRpb25UcmlnZ2VyRW51bS5PblJvdXRlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEFjdGlvbiBpbnN0YW5jZSAke2luc3RhbmNlLmluc3RhbmNlTG9uZ05hbWV9IGlzIG5vdCB0cmlnZ2VyZWQgb24gcm91dGUsIGNhbm5vdCBiZSBkZWFjdGl2YXRlZCB0aHJvdWdoIFwib25BY3Rpb25Sb3V0ZU9uRGVzdHJveVwiYCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5maW5pc2hBY3Rpb24oaW5zdGFuY2UsIHRydWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlYWN0aXZhdGVzIGFjdGlvbiBieSBjaG9vc2luZyBmaW5hbCBzdGF0ZSwgY2xvc2luZyBkaWFsb2cgYW5kIGNvbXBsZXRpbmcgYWxsIHN1YmplY3RzIGluIGluc3RhbmNlIGFuZCBjb250ZXh0cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnN0YW5jZSBBY3Rpb24gaW5zdGFuY2UuXG4gICAgICogQHBhcmFtIG9uRGVzdHJveSBNYXJrcyBpZiBmaW5pc2ggaXMgY2FsbGVkIG9uIGNvbXBvbmVudCBkZXN0cm95IGxpZmVjeWNsZSBob29rLlxuICAgICAqL1xuICAgIHB1YmxpYyBmaW5pc2hBY3Rpb248VCwgUz4oaW5zdGFuY2U6IEFjdGlvbkluc3RhbmNlPFQsIFM+LCBvbkRlc3Ryb3kgPSBmYWxzZSkge1xuICAgICAgICBpbnN0YW5jZSA9IHRoaXMuZ2V0T3JDcmVhdGVJbnN0YW5jZShpbnN0YW5jZSk7XG4gICAgICAgIGlmIChpbnN0YW5jZS5zdGF0ZSA+PSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5GaW5pc2hTdWNjZXNzRmluYWwpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnTG9nKSB7XG4gICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGUsIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhgQWN0aW9uSW5zdGFuY2UgJHtpbnN0YW5jZS5pbnN0YW5jZUxvbmdOYW1lfSBhbHJlYWR5IGZpbmlzaGVkYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgZmluYWxTdGF0ZTogQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW07XG4gICAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UucmVzdWx0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgZmluYWxTdGF0ZSA9IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkZpbmlzaFN1Y2Nlc3NGaW5hbDtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXJyb3IgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBmaW5hbFN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uRmluaXNoRXJyb3JGaW5hbDtcbiAgICAgICAgfSBlbHNlIGlmIChvbkRlc3Ryb3kpIHtcbiAgICAgICAgICAgIGZpbmFsU3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5GaW5pc2hDb21wb25lbnREZXN0cm95RmluYWw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmaW5hbFN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uRmluaXNoRGlzbWlzc2VkRmluYWw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW5zdGFuY2UuYWN0aW9uLnR5cGUgPT09IEFjdGlvblR5cGVFbnVtLkVkaXRvcikge1xuICAgICAgICAgICAgY29uc3QgaGFzRGlhbG9nID0gdHlwZW9mIGluc3RhbmNlLmFjdGl2YXRpb25EaWFsb2dSZWYgIT09ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgY29uc3QgcmVzdWJtaXRFbmFibGVkID0gKGluc3RhbmNlLmFjdGlvbiBhcyBBY3Rpb25FZGl0b3JEZXNjcmlwdG9yPFQ+KS5yZXN1Ym1pdEVuYWJsZWQ7XG5cbiAgICAgICAgICAgIGlmIChmaW5hbFN0YXRlID09PSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5GaW5pc2hTdWNjZXNzRmluYWwpIHtcbiAgICAgICAgICAgICAgICBpZiAoKGhhc0RpYWxvZyAmJiByZXN1Ym1pdEVuYWJsZWQgPT09IHRydWUpIHx8ICghaGFzRGlhbG9nICYmIHJlc3VibWl0RW5hYmxlZCAhPT0gZmFsc2UpKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpbmFsU3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5GaW5pc2hTdWNjZXNzUmVhY3RpdmF0ZUZpbmFsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGhhc0RpYWxvZyAmJiBmaW5hbFN0YXRlICE9PSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5GaW5pc2hTdWNjZXNzUmVhY3RpdmF0ZUZpbmFsKSB7XG4gICAgICAgICAgICAgICAgLy8gaWYgc3RhdGUgaXMgZmluaXNoIGFuZCBub3QgY2FsbGVkIGZyb20gZGlhbG9nIGxpc3RlbmVyLCBjbG9zZSB0aGUgZGlhbG9nIGZpcnN0IHdoaWNoIHdpbGwgcmV0cmlnZ2VyIHRoaXMgZnVuY3Rpb24sIHRoZW4gZmluaXNoIGl0XG4gICAgICAgICAgICAgICAgaW5zdGFuY2UuYWN0aXZhdGlvbkRpYWxvZ1JlZiEuY2xvc2UoaW5zdGFuY2UucmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHVuc2V0IGluc3RhbmNlIGluIHZpZXcgY29udGFpbmVyXG4gICAgICAgIChpbnN0YW5jZS5jb250ZXh0Py5wYXJhbWV0ZXJzLnZpZXdDb250YWluZXIgYXMgSVZpZXdBY3Rpb25Sb3V0ZVRyaWdnZXJlZENvbnRhaW5lcjxULCBTPiB8IHVuZGVmaW5lZCk/LnVuc2V0QWN0aW9uUm91dGVUcmlnZ2VyZWRJbnN0YW5jZT8uKCk7XG5cbiAgICAgICAgLy8gc2V0IGZpbmFsIHN0YXRlIG9uIGluc3RhbmNlXG4gICAgICAgIGluc3RhbmNlLnN0YXRlID0gZmluYWxTdGF0ZTtcblxuICAgICAgICBpZiAoZmluYWxTdGF0ZSA9PT0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uRmluaXNoU3VjY2Vzc1JlYWN0aXZhdGVGaW5hbCkge1xuICAgICAgICAgICAgLy8gcHJlcGFyZSByZWFjdGl2YXRpb24gaW5zdGFuY2VcbiAgICAgICAgICAgIGNvbnN0IG5ld0luc3RhbmNlU3RhdHVzID0gKGluc3RhbmNlLmFjdGlvbiBhcyBBY3Rpb25FZGl0b3JEZXNjcmlwdG9yPFQ+KS5yZXN1Ym1pdFJlZmV0Y2ggPyBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5BY3RpdmF0aW9uRW5kIDogQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uRmV0Y2hFbmQ7XG4gICAgICAgICAgICAvLyBtdXN0IHNraXAgaW5pdGlhbGl6YXRpb24gZnJvbSB2aWV3IGNvbnRhaW5lciwgYmVjYXVzZSBpdCB3b3VsZCBvbmx5IGdldCBvbGQgaW5zdGFuY2UuXG4gICAgICAgICAgICAvLyB3ZSBuZWVkIG5ldyBpbnN0YW5jZSBiZWZvcmUgd2UgY2FuIHNldCBuZXcgb25lIG9uIHRoZSB2aWV3IGNvbnRhaW5lci5cbiAgICAgICAgICAgIGNvbnN0IG5ld0luc3RhbmNlID0gdGhpcy5nZXRPckNyZWF0ZUluc3RhbmNlPFQsIFM+KHVuZGVmaW5lZCwgaW5zdGFuY2UuYWN0aW9uLCB1bmRlZmluZWQsIG5ld0luc3RhbmNlU3RhdHVzLCB0cnVlKTtcbiAgICAgICAgICAgIG5ld0luc3RhbmNlLnByZXZpb3VzSW5zdGFuY2UgPSBpbnN0YW5jZTtcbiAgICAgICAgICAgIC8vIGNvcHkgc29tZSBhZGRpdGlvbmFsIHNldHRpbmdzXG4gICAgICAgICAgICBuZXdJbnN0YW5jZS5hY3RpdmF0aW9uRGlhbG9nUmVmID0gaW5zdGFuY2UuYWN0aXZhdGlvbkRpYWxvZ1JlZjtcbiAgICAgICAgICAgIG5ld0luc3RhbmNlLnRyaWdnZXJQYXJhbWV0ZXJzID0gaW5zdGFuY2UudHJpZ2dlclBhcmFtZXRlcnM7XG4gICAgICAgICAgICBuZXdJbnN0YW5jZS5hY3RpdmF0aW9uUGFyYW1ldGVycyA9IGluc3RhbmNlLmFjdGl2YXRpb25QYXJhbWV0ZXJzO1xuXG4gICAgICAgICAgICAoaW5zdGFuY2UuY29udGV4dD8ucGFyYW1ldGVycy52aWV3Q29udGFpbmVyIGFzIElWaWV3QWN0aW9uUm91dGVUcmlnZ2VyZWRDb250YWluZXI8VCwgUz4gfCB1bmRlZmluZWQpPy5zZXRBY3Rpb25Sb3V0ZVRyaWdnZXJlZEluc3RhbmNlPy4obmV3SW5zdGFuY2UpO1xuICAgICAgICAgICAgaW5zdGFuY2UucmVhY3RpdmF0aW9uSW5zdGFuY2UgPSBuZXdJbnN0YW5jZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJzIGFjdGlvbiB3aXRoIHBhcmFtZXRlcnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uIEFjdGlvbiBkZXNjcmlwdG9yLlxuICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJzIEFjdGlvbiBwYXJhbWV0ZXJzIGZvciBhY3Rpb24gZXhlY3V0aW9uIHRvIGNvbnN0cnVjdCBuZXcgcm91dGUuXG4gICAgICogQHBhcmFtIHJ1bkNvbnRleHQgTWFya3MgaWYgY29udGV4dCBzaG91bGQgYmUgcnVuLlxuICAgICAqXG4gICAgICogQHJldHVybiBBY3Rpb24gaW5zdGFuY2UgLSBpZiBub24gcHJvdmlkZWQgaW4gcGFyYW1ldGVycywgdGhlIG5ld2x5IGNyZWF0ZWQgd2lsbCBiZSByZXR1cm5lZC5cbiAgICAgKi9cbiAgICBwdWJsaWMgdHJpZ2dlckFjdGlvbjxULCBTPihhY3Rpb246IEFjdGlvbkRlc2NyaXB0b3I8VD4sIHBhcmFtZXRlcnM6IEFjdGlvblBhcmFtZXRlcnM8VD4sIHJ1bkNvbnRleHQgPSBmYWxzZSk6IEFjdGlvbkluc3RhbmNlPFQsIFM+IHtcbiAgICAgICAgY29uc3QgaW5zdGFuY2UgPSB0aGlzLmdldE9yQ3JlYXRlSW5zdGFuY2U8VCwgUz4odW5kZWZpbmVkLCBhY3Rpb24sIHBhcmFtZXRlcnMpO1xuICAgICAgICBpbnN0YW5jZS50cmlnZ2VyUGFyYW1ldGVycyA9IHBhcmFtZXRlcnM7XG4gICAgICAgIGluc3RhbmNlLnN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uVHJpZ2dlclN0YXJ0O1xuICAgICAgICBpZiAoYWN0aW9uLmFjdGl2YXRpb25UcmlnZ2VyID09PSBBY3Rpb25BY3RpdmF0aW9uVHJpZ2dlckVudW0uT25Sb3V0ZSkge1xuICAgICAgICAgICAgY29uc3QgYmFzZVVybCA9IHRoaXMucm91dGVyLnVybC5zcGxpdCgnPycpWzBdO1xuICAgICAgICAgICAgY29uc3QgcGFyc2VkVXJsOiBVcmxUcmVlID0gdGhpcy5yb3V0ZXIucGFyc2VVcmwodGhpcy5yb3V0ZXIudXJsKTtcbiAgICAgICAgICAgIGxldCBhY3Rpb25VcmwgPSBhY3Rpb24ucm91dGVVcmwgPz8gJyc7XG4gICAgICAgICAgICAvLyBUT0RPOiBkb250IHN0cmlwICcvJywgYnV0IHVzZSBpdCBhY2NvcmRpbmdseSB3aXRoIEFuZ3VsYXIncyByb3V0ZXIgcGF0dGVybnMgKC8sIC4vLCAuLi8pXG4gICAgICAgICAgICBpZiAoYWN0aW9uVXJsLnN0YXJ0c1dpdGgoJy8nKSkge1xuICAgICAgICAgICAgICAgIGFjdGlvblVybCA9IGFjdGlvblVybC5zdWJzdHJpbmcoMSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGFjdGlvblVybFNlZ21lbnRzID0gdGhpcy5wYXJhbWV0cml6ZS50cmFuc2Zvcm0oYWN0aW9uVXJsLCBwYXJhbWV0ZXJzLml0ZW1JZCwgcGFyYW1ldGVycy5pdGVtLCBwYXJhbWV0ZXJzLmFjdGlvbkRhdGEpLnNwbGl0KCcvJyk7XG5cbiAgICAgICAgICAgIC8vIHNldCBpbnN0YW5jZSBpbiB2aWV3IGNvbnRhaW5lclxuICAgICAgICAgICAgKHBhcmFtZXRlcnMudmlld0NvbnRhaW5lciBhcyBJVmlld0FjdGlvblJvdXRlVHJpZ2dlcmVkQ29udGFpbmVyPFQsIFM+IHwgdW5kZWZpbmVkKT8uc2V0QWN0aW9uUm91dGVUcmlnZ2VyZWRJbnN0YW5jZT8uKGluc3RhbmNlKTtcblxuICAgICAgICAgICAgZnJvbSh0aGlzLnJvdXRlci5uYXZpZ2F0ZShbYmFzZVVybCwgLi4uYWN0aW9uVXJsU2VnbWVudHNdLCB7cmVsYXRpdmVUbzogcGFyYW1ldGVycy5yb3V0ZSwgcXVlcnlQYXJhbXM6IHBhcnNlZFVybC5xdWVyeVBhcmFtc30pKVxuICAgICAgICAgICAgICAgIC5waXBlKHRha2UoMSkpXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiAoaW5zdGFuY2Uuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5UcmlnZ2VyRW5kKSk7XG5cbiAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluc3RhbmNlLnN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uVHJpZ2dlckVuZDtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZhdGVBY3Rpb24oYWN0aW9uLCBwYXJhbWV0ZXJzLCBpbnN0YW5jZSk7XG5cbiAgICAgICAgICAgIGlmIChydW5Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29udGV4dCA9IGluc3RhbmNlLmNvbnRleHQ7XG4gICAgICAgICAgICAgICAgaWYgKGNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ydW4oY29udGV4dCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWFjdGl2YXRlcyBvbiByb3V0ZSB0cmlnZ2VyZWQgYWN0aW9uIGJ5IHRyeWluZyB0byByZXJvdXRlIGJhY2sgdG8gbG9jYXRpb24gd2hlcmUgYWN0aW9uIHdhcyB0cmlnZ2VyZWQuXG4gICAgICogQHBhcmFtIGluc3RhbmNlIEFjdGlvbiBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgZmluaXNoQWN0aW9uUm91dGVVbnRyaWdnZXI8VCwgUz4oaW5zdGFuY2U6IEFjdGlvbkluc3RhbmNlPFQsIFM+KSB7XG4gICAgICAgIGlmIChpbnN0YW5jZS5hY3Rpb24uYWN0aXZhdGlvblRyaWdnZXIgIT09IEFjdGlvbkFjdGl2YXRpb25UcmlnZ2VyRW51bS5PblJvdXRlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpbnN0YW5jZSA9IHRoaXMuZ2V0T3JDcmVhdGVJbnN0YW5jZShpbnN0YW5jZSk7XG5cbiAgICAgICAgaW5zdGFuY2Uuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5GaW5pc2hSb3V0ZVVudHJpZ2dlclN0YXJ0O1xuXG4gICAgICAgIGxldCB1cmwgPSB0aGlzLm5hdmlnYXRpb25TZXJ2aWNlLmdldEN1cnJlbnRMb2NhdGlvbkZyb21IaXN0b3J5KCkgPz8gdGhpcy5uYXZpZ2F0aW9uU2VydmljZS5nZXRDdXJyZW50TG9jYXRpb25Gcm9tVXJsKCk7XG4gICAgICAgIGlmICghdXJsKSB7XG4gICAgICAgICAgICB0aGlzLm5hdmlnYXRpb25TZXJ2aWNlLmJhY2soKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh1cmwuc3RhcnRzV2l0aCgnLycpKSB7XG4gICAgICAgICAgICAgICAgdXJsID0gdXJsLnN1YnN0cmluZygxKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgc3BsaXRVcmxRdWVyeVBhcmFtID0gdXJsLnNwbGl0KCc/Jyk7XG4gICAgICAgICAgICBjb25zdCB1cmxQYXRoU2VnbWVudHMgPSBzcGxpdFVybFF1ZXJ5UGFyYW1bMF0uc3BsaXQoJyMnKVswXS5zcGxpdCgnLycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbSA9IHNwbGl0VXJsUXVlcnlQYXJhbVsxXT8uc3BsaXQoJyMnKVswXTtcblxuICAgICAgICAgICAgbGV0IGFjdGlvblVybCA9IGluc3RhbmNlLmFjdGlvbj8ucm91dGVVcmwgPz8gJyc7XG4gICAgICAgICAgICBpZiAoYWN0aW9uVXJsLnN0YXJ0c1dpdGgoJy8nKSkge1xuICAgICAgICAgICAgICAgIGFjdGlvblVybCA9IGFjdGlvblVybC5zdWJzdHJpbmcoMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBhY3Rpb25VcmxTZWdtZW50cyA9IGFjdGlvblVybC5zcGxpdCgnLycpO1xuICAgICAgICAgICAgbGV0IHJlZGlyZWN0VXJsID0gJy8nICsgdXJsUGF0aFNlZ21lbnRzLnNsaWNlKDAsIHVybFBhdGhTZWdtZW50cy5sZW5ndGggLSBhY3Rpb25VcmxTZWdtZW50cy5sZW5ndGgpLmpvaW4oJy8nKTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcXVlcnlQYXJhbSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICByZWRpcmVjdFVybCA9IGAke3JlZGlyZWN0VXJsfT8ke3F1ZXJ5UGFyYW19YDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gTm8gVVJMIHJlcGxhY2VzLCBwcm9iYWJseSBvaywgdG8gYWxsb3cgZ29pbmcgYmFja1xuICAgICAgICAgICAgZnJvbSh0aGlzLnJvdXRlci5uYXZpZ2F0ZUJ5VXJsKHJlZGlyZWN0VXJsKSlcbiAgICAgICAgICAgICAgICAucGlwZShmaXJzdCgpLCB0aW1lb3V0KDEwMDApKVxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgICAgICAgICBuZXh0OiAoKSA9PiAoaW5zdGFuY2Uuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5GaW5pc2hSb3V0ZVVudHJpZ2dlckVuZEZpbmFsKSxcbiAgICAgICAgICAgICAgICAgICAgZXJyb3I6ICgpID0+IChpbnN0YW5jZS5zdGF0ZSA9IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkZpbmlzaFJvdXRlVW50cmlnZ2VyVGltZW91dEZpbmFsKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJhbnNmb3JtIGVycm9yIG9mIGFueSB0eXBlIHRvIG1uZyBlcnJvciBieSB1c2luZyBlcnJvciBtYXBwZXIgdGhhdCBjb3VsZCBiZSBwcm92aWRlZCBieSBmaW5hbCBwcm9qZWN0LlxuICAgICAqIEBwYXJhbSBlcnJvciBlcnJvciBvZiBhbnkgdHlwZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm4gbWFwcGVkIE1uZ0Vycm9yLlxuICAgICAqL1xuICAgIHB1YmxpYyB0b01uZ0FjdGlvbkVycm9yKGVycm9yPzogYW55KTogTW5nRXJyb3Ige1xuICAgICAgICBjb25zdCBhY3Rpb25FcnJvcjogTW5nRXJyb3IgPSB7XG4gICAgICAgICAgICBuYW1lOiBlcnJvcj8ubmFtZSA/PyAnVW5rbm93bkVycm9yJyxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yPy5tZXNzYWdlID8/ICdVbmtub3duIGVycm9yJyxcbiAgICAgICAgICAgIGNhdXNlOiBlcnJvclxuICAgICAgICB9O1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBIdHRwRXJyb3JSZXNwb25zZSkge1xuICAgICAgICAgICAgYWN0aW9uRXJyb3Iuc3RhdHVzID0gZXJyb3Iuc3RhdHVzO1xuICAgICAgICAgICAgYWN0aW9uRXJyb3Iuc3RhdHVzRGVzY3JpcHRpb24gPSBlcnJvci5zdGF0dXNUZXh0O1xuICAgICAgICAgICAgYWN0aW9uRXJyb3IudXJsID0gZXJyb3IudXJsID8/IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5lcnJvck1hcHBlci50b01uZ0Vycm9yKGVycm9yLCBhY3Rpb25FcnJvcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBvciBnZXRzIGV4aXN0aW5nIGFjdGlvbiBpbnN0YW5jZS5cbiAgICAgKiBAcGFyYW0gaW5zdGFuY2UgQWN0aW9uIGluc3RhbmNlLlxuICAgICAqIEBwYXJhbSBhY3Rpb24gQWN0aW9uIGRlc2NyaXB0b3IuXG4gICAgICogQHBhcmFtIHBhcmFtZXRlcnMgQWN0aW9uIHBhcmFtZXRlcnMuXG4gICAgICogQHBhcmFtIGluc3RhbmNlSW5pdGlhbFN0YXR1cyBBY3Rpb24gaW5zdGFuY2UgaW5pdGlhbCBzdGF0dXMuXG4gICAgICogQHBhcmFtIHNraXBJbml0aWFsaXphdGlvbkZyb21WaWV3Q29udGFpbmVyIElmIGluaXRpYWxpemF0aW9uIG9mIGluc3RhbmNlIGZyb20gdmlldyBjb250YWluZXIgc2hvdWxkIGJlIHNraXBwZWQuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIGdldE9yQ3JlYXRlSW5zdGFuY2U8VCwgUz4oXG4gICAgICAgIGluc3RhbmNlOiBBY3Rpb25JbnN0YW5jZTxULCBTPiB8IHVuZGVmaW5lZCxcbiAgICAgICAgYWN0aW9uPzogQWN0aW9uRGVzY3JpcHRvcjxUPixcbiAgICAgICAgcGFyYW1ldGVycz86IEFjdGlvblBhcmFtZXRlcnM8VD4sXG4gICAgICAgIGluc3RhbmNlSW5pdGlhbFN0YXR1cz86IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLFxuICAgICAgICBza2lwSW5pdGlhbGl6YXRpb25Gcm9tVmlld0NvbnRhaW5lciA9IGZhbHNlXG4gICAgKTogQWN0aW9uSW5zdGFuY2U8VCwgUz4ge1xuICAgICAgICBpZiAoIXNraXBJbml0aWFsaXphdGlvbkZyb21WaWV3Q29udGFpbmVyICYmICFpbnN0YW5jZSAmJiBhY3Rpb24/LmFjdGl2YXRpb25UcmlnZ2VyID09PSBBY3Rpb25BY3RpdmF0aW9uVHJpZ2dlckVudW0uT25Sb3V0ZSAmJiBwYXJhbWV0ZXJzKSB7XG4gICAgICAgICAgICBpbnN0YW5jZSA9IChwYXJhbWV0ZXJzLnZpZXdDb250YWluZXIgYXMgSVZpZXdBY3Rpb25Sb3V0ZVRyaWdnZXJlZENvbnRhaW5lcjxULCBTPiB8IHVuZGVmaW5lZCk/LmdldEFjdGlvblJvdXRlVHJpZ2dlcmVkSW5zdGFuY2U/LigpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaW5zdGFuY2UpIHtcbiAgICAgICAgICAgIGlmICghYWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1uZ0Vycm9ySW50ZXJuYWwoJ0FjdGlvbiBkZXNjcmlwdG9yIGlzIG5vdCBwcm92aWRlZCwgaW5zdGFuY2UgY2Fubm90IGJlIGNyZWF0ZWQuJywgJ0FjdGlvbkV4ZWN1dG9yU2VydmljZSBlcnJvcicpLmNvbnNvbGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gY3JlYXRlIG5ldyBpbnN0YW5jZSBpZiBub24gcHJvdmlkZWRcbiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IEFjdGlvbkluc3RhbmNlPFQsIFM+KGFjdGlvbiwgaW5zdGFuY2VJbml0aWFsU3RhdHVzLCB0aGlzLmRlYnVnTG9nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLm1uZ0NvbW1vbnMuYWN0aW9uc0RlYnVnSW5zdGFuY2VzICYmICF0aGlzLl9pbnN0YW5jZXMuc29tZShpID0+IGkuaW5zdGFuY2VMb25nTmFtZSA9PT0gaW5zdGFuY2UhLmluc3RhbmNlTG9uZ05hbWUpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5faW5zdGFuY2VzLmxlbmd0aCA+PSB0aGlzLmluc3RhbmNlc0J1ZmZlck1heCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxhc3RJbnN0YW5jZSA9IHRoaXMuX2luc3RhbmNlcy5zaGlmdCgpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVidWdMb2cgJiYgbGFzdEluc3RhbmNlIS5zdGF0ZSA8IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkZpbmlzaFN1Y2Nlc3NGaW5hbCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBOb3QgYWxsIGluc3RhbmNlcyBhcmUgZmluaXNoZWQhIEZpbmlzaGluZyBpbnN0YW5jZSAke2luc3RhbmNlLmluc3RhbmNlTG9uZ05hbWV9IHdpdGggZGlzbWlzc2FsLmApO1xuICAgICAgICAgICAgICAgICAgICBsYXN0SW5zdGFuY2UhLmZvcmNlRmluaXNoKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9pbnN0YW5jZXMucHVzaChpbnN0YW5jZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgfVxufVxuIl19