@sumaris-net/ngx-components 2.0.0-rc9 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. package/README.md +3 -1
  2. package/esm2020/public_api.mjs +35 -22
  3. package/esm2020/src/app/admin/admin-routing.module.mjs +6 -6
  4. package/esm2020/src/app/admin/admin.module.mjs +6 -6
  5. package/esm2020/src/app/admin/services/person.service.mjs +3 -3
  6. package/esm2020/src/app/admin/services/validator/person.validator.mjs +3 -3
  7. package/esm2020/src/app/admin/users/users.mjs +233 -0
  8. package/esm2020/src/app/admin/users/users.module.mjs +54 -0
  9. package/esm2020/src/app/core/about/about.modal.mjs +71 -0
  10. package/esm2020/src/app/core/about/about.module.mjs +34 -0
  11. package/esm2020/src/app/core/account/account.module.mjs +43 -0
  12. package/esm2020/src/app/core/account/account.page.mjs +239 -0
  13. package/esm2020/src/app/core/auth/auth.form.mjs +131 -0
  14. package/esm2020/src/app/core/auth/auth.modal.mjs +72 -0
  15. package/esm2020/src/app/core/auth/auth.module.mjs +47 -0
  16. package/esm2020/src/app/core/core.module.mjs +86 -125
  17. package/esm2020/src/app/core/core.testing.module.mjs +7 -7
  18. package/esm2020/src/app/core/form/{form-buttons-bar.component.mjs → buttons/form-buttons-bar.component.mjs} +7 -7
  19. package/esm2020/src/app/core/form/buttons/form-buttons-bar.module.mjs +35 -0
  20. package/esm2020/src/app/core/form/entity/editor.class.mjs +675 -0
  21. package/esm2020/src/app/core/form/entity/entity-editor-modal.class.mjs +421 -0
  22. package/esm2020/src/app/core/form/entity/entity-editor.class.mjs +646 -0
  23. package/esm2020/src/app/core/form/{entity-metadata.component.mjs → entity/entity-metadata.component.mjs} +6 -6
  24. package/esm2020/src/app/core/form/entity/entity.module.mjs +38 -0
  25. package/esm2020/src/app/core/form/form.class.mjs +4 -4
  26. package/esm2020/src/app/core/form/form.module.mjs +66 -0
  27. package/esm2020/src/app/core/form/list/list.form.mjs +222 -0
  28. package/esm2020/src/app/core/form/list/list.module.mjs +35 -0
  29. package/esm2020/src/app/core/form/properties/properties.form.mjs +3 -3
  30. package/esm2020/src/app/core/form/properties/properties.module.mjs +35 -0
  31. package/esm2020/src/app/core/form/properties/property.validator.mjs +4 -4
  32. package/esm2020/src/app/core/form/properties/testing/properties-form.test.mjs +3 -3
  33. package/esm2020/src/app/core/form/properties/testing/properties-form.testing.module.mjs +4 -4
  34. package/esm2020/src/app/core/{text-popover → form/text-popover}/testing/text-popover.testing.mjs +4 -4
  35. package/esm2020/src/app/core/form/text-popover/testing/text-popover.testing.module.mjs +45 -0
  36. package/esm2020/src/app/core/form/text-popover/text-form.component.mjs +89 -0
  37. package/esm2020/src/app/core/form/text-popover/text-popover.component.mjs +105 -0
  38. package/esm2020/src/app/core/form/text-popover/text-popover.module.mjs +40 -0
  39. package/esm2020/src/app/core/graphql/graphql.module.mjs +4 -4
  40. package/esm2020/src/app/core/graphql/graphql.service.mjs +12 -7
  41. package/esm2020/src/app/core/graphql/graphql.utils.mjs +2 -2
  42. package/esm2020/src/app/core/home/home.mjs +8 -8
  43. package/esm2020/src/app/core/home/home.module.mjs +48 -0
  44. package/esm2020/src/app/core/icon/icon.component.mjs +3 -3
  45. package/esm2020/src/app/core/icon/icon.module.mjs +4 -4
  46. package/esm2020/src/app/core/install/install-upgrade-card.component.mjs +3 -3
  47. package/esm2020/src/app/core/install/install-upgrade-card.module.mjs +17 -15
  48. package/esm2020/src/app/core/menu/menu.component.mjs +5 -5
  49. package/esm2020/src/app/core/menu/menu.module.mjs +9 -10
  50. package/esm2020/src/app/core/menu/menu.service.mjs +3 -3
  51. package/esm2020/src/app/core/offline/update-offline-mode-card.component.mjs +3 -3
  52. package/esm2020/src/app/core/offline/update-offline-mode-card.module.mjs +35 -0
  53. package/esm2020/src/app/core/peer/select-peer.modal.mjs +55 -11
  54. package/esm2020/src/app/core/peer/select-peer.module.mjs +17 -10
  55. package/esm2020/src/app/core/register/register-confirm.page.mjs +81 -0
  56. package/esm2020/src/app/core/register/register.form.mjs +181 -0
  57. package/esm2020/src/app/core/register/register.modal.mjs +52 -0
  58. package/esm2020/src/app/core/register/register.module.mjs +17 -15
  59. package/esm2020/src/app/core/services/account.service.mjs +22 -23
  60. package/esm2020/src/app/core/services/auth-guard.service.mjs +6 -6
  61. package/esm2020/src/app/core/services/base-entity-service.class.mjs +3 -3
  62. package/esm2020/src/app/core/services/base-graphql-service.class.mjs +8 -8
  63. package/esm2020/src/app/core/services/base58.mjs +2 -2
  64. package/esm2020/src/app/core/services/config.service.mjs +4 -4
  65. package/esm2020/src/app/core/services/crypto.service.mjs +82 -97
  66. package/esm2020/src/app/core/services/local-settings.service.mjs +8 -10
  67. package/esm2020/src/app/core/services/model/entity.decorators.mjs +44 -54
  68. package/esm2020/src/app/core/services/model/peer.model.mjs +3 -3
  69. package/esm2020/src/app/core/services/network.service.mjs +7 -7
  70. package/esm2020/src/app/core/services/pipes/account.pipes.mjs +8 -8
  71. package/esm2020/src/app/core/services/pipes/department-to-string.pipe.mjs +4 -4
  72. package/esm2020/src/app/core/services/pipes/person-to-string.pipe.mjs +4 -4
  73. package/esm2020/src/app/core/services/pipes/usage-mode.pipes.mjs +8 -8
  74. package/esm2020/src/app/core/services/platform.service.mjs +9 -10
  75. package/esm2020/src/app/core/services/storage/entities-storage.service.mjs +3 -3
  76. package/esm2020/src/app/core/services/storage/entity-store.class.mjs +4 -4
  77. package/esm2020/src/app/core/services/testing/referential.validator.mjs +3 -3
  78. package/esm2020/src/app/core/services/validator/account.validator.mjs +3 -3
  79. package/esm2020/src/app/core/services/validator/base.validator.class.mjs +3 -3
  80. package/esm2020/src/app/core/services/validator/local-settings.validator.mjs +3 -3
  81. package/esm2020/src/app/core/services/validator/user-settings.validator.mjs +3 -3
  82. package/esm2020/src/app/core/settings/settings.module.mjs +34 -0
  83. package/esm2020/src/app/core/settings/settings.page.mjs +12 -9
  84. package/esm2020/src/app/core/table/actions-column.component.mjs +3 -3
  85. package/esm2020/src/app/core/table/entities-table-datasource.class.mjs +13 -8
  86. package/esm2020/src/app/core/table/memory-table.class.mjs +3 -3
  87. package/esm2020/src/app/core/table/table-select-columns.component.mjs +3 -3
  88. package/esm2020/src/app/core/table/table.class.mjs +11 -16
  89. package/esm2020/src/app/core/table/table.module.mjs +40 -0
  90. package/esm2020/src/app/core/table/testing/table.testing.mjs +8 -8
  91. package/esm2020/src/app/core/table/testing/table.testing.module.mjs +4 -4
  92. package/esm2020/src/app/shared/audio/audio.mjs +3 -3
  93. package/esm2020/src/app/shared/audio/audio.testing.mjs +3 -3
  94. package/esm2020/src/app/shared/audio/audio.testing.module.mjs +4 -4
  95. package/esm2020/src/app/shared/capacitor/keyboard.mjs +3 -3
  96. package/esm2020/src/app/shared/constants.mjs +4 -2
  97. package/esm2020/src/app/shared/dates.mjs +20 -14
  98. package/esm2020/src/app/shared/debug/debug.component.mjs +3 -3
  99. package/esm2020/src/app/shared/debug/debug.module.mjs +4 -4
  100. package/esm2020/src/app/shared/directives/autofocus.directive.mjs +3 -3
  101. package/esm2020/src/app/shared/directives/autotitle.directive.mjs +3 -3
  102. package/esm2020/src/app/shared/directives/directives.module.mjs +4 -4
  103. package/esm2020/src/app/shared/directives/drag-and-drop.directive.mjs +3 -3
  104. package/esm2020/src/app/shared/directives/ng-var.directive.mjs +3 -3
  105. package/esm2020/src/app/shared/directives/resizable/resizable.component.mjs +3 -3
  106. package/esm2020/src/app/shared/directives/resizable/resizable.directive.mjs +3 -3
  107. package/esm2020/src/app/shared/directives/resizable/resizable.module.mjs +4 -4
  108. package/esm2020/src/app/shared/file/file.service.mjs +5 -5
  109. package/esm2020/src/app/shared/form/field.component.mjs +3 -3
  110. package/esm2020/src/app/shared/form/loading-spinner.mjs +3 -3
  111. package/esm2020/src/app/shared/gesture/gesture-config.mjs +3 -3
  112. package/esm2020/src/app/shared/guard/component-dirty.guard.mjs +3 -3
  113. package/esm2020/src/app/shared/help/help.modal.mjs +3 -3
  114. package/esm2020/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.mjs +3 -3
  115. package/esm2020/src/app/shared/hotkeys/hotkeys.service.mjs +3 -3
  116. package/esm2020/src/app/shared/hotkeys/shared-hotkeys.module.mjs +4 -4
  117. package/esm2020/src/app/shared/image/gallery/image-gallery.component.mjs +134 -60
  118. package/esm2020/src/app/shared/image/gallery/image-gallery.module.mjs +19 -7
  119. package/esm2020/src/app/shared/image/gallery/testing/gallery.service.testing.mjs +3 -3
  120. package/esm2020/src/app/shared/image/gallery/testing/gallery.testing.mjs +13 -7
  121. package/esm2020/src/app/shared/image/gallery/testing/gallery.testing.module.mjs +4 -4
  122. package/esm2020/src/app/shared/image/image.module.mjs +5 -5
  123. package/esm2020/src/app/shared/image/image.service.mjs +3 -3
  124. package/esm2020/src/app/shared/material/autocomplete/material.autocomplete.mjs +7 -6
  125. package/esm2020/src/app/shared/material/autocomplete/material.autocomplete.module.mjs +4 -4
  126. package/esm2020/src/app/shared/material/autocomplete/testing/autocomplete.test.mjs +3 -3
  127. package/esm2020/src/app/shared/material/badge/badge.directive.mjs +3 -3
  128. package/esm2020/src/app/shared/material/badge/badge.module.mjs +4 -4
  129. package/esm2020/src/app/shared/material/badge/badge.test.mjs +3 -3
  130. package/esm2020/src/app/shared/material/boolean/boolean.module.mjs +4 -4
  131. package/esm2020/src/app/shared/material/boolean/material.boolean.mjs +5 -5
  132. package/esm2020/src/app/shared/material/chips/chips.module.mjs +4 -4
  133. package/esm2020/src/app/shared/material/chips/material.chips.mjs +5 -5
  134. package/esm2020/src/app/shared/material/chips/testing/chips.test.mjs +3 -3
  135. package/esm2020/src/app/shared/material/datetime/datetime.module.mjs +4 -4
  136. package/esm2020/src/app/shared/material/datetime/material.date.mjs +7 -8
  137. package/esm2020/src/app/shared/material/datetime/material.dateshort.mjs +6 -6
  138. package/esm2020/src/app/shared/material/datetime/material.datetime.mjs +7 -8
  139. package/esm2020/src/app/shared/material/datetime/testing/mat-date-time.test.mjs +5 -7
  140. package/esm2020/src/app/shared/material/datetime/testing/mat-date.test.mjs +7 -8
  141. package/esm2020/src/app/shared/material/duration/duration.module.mjs +4 -4
  142. package/esm2020/src/app/shared/material/duration/material.duration.mjs +3 -3
  143. package/esm2020/src/app/shared/material/latlong/material.latlong.mjs +3 -3
  144. package/esm2020/src/app/shared/material/latlong/material.latlong.module.mjs +4 -4
  145. package/esm2020/src/app/shared/material/latlong/testing/latlong.test.mjs +3 -3
  146. package/esm2020/src/app/shared/material/material.module.mjs +4 -4
  147. package/esm2020/src/app/shared/material/material.testing.module.mjs +4 -4
  148. package/esm2020/src/app/shared/material/numpad/numpad.append-to-input.directive.mjs +3 -3
  149. package/esm2020/src/app/shared/material/numpad/numpad.component.mjs +3 -3
  150. package/esm2020/src/app/shared/material/numpad/numpad.container.mjs +3 -3
  151. package/esm2020/src/app/shared/material/numpad/numpad.content.mjs +3 -3
  152. package/esm2020/src/app/shared/material/numpad/numpad.directive.mjs +3 -3
  153. package/esm2020/src/app/shared/material/numpad/numpad.dom-service.mjs +3 -3
  154. package/esm2020/src/app/shared/material/numpad/numpad.module.mjs +4 -4
  155. package/esm2020/src/app/shared/material/numpad/testing/numpad.test.mjs +3 -3
  156. package/esm2020/src/app/shared/material/paginator/material.paginator-i18n.mjs +3 -3
  157. package/esm2020/src/app/shared/material/stepper/material.stepper-i18n.mjs +3 -3
  158. package/esm2020/src/app/shared/material/swipe/material.swipe.mjs +3 -3
  159. package/esm2020/src/app/shared/material/swipe/swipe.module.mjs +4 -4
  160. package/esm2020/src/app/shared/material/swipe/testing/swipe.test.mjs +7 -8
  161. package/esm2020/src/app/shared/modules.mjs +11 -0
  162. package/esm2020/src/app/shared/pipes/arrays.pipe.mjs +24 -24
  163. package/esm2020/src/app/shared/pipes/colors.pipe.mjs +4 -4
  164. package/esm2020/src/app/shared/pipes/date-diff-duration.pipe.mjs +8 -9
  165. package/esm2020/src/app/shared/pipes/date-format.pipe.mjs +4 -4
  166. package/esm2020/src/app/shared/pipes/date-from-now.pipe.mjs +4 -4
  167. package/esm2020/src/app/shared/pipes/duration.pipe.mjs +4 -4
  168. package/esm2020/src/app/shared/pipes/file-size.pipe.mjs +3 -3
  169. package/esm2020/src/app/shared/pipes/form.pipes.mjs +18 -18
  170. package/esm2020/src/app/shared/pipes/highlight.pipe.mjs +4 -4
  171. package/esm2020/src/app/shared/pipes/latlong-format.pipe.mjs +9 -9
  172. package/esm2020/src/app/shared/pipes/maps.pipe.mjs +12 -12
  173. package/esm2020/src/app/shared/pipes/math.pipes.mjs +12 -12
  174. package/esm2020/src/app/shared/pipes/ng-init.pipe.mjs +3 -3
  175. package/esm2020/src/app/shared/pipes/number-format.pipe.mjs +4 -4
  176. package/esm2020/src/app/shared/pipes/pipes.module.mjs +14 -6
  177. package/esm2020/src/app/shared/pipes/property.pipes.mjs +7 -7
  178. package/esm2020/src/app/shared/pipes/string.pipes.mjs +43 -17
  179. package/esm2020/src/app/shared/pipes/translate-context.pipe.mjs +8 -8
  180. package/esm2020/src/app/shared/services/memory-entity-service.class.mjs +3 -3
  181. package/esm2020/src/app/shared/services/progress-bar.service.mjs +3 -3
  182. package/esm2020/src/app/shared/services/storage/storage.service.mjs +3 -3
  183. package/esm2020/src/app/shared/services/translate-context.service.mjs +3 -3
  184. package/esm2020/src/app/shared/shared-routing.module.mjs +7 -7
  185. package/esm2020/src/app/shared/shared.module.mjs +9 -5
  186. package/esm2020/src/app/shared/shared.testing.module.mjs +4 -4
  187. package/esm2020/src/app/shared/testing/observable.test.mjs +6 -7
  188. package/esm2020/src/app/shared/testing/tests.page.mjs +3 -3
  189. package/esm2020/src/app/shared/toast/toast.testing.mjs +3 -3
  190. package/esm2020/src/app/shared/toast/toast.testing.module.mjs +4 -4
  191. package/esm2020/src/app/shared/toast/toasts.mjs +1 -1
  192. package/esm2020/src/app/shared/toolbar/modal-toolbar.mjs +3 -3
  193. package/esm2020/src/app/shared/toolbar/toolbar.mjs +3 -3
  194. package/esm2020/src/app/shared/toolbar/toolbar.module.mjs +4 -4
  195. package/esm2020/src/app/shared/upload-file/testing/upload-file.testing.mjs +3 -3
  196. package/esm2020/src/app/shared/upload-file/testing/upload-file.testing.module.mjs +4 -4
  197. package/esm2020/src/app/shared/upload-file/upload-file-popover.component.mjs +5 -5
  198. package/esm2020/src/app/shared/upload-file/upload-file.component.mjs +3 -3
  199. package/esm2020/src/app/shared/validator/form-error-adapter.class.mjs +3 -3
  200. package/esm2020/src/app/shared/validator/validators.mjs +4 -5
  201. package/esm2020/src/app/social/job/job.module.mjs +4 -4
  202. package/esm2020/src/app/social/job/job.service.mjs +3 -3
  203. package/esm2020/src/app/social/job/progression/job-progression.icon.mjs +3 -3
  204. package/esm2020/src/app/social/job/progression/job-progression.list.mjs +3 -3
  205. package/esm2020/src/app/social/job/testing/job-progression.testing.mjs +3 -3
  206. package/esm2020/src/app/social/job/testing/job-progression.testing.service.mjs +3 -3
  207. package/esm2020/src/app/social/job/testing/job.testing.module.mjs +4 -4
  208. package/esm2020/src/app/social/message/message.form.mjs +3 -3
  209. package/esm2020/src/app/social/message/message.modal.mjs +3 -3
  210. package/esm2020/src/app/social/message/message.module.mjs +4 -4
  211. package/esm2020/src/app/social/message/message.service.mjs +3 -3
  212. package/esm2020/src/app/social/social.module.mjs +4 -4
  213. package/esm2020/src/app/social/social.testing.module.mjs +4 -4
  214. package/esm2020/src/app/social/user-event/notification/user-event-notification.icon.mjs +3 -3
  215. package/esm2020/src/app/social/user-event/notification/user-event-notification.list.mjs +6 -6
  216. package/esm2020/src/app/social/user-event/testing/user-event.testing.mjs +13 -12
  217. package/esm2020/src/app/social/user-event/testing/user-event.testing.module.mjs +4 -4
  218. package/esm2020/src/app/social/user-event/testing/user-event.testing.service.mjs +3 -3
  219. package/esm2020/src/app/social/user-event/user-event.module.mjs +4 -4
  220. package/esm2020/src/app/social/user-event/user-event.service.mjs +6 -8
  221. package/fesm2015/sumaris-net.ngx-components.mjs +10181 -9595
  222. package/fesm2015/sumaris-net.ngx-components.mjs.map +1 -1
  223. package/fesm2020/sumaris-net.ngx-components.mjs +10395 -9817
  224. package/fesm2020/sumaris-net.ngx-components.mjs.map +1 -1
  225. package/package.json +2 -1
  226. package/public_api.d.ts +34 -21
  227. package/src/app/admin/admin.module.d.ts +1 -1
  228. package/src/app/admin/users/{list/users.d.ts → users.d.ts} +11 -11
  229. package/src/app/admin/users/users.module.d.ts +13 -0
  230. package/src/app/core/about/{modal-about.d.ts → about.modal.d.ts} +1 -1
  231. package/src/app/core/about/about.module.d.ts +10 -0
  232. package/src/app/core/account/account.module.d.ts +11 -0
  233. package/src/app/core/account/{account.d.ts → account.page.d.ts} +5 -1
  234. package/src/app/core/auth/{form/form-auth.d.ts → auth.form.d.ts} +9 -9
  235. package/src/app/core/auth/{modal/modal-auth.d.ts → auth.modal.d.ts} +4 -4
  236. package/src/app/core/auth/auth.module.d.ts +11 -0
  237. package/src/app/core/core.module.d.ts +20 -29
  238. package/src/app/core/core.testing.module.d.ts +1 -1
  239. package/src/app/core/form/{form-buttons-bar.component.d.ts → buttons/form-buttons-bar.component.d.ts} +2 -2
  240. package/src/app/core/form/buttons/form-buttons-bar.module.d.ts +9 -0
  241. package/src/app/core/form/{editor.class.d.ts → entity/editor.class.d.ts} +9 -9
  242. package/src/app/core/form/{entity-editor-modal.class.d.ts → entity/entity-editor-modal.class.d.ts} +7 -7
  243. package/src/app/core/form/{entity-editor.class.d.ts → entity/entity-editor.class.d.ts} +10 -10
  244. package/src/app/core/form/{entity-metadata.component.d.ts → entity/entity-metadata.component.d.ts} +1 -1
  245. package/src/app/core/form/entity/entity.module.d.ts +10 -0
  246. package/src/app/core/form/form.module.d.ts +13 -0
  247. package/src/app/core/form/{list.form.d.ts → list/list.form.d.ts} +3 -3
  248. package/src/app/core/form/list/list.module.d.ts +9 -0
  249. package/src/app/core/form/properties/properties.module.d.ts +9 -0
  250. package/src/app/core/{text-popover → form/text-popover}/testing/text-popover.testing.d.ts +0 -0
  251. package/src/app/core/{text-popover → form/text-popover}/testing/text-popover.testing.module.d.ts +0 -0
  252. package/src/app/core/{text-popover → form/text-popover}/text-form.component.d.ts +4 -3
  253. package/src/app/core/{text-popover → form/text-popover}/text-popover.component.d.ts +7 -2
  254. package/src/app/core/form/text-popover/text-popover.module.d.ts +10 -0
  255. package/src/app/core/home/home.module.d.ts +12 -0
  256. package/src/app/core/install/install-upgrade-card.module.d.ts +6 -7
  257. package/src/app/core/menu/menu.component.d.ts +1 -1
  258. package/src/app/core/offline/update-offline-mode-card.module.d.ts +9 -0
  259. package/src/app/core/peer/select-peer.modal.d.ts +19 -5
  260. package/src/app/core/peer/select-peer.module.d.ts +6 -4
  261. package/src/app/core/register/{confirm/confirm.d.ts → register-confirm.page.d.ts} +4 -4
  262. package/src/app/core/register/{form/form-register.d.ts → register.form.d.ts} +7 -7
  263. package/src/app/core/register/{modal/modal-register.d.ts → register.modal.d.ts} +2 -2
  264. package/src/app/core/register/register.module.d.ts +6 -6
  265. package/src/app/core/services/account.service.d.ts +8 -9
  266. package/src/app/core/services/base-graphql-service.class.d.ts +9 -8
  267. package/src/app/core/services/crypto.service.d.ts +23 -18
  268. package/src/app/core/services/model/entity.decorators.d.ts +1 -9
  269. package/src/app/core/services/network.service.d.ts +3 -4
  270. package/src/app/core/settings/settings.module.d.ts +10 -0
  271. package/src/app/core/settings/settings.page.d.ts +2 -4
  272. package/src/app/core/table/entities-table-datasource.class.d.ts +1 -0
  273. package/src/app/core/table/table.class.d.ts +2 -6
  274. package/src/app/core/table/table.module.d.ts +10 -0
  275. package/src/app/shared/constants.d.ts +1 -1
  276. package/src/app/shared/dates.d.ts +5 -3
  277. package/src/app/shared/image/gallery/image-gallery.component.d.ts +39 -17
  278. package/src/app/shared/image/gallery/image-gallery.module.d.ts +6 -4
  279. package/src/app/shared/image/gallery/testing/gallery.testing.d.ts +1 -0
  280. package/src/app/shared/material/datetime/testing/mat-date.test.d.ts +1 -0
  281. package/src/app/shared/material/swipe/testing/swipe.test.d.ts +2 -3
  282. package/src/app/shared/modules.d.ts +8 -0
  283. package/src/app/shared/pipes/pipes.module.d.ts +1 -1
  284. package/src/app/shared/pipes/string.pipes.d.ts +10 -0
  285. package/src/app/shared/shared.module.d.ts +2 -1
  286. package/src/assets/i18n/fr.json +4 -1
  287. package/src/theme/_ngx-components.scss +22 -4
  288. package/esm2020/src/app/admin/users/list/users.mjs +0 -233
  289. package/esm2020/src/app/admin/users/list/users.module.mjs +0 -58
  290. package/esm2020/src/app/core/about/modal-about.mjs +0 -71
  291. package/esm2020/src/app/core/account/account.mjs +0 -230
  292. package/esm2020/src/app/core/auth/form/form-auth.mjs +0 -131
  293. package/esm2020/src/app/core/auth/modal/modal-auth.mjs +0 -72
  294. package/esm2020/src/app/core/form/editor.class.mjs +0 -675
  295. package/esm2020/src/app/core/form/entity-editor-modal.class.mjs +0 -421
  296. package/esm2020/src/app/core/form/entity-editor.class.mjs +0 -646
  297. package/esm2020/src/app/core/form/list.form.mjs +0 -222
  298. package/esm2020/src/app/core/register/confirm/confirm.mjs +0 -81
  299. package/esm2020/src/app/core/register/form/form-register.mjs +0 -181
  300. package/esm2020/src/app/core/register/modal/modal-register.mjs +0 -52
  301. package/esm2020/src/app/core/text-popover/testing/text-popover.testing.module.mjs +0 -45
  302. package/esm2020/src/app/core/text-popover/text-form.component.mjs +0 -84
  303. package/esm2020/src/app/core/text-popover/text-popover.component.mjs +0 -92
  304. package/esm2020/src/app/vendor.mjs +0 -16
  305. package/src/app/admin/users/list/users.module.d.ts +0 -14
  306. package/src/app/vendor.d.ts +0 -11
@@ -0,0 +1,675 @@
1
+ import { Directive, EventEmitter, Input, Optional, Output, ViewChild } from '@angular/core';
2
+ import { IonContent } from '@ionic/angular';
3
+ import { BehaviorSubject, Subject, Subscription } from 'rxjs';
4
+ import { AppTable } from '../../table/table.class';
5
+ import { AppForm } from '../form.class';
6
+ import { FormButtonsBarToken } from '../buttons/form-buttons-bar.component';
7
+ import { AppFormProvider, AppFormUtils } from '../form.utils';
8
+ import { Toasts } from '../../../shared/toast/toasts';
9
+ import { ToolbarToken } from '../../../shared/toolbar/toolbar';
10
+ import { isNotNil, toNumber } from '../../../shared/functions';
11
+ import { AbstractControl } from '@angular/forms';
12
+ import { waitForFalse, waitForTrue } from '../../../shared/observables';
13
+ import * as i0 from "@angular/core";
14
+ import * as i1 from "@angular/router";
15
+ import * as i2 from "@ionic/angular";
16
+ import * as i3 from "@ngx-translate/core";
17
+ export class AppTabEditorOptions {
18
+ }
19
+ // eslint-disable-next-line @angular-eslint/directive-class-suffix
20
+ export class AppEditor {
21
+ constructor(route, router, alertCtrl, translate) {
22
+ this.route = route;
23
+ this.router = router;
24
+ this.alertCtrl = alertCtrl;
25
+ this.translate = translate;
26
+ this._subscription = new Subscription();
27
+ this._enabled = false;
28
+ this.destroySubject = new Subject();
29
+ this.readySubject = new BehaviorSubject(false);
30
+ this.dirtySubject = new BehaviorSubject(false);
31
+ this.loadingSubject = new BehaviorSubject(true);
32
+ this.errorSubject = new BehaviorSubject(undefined);
33
+ this.savingSubject = new BehaviorSubject(false);
34
+ this.touchedSubject = new BehaviorSubject(false);
35
+ this.debug = false;
36
+ this.submitted = false;
37
+ this.toolbar = null;
38
+ this.formButtonsBar = null;
39
+ }
40
+ /**
41
+ * @deprecated
42
+ */
43
+ set _loading(value) {
44
+ this.loadingSubject.next(value);
45
+ }
46
+ /**
47
+ * @deprecated
48
+ */
49
+ get _loading() {
50
+ return this.loadingSubject.value;
51
+ }
52
+ /**
53
+ * @deprecated
54
+ */
55
+ get _$ready() {
56
+ return this.readySubject;
57
+ }
58
+ /**
59
+ * @deprecated
60
+ */
61
+ get _$loading() {
62
+ return this.loadingSubject;
63
+ }
64
+ get error() {
65
+ return this.errorSubject.value;
66
+ }
67
+ set error(error) {
68
+ this.setError(error);
69
+ }
70
+ get saving() {
71
+ return this.savingSubject.value || this.editors?.some(e => e.saving);
72
+ }
73
+ get destroyed() {
74
+ return this.destroySubject?.closed !== false;
75
+ }
76
+ get tables() {
77
+ return this._children && this._children.filter(c => c instanceof AppTable);
78
+ }
79
+ get forms() {
80
+ return this._children && this._children.filter(c => c instanceof AppForm);
81
+ }
82
+ get editors() {
83
+ return this._children && this._children.filter(c => c instanceof AppEditor);
84
+ }
85
+ get dirty() {
86
+ return this.dirtySubject.value || (this._children && this._children.findIndex(c => c.enabled && c.dirty) !== -1) || false;
87
+ }
88
+ /**
89
+ * Is valid (tables and forms)
90
+ */
91
+ get valid() {
92
+ // Important: Should be not invalid AND not pending, so use '!valid' (DO NOT use 'invalid')
93
+ return !this._children || this._children.findIndex(c => c.enabled && !c.valid) === -1;
94
+ }
95
+ get invalid() {
96
+ return (this._children && this._children.findIndex(c => c.enabled && c.invalid) !== -1) || false;
97
+ }
98
+ get pending() {
99
+ return (this._children && this._children.findIndex(c => c.enabled && c.pending) !== -1) || false;
100
+ }
101
+ get loading() {
102
+ return this.loadingSubject.value || (this._children && this._children.findIndex(c => c.enabled && c.loading) !== -1) || false;
103
+ }
104
+ get loaded() {
105
+ return !this.loadingSubject.value && (!this._children || this._children.findIndex(c => c.enabled && c.loading) === -1) || false;
106
+ }
107
+ get touched() {
108
+ return this.touchedSubject.value || (this._children && this._children.findIndex(c => c.enabled && c.touched) !== -1) || false;
109
+ }
110
+ get untouched() {
111
+ return !this.touchedSubject.value && (!this._children || this._children.findIndex(c => c.enabled && c.touched) === -1) || false;
112
+ }
113
+ get enabled() {
114
+ return this._enabled;
115
+ }
116
+ get disabled() {
117
+ return !this._enabled;
118
+ }
119
+ get children() {
120
+ return this._children;
121
+ }
122
+ get empty() {
123
+ return !this._enabled;
124
+ }
125
+ ngOnInit() {
126
+ if (this.formButtonsBar) {
127
+ this.registerSubscription(this.formButtonsBar.onBack.subscribe(event => this.goBack(event)));
128
+ }
129
+ }
130
+ ngAfterViewInit() {
131
+ // Can be overridden by subclasses
132
+ }
133
+ ngOnDestroy() {
134
+ this._subscription.unsubscribe();
135
+ this.readySubject.unsubscribe();
136
+ this.loadingSubject.unsubscribe();
137
+ this.errorSubject.unsubscribe();
138
+ this.destroySubject.next();
139
+ this.destroySubject.unsubscribe();
140
+ }
141
+ addChildForm(form) {
142
+ if (!form)
143
+ throw new Error('Trying to register an undefined child form');
144
+ this._children = this._children || [];
145
+ if (typeof form === 'function') {
146
+ this._children.push(new AppFormProvider(form));
147
+ }
148
+ else {
149
+ this._children.push(form);
150
+ }
151
+ return this;
152
+ }
153
+ addChildForms(forms) {
154
+ (forms || []).forEach(form => this.addChildForm(form));
155
+ }
156
+ removeChildForm(form) {
157
+ if (!form)
158
+ throw new Error('Trying to remove an undefined child form');
159
+ const index = (this._children || []).findIndex(c => c === form);
160
+ if (index !== -1) {
161
+ return this._children.splice(index, 1)[0];
162
+ }
163
+ return undefined;
164
+ }
165
+ disable(opts) {
166
+ this._enabled = false;
167
+ this._children?.forEach(c => c.disable(opts));
168
+ if (!this.loading && (!opts || opts.emitEvent !== false))
169
+ this.markForCheck();
170
+ }
171
+ enable(opts) {
172
+ this._enabled = true;
173
+ this._children?.forEach(c => c.enable(opts));
174
+ if (!this.loading && (!opts || opts.emitEvent !== false))
175
+ this.markForCheck();
176
+ }
177
+ markAsPristine(opts) {
178
+ this.error = null;
179
+ this.submitted = false;
180
+ if (this.dirtySubject.value !== false) {
181
+ this.dirtySubject.next(false);
182
+ }
183
+ this._children?.forEach(c => c.markAsPristine(opts));
184
+ if (!this.loading && (!opts || opts.emitEvent !== false))
185
+ this.markForCheck();
186
+ }
187
+ markAsUntouched(opts) {
188
+ if (this.touchedSubject.value !== false) {
189
+ this.touchedSubject.next(false);
190
+ }
191
+ this._children?.forEach(c => c.markAsUntouched());
192
+ if (!this.loading && (!opts || opts.emitEvent !== false))
193
+ this.markForCheck();
194
+ }
195
+ /**
196
+ * @deprecated prefer to use markAllAsTouched()
197
+ * @param opts
198
+ */
199
+ markAsTouched(opts) {
200
+ if (!this.touchedSubject.value !== true) {
201
+ this.touchedSubject.next(true);
202
+ }
203
+ this._children?.forEach(c => c.markAsTouched(opts));
204
+ if (!this.loading && (!opts || opts.emitEvent !== false))
205
+ this.markForCheck();
206
+ }
207
+ markAllAsTouched(opts) {
208
+ if (this.touchedSubject.value !== true) {
209
+ this.touchedSubject.next(true);
210
+ }
211
+ this._children?.forEach(c => c.markAllAsTouched(opts));
212
+ if (!this.loading && (!opts || opts.emitEvent !== false))
213
+ this.markForCheck();
214
+ }
215
+ markAsDirty(opts) {
216
+ if (!this.dirtySubject.value) {
217
+ this.dirtySubject.next(true);
218
+ if (!this.loading && (!opts || opts.emitEvent !== false))
219
+ this.markForCheck();
220
+ }
221
+ }
222
+ markAsLoading(opts) {
223
+ if (!this.loadingSubject.value) {
224
+ this.loadingSubject.next(true);
225
+ if (!opts || opts.emitEvent !== false)
226
+ this.markForCheck();
227
+ }
228
+ }
229
+ markAsLoaded(opts) {
230
+ if (this.loadingSubject.value) {
231
+ this.loadingSubject.next(false);
232
+ if (!opts || opts.onlySelf !== true) {
233
+ // Emit to children forms and editors
234
+ // note: tables should be changed by parent
235
+ this.forms?.forEach(f => f.markAsLoaded(opts));
236
+ this.editors?.forEach(e => e.markAsLoaded(opts));
237
+ }
238
+ if (!opts || opts.emitEvent !== false) {
239
+ this.markForCheck();
240
+ }
241
+ }
242
+ }
243
+ markAsReady(opts) {
244
+ this._children?.forEach(c => c.markAsReady(opts));
245
+ this.readySubject.next(true);
246
+ }
247
+ ready(opts) {
248
+ if (this.readySubject.value)
249
+ return Promise.resolve();
250
+ return waitForTrue(this.readySubject, opts);
251
+ }
252
+ waitIdle(opts) {
253
+ if (!this.loadingSubject.value)
254
+ return Promise.resolve();
255
+ return waitForFalse(this.loadingSubject, opts);
256
+ }
257
+ markAsSaving(opts) {
258
+ if (this.savingSubject.value !== true) {
259
+ this.savingSubject.next(true);
260
+ if (!opts || opts.emitEvent !== false)
261
+ this.markForCheck();
262
+ }
263
+ }
264
+ markAsSaved(opts) {
265
+ if (this.savingSubject.value !== false) {
266
+ this.savingSubject.next(false);
267
+ if (!opts || opts.emitEvent !== false)
268
+ this.markForCheck();
269
+ }
270
+ }
271
+ async cancel(event) {
272
+ if (this.isNewData) {
273
+ await this.unload(); // async reset
274
+ }
275
+ else if (this.dirty) {
276
+ await this.reload(); // async reload
277
+ }
278
+ }
279
+ /**
280
+ * Unload the page (remove all data). Useful when reusing angular cache a cancelled page
281
+ *
282
+ * @param opts
283
+ */
284
+ async unload(opts) {
285
+ console.debug('[editor] Unloading data...');
286
+ this.markAsLoading();
287
+ this._children?.forEach(f => {
288
+ if (f instanceof AppForm) {
289
+ f.reset(null, opts);
290
+ }
291
+ else if (f instanceof AppTable) {
292
+ f.dataSource.disconnect();
293
+ }
294
+ else if (f instanceof AppEditor) {
295
+ f.unload(opts);
296
+ }
297
+ });
298
+ this.markAsPristine(opts);
299
+ this.markAsSaved(opts);
300
+ }
301
+ async reloadWithConfirmation(confirm) {
302
+ const needConfirm = this.dirty;
303
+ // if not confirm yet: ask confirmation
304
+ if (!confirm && needConfirm) {
305
+ const translations = this.translate.instant(['COMMON.BTN_ABORT_CHANGES', 'COMMON.BTN_CANCEL', 'CONFIRM.CANCEL_CHANGES', 'CONFIRM.ALERT_HEADER']);
306
+ const alert = await this.alertCtrl.create({
307
+ header: translations['CONFIRM.ALERT_HEADER'],
308
+ message: translations['CONFIRM.CANCEL_CHANGES'],
309
+ buttons: [
310
+ {
311
+ text: translations['COMMON.BTN_ABORT_CHANGES'],
312
+ cssClass: 'secondary',
313
+ handler: () => {
314
+ confirm = true; // update upper value
315
+ }
316
+ },
317
+ {
318
+ text: translations['COMMON.BTN_CANCEL'],
319
+ role: 'cancel',
320
+ handler: () => {
321
+ }
322
+ }
323
+ ]
324
+ });
325
+ await alert.present();
326
+ await alert.onDidDismiss();
327
+ }
328
+ // If confirm: execute the reload
329
+ if (confirm || !needConfirm) {
330
+ this.scrollToTop();
331
+ this.disable();
332
+ return await this.reload();
333
+ }
334
+ }
335
+ async goBack(event) {
336
+ // Go back
337
+ if (this.toolbar?.canGoBack) {
338
+ return this.toolbar.goBack();
339
+ }
340
+ else {
341
+ // Back to home
342
+ return this.router.navigateByUrl('/');
343
+ }
344
+ }
345
+ logFormErrors(prefix) {
346
+ if (this.debug)
347
+ console.debug('[editor] Editor not valid. Checking where (forms, tables)...');
348
+ this._children?.forEach(c => this.logChildrenErrors(c, prefix));
349
+ }
350
+ /* -- protected methods -- */
351
+ async scrollToTop(duration) {
352
+ duration = toNumber(duration, 500);
353
+ if (!this.content) {
354
+ console.warn(`[tab-editor] Cannot scroll to top. (no 'ion-content' tag found ${this.constructor.name}`);
355
+ // TODO: FIXME (not working as the page is not the window)
356
+ const scrollToTop = window.setInterval(() => {
357
+ const pos = window.scrollY;
358
+ if (pos > 0) {
359
+ window.scrollTo(0, pos - 20); // how far to scroll on each step
360
+ }
361
+ else {
362
+ window.clearInterval(scrollToTop);
363
+ }
364
+ }, 16);
365
+ return;
366
+ }
367
+ return this.content.scrollToTop(duration);
368
+ }
369
+ registerSubscription(sub) {
370
+ this._subscription.add(sub);
371
+ }
372
+ unregisterSubscription(sub) {
373
+ this._subscription.remove(sub);
374
+ }
375
+ async saveIfDirtyAndConfirm(event, opts) {
376
+ if (!this.dirty)
377
+ return true;
378
+ let confirmed = opts?.confirmed || false;
379
+ if (!confirmed) {
380
+ let cancel = false;
381
+ const translations = this.translate.instant(['COMMON.BTN_SAVE', 'COMMON.BTN_CANCEL', 'COMMON.BTN_ABORT_CHANGES', 'CONFIRM.SAVE', 'CONFIRM.ALERT_HEADER']);
382
+ const alert = await this.alertCtrl.create({
383
+ header: translations['CONFIRM.ALERT_HEADER'],
384
+ message: translations['CONFIRM.SAVE'],
385
+ buttons: [
386
+ {
387
+ text: translations['COMMON.BTN_CANCEL'],
388
+ role: 'cancel',
389
+ cssClass: 'secondary',
390
+ handler: () => {
391
+ cancel = true;
392
+ }
393
+ },
394
+ {
395
+ text: translations['COMMON.BTN_ABORT_CHANGES'],
396
+ cssClass: 'secondary',
397
+ handler: () => {
398
+ }
399
+ },
400
+ {
401
+ text: translations['COMMON.BTN_SAVE'],
402
+ handler: () => {
403
+ confirmed = true; // update upper value
404
+ }
405
+ }
406
+ ]
407
+ });
408
+ await alert.present();
409
+ await alert.onDidDismiss();
410
+ if (!confirmed) {
411
+ return !cancel;
412
+ }
413
+ }
414
+ return await this.save(event, opts);
415
+ }
416
+ async showToast(opts) {
417
+ if (!this.toastController)
418
+ throw new Error('Missing toastController in component\'s constructor');
419
+ await Toasts.show(this.toastController, this.translate, opts);
420
+ }
421
+ logChildrenErrors(c, prefix, path) {
422
+ prefix = prefix || '[app-tab-editor] ';
423
+ // If editor
424
+ if (c instanceof AppEditor) {
425
+ c.logFormErrors();
426
+ }
427
+ // Angular form control
428
+ else if (c instanceof AbstractControl) {
429
+ AppFormUtils.logFormErrors(c, prefix, path);
430
+ }
431
+ // If form provider: get delegate
432
+ else if (c instanceof AppFormProvider) {
433
+ if (!c.empty && !c.valid) {
434
+ c.waitDelegate({ timeout: 1000 }).then(delegate => this.logChildrenErrors(delegate, prefix, 'provider'));
435
+ }
436
+ }
437
+ // If table
438
+ else if (c instanceof AppTable) {
439
+ if (c.invalid && c.editedRow && c.editedRow.validator) {
440
+ const path = c.constructor.name.toLowerCase();
441
+ AppFormUtils.logFormErrors(c.editedRow.validator, prefix, path);
442
+ }
443
+ }
444
+ // If form
445
+ else if (c instanceof AppForm) {
446
+ if (!c.empty && !c.valid) {
447
+ if (c.pending) {
448
+ const path = c.constructor.name.toLowerCase();
449
+ console.warn(`${prefix} -> ${path}: waiting while pending...`);
450
+ AppFormUtils.waitWhilePending(c, { timeout: 1000 })
451
+ .then(() => this.logChildrenErrors(c.form, prefix, path));
452
+ }
453
+ else {
454
+ AppFormUtils.logFormErrors(c.form, prefix);
455
+ }
456
+ }
457
+ }
458
+ // If editor
459
+ else if (c instanceof AppEditor) {
460
+ if (!c.empty && !c.valid) {
461
+ if (c.pending) {
462
+ const path = c.constructor.name.toLowerCase();
463
+ console.warn(`${prefix} -> ${path}: waiting while pending...`);
464
+ AppFormUtils.waitWhilePending(c, { timeout: 1000 })
465
+ .then(() => c.logFormErrors(prefix));
466
+ }
467
+ else {
468
+ c.logFormErrors(prefix);
469
+ }
470
+ }
471
+ }
472
+ else {
473
+ console.warn(`${prefix} Unknown children sub-form: `, c);
474
+ }
475
+ }
476
+ setError(value, opts) {
477
+ if (this.errorSubject.value !== value) {
478
+ this.errorSubject.next(value);
479
+ if (!opts || opts.emitEvent !== false)
480
+ this.markForCheck();
481
+ }
482
+ }
483
+ resetError(opts) {
484
+ this.setError(undefined, opts);
485
+ }
486
+ markForCheck() {
487
+ // Should be override by subclasses, if change detection is Push
488
+ }
489
+ }
490
+ AppEditor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: AppEditor, deps: [{ token: i1.ActivatedRoute }, { token: i1.Router }, { token: i2.AlertController }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Directive });
491
+ AppEditor.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.8", type: AppEditor, viewQueries: [{ propertyName: "toolbar", first: true, predicate: ToolbarToken, descendants: true }, { propertyName: "formButtonsBar", first: true, predicate: FormButtonsBarToken, descendants: true, static: true }, { propertyName: "content", first: true, predicate: IonContent, descendants: true, static: true }], ngImport: i0 });
492
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: AppEditor, decorators: [{
493
+ type: Directive
494
+ }], ctorParameters: function () { return [{ type: i1.ActivatedRoute }, { type: i1.Router }, { type: i2.AlertController }, { type: i3.TranslateService }]; }, propDecorators: { toolbar: [{
495
+ type: ViewChild,
496
+ args: [ToolbarToken]
497
+ }], formButtonsBar: [{
498
+ type: ViewChild,
499
+ args: [FormButtonsBarToken, { static: true }]
500
+ }], content: [{
501
+ type: ViewChild,
502
+ args: [IonContent, { static: true }]
503
+ }] } });
504
+ // eslint-disable-next-line @angular-eslint/directive-class-suffix
505
+ export class AppTabEditor extends AppEditor {
506
+ constructor(route, // Modal editor give 'null'
507
+ router, alertCtrl, translate, options) {
508
+ super(route, router, alertCtrl, translate);
509
+ this.route = route;
510
+ this.router = router;
511
+ this.alertCtrl = alertCtrl;
512
+ this.translate = translate;
513
+ this._selectedTabIndex = 0;
514
+ this.selectedTabIndexChange = new EventEmitter();
515
+ options = {
516
+ tabCount: 1,
517
+ enableSwipe: true,
518
+ tabGroupAnimationDuration: '200ms',
519
+ ...options
520
+ };
521
+ this.tabCount = options.tabCount;
522
+ this.enableSwipe = options.enableSwipe;
523
+ this.tabGroupAnimationDuration = options.tabGroupAnimationDuration;
524
+ this.queryTabIndexParamName = 'tab';
525
+ }
526
+ set selectedTabIndex(value) {
527
+ this.setSelectedTabIndex(value);
528
+ }
529
+ get selectedTabIndex() {
530
+ return this._selectedTabIndex;
531
+ }
532
+ ngOnInit() {
533
+ super.ngOnInit();
534
+ // Read the selected tab index, from path query params
535
+ if (this.tabGroup && this.route && this.queryTabIndexParamName) {
536
+ this.registerSubscription(this.route.queryParams
537
+ .subscribe(queryParams => {
538
+ this.queryParams = { ...queryParams };
539
+ // Parse tab param
540
+ if (this.tabCount > 1 && this.queryTabIndexParamName) {
541
+ const tabIndex = queryParams[this.queryTabIndexParamName];
542
+ this.queryParams[this.queryTabIndexParamName] = tabIndex && parseInt(tabIndex) || undefined;
543
+ if (isNotNil(this.queryParams[this.queryTabIndexParamName])) {
544
+ this.selectedTabIndex = this.queryParams[this.queryTabIndexParamName];
545
+ }
546
+ }
547
+ // Realign tab, after a delay because the tab can be disabled when component is created
548
+ setTimeout(() => this.tabGroup.realignInkBar(), 500);
549
+ }));
550
+ }
551
+ }
552
+ ngOnDestroy() {
553
+ super.ngOnDestroy();
554
+ this.selectedTabIndexChange.complete();
555
+ this.loadingSubject.unsubscribe();
556
+ this.errorSubject.unsubscribe();
557
+ }
558
+ setSelectedTabIndex(value, opts) {
559
+ // Fix value
560
+ if (value < 0) {
561
+ value = 0;
562
+ }
563
+ else if (value > this.tabCount - 1) {
564
+ console.warn(`[tab-editor] Invalid tab index ${value}. Max value is ${this.tabCount - 1}`);
565
+ value = this._selectedTabIndex;
566
+ }
567
+ this._selectedTabIndex = value;
568
+ this.selectedTabIndexChange.next(value);
569
+ if (this.tabGroup && (!opts || opts.realignInkBar !== false)) {
570
+ this.tabGroup.selectedIndex = value;
571
+ this.markForCheck();
572
+ // Wait tab change in UI, before realign ink tab
573
+ setTimeout(() => this.tabGroup.realignInkBar(), 200);
574
+ }
575
+ else if (!opts || opts.emitEvent !== false) {
576
+ this.markForCheck();
577
+ }
578
+ }
579
+ realignInkBar() {
580
+ this.tabGroup?.realignInkBar();
581
+ }
582
+ onTabChange(event, queryTabIndexParamName) {
583
+ queryTabIndexParamName = queryTabIndexParamName || this.queryTabIndexParamName;
584
+ if (!queryTabIndexParamName || !this.route)
585
+ return true; // Skip if tab query param not set, or no route
586
+ if (!this.queryParams || +this.queryParams[queryTabIndexParamName] !== event.index) {
587
+ this.queryParams = this.queryParams || {};
588
+ this.queryParams[queryTabIndexParamName] = event.index;
589
+ if (queryTabIndexParamName === 'tab' && isNotNil(this.queryParams['subtab'])) {
590
+ delete this.queryParams.subtab; // clean subtab
591
+ }
592
+ this.router.navigate(['.'], {
593
+ relativeTo: this.route,
594
+ queryParams: this.queryParams,
595
+ replaceUrl: true
596
+ });
597
+ return true;
598
+ }
599
+ return false;
600
+ }
601
+ /**
602
+ * Action triggered when user swipes
603
+ */
604
+ onSwipeTab(event) {
605
+ // DEBUG
606
+ // if (this.debug) console.debug("[tab-page] onSwipeTab()");
607
+ // Skip, if not a valid swipe event
608
+ if (!this.enableSwipe || !event
609
+ || event.defaultPrevented || (event.srcEvent && event.srcEvent.defaultPrevented)
610
+ || event.pointerType !== 'touch') {
611
+ return false;
612
+ }
613
+ // DEBUG
614
+ //if (this.debug)
615
+ //console.debug("[tab-page] Detected swipe: " + event.type, event);
616
+ let selectTabIndex = this.selectedTabIndex;
617
+ switch (event.type) {
618
+ // Open next tab
619
+ case 'swipeleft':
620
+ const isLast = selectTabIndex >= (this.tabCount - 1);
621
+ selectTabIndex = isLast ? 0 : selectTabIndex + 1;
622
+ break;
623
+ // Open previous tab
624
+ case 'swiperight':
625
+ const isFirst = selectTabIndex <= 0;
626
+ selectTabIndex = isFirst ? this.tabCount : selectTabIndex - 1;
627
+ break;
628
+ // Other case
629
+ default:
630
+ console.error('[tab-page] Unknown swipe action: ' + event.type);
631
+ return false;
632
+ }
633
+ setTimeout(() => {
634
+ this.selectedTabIndex = selectTabIndex;
635
+ this.markForCheck();
636
+ });
637
+ return true;
638
+ }
639
+ onSubTabChange(event) {
640
+ this.onTabChange(event, 'subtab');
641
+ }
642
+ async unload(opts) {
643
+ this.selectedTabIndex = 0;
644
+ await super.unload(opts);
645
+ }
646
+ async saveDirtyChildren() {
647
+ // Save all dirty tables
648
+ const results = await Promise.all([
649
+ ...this.tables,
650
+ ...this.editors
651
+ ]
652
+ .filter(c => c.dirty)
653
+ .map(c => c.save()));
654
+ return !results.some(saved => saved !== true);
655
+ }
656
+ }
657
+ AppTabEditor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: AppTabEditor, deps: [{ token: i1.ActivatedRoute, optional: true }, { token: i1.Router }, { token: i2.AlertController }, { token: i3.TranslateService }, { token: AppTabEditorOptions, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
658
+ AppTabEditor.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.8", type: AppTabEditor, inputs: { queryTabIndexParamName: "queryTabIndexParamName", selectedTabIndex: "selectedTabIndex" }, outputs: { selectedTabIndexChange: "selectedTabIndexChange" }, viewQueries: [{ propertyName: "tabGroup", first: true, predicate: ["tabGroup"], descendants: true, static: true }], usesInheritance: true, ngImport: i0 });
659
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: AppTabEditor, decorators: [{
660
+ type: Directive
661
+ }], ctorParameters: function () { return [{ type: i1.ActivatedRoute, decorators: [{
662
+ type: Optional
663
+ }] }, { type: i1.Router }, { type: i2.AlertController }, { type: i3.TranslateService }, { type: AppTabEditorOptions, decorators: [{
664
+ type: Optional
665
+ }] }]; }, propDecorators: { queryTabIndexParamName: [{
666
+ type: Input
667
+ }], selectedTabIndex: [{
668
+ type: Input
669
+ }], selectedTabIndexChange: [{
670
+ type: Output
671
+ }], tabGroup: [{
672
+ type: ViewChild,
673
+ args: ['tabGroup', { static: true }]
674
+ }] } });
675
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdG9yLmNsYXNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2Zvcm0vZW50aXR5L2VkaXRvci5jbGFzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWdCLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFxQixRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUc1SCxPQUFPLEVBQWtCLFVBQVUsRUFBa0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUU1RSxPQUFPLEVBQUMsZUFBZSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBQzNFLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQztBQUNqRCxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3RDLE9BQU8sRUFBQyxtQkFBbUIsRUFBQyxNQUFNLHVDQUF1QyxDQUFDO0FBQzFFLE9BQU8sRUFBQyxlQUFlLEVBQUUsWUFBWSxFQUEyQixNQUFNLGVBQWUsQ0FBQztBQUN0RixPQUFPLEVBQW1CLE1BQU0sRUFBQyxNQUFNLDhCQUE4QixDQUFDO0FBRXRFLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxpQ0FBaUMsQ0FBQztBQUM3RCxPQUFPLEVBQUMsUUFBUSxFQUFFLFFBQVEsRUFBQyxNQUFNLDJCQUEyQixDQUFDO0FBRTdELE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvQyxPQUFPLEVBQUMsWUFBWSxFQUFrQixXQUFXLEVBQUMsTUFBTSw2QkFBNkIsQ0FBQzs7Ozs7QUFldEYsTUFBTSxPQUFPLG1CQUFtQjtDQWdCL0I7QUFHRCxrRUFBa0U7QUFDbEUsTUFBTSxPQUFnQixTQUFTO0lBdUk3QixZQUNZLEtBQXFCLEVBQ3JCLE1BQWMsRUFDZCxTQUEwQixFQUMxQixTQUEyQjtRQUgzQixVQUFLLEdBQUwsS0FBSyxDQUFnQjtRQUNyQixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2QsY0FBUyxHQUFULFNBQVMsQ0FBaUI7UUFDMUIsY0FBUyxHQUFULFNBQVMsQ0FBa0I7UUF2SS9CLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUVqQyxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBRVIsbUJBQWMsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBRS9DLGlCQUFZLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDbkQsaUJBQVksR0FBRyxJQUFJLGVBQWUsQ0FBVSxLQUFLLENBQUMsQ0FBQztRQUNuRCxtQkFBYyxHQUFHLElBQUksZUFBZSxDQUFVLElBQUksQ0FBQyxDQUFDO1FBQ3BELGlCQUFZLEdBQUcsSUFBSSxlQUFlLENBQVMsU0FBUyxDQUFDLENBQUM7UUFDdEQsa0JBQWEsR0FBRyxJQUFJLGVBQWUsQ0FBVSxLQUFLLENBQUMsQ0FBQztRQUNwRCxtQkFBYyxHQUFHLElBQUksZUFBZSxDQUFVLEtBQUssQ0FBQyxDQUFDO1FBRTlELFVBQUssR0FBRyxLQUFLLENBQUM7UUFFZCxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBaURPLFlBQU8sR0FBc0IsSUFBSSxDQUFDO1FBQ1QsbUJBQWMsR0FBNkIsSUFBSSxDQUFDO0lBd0VsRyxDQUFDO0lBbkhEOztPQUVHO0lBQ0gsSUFBYyxRQUFRLENBQUMsS0FBYztRQUNuQyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFjLFFBQVE7UUFDcEIsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQztJQUNuQyxDQUFDO0lBQ0Q7O09BRUc7SUFDSCxJQUFjLE9BQU87UUFDbkIsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQzNCLENBQUM7SUFDRDs7T0FFRztJQUNILElBQWMsU0FBUztRQUNyQixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDN0IsQ0FBQztJQUVELElBQUksS0FBSztRQUNQLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUM7SUFDakMsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLEtBQWE7UUFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2QixDQUFDO0lBRUQsSUFBSSxNQUFNO1FBQ1IsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBRUQsSUFBSSxTQUFTO1FBQ1gsT0FBTyxJQUFJLENBQUMsY0FBYyxFQUFFLE1BQU0sS0FBSyxLQUFLLENBQUE7SUFDOUMsQ0FBQztJQU1ELElBQUksTUFBTTtRQUNSLE9BQU8sSUFBSSxDQUFDLFNBQVMsSUFBSyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsWUFBWSxRQUFRLENBQXFCLENBQUM7SUFDbEcsQ0FBQztJQUNELElBQUksS0FBSztRQUNQLE9BQU8sSUFBSSxDQUFDLFNBQVMsSUFBSyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsWUFBWSxPQUFPLENBQW9CLENBQUM7SUFDaEcsQ0FBQztJQUNELElBQUksT0FBTztRQUNULE9BQU8sSUFBSSxDQUFDLFNBQVMsSUFBSyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsWUFBWSxTQUFTLENBQWlCLENBQUM7SUFDL0YsQ0FBQztJQUNELElBQUksS0FBSztRQUNQLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUM7SUFDNUgsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxLQUFLO1FBQ1AsMkZBQTJGO1FBQzNGLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUN4RixDQUFDO0lBRUQsSUFBSSxPQUFPO1FBQ1QsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQztJQUNuRyxDQUFDO0lBRUQsSUFBSSxPQUFPO1FBQ1QsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQztJQUNuRyxDQUFDO0lBRUQsSUFBSSxPQUFPO1FBQ1QsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQztJQUNoSSxDQUFDO0lBRUQsSUFBSSxNQUFNO1FBQ1IsT0FBTyxDQUFDLElB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QUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVELEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBOEI7UUFDekMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLENBQUMsQ0FBQztRQUMxQixNQUFNLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDM0IsQ0FBQztJQUlTLEtBQUssQ0FBQyxpQkFBaUI7UUFDL0Isd0JBQXdCO1FBQ3hCLE1BQU0sT0FBTyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztZQUNoQyxHQUFHLElBQUksQ0FBQyxNQUFNO1lBQ2QsR0FBRyxJQUFJLENBQUMsT0FBTztTQUNoQjthQUNFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7YUFDcEIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUV2QixPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssS0FBSyxJQUFJLENBQUMsQ0FBQztJQUNoRCxDQUFDOzt5R0FwTW1CLFlBQVk7NkZBQVosWUFBWTsyRkFBWixZQUFZO2tCQUZqQyxTQUFTOzswQkEyQkwsUUFBUTs7MEJBSVIsUUFBUTs0Q0FsQkYsc0JBQXNCO3NCQUE5QixLQUFLO2dCQUVPLGdCQUFnQjtzQkFBNUIsS0FBSztnQkFPYSxzQkFBc0I7c0JBQXhDLE1BQU07Z0JBRWtDLFFBQVE7c0JBQWhELFNBQVM7dUJBQUMsVUFBVSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7QWZ0ZXJWaWV3SW5pdCwgRGlyZWN0aXZlLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3B0aW9uYWwsIE91dHB1dCwgVmlld0NoaWxkfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7QWN0aXZhdGVkUm91dGUsIFBhcmFtcywgUm91dGVyfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHtNYXRUYWJDaGFuZ2VFdmVudCwgTWF0VGFiR3JvdXB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3RhYnMnO1xuaW1wb3J0IHtBbGVydENvbnRyb2xsZXIsIElvbkNvbnRlbnQsIFRvYXN0Q29udHJvbGxlcn0gZnJvbSAnQGlvbmljL2FuZ3VsYXInO1xuaW1wb3J0IHtUcmFuc2xhdGVTZXJ2aWNlfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7QmVoYXZpb3JTdWJqZWN0LCBTdWJqZWN0LCBTdWJzY3JpcHRpb24sIFRlYXJkb3duTG9naWN9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtBcHBUYWJsZX0gZnJvbSAnLi4vLi4vdGFibGUvdGFibGUuY2xhc3MnO1xuaW1wb3J0IHtBcHBGb3JtfSBmcm9tICcuLi9mb3JtLmNsYXNzJztcbmltcG9ydCB7Rm9ybUJ1dHRvbnNCYXJUb2tlbn0gZnJvbSAnLi4vYnV0dG9ucy9mb3JtLWJ1dHRvbnMtYmFyLmNvbXBvbmVudCc7XG5pbXBvcnQge0FwcEZvcm1Qcm92aWRlciwgQXBwRm9ybVV0aWxzLCBJQXBwRm9ybSwgSUFwcEZvcm1HZXR0ZXJ9IGZyb20gJy4uL2Zvcm0udXRpbHMnO1xuaW1wb3J0IHtTaG93VG9hc3RPcHRpb25zLCBUb2FzdHN9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC90b2FzdC90b2FzdHMnO1xuaW1wb3J0IHtIYW1tZXJTd2lwZUV2ZW50fSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvZ2VzdHVyZS9oYW1tZXIudXRpbHMnO1xuaW1wb3J0IHtUb29sYmFyVG9rZW59IGZyb20gJy4uLy4uLy4uL3NoYXJlZC90b29sYmFyL3Rvb2xiYXInO1xuaW1wb3J0IHtpc05vdE5pbCwgdG9OdW1iZXJ9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9mdW5jdGlvbnMnO1xuaW1wb3J0IHtDYW5MZWF2ZX0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL2d1YXJkL2NvbXBvbmVudC1kaXJ0eS5ndWFyZCc7XG5pbXBvcnQge0Fic3RyYWN0Q29udHJvbH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHt3YWl0Rm9yRmFsc2UsIFdhaXRGb3JPcHRpb25zLCB3YWl0Rm9yVHJ1ZX0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL29ic2VydmFibGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBJQXBwRWRpdG9yIGV4dGVuZHMgQ2FuTGVhdmUsIElBcHBGb3JtIHtcbiAgc2F2ZShldmVudD86IEV2ZW50LCBvcHRpb25zPzogYW55KTogUHJvbWlzZTxib29sZWFuPjtcbiAgY2FuY2VsKGV2ZW50PzogRXZlbnQpOiBQcm9taXNlPHZvaWQ+O1xuICBhZGRDaGlsZEZvcm0oZm9ybTogSUFwcEZvcm0gfCBJQXBwRm9ybUdldHRlcik6IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUFwcFRhYkVkaXRvciBleHRlbmRzIElBcHBFZGl0b3Ige1xuICBzZWxlY3RlZFRhYkluZGV4OiBudW1iZXI7XG4gIHNldFNlbGVjdGVkVGFiSW5kZXgodmFsdWU6IG51bWJlciwgb3B0cz86IHtlbWl0RXZlbnQ/OiBib29sZWFuOyByZWFsaWduSW5rQmFyPzogYm9vbGVhbjt9KTogdm9pZDtcbiAgdW5sb2FkKG9wdHM/OiB7ZW1pdEV2ZW50PzogYm9vbGVhbn0pOiBQcm9taXNlPHZvaWQ+O1xuICByZWFsaWduSW5rQmFyKCk7XG59XG5cbmV4cG9ydCBjbGFzcyBBcHBUYWJFZGl0b3JPcHRpb25zIHtcblxuICAvKipcbiAgICogTnVtYmVyIG9mIHRhYi4gMSBieSBkZWZhdWx0XG4gICAqL1xuICB0YWJDb3VudD86IG51bWJlcjtcblxuICAvKipcbiAgICogJzIwMG1zJyBieSBkZWZhdWx0XG4gICAqL1xuICB0YWJHcm91cEFuaW1hdGlvbkR1cmF0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTaG91bGQgZW5hYmxlIHN3aXBlIGJldHdlZW4gdGFiLCBvbiB0b3VjaCBzY3JlZW5cbiAgICovXG4gIGVuYWJsZVN3aXBlPzogYm9vbGVhbjsgLy8gdHJ1ZSBieSBkZWZhdWx0XG59XG5cbkBEaXJlY3RpdmUoKVxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9kaXJlY3RpdmUtY2xhc3Mtc3VmZml4XG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQXBwRWRpdG9yPFQgPSBhbnksIElEID0gbnVtYmVyLCBPID0gYW55PlxuICBpbXBsZW1lbnRzIElBcHBFZGl0b3IsIE9uSW5pdCwgT25EZXN0cm95LCBBZnRlclZpZXdJbml0IHtcblxuICBwcml2YXRlIF9jaGlsZHJlbjogSUFwcEZvcm1bXTtcbiAgcHJpdmF0ZSBfc3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG4gIHByb3RlY3RlZCBfZW5hYmxlZCA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgdG9hc3RDb250cm9sbGVyOiBUb2FzdENvbnRyb2xsZXI7XG4gIHByb3RlY3RlZCByZWFkb25seSBkZXN0cm95U3ViamVjdCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgcmVhZG9ubHkgcmVhZHlTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG4gIHJlYWRvbmx5IGRpcnR5U3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICByZWFkb25seSBsb2FkaW5nU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4odHJ1ZSk7XG4gIHJlYWRvbmx5IGVycm9yU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPih1bmRlZmluZWQpO1xuICByZWFkb25seSBzYXZpbmdTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG4gIHJlYWRvbmx5IHRvdWNoZWRTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG5cbiAgZGVidWcgPSBmYWxzZTtcbiAgcHJldmlvdXNEYXRhSWQ6IElEO1xuICBzdWJtaXR0ZWQgPSBmYWxzZTtcbiAgcXVlcnlQYXJhbXM6IFBhcmFtcztcbiAgaTE4bkNvbnRleHQ6IHtcbiAgICBwcmVmaXg6IHN0cmluZztcbiAgICBzdWZmaXg6IHN0cmluZztcbiAgfTtcblxuICAvKipcbiAgICogIEBkZXByZWNhdGVkXG4gICAqL1xuICBwcm90ZWN0ZWQgc2V0IF9sb2FkaW5nKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5sb2FkaW5nU3ViamVjdC5uZXh0KHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAgQGRlcHJlY2F0ZWRcbiAgICovXG4gIHByb3RlY3RlZCBnZXQgX2xvYWRpbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubG9hZGluZ1N1YmplY3QudmFsdWU7XG4gIH1cbiAgLyoqXG4gICAqICBAZGVwcmVjYXRlZFxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBfJHJlYWR5KCk6IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMucmVhZHlTdWJqZWN0O1xuICB9XG4gIC8qKlxuICAgKiAgQGRlcHJlY2F0ZWRcbiAgICovXG4gIHByb3RlY3RlZCBnZXQgXyRsb2FkaW5nKCk6IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMubG9hZGluZ1N1YmplY3Q7XG4gIH1cblxuICBnZXQgZXJyb3IoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5lcnJvclN1YmplY3QudmFsdWU7XG4gIH1cblxuICBzZXQgZXJyb3IoZXJyb3I6IHN0cmluZykge1xuICAgIHRoaXMuc2V0RXJyb3IoZXJyb3IpO1xuICB9XG5cbiAgZ2V0IHNhdmluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zYXZpbmdTdWJqZWN0LnZhbHVlIHx8IHRoaXMuZWRpdG9ycz8uc29tZShlID0+IGUuc2F2aW5nKTtcbiAgfVxuXG4gIGdldCBkZXN0cm95ZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZGVzdHJveVN1YmplY3Q/LmNsb3NlZCAhPT0gZmFsc2VcbiAgfVxuXG4gIEBWaWV3Q2hpbGQoVG9vbGJhclRva2VuKSB0b29sYmFyOiBUb29sYmFyVG9rZW58bnVsbCA9IG51bGw7XG4gIEBWaWV3Q2hpbGQoRm9ybUJ1dHRvbnNCYXJUb2tlbiwgeyBzdGF0aWM6IHRydWUgfSkgZm9ybUJ1dHRvbnNCYXI6IEZvcm1CdXR0b25zQmFyVG9rZW58bnVsbCA9IG51bGw7XG4gIEBWaWV3Q2hpbGQoSW9uQ29udGVudCwge3N0YXRpYzogdHJ1ZX0pIGNvbnRlbnQ6IElvbkNvbnRlbnQ7XG5cbiAgZ2V0IHRhYmxlcygpOiBBcHBUYWJsZTxhbnk+W10ge1xuICAgIHJldHVybiB0aGlzLl9jaGlsZHJlbiAmJiAodGhpcy5fY2hpbGRyZW4uZmlsdGVyKGMgPT4gYyBpbnN0YW5jZW9mIEFwcFRhYmxlKSBhcyBBcHBUYWJsZTxhbnk+W10pO1xuICB9XG4gIGdldCBmb3JtcygpOiBBcHBGb3JtPGFueT5bXSB7XG4gICAgcmV0dXJuIHRoaXMuX2NoaWxkcmVuICYmICh0aGlzLl9jaGlsZHJlbi5maWx0ZXIoYyA9PiBjIGluc3RhbmNlb2YgQXBwRm9ybSkgYXMgQXBwRm9ybTxhbnk+W10pO1xuICB9XG4gIGdldCBlZGl0b3JzKCk6IEFwcEVkaXRvcjxhbnk+W10ge1xuICAgIHJldHVybiB0aGlzLl9jaGlsZHJlbiAmJiAodGhpcy5fY2hpbGRyZW4uZmlsdGVyKGMgPT4gYyBpbnN0YW5jZW9mIEFwcEVkaXRvcikgYXMgQXBwRWRpdG9yW10pO1xuICB9XG4gIGdldCBkaXJ0eSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5kaXJ0eVN1YmplY3QudmFsdWUgfHwgKHRoaXMuX2NoaWxkcmVuICYmIHRoaXMuX2NoaWxkcmVuLmZpbmRJbmRleChjID0+IGMuZW5hYmxlZCAmJiBjLmRpcnR5KSAhPT0gLTEpIHx8IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIElzIHZhbGlkICh0YWJsZXMgYW5kIGZvcm1zKVxuICAgKi9cbiAgZ2V0IHZhbGlkKCk6IGJvb2xlYW4ge1xuICAgIC8vIEltcG9ydGFudDogU2hvdWxkIGJlIG5vdCBpbnZhbGlkIEFORCBub3QgcGVuZGluZywgc28gdXNlICchdmFsaWQnIChETyBOT1QgdXNlICdpbnZhbGlkJylcbiAgICByZXR1cm4gIXRoaXMuX2NoaWxkcmVuIHx8IHRoaXMuX2NoaWxkcmVuLmZpbmRJbmRleChjID0+IGMuZW5hYmxlZCAmJiAhYy52YWxpZCkgPT09IC0xO1xuICB9XG5cbiAgZ2V0IGludmFsaWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLl9jaGlsZHJlbiAmJiB0aGlzLl9jaGlsZHJlbi5maW5kSW5kZXgoYyA9PiBjLmVuYWJsZWQgJiYgYy5pbnZhbGlkKSAhPT0gLTEpIHx8IGZhbHNlO1xuICB9XG5cbiAgZ2V0IHBlbmRpbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLl9jaGlsZHJlbiAmJiB0aGlzLl9jaGlsZHJlbi5maW5kSW5kZXgoYyA9PiBjLmVuYWJsZWQgJiYgYy5wZW5kaW5nKSAhPT0gLTEpIHx8IGZhbHNlO1xuICB9XG5cbiAgZ2V0IGxvYWRpbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubG9hZGluZ1N1YmplY3QudmFsdWUgfHwgKHRoaXMuX2NoaWxkcmVuICYmIHRoaXMuX2NoaWxkcmVuLmZpbmRJbmRleChjID0+IGMuZW5hYmxlZCAmJiBjLmxvYWRpbmcpICE9PSAtMSkgfHwgZmFsc2U7XG4gIH1cblxuICBnZXQgbG9hZGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhdGhpcy5sb2FkaW5nU3ViamVjdC52YWx1ZSAmJiAoIXRoaXMuX2NoaWxkcmVuIHx8IHRoaXMuX2NoaWxkcmVuLmZpbmRJbmRleChjID0+IGMuZW5hYmxlZCAmJiBjLmxvYWRpbmcpID09PSAtMSkgfHwgZmFsc2U7XG4gIH1cblxuICBnZXQgdG91Y2hlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy50b3VjaGVkU3ViamVjdC52YWx1ZSB8fCAodGhpcy5fY2hpbGRyZW4gJiYgdGhpcy5fY2hpbGRyZW4uZmluZEluZGV4KGMgPT4gYy5lbmFibGVkICYmIGMudG91Y2hlZCkgIT09IC0xKSB8fCBmYWxzZTtcbiAgfVxuXG4gIGdldCB1bnRvdWNoZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLnRvdWNoZWRTdWJqZWN0LnZhbHVlICYmICghdGhpcy5fY2hpbGRyZW4gfHwgdGhpcy5fY2hpbGRyZW4uZmluZEluZGV4KGMgPT4gYy5lbmFibGVkICYmIGMudG91Y2hlZCkgPT09IC0xKSB8fCBmYWxzZTtcbiAgfVxuXG4gIGdldCBlbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9lbmFibGVkO1xuICB9XG5cbiAgZ2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhdGhpcy5fZW5hYmxlZDtcbiAgfVxuXG4gIGdldCBjaGlsZHJlbigpOiBJQXBwRm9ybVtdIHtcbiAgICByZXR1cm4gdGhpcy5fY2hpbGRyZW47XG4gIH1cblxuICBnZXQgZW1wdHkoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLl9lbmFibGVkO1xuICB9XG5cbiAgYWJzdHJhY3QgZ2V0IGlzTmV3RGF0YSgpOiBib29sZWFuO1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgIHByb3RlY3RlZCByb3V0ZXI6IFJvdXRlcixcbiAgICBwcm90ZWN0ZWQgYWxlcnRDdHJsOiBBbGVydENvbnRyb2xsZXIsXG4gICAgcHJvdGVjdGVkIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZVxuICApIHtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuXG4gICAgaWYgKHRoaXMuZm9ybUJ1dHRvbnNCYXIpIHtcbiAgICAgIHRoaXMucmVnaXN0ZXJTdWJzY3JpcHRpb24odGhpcy5mb3JtQnV0dG9uc0Jhci5vbkJhY2suc3Vic2NyaWJlKGV2ZW50ID0+IHRoaXMuZ29CYWNrKGV2ZW50KSkpO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAvLyBDYW4gYmUgb3ZlcnJpZGRlbiBieSBzdWJjbGFzc2VzXG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcblxuICAgIHRoaXMucmVhZHlTdWJqZWN0LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5sb2FkaW5nU3ViamVjdC51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuZXJyb3JTdWJqZWN0LnVuc3Vic2NyaWJlKCk7XG5cbiAgICB0aGlzLmRlc3Ryb3lTdWJqZWN0Lm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3lTdWJqZWN0LnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBhZGRDaGlsZEZvcm0oZm9ybTogSUFwcEZvcm0gfCBJQXBwRm9ybUdldHRlcikge1xuICAgIGlmICghZm9ybSkgdGhyb3cgbmV3IEVycm9yKCdUcnlpbmcgdG8gcmVnaXN0ZXIgYW4gdW5kZWZpbmVkIGNoaWxkIGZvcm0nKTtcbiAgICB0aGlzLl9jaGlsZHJlbiA9IHRoaXMuX2NoaWxkcmVuIHx8IFtdO1xuICAgIGlmICh0eXBlb2YgZm9ybSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy5fY2hpbGRyZW4ucHVzaChuZXcgQXBwRm9ybVByb3ZpZGVyKGZvcm0pKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLl9jaGlsZHJlbi5wdXNoKGZvcm0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGFkZENoaWxkRm9ybXMoZm9ybXM6IChJQXBwRm9ybSB8IElBcHBGb3JtR2V0dGVyKVtdKSB7XG4gICAgKGZvcm1zIHx8IFtdKS5mb3JFYWNoKGZvcm0gPT4gdGhpcy5hZGRDaGlsZEZvcm0oZm9ybSkpO1xuICB9XG5cbiAgcmVtb3ZlQ2hpbGRGb3JtKGZvcm06IElBcHBGb3JtIHwgSUFwcEZvcm1HZXR0ZXIpOiBJQXBwRm9ybSB8IElBcHBGb3JtR2V0dGVyIHtcbiAgICBpZiAoIWZvcm0pIHRocm93IG5ldyBFcnJvcignVHJ5aW5nIHRvIHJlbW92ZSBhbiB1bmRlZmluZWQgY2hpbGQgZm9ybScpO1xuICAgIGNvbnN0IGluZGV4ID0gKHRoaXMuX2NoaWxkcmVuIHx8IFtdKS5maW5kSW5kZXgoYyA9PiBjID09PSBmb3JtKTtcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2hpbGRyZW4uc3BsaWNlKGluZGV4LCAxKVswXTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGRpc2FibGUob3B0cz86IHtvbmx5U2VsZj86IGJvb2xlYW47IGVtaXRFdmVudD86IGJvb2xlYW4gfSkge1xuICAgIHRoaXMuX2VuYWJsZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9jaGlsZHJlbj8uZm9yRWFjaChjID0+IGMuZGlzYWJsZShvcHRzKSk7XG4gICAgaWYgKCF0aGlzLmxvYWRpbmcgJiYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkpIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBlbmFibGUob3B0cz86IHtvbmx5U2VsZj86IGJvb2xlYW47IGVtaXRFdmVudD86IGJvb2xlYW4gfSkge1xuICAgIHRoaXMuX2VuYWJsZWQgPSB0cnVlO1xuICAgIHRoaXMuX2NoaWxkcmVuPy5mb3JFYWNoKGMgPT4gYy5lbmFibGUob3B0cykpO1xuICAgIGlmICghdGhpcy5sb2FkaW5nICYmICghb3B0cyB8fCBvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpKSB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgbWFya0FzUHJpc3RpbmUob3B0cz86IHtvbmx5U2VsZj86IGJvb2xlYW47IGVtaXRFdmVudD86IGJvb2xlYW4gfSkge1xuICAgIHRoaXMuZXJyb3IgPSBudWxsO1xuICAgIHRoaXMuc3VibWl0dGVkID0gZmFsc2U7XG4gICAgaWYgKHRoaXMuZGlydHlTdWJqZWN0LnZhbHVlICE9PSBmYWxzZSkge1xuICAgICAgdGhpcy5kaXJ0eVN1YmplY3QubmV4dChmYWxzZSk7XG4gICAgfVxuICAgIHRoaXMuX2NoaWxkcmVuPy5mb3JFYWNoKGMgPT4gYy5tYXJrQXNQcmlzdGluZShvcHRzKSk7XG4gICAgaWYgKCF0aGlzLmxvYWRpbmcgJiYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkpIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBtYXJrQXNVbnRvdWNoZWQob3B0cz86IHtvbmx5U2VsZj86IGJvb2xlYW47IGVtaXRFdmVudD86IGJvb2xlYW4gfSkge1xuICAgIGlmICh0aGlzLnRvdWNoZWRTdWJqZWN0LnZhbHVlICE9PSBmYWxzZSkge1xuICAgICAgdGhpcy50b3VjaGVkU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICB9XG4gICAgdGhpcy5fY2hpbGRyZW4/LmZvckVhY2goYyA9PiBjLm1hcmtBc1VudG91Y2hlZCgpKTtcbiAgICBpZiAoIXRoaXMubG9hZGluZyAmJiAoIW9wdHMgfHwgb3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSkgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBwcmVmZXIgdG8gdXNlIG1hcmtBbGxBc1RvdWNoZWQoKVxuICAgKiBAcGFyYW0gb3B0c1xuICAgKi9cbiAgbWFya0FzVG91Y2hlZChvcHRzPzoge29ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbiB9KSB7XG4gICAgaWYgKCF0aGlzLnRvdWNoZWRTdWJqZWN0LnZhbHVlICE9PSB0cnVlKSB7XG4gICAgICB0aGlzLnRvdWNoZWRTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgfVxuICAgIHRoaXMuX2NoaWxkcmVuPy5mb3JFYWNoKGMgPT4gYy5tYXJrQXNUb3VjaGVkKG9wdHMpKTtcbiAgICBpZiAoIXRoaXMubG9hZGluZyAmJiAoIW9wdHMgfHwgb3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSkgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG1hcmtBbGxBc1RvdWNoZWQob3B0cz86IHtlbWl0RXZlbnQ/OiBib29sZWFuIH0pIHtcbiAgICBpZiAodGhpcy50b3VjaGVkU3ViamVjdC52YWx1ZSAhPT0gdHJ1ZSkge1xuICAgICAgdGhpcy50b3VjaGVkU3ViamVjdC5uZXh0KHRydWUpO1xuICAgIH1cbiAgICB0aGlzLl9jaGlsZHJlbj8uZm9yRWFjaChjID0+IGMubWFya0FsbEFzVG91Y2hlZChvcHRzKSk7XG4gICAgaWYgKCF0aGlzLmxvYWRpbmcgJiYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkpIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBtYXJrQXNEaXJ0eShvcHRzPzoge29ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbjt9KXtcbiAgICBpZiAoIXRoaXMuZGlydHlTdWJqZWN0LnZhbHVlKSB7XG4gICAgICB0aGlzLmRpcnR5U3ViamVjdC5uZXh0KHRydWUpO1xuICAgICAgaWYgKCF0aGlzLmxvYWRpbmcgJiYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkpIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgbWFya0FzTG9hZGluZyhvcHRzPzoge29ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbjt9KXtcbiAgICBpZiAoIXRoaXMubG9hZGluZ1N1YmplY3QudmFsdWUpIHtcbiAgICAgIHRoaXMubG9hZGluZ1N1YmplY3QubmV4dCh0cnVlKTtcbiAgICAgIGlmICghb3B0cyB8fCBvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgbWFya0FzTG9hZGVkKG9wdHM/OiB7XG4gICAgb25seVNlbGY/OiBib29sZWFuO1xuICAgIGVtaXRFdmVudD86IGJvb2xlYW47XG4gIH0pe1xuICAgIGlmICh0aGlzLmxvYWRpbmdTdWJqZWN0LnZhbHVlKSB7XG4gICAgICB0aGlzLmxvYWRpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgaWYgKCFvcHRzIHx8IG9wdHMub25seVNlbGYgIT09IHRydWUpIHtcbiAgICAgICAgLy8gRW1pdCB0byBjaGlsZHJlbiBmb3JtcyBhbmQgZWRpdG9yc1xuICAgICAgICAvLyBub3RlOiB0YWJsZXMgc2hvdWxkIGJlIGNoYW5nZWQgYnkgcGFyZW50XG4gICAgICAgIHRoaXMuZm9ybXM/LmZvckVhY2goZiA9PiBmLm1hcmtBc0xvYWRlZChvcHRzKSk7XG4gICAgICAgIHRoaXMuZWRpdG9ycz8uZm9yRWFjaChlID0+IGUubWFya0FzTG9hZGVkKG9wdHMpKTtcbiAgICAgIH1cbiAgICAgIGlmICghb3B0cyB8fCBvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBtYXJrQXNSZWFkeShvcHRzPzoge2VtaXRFdmVudD86IGJvb2xlYW4gfSkge1xuICAgIHRoaXMuX2NoaWxkcmVuPy5mb3JFYWNoKGMgPT4gYy5tYXJrQXNSZWFkeShvcHRzKSk7XG4gICAgdGhpcy5yZWFkeVN1YmplY3QubmV4dCh0cnVlKTtcbiAgfVxuXG4gIHJlYWR5KG9wdHM/OiBXYWl0Rm9yT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLnJlYWR5U3ViamVjdC52YWx1ZSkgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIHJldHVybiB3YWl0Rm9yVHJ1ZSh0aGlzLnJlYWR5U3ViamVjdCwgb3B0cyk7XG4gIH1cblxuICB3YWl0SWRsZShvcHRzPzogV2FpdEZvck9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMubG9hZGluZ1N1YmplY3QudmFsdWUpIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICByZXR1cm4gd2FpdEZvckZhbHNlKHRoaXMubG9hZGluZ1N1YmplY3QsIG9wdHMpO1xuICB9XG5cbiAgbWFya0FzU2F2aW5nKG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW4gfSl7XG4gICAgaWYgKHRoaXMuc2F2aW5nU3ViamVjdC52YWx1ZSAhPT0gdHJ1ZSkge1xuICAgICAgdGhpcy5zYXZpbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICBpZiAoIW9wdHMgfHwgb3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIG1hcmtBc1NhdmVkKG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW4gfSl7XG4gICAgaWYgKHRoaXMuc2F2aW5nU3ViamVjdC52YWx1ZSAhPT0gZmFsc2UpIHtcbiAgICAgIHRoaXMuc2F2aW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICAgIGlmICghb3B0cyB8fCBvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY2FuY2VsKGV2ZW50PzogRXZlbnQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5pc05ld0RhdGEpIHtcbiAgICAgIGF3YWl0IHRoaXMudW5sb2FkKCk7IC8vIGFzeW5jIHJlc2V0XG4gICAgfVxuICAgIGVsc2UgaWYgKHRoaXMuZGlydHkpe1xuICAgICAgYXdhaXQgdGhpcy5yZWxvYWQoKTsgLy8gYXN5bmMgcmVsb2FkXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVubG9hZCB0aGUgcGFnZSAocmVtb3ZlIGFsbCBkYXRhKS4gVXNlZnVsIHdoZW4gcmV1c2luZyBhbmd1bGFyIGNhY2hlIGEgY2FuY2VsbGVkIHBhZ2VcbiAgICpcbiAgICogQHBhcmFtIG9wdHNcbiAgICovXG4gIGFzeW5jIHVubG9hZChvcHRzPzoge2VtaXRFdmVudD86IGJvb2xlYW4gfSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnNvbGUuZGVidWcoJ1tlZGl0b3JdIFVubG9hZGluZyBkYXRhLi4uJyk7XG4gICAgdGhpcy5tYXJrQXNMb2FkaW5nKCk7XG4gICAgdGhpcy5fY2hpbGRyZW4/LmZvckVhY2goZiA9PiB7XG4gICAgICBpZiAoZiBpbnN0YW5jZW9mIEFwcEZvcm0pIHtcbiAgICAgICAgZi5yZXNldChudWxsLCBvcHRzKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGYgaW5zdGFuY2VvZiBBcHBUYWJsZSkge1xuICAgICAgICBmLmRhdGFTb3VyY2UuZGlzY29ubmVjdCgpO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoZiBpbnN0YW5jZW9mIEFwcEVkaXRvcikge1xuICAgICAgICBmLnVubG9hZChvcHRzKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMubWFya0FzUHJpc3RpbmUob3B0cyk7XG4gICAgdGhpcy5tYXJrQXNTYXZlZChvcHRzKTtcbiAgfVxuXG4gIGFzeW5jIHJlbG9hZFdpdGhDb25maXJtYXRpb24oY29uZmlybT86IGJvb2xlYW4pIHtcbiAgICBjb25zdCBuZWVkQ29uZmlybSA9IHRoaXMuZGlydHk7XG4gICAgLy8gaWYgbm90IGNvbmZpcm0geWV0OiBhc2sgY29uZmlybWF0aW9uXG4gICAgaWYgKCFjb25maXJtICYmIG5lZWRDb25maXJtKSB7XG4gICAgICBjb25zdCB0cmFuc2xhdGlvbnMgPSB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KFsnQ09NTU9OLkJUTl9BQk9SVF9DSEFOR0VTJywgJ0NPTU1PTi5CVE5fQ0FOQ0VMJywgJ0NPTkZJUk0uQ0FOQ0VMX0NIQU5HRVMnLCAnQ09ORklSTS5BTEVSVF9IRUFERVInXSk7XG4gICAgICBjb25zdCBhbGVydCA9IGF3YWl0IHRoaXMuYWxlcnRDdHJsLmNyZWF0ZSh7XG4gICAgICAgIGhlYWRlcjogdHJhbnNsYXRpb25zWydDT05GSVJNLkFMRVJUX0hFQURFUiddLFxuICAgICAgICBtZXNzYWdlOiB0cmFuc2xhdGlvbnNbJ0NPTkZJUk0uQ0FOQ0VMX0NIQU5HRVMnXSxcbiAgICAgICAgYnV0dG9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHRleHQ6IHRyYW5zbGF0aW9uc1snQ09NTU9OLkJUTl9BQk9SVF9DSEFOR0VTJ10sXG4gICAgICAgICAgICBjc3NDbGFzczogJ3NlY29uZGFyeScsXG4gICAgICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgICAgIGNvbmZpcm0gPSB0cnVlOyAvLyB1cGRhdGUgdXBwZXIgdmFsdWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHRleHQ6IHRyYW5zbGF0aW9uc1snQ09NTU9OLkJUTl9DQU5DRUwnXSxcbiAgICAgICAgICAgIHJvbGU6ICdjYW5jZWwnLFxuICAgICAgICAgICAgaGFuZGxlcjogKCkgPT4ge1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSk7XG4gICAgICBhd2FpdCBhbGVydC5wcmVzZW50KCk7XG4gICAgICBhd2FpdCBhbGVydC5vbkRpZERpc21pc3MoKTtcbiAgICB9XG5cbiAgICAvLyBJZiBjb25maXJtOiBleGVjdXRlIHRoZSByZWxvYWRcbiAgICBpZiAoY29uZmlybSB8fCAhbmVlZENvbmZpcm0pIHtcbiAgICAgIHRoaXMuc2Nyb2xsVG9Ub3AoKTtcbiAgICAgIHRoaXMuZGlzYWJsZSgpO1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucmVsb2FkKCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ29CYWNrKGV2ZW50PzogRXZlbnQpOiBQcm9taXNlPHZvaWQgfCBib29sZWFuPiB7XG4gICAgLy8gR28gYmFja1xuICAgIGlmICh0aGlzLnRvb2xiYXI/LmNhbkdvQmFjaykge1xuICAgICAgcmV0dXJuIHRoaXMudG9vbGJhci5nb0JhY2soKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQmFjayB0byBob21lXG4gICAgICByZXR1cm4gdGhpcy5yb3V0ZXIubmF2aWdhdGVCeVVybCgnLycpO1xuICAgIH1cbiAgfVxuXG5cblxuICBhYnN0cmFjdCBsb2FkKGlkPzogSUQsIG9wdGlvbnM/OiBPKTogUHJvbWlzZTx2b2lkPjtcblxuICBhYnN0cmFjdCBzYXZlKGV2ZW50PzogRXZlbnQsIG9wdGlvbnM/OiBhbnkpOiBQcm9taXNlPGJvb2xlYW4+O1xuXG4gIGFic3RyYWN0IHJlbG9hZCgpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIGxvZ0Zvcm1FcnJvcnMocHJlZml4Pzogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUuZGVidWcoJ1tlZGl0b3JdIEVkaXRvciBub3QgdmFsaWQuIENoZWNraW5nIHdoZXJlIChmb3JtcywgdGFibGVzKS4uLicpO1xuICAgIHRoaXMuX2NoaWxkcmVuPy5mb3JFYWNoKGMgPT4gdGhpcy5sb2dDaGlsZHJlbkVycm9ycyhjLCBwcmVmaXgpKTtcbiAgfVxuXG4gIC8qIC0tIHByb3RlY3RlZCBtZXRob2RzIC0tICovXG5cbiAgcHJvdGVjdGVkIGFzeW5jIHNjcm9sbFRvVG9wKGR1cmF0aW9uPzogbnVtYmVyKSB7XG4gICAgZHVyYXRpb24gPSB0b051bWJlcihkdXJhdGlvbiwgNTAwKTtcblxuICAgIGlmICghdGhpcy5jb250ZW50KSB7XG4gICAgICBjb25zb2xlLndhcm4oYFt0YWItZWRpdG9yXSBDYW5ub3Qgc2Nyb2xsIHRvIHRvcC4gKG5vICdpb24tY29udGVudCcgdGFnIGZvdW5kICR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfWApO1xuXG4gICAgICAvLyBUT0RPOiBGSVhNRSAobm90IHdvcmtpbmcgYXMgdGhlIHBhZ2UgaXMgbm90IHRoZSB3aW5kb3cpXG4gICAgICBjb25zdCBzY3JvbGxUb1RvcCA9IHdpbmRvdy5zZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBvcyA9IHdpbmRvdy5zY3JvbGxZO1xuICAgICAgICBpZiAocG9zID4gMCkge1xuICAgICAgICAgIHdpbmRvdy5zY3JvbGxUbygwLCBwb3MgLSAyMCk7IC8vIGhvdyBmYXIgdG8gc2Nyb2xsIG9uIGVhY2ggc3RlcFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKHNjcm9sbFRvVG9wKTtcbiAgICAgICAgfVxuICAgICAgfSwgMTYpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbnRlbnQuc2Nyb2xsVG9Ub3AoZHVyYXRpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJlZ2lzdGVyU3Vic2NyaXB0aW9uKHN1YjogU3Vic2NyaXB0aW9ufFRlYXJkb3duTG9naWMpIHtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24uYWRkKHN1Yik7XG4gIH1cblxuICBwcm90ZWN0ZWQgdW5yZWdpc3RlclN1YnNjcmlwdGlvbihzdWI6IFN1YnNjcmlwdGlvbikge1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbi5yZW1vdmUoc3ViKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBzYXZlSWZEaXJ0eUFuZENvbmZpcm0oZXZlbnQ/OiBFdmVudCwgb3B0cz86IHtcbiAgICBlbWl0RXZlbnQ/OiBib29sZWFuO1xuICAgIGNvbmZpcm1lZD86IGJvb2xlYW5cbiAgfSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICghdGhpcy5kaXJ0eSkgcmV0dXJuIHRydWU7XG5cbiAgICBsZXQgY29uZmlybWVkID0gb3B0cz8uY29uZmlybWVkIHx8IGZhbHNlO1xuICAgIGlmICghY29uZmlybWVkKSB7XG4gICAgICBsZXQgY2FuY2VsID0gZmFsc2U7XG4gICAgICBjb25zdCB0cmFuc2xhdGlvbnMgPSB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KFsnQ09NTU9OLkJUTl9TQVZFJywgJ0NPTU1PTi5CVE5fQ0FOQ0VMJywgJ0NPTU1PTi5CVE5fQUJPUlRfQ0hBTkdFUycsICdDT05GSVJNLlNBVkUnLCAnQ09ORklSTS5BTEVSVF9IRUFERVInXSk7XG4gICAgICBjb25zdCBhbGVydCA9IGF3YWl0IHRoaXMuYWxlcnRDdHJsLmNyZWF0ZSh7XG4gICAgICAgIGhlYWRlcjogdHJhbnNsYXRpb25zWydDT05GSVJNLkFMRVJUX0hFQURFUiddLFxuICAgICAgICBtZXNzYWdlOiB0cmFuc2xhdGlvbnNbJ0NPTkZJUk0uU0FWRSddLFxuICAgICAgICBidXR0b25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdGV4dDogdHJhbnNsYXRpb25zWydDT01NT04uQlROX0NBTkNFTCddLFxuICAgICAgICAgICAgcm9sZTogJ2NhbmNlbCcsXG4gICAgICAgICAgICBjc3NDbGFzczogJ3NlY29uZGFyeScsXG4gICAgICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgICAgIGNhbmNlbCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0ZXh0OiB0cmFuc2xhdGlvbnNbJ0NPTU1PTi5CVE5fQUJPUlRfQ0hBTkdFUyddLFxuICAgICAgICAgICAgY3NzQ2xhc3M6ICdzZWNvbmRhcnknLFxuICAgICAgICAgICAgaGFuZGxlcjogKCkgPT4ge1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgdGV4dDogdHJhbnNsYXRpb25zWydDT01NT04uQlROX1NBVkUnXSxcbiAgICAgICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICAgICAgY29uZmlybWVkID0gdHJ1ZTsgLy8gdXBkYXRlIHVwcGVyIHZhbHVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IGFsZXJ0LnByZXNlbnQoKTtcbiAgICAgIGF3YWl0IGFsZXJ0Lm9uRGlkRGlzbWlzcygpO1xuXG4gICAgICBpZiAoIWNvbmZpcm1lZCkge1xuICAgICAgICByZXR1cm4gIWNhbmNlbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5zYXZlKGV2ZW50LCBvcHRzKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBzaG93VG9hc3Qob3B0czogU2hvd1RvYXN0T3B0aW9ucykge1xuICAgIGlmICghdGhpcy50b2FzdENvbnRyb2xsZXIpIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0b2FzdENvbnRyb2xsZXIgaW4gY29tcG9uZW50XFwncyBjb25zdHJ1Y3RvcicpO1xuICAgIGF3YWl0IFRvYXN0cy5zaG93KHRoaXMudG9hc3RDb250cm9sbGVyLCB0aGlzLnRyYW5zbGF0ZSwgb3B0cyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgbG9nQ2hpbGRyZW5FcnJvcnMoYzogSUFwcEZvcm0gfCBBYnN0cmFjdENvbnRyb2wsIHByZWZpeD86IHN0cmluZywgcGF0aD86IHN0cmluZykge1xuICAgIHByZWZpeCA9IHByZWZpeCB8fCAnW2FwcC10YWItZWRpdG9yXSAnO1xuICAgIC8vIElmIGVkaXRvclxuICAgIGlmIChjIGluc3RhbmNlb2YgQXBwRWRpdG9yKSB7XG4gICAgICBjLmxvZ0Zvcm1FcnJvcnMoKTtcbiAgICB9XG4gICAgLy8gQW5ndWxhciBmb3JtIGNvbnRyb2xcbiAgICBlbHNlIGlmIChjIGluc3RhbmNlb2YgQWJzdHJhY3RDb250cm9sKSB7XG4gICAgICBBcHBGb3JtVXRpbHMubG9nRm9ybUVycm9ycyhjLCBwcmVmaXgsIHBhdGgpO1xuICAgIH1cbiAgICAvLyBJZiBmb3JtIHByb3ZpZGVyOiBnZXQgZGVsZWdhdGVcbiAgICBlbHNlIGlmIChjIGluc3RhbmNlb2YgQXBwRm9ybVByb3ZpZGVyKSB7XG4gICAgICBpZiAoIWMuZW1wdHkgJiYgIWMudmFsaWQpIHtcbiAgICAgICAgYy53YWl0RGVsZWdhdGUoe3RpbWVvdXQ6IDEwMDB9KS50aGVuKGRlbGVnYXRlID0+IHRoaXMubG9nQ2hpbGRyZW5FcnJvcnMoZGVsZWdhdGUsIHByZWZpeCwgJ3Byb3ZpZGVyJykpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBJZiB0YWJsZVxuICAgIGVsc2UgaWYgKGMgaW5zdGFuY2VvZiBBcHBUYWJsZSkge1xuICAgICAgaWYgKGMuaW52YWxpZCAmJiBjLmVkaXRlZFJvdyAmJiBjLmVkaXRlZFJvdy52YWxpZGF0b3IpIHtcbiAgICAgICAgY29uc3QgcGF0aCA9IGMuY29uc3RydWN0b3IubmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBBcHBGb3JtVXRpbHMubG9nRm9ybUVycm9ycyhjLmVkaXRlZFJvdy52YWxpZGF0b3IsIHByZWZpeCwgcGF0aCk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIElmIGZvcm1cbiAgICBlbHNlIGlmIChjIGluc3RhbmNlb2YgQXBwRm9ybSkge1xuICAgICAgaWYgKCFjLmVtcHR5ICYmICFjLnZhbGlkKSB7XG4gICAgICAgIGlmIChjLnBlbmRpbmcpIHtcbiAgICAgICAgICBjb25zdCBwYXRoID0gYy5jb25zdHJ1Y3Rvci5uYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgY29uc29sZS53YXJuKCBgJHtwcmVmaXh9IC0+ICR7cGF0aH06IHdhaXRpbmcgd2hpbGUgcGVuZGluZy4uLmApO1xuICAgICAgICAgIEFwcEZvcm1VdGlscy53YWl0V2hpbGVQZW5kaW5nKGMsIHt0aW1lb3V0OiAxMDAwfSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMubG9nQ2hpbGRyZW5FcnJvcnMoYy5mb3JtLCBwcmVmaXgsIHBhdGgpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBBcHBGb3JtVXRpbHMubG9nRm9ybUVycm9ycyhjLmZvcm0sIHByZWZpeCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gSWYgZWRpdG9yXG4gICAgZWxzZSBpZiAoYyBpbnN0YW5jZW9mIEFwcEVkaXRvcikge1xuICAgICAgaWYgKCFjLmVtcHR5ICYmICFjLnZhbGlkKSB7XG4gICAgICAgIGlmIChjLnBlbmRpbmcpIHtcbiAgICAgICAgICBjb25zdCBwYXRoID0gYy5jb25zdHJ1Y3Rvci5uYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgY29uc29sZS53YXJuKCBgJHtwcmVmaXh9IC0+ICR7cGF0aH06IHdhaXRpbmcgd2hpbGUgcGVuZGluZy4uLmApO1xuICAgICAgICAgIEFwcEZvcm1VdGlscy53YWl0V2hpbGVQZW5kaW5nKGMsIHt0aW1lb3V0OiAxMDAwfSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+IGMubG9nRm9ybUVycm9ycyhwcmVmaXgpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBjLmxvZ0Zvcm1FcnJvcnMocHJlZml4KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybiggYCR7cHJlZml4fSBVbmtub3duIGNoaWxkcmVuIHN1Yi1mb3JtOiBgLCBjKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0RXJyb3IodmFsdWU6IHN0cmluZywgb3B0cz86IHtlbWl0RXZlbnQ/OiBib29sZWFuO30pIHtcbiAgICBpZiAodGhpcy5lcnJvclN1YmplY3QudmFsdWUgIT09IHZhbHVlKSB7XG4gICAgICB0aGlzLmVycm9yU3ViamVjdC5uZXh0KHZhbHVlKTtcbiAgICAgIGlmICghb3B0cyB8fCBvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIHJlc2V0RXJyb3Iob3B0cz86IHtlbWl0RXZlbnQ/OiBib29sZWFufSkge1xuICAgIHRoaXMuc2V0RXJyb3IodW5kZWZpbmVkLCBvcHRzKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBtYXJrRm9yQ2hlY2soKSB7XG4gICAgLy8gU2hvdWxkIGJlIG92ZXJyaWRlIGJ5IHN1YmNsYXNzZXMsIGlmIGNoYW5nZSBkZXRlY3Rpb24gaXMgUHVzaFxuICB9XG59XG5cbkBEaXJlY3RpdmUoKVxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9kaXJlY3RpdmUtY2xhc3Mtc3VmZml4XG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQXBwVGFiRWRpdG9yPFQgPSBhbnksIElEID0gbnVtYmVyLCBPID0gYW55PlxuICBleHRlbmRzIEFwcEVkaXRvcjxULCBJRCwgTz5cbiAgaW1wbGVtZW50cyBJQXBwVGFiRWRpdG9yIHtcblxuICBwcm90ZWN0ZWQgX3NlbGVjdGVkVGFiSW5kZXggPSAwO1xuXG4gIC8vIEVkaXRvciBvcHRpb25zXG4gIHRhYkNvdW50OiBudW1iZXI7XG4gIGVuYWJsZVN3aXBlOiBib29sZWFuO1xuICB0YWJHcm91cEFuaW1hdGlvbkR1cmF0aW9uOiBzdHJpbmc7XG5cbiAgQElucHV0KCkgcXVlcnlUYWJJbmRleFBhcmFtTmFtZTogc3RyaW5nO1xuXG4gIEBJbnB1dCgpIHNldCBzZWxlY3RlZFRhYkluZGV4KHZhbHVlOiBudW1iZXIpIHtcbiAgICB0aGlzLnNldFNlbGVjdGVkVGFiSW5kZXgodmFsdWUpO1xuICB9XG4gIGdldCBzZWxlY3RlZFRhYkluZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkVGFiSW5kZXg7XG4gIH1cblxuICBAT3V0cHV0KCkgcmVhZG9ubHkgc2VsZWN0ZWRUYWJJbmRleENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuXG4gIEBWaWV3Q2hpbGQoJ3RhYkdyb3VwJywgeyBzdGF0aWM6IHRydWUgfSkgdGFiR3JvdXA6IE1hdFRhYkdyb3VwO1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihcbiAgICBAT3B0aW9uYWwoKSBwcm90ZWN0ZWQgcm91dGU6IEFjdGl2YXRlZFJvdXRlLCAvLyBNb2RhbCBlZGl0b3IgZ2l2ZSAnbnVsbCdcbiAgICBwcm90ZWN0ZWQgcm91dGVyOiBSb3V0ZXIsXG4gICAgcHJvdGVjdGVkIGFsZXJ0Q3RybDogQWxlcnRDb250cm9sbGVyLFxuICAgIHByb3RlY3RlZCB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgb3B0aW9ucz86IEFwcFRhYkVkaXRvck9wdGlvbnMpIHtcbiAgICBzdXBlcihyb3V0ZSwgcm91dGVyLCBhbGVydEN0cmwsIHRyYW5zbGF0ZSk7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIHRhYkNvdW50OiAxLFxuICAgICAgZW5hYmxlU3dpcGU6IHRydWUsXG4gICAgICB0YWJHcm91cEFuaW1hdGlvbkR1cmF0aW9uOiAnMjAwbXMnLFxuICAgICAgLi4ub3B0aW9uc1xuICAgIH1cbiAgICB0aGlzLnRhYkNvdW50ID0gb3B0aW9ucy50YWJDb3VudDtcbiAgICB0aGlzLmVuYWJsZVN3aXBlID0gb3B0aW9ucy5lbmFibGVTd2lwZTtcbiAgICB0aGlzLnRhYkdyb3VwQW5pbWF0aW9uRHVyYXRpb24gPSBvcHRpb25zLnRhYkdyb3VwQW5pbWF0aW9uRHVyYXRpb247XG4gICAgdGhpcy5xdWVyeVRhYkluZGV4UGFyYW1OYW1lID0gJ3RhYic7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICBzdXBlci5uZ09uSW5pdCgpO1xuXG4gICAgLy8gUmVhZCB0aGUgc2VsZWN0ZWQgdGFiIGluZGV4LCBmcm9tIHBhdGggcXVlcnkgcGFyYW1zXG4gICAgaWYgKHRoaXMudGFiR3JvdXAgJiYgdGhpcy5yb3V0ZSAmJiB0aGlzLnF1ZXJ5VGFiSW5kZXhQYXJhbU5hbWUpIHtcbiAgICAgIHRoaXMucmVnaXN0ZXJTdWJzY3JpcHRpb24odGhpcy5yb3V0ZS5xdWVyeVBhcmFtc1xuICAgICAgICAuc3Vic2NyaWJlKHF1ZXJ5UGFyYW1zID0+IHtcbiAgICAgICAgICB0aGlzLnF1ZXJ5UGFyYW1zID0gey4uLnF1ZXJ5UGFyYW1zfTtcblxuICAgICAgICAgIC8vIFBhcnNlIHRhYiBwYXJhbVxuICAgICAgICAgIGlmICh0aGlzLnRhYkNvdW50ID4gMSAmJiB0aGlzLnF1ZXJ5VGFiSW5kZXhQYXJhbU5hbWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHRhYkluZGV4ID0gcXVlcnlQYXJhbXNbdGhpcy5xdWVyeVRhYkluZGV4UGFyYW1OYW1lXTtcbiAgICAgICAgICAgIHRoaXMucXVlcnlQYXJhbXNbdGhpcy5xdWVyeVRhYkluZGV4UGFyYW1OYW1lXSA9IHRhYkluZGV4ICYmIHBhcnNlSW50KHRhYkluZGV4KSB8fCB1bmRlZmluZWQ7XG4gICAgICAgICAgICBpZiAoaXNOb3ROaWwodGhpcy5xdWVyeVBhcmFtc1t0aGlzLnF1ZXJ5VGFiSW5kZXhQYXJhbU5hbWVdKSkge1xuICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkVGFiSW5kZXggPSB0aGlzLnF1ZXJ5UGFyYW1zW3RoaXMucXVlcnlUYWJJbmRleFBhcmFtTmFtZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gUmVhbGlnbiB0YWIsIGFmdGVyIGEgZGVsYXkgYmVjYXVzZSB0aGUgdGFiIGNhbiBiZSBkaXNhYmxlZCB3aGVuIGNvbXBvbmVudCBpcyBjcmVhdGVkXG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnRhYkdyb3VwLnJlYWxpZ25JbmtCYXIoKSwgNTAwKTtcbiAgICAgICAgfSkpO1xuICAgIH1cbiAgfVxuXG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgc3VwZXIubmdPbkRlc3Ryb3koKTtcbiAgICB0aGlzLnNlbGVjdGVkVGFiSW5kZXhDaGFuZ2UuY29tcGxldGUoKTtcbiAgICB0aGlzLmxvYWRpbmdTdWJqZWN0LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5lcnJvclN1YmplY3QudW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHNldFNlbGVjdGVkVGFiSW5kZXgodmFsdWU6IG51bWJlciwgb3B0cz86IHtlbWl0RXZlbnQ/OiBib29sZWFuOyByZWFsaWduSW5rQmFyPzogYm9vbGVhbiB9KSB7XG4gICAgLy8gRml4IHZhbHVlXG4gICAgaWYgKHZhbHVlIDwgMCkge1xuICAgICAgdmFsdWUgPSAwO1xuICAgIH1cbiAgICBlbHNlIGlmICh2YWx1ZSA+IHRoaXMudGFiQ291bnQgLSAxKSB7XG4gICAgICBjb25zb2xlLndhcm4oYFt0YWItZWRpdG9yXSBJbnZhbGlkIHRhYiBpbmRleCAke3ZhbHVlfS4gTWF4IHZhbHVlIGlzICR7dGhpcy50YWJDb3VudC0xfWApXG4gICAgICB2YWx1ZSA9IHRoaXMuX3NlbGVjdGVkVGFiSW5kZXg7XG4gICAgfVxuXG4gICAgdGhpcy5fc2VsZWN0ZWRUYWJJbmRleCA9IHZhbHVlO1xuICAgIHRoaXMuc2VsZWN0ZWRUYWJJbmRleENoYW5nZS5uZXh0KHZhbHVlKTtcblxuICAgIGlmICh0aGlzLnRhYkdyb3VwICYmICghb3B0cyB8fCBvcHRzLnJlYWxpZ25JbmtCYXIgIT09IGZhbHNlKSkge1xuICAgICAgdGhpcy50YWJHcm91cC5zZWxlY3RlZEluZGV4ID0gdmFsdWU7XG4gICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgICAgLy8gV2FpdCB0YWIgY2hhbmdlIGluIFVJLCBiZWZvcmUgcmVhbGlnbiBpbmsgdGFiXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMudGFiR3JvdXAucmVhbGlnbklua0JhcigpLCAyMDApO1xuICAgIH1cbiAgICBlbHNlIGlmICghb3B0cyB8fCBvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpIHtcbiAgICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgcmVhbGlnbklua0JhcigpIHtcbiAgICB0aGlzLnRhYkdyb3VwPy5yZWFsaWduSW5rQmFyKCk7XG4gIH1cblxuXG4gIG9uVGFiQ2hhbmdlKGV2ZW50OiBNYXRUYWJDaGFuZ2VFdmVudCwgcXVlcnlUYWJJbmRleFBhcmFtTmFtZT86IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHF1ZXJ5VGFiSW5kZXhQYXJhbU5hbWUgPSBxdWVyeVRhYkluZGV4UGFyYW1OYW1lIHx8IHRoaXMucXVlcnlUYWJJbmRleFBhcmFtTmFtZTtcblxuICAgIGlmICghcXVlcnlUYWJJbmRleFBhcmFtTmFtZSB8fCAhdGhpcy5yb3V0ZSkgcmV0dXJuIHRydWU7IC8vIFNraXAgaWYgdGFiIHF1ZXJ5IHBhcmFtIG5vdCBzZXQsIG9yIG5vIHJvdXRlXG5cbiAgICBpZiAoIXRoaXMucXVlcnlQYXJhbXMgfHwgK3RoaXMucXVlcnlQYXJhbXNbcXVlcnlUYWJJbmRleFBhcmFtTmFtZV0gIT09IGV2ZW50LmluZGV4KSB7XG5cbiAgICAgIHRoaXMucXVlcnlQYXJhbXMgPSB0aGlzLnF1ZXJ5UGFyYW1zIHx8IHt9O1xuICAgICAgdGhpcy5xdWVyeVBhcmFtc1txdWVyeVRhYkluZGV4UGFyYW1OYW1lXSA9IGV2ZW50LmluZGV4O1xuXG4gICAgICBpZiAocXVlcnlUYWJJbmRleFBhcmFtTmFtZSA9PT0gJ3RhYicgJiYgaXNOb3ROaWwodGhpcy5xdWVyeVBhcmFtc1snc3VidGFiJ10pKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnF1ZXJ5UGFyYW1zLnN1YnRhYjsgLy8gY2xlYW4gc3VidGFiXG4gICAgICB9XG4gICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbJy4nXSwge1xuICAgICAgICByZWxhdGl2ZVRvOiB0aGlzLnJvdXRlLFxuICAgICAgICBxdWVyeVBhcmFtczogdGhpcy5xdWVyeVBhcmFtcyxcbiAgICAgICAgcmVwbGFjZVVybDogdHJ1ZVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEFjdGlvbiB0cmlnZ2VyZWQgd2hlbiB1c2VyIHN3aXBlc1xuICAgKi9cbiAgb25Td2lwZVRhYihldmVudDogSGFtbWVyU3dpcGVFdmVudCk6IGJvb2xlYW4ge1xuICAgIC8vIERFQlVHXG4gICAgLy8gaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUuZGVidWcoXCJbdGFiLXBhZ2VdIG9uU3dpcGVUYWIoKVwiKTtcblxuICAgIC8vIFNraXAsIGlmIG5vdCBhIHZhbGlkIHN3aXBlIGV2ZW50XG4gICAgaWYgKCF0aGlzLmVuYWJsZVN3aXBlIHx8ICFldmVudFxuICAgICAgfHwgZXZlbnQuZGVmYXVsdFByZXZlbnRlZCB8fCAoZXZlbnQuc3JjRXZlbnQgJiYgZXZlbnQuc3JjRXZlbnQuZGVmYXVsdFByZXZlbnRlZClcbiAgICAgIHx8IGV2ZW50LnBvaW50ZXJUeXBlICE9PSAndG91Y2gnXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gREVCVUdcbiAgICAvL2lmICh0aGlzLmRlYnVnKVxuICAgIC8vY29uc29sZS5kZWJ1ZyhcIlt0YWItcGFnZV0gRGV0ZWN0ZWQgc3dpcGU6IFwiICsgZXZlbnQudHlwZSwgZXZlbnQpO1xuXG4gICAgbGV0IHNlbGVjdFRhYkluZGV4ID0gdGhpcy5zZWxlY3RlZFRhYkluZGV4O1xuICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xuICAgICAgLy8gT3BlbiBuZXh0IHRhYlxuICAgICAgY2FzZSAnc3dpcGVsZWZ0JzpcbiAgICAgICAgY29uc3QgaXNMYXN0ID0gc2VsZWN0VGFiSW5kZXggPj0gKHRoaXMudGFiQ291bnQgLSAxKTtcbiAgICAgICAgc2VsZWN0VGFiSW5kZXggPSBpc0xhc3QgPyAwIDogc2VsZWN0VGFiSW5kZXggKyAxO1xuICAgICAgICBicmVhaztcblxuXG4gICAgICAvLyBPcGVuIHByZXZpb3VzIHRhYlxuICAgICAgY2FzZSAnc3dpcGVyaWdodCc6XG4gICAgICAgIGNvbnN0IGlzRmlyc3QgPSBzZWxlY3RUYWJJbmRleCA8PSAwO1xuICAgICAgICBzZWxlY3RUYWJJbmRleCA9IGlzRmlyc3QgPyB0aGlzLnRhYkNvdW50IDogc2VsZWN0VGFiSW5kZXggLSAxO1xuICAgICAgICBicmVhaztcblxuICAgICAgLy8gT3RoZXIgY2FzZVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgY29uc29sZS5lcnJvcignW3RhYi1wYWdlXSBVbmtub3duIHN3aXBlIGFjdGlvbjogJyArIGV2ZW50LnR5cGUpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnNlbGVjdGVkVGFiSW5kZXggPSBzZWxlY3RUYWJJbmRleDtcbiAgICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIG9uU3ViVGFiQ2hhbmdlKGV2ZW50OiBNYXRUYWJDaGFuZ2VFdmVudCkge1xuICAgIHRoaXMub25UYWJDaGFuZ2UoZXZlbnQsICdzdWJ0YWInKTtcbiAgfVxuXG4gIGFzeW5jIHVubG9hZChvcHRzPzogeyBlbWl0RXZlbnQ/OiBib29sZWFuIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnNlbGVjdGVkVGFiSW5kZXggPSAwO1xuICAgIGF3YWl0IHN1cGVyLnVubG9hZChvcHRzKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXRGaXJzdEludmFsaWRUYWJJbmRleCgpOiBudW1iZXI7XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHNhdmVEaXJ0eUNoaWxkcmVuKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIC8vIFNhdmUgYWxsIGRpcnR5IHRhYmxlc1xuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAuLi50aGlzLnRhYmxlcyxcbiAgICAgIC4uLnRoaXMuZWRpdG9yc1xuICAgIF1cbiAgICAgIC5maWx0ZXIoYyA9PiBjLmRpcnR5KVxuICAgICAgLm1hcChjID0+IGMuc2F2ZSgpKSk7XG5cbiAgICByZXR1cm4gIXJlc3VsdHMuc29tZShzYXZlZCA9PiBzYXZlZCAhPT0gdHJ1ZSk7XG4gIH1cbn1cbiJdfQ==