@sumaris-net/ngx-components 4.0.0-rc8 → 18.0.0-rc1

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 (555) hide show
  1. package/README.md +5 -3
  2. package/doc/changelog.md +522 -280
  3. package/esm2022/public_api.mjs +38 -19
  4. package/esm2022/src/app/admin/admin-routing.module.mjs +10 -17
  5. package/esm2022/src/app/admin/admin.module.mjs +7 -9
  6. package/esm2022/src/app/admin/services/filter/person.filter.mjs +3 -3
  7. package/esm2022/src/app/admin/services/person.service.mjs +31 -31
  8. package/esm2022/src/app/admin/services/validator/person.validator.mjs +10 -10
  9. package/esm2022/src/app/admin/users/users.mjs +22 -19
  10. package/esm2022/src/app/admin/users/users.module.mjs +8 -10
  11. package/esm2022/src/app/core/about/about.modal.mjs +7 -7
  12. package/esm2022/src/app/core/about/about.module.mjs +8 -21
  13. package/esm2022/src/app/core/account/account.module.mjs +28 -18
  14. package/esm2022/src/app/core/account/account.page.mjs +19 -5
  15. package/esm2022/src/app/core/account/new-token.form.mjs +106 -0
  16. package/esm2022/src/app/core/account/new-token.modal.mjs +27 -86
  17. package/esm2022/src/app/core/account/password/change-password.form.mjs +60 -0
  18. package/esm2022/src/app/core/account/password/change-password.module.mjs +22 -0
  19. package/esm2022/src/app/core/account/password/change-password.page.mjs +144 -0
  20. package/esm2022/src/app/core/account/token.table.mjs +47 -35
  21. package/esm2022/src/app/core/auth/auth.form.mjs +47 -28
  22. package/esm2022/src/app/core/auth/auth.modal.mjs +6 -6
  23. package/esm2022/src/app/core/auth/auth.module.mjs +22 -13
  24. package/esm2022/src/app/core/auth/reset-password.modal.mjs +77 -0
  25. package/esm2022/src/app/core/core.module.mjs +28 -61
  26. package/esm2022/src/app/core/core.testing.module.mjs +34 -20
  27. package/esm2022/src/app/core/form/array/form-array.mjs +325 -0
  28. package/esm2022/src/app/core/form/array/testing/form-array-test.module.mjs +23 -0
  29. package/esm2022/src/app/core/form/array/testing/form-array.test.mjs +94 -0
  30. package/esm2022/src/app/core/form/buttons/form-buttons-bar.component.mjs +24 -25
  31. package/esm2022/src/app/core/form/buttons/form-buttons-bar.module.mjs +9 -13
  32. package/esm2022/src/app/core/form/entity/editor.class.mjs +64 -517
  33. package/esm2022/src/app/core/form/entity/entity-editor-modal.class.mjs +26 -42
  34. package/esm2022/src/app/core/form/entity/entity-editor.class.mjs +42 -41
  35. package/esm2022/src/app/core/form/entity/entity-metadata.component.mjs +5 -5
  36. package/esm2022/src/app/core/form/entity/entity.module.mjs +8 -14
  37. package/esm2022/src/app/core/form/entity/tab-editor.class.mjs +194 -0
  38. package/esm2022/src/app/core/form/form-container.class.mjs +327 -0
  39. package/esm2022/src/app/core/form/form.class.mjs +39 -56
  40. package/esm2022/src/app/core/form/form.module.mjs +14 -10
  41. package/esm2022/src/app/core/form/form.utils.mjs +23 -306
  42. package/esm2022/src/app/core/form/list/list.form.mjs +16 -14
  43. package/esm2022/src/app/core/form/list/list.module.mjs +8 -12
  44. package/esm2022/src/app/core/form/properties/properties.form.mjs +139 -57
  45. package/esm2022/src/app/core/form/properties/properties.module.mjs +9 -15
  46. package/esm2022/src/app/core/form/properties/properties.table.mjs +27 -28
  47. package/esm2022/src/app/core/form/properties/properties.utils.mjs +60 -0
  48. package/esm2022/src/app/core/form/properties/property.validator.mjs +23 -9
  49. package/esm2022/src/app/core/form/properties/testing/properties-form.test.mjs +18 -18
  50. package/esm2022/src/app/core/form/properties/testing/properties-form.testing.module.mjs +8 -24
  51. package/esm2022/src/app/core/form/text-popover/testing/text-popover.testing.mjs +15 -15
  52. package/esm2022/src/app/core/form/text-popover/testing/text-popover.testing.module.mjs +10 -25
  53. package/esm2022/src/app/core/form/text-popover/text-popover.component.mjs +7 -7
  54. package/esm2022/src/app/core/form/text-popover/text-popover.module.mjs +9 -13
  55. package/esm2022/src/app/core/form/username/username.form.mjs +52 -0
  56. package/esm2022/src/app/core/form/username/username.module.mjs +20 -0
  57. package/esm2022/src/app/core/graphql/graphql.module.mjs +8 -16
  58. package/esm2022/src/app/core/graphql/graphql.service.mjs +101 -109
  59. package/esm2022/src/app/core/graphql/graphql.utils.mjs +12 -11
  60. package/esm2022/src/app/core/home/home.mjs +81 -52
  61. package/esm2022/src/app/core/home/home.module.mjs +10 -19
  62. package/esm2022/src/app/core/icon/icon.component.mjs +5 -5
  63. package/esm2022/src/app/core/icon/icon.module.mjs +8 -17
  64. package/esm2022/src/app/core/install/install-upgrade-card.component.mjs +33 -37
  65. package/esm2022/src/app/core/install/install-upgrade-card.module.mjs +9 -13
  66. package/esm2022/src/app/core/menu/menu.component.mjs +5 -6
  67. package/esm2022/src/app/core/menu/menu.model.mjs +21 -18
  68. package/esm2022/src/app/core/menu/menu.module.mjs +7 -12
  69. package/esm2022/src/app/core/menu/menu.service.mjs +44 -60
  70. package/esm2022/src/app/core/menu/sub-menu-tab.directive.mjs +4 -4
  71. package/esm2022/src/app/core/menu/testing/menu-other.testing.mjs +7 -6
  72. package/esm2022/src/app/core/menu/testing/menu.testing.mjs +43 -8
  73. package/esm2022/src/app/core/menu/testing/menu.testing.module.mjs +8 -27
  74. package/esm2022/src/app/core/offline/update-offline-mode-card.component.mjs +6 -7
  75. package/esm2022/src/app/core/offline/update-offline-mode-card.module.mjs +9 -13
  76. package/esm2022/src/app/core/peer/select-peer.modal.mjs +31 -21
  77. package/esm2022/src/app/core/peer/select-peer.module.mjs +11 -23
  78. package/esm2022/src/app/core/register/register-confirm.page.mjs +18 -16
  79. package/esm2022/src/app/core/register/register.form.mjs +7 -7
  80. package/esm2022/src/app/core/register/register.modal.mjs +6 -6
  81. package/esm2022/src/app/core/register/register.module.mjs +8 -29
  82. package/esm2022/src/app/core/services/account.service.mjs +272 -170
  83. package/esm2022/src/app/core/services/auth-guard.service.mjs +13 -15
  84. package/esm2022/src/app/core/services/base-entity-service.class.mjs +55 -64
  85. package/esm2022/src/app/core/services/base-graphql-service.class.mjs +39 -33
  86. package/esm2022/src/app/core/services/base58.mjs +8 -4
  87. package/esm2022/src/app/core/services/config/core.config.mjs +88 -37
  88. package/esm2022/src/app/core/services/config.service.mjs +81 -62
  89. package/esm2022/src/app/core/services/crypto.service.mjs +11 -11
  90. package/esm2022/src/app/core/services/errors.mjs +6 -5
  91. package/esm2022/src/app/core/services/local-settings.service.mjs +58 -44
  92. package/esm2022/src/app/core/services/model/account.model.mjs +12 -17
  93. package/esm2022/src/app/core/services/model/config.model.mjs +7 -7
  94. package/esm2022/src/app/core/services/model/department.model.mjs +3 -2
  95. package/esm2022/src/app/core/services/model/entity.decorators.mjs +6 -6
  96. package/esm2022/src/app/core/services/model/entity.model.mjs +27 -31
  97. package/esm2022/src/app/core/services/model/filter.model.mjs +12 -15
  98. package/esm2022/src/app/core/services/model/history.model.mjs +1 -1
  99. package/esm2022/src/app/core/services/model/model.enum.mjs +2 -2
  100. package/esm2022/src/app/core/services/model/peer.model.mjs +19 -9
  101. package/esm2022/src/app/core/services/model/person.model.mjs +26 -22
  102. package/esm2022/src/app/core/services/model/referential.model.mjs +36 -23
  103. package/esm2022/src/app/core/services/model/settings.model.mjs +2 -1
  104. package/esm2022/src/app/core/services/model/token.model.mjs +7 -3
  105. package/esm2022/src/app/core/services/model/tree-item-entity.model.mjs +3 -7
  106. package/esm2022/src/app/core/services/network.service.mjs +99 -76
  107. package/esm2022/src/app/core/services/network.types.mjs +1 -1
  108. package/esm2022/src/app/core/services/network.utils.mjs +3 -3
  109. package/esm2022/src/app/core/services/pipes/account.pipes.mjs +11 -11
  110. package/esm2022/src/app/core/services/pipes/department-to-string.pipe.mjs +6 -6
  111. package/esm2022/src/app/core/services/pipes/person-to-string.pipe.mjs +9 -9
  112. package/esm2022/src/app/core/services/pipes/pipes.module.mjs +54 -0
  113. package/esm2022/src/app/core/services/pipes/referential-to-string.pipe.mjs +21 -0
  114. package/esm2022/src/app/core/services/pipes/usage-mode.pipes.mjs +11 -11
  115. package/esm2022/src/app/core/services/platform.service.mjs +102 -69
  116. package/esm2022/src/app/core/services/storage/entities-storage.service.mjs +32 -39
  117. package/esm2022/src/app/core/services/storage/entity-store.class.mjs +36 -45
  118. package/esm2022/src/app/core/services/testing/referential-filter.model.mjs +1 -1
  119. package/esm2022/src/app/core/services/testing/referential.validator.mjs +14 -14
  120. package/esm2022/src/app/core/services/validator/account.validator.mjs +5 -5
  121. package/esm2022/src/app/core/services/validator/base.validator.class.mjs +5 -5
  122. package/esm2022/src/app/core/services/validator/local-settings.validator.mjs +34 -20
  123. package/esm2022/src/app/core/services/validator/user-settings.validator.mjs +5 -5
  124. package/esm2022/src/app/core/services/validator/user-token.validator.mjs +12 -9
  125. package/esm2022/src/app/core/settings/settings.module.mjs +9 -21
  126. package/esm2022/src/app/core/settings/settings.page.mjs +76 -63
  127. package/esm2022/src/app/core/table/async-table.class.mjs +219 -201
  128. package/esm2022/src/app/core/table/column/actions-column.component.mjs +127 -0
  129. package/esm2022/src/app/core/table/column/nav-actions-column.component.mjs +117 -0
  130. package/esm2022/src/app/core/table/column/row-field.component.mjs +116 -0
  131. package/esm2022/src/app/core/table/entities-async-table-datasource.class.mjs +31 -33
  132. package/esm2022/src/app/core/table/entities-table-datasource.class.mjs +36 -36
  133. package/esm2022/src/app/core/table/memory-table.class.mjs +5 -5
  134. package/esm2022/src/app/core/table/table-select-columns.component.mjs +8 -8
  135. package/esm2022/src/app/core/table/table.class.mjs +193 -152
  136. package/esm2022/src/app/core/table/table.model.mjs +1 -1
  137. package/esm2022/src/app/core/table/table.module.mjs +35 -24
  138. package/esm2022/src/app/core/table/table.pipes.mjs +77 -0
  139. package/esm2022/src/app/core/table/table.utils.mjs +2 -4
  140. package/esm2022/src/app/core/table/testing/table-validator.service.mjs +9 -5
  141. package/esm2022/src/app/core/table/testing/table.testing.mjs +116 -78
  142. package/esm2022/src/app/core/table/testing/table.testing.module.mjs +8 -33
  143. package/esm2022/src/app/core/table/testing/table2-validator.service.mjs +4 -4
  144. package/esm2022/src/app/core/table/testing/table2.testing.mjs +68 -45
  145. package/esm2022/src/app/shared/alerts.mjs +49 -45
  146. package/esm2022/src/app/shared/audio/audio.mjs +25 -27
  147. package/esm2022/src/app/shared/audio/audio.testing.mjs +5 -5
  148. package/esm2022/src/app/shared/audio/audio.testing.module.mjs +10 -25
  149. package/esm2022/src/app/shared/capacitor/keyboard.mjs +5 -5
  150. package/esm2022/src/app/shared/capacitor/plugins.mjs +1 -1
  151. package/esm2022/src/app/shared/constants.mjs +9 -4
  152. package/esm2022/src/app/shared/dates.mjs +18 -16
  153. package/esm2022/src/app/shared/debug/debug-service.class.mjs +1 -1
  154. package/esm2022/src/app/shared/debug/debug.component.mjs +5 -5
  155. package/esm2022/src/app/shared/debug/debug.module.mjs +8 -29
  156. package/esm2022/src/app/shared/directives/autofocus.directive.mjs +8 -15
  157. package/esm2022/src/app/shared/directives/autotitle.directive.mjs +4 -4
  158. package/esm2022/src/app/shared/directives/directives.module.mjs +8 -29
  159. package/esm2022/src/app/shared/directives/drag-and-drop.directive.mjs +4 -4
  160. package/esm2022/src/app/shared/directives/ng-var.directive.mjs +4 -4
  161. package/esm2022/src/app/shared/directives/resizable/resizable.component.mjs +4 -4
  162. package/esm2022/src/app/shared/directives/resizable/resizable.directive.mjs +4 -4
  163. package/esm2022/src/app/shared/directives/resizable/resizable.module.mjs +4 -4
  164. package/esm2022/src/app/shared/events.mjs +6 -8
  165. package/esm2022/src/app/shared/file/csv.utils.mjs +38 -18
  166. package/esm2022/src/app/shared/file/file.service.mjs +11 -15
  167. package/esm2022/src/app/shared/file/file.utils.mjs +13 -11
  168. package/esm2022/src/app/shared/file/images.utils.mjs +29 -4
  169. package/esm2022/src/app/shared/file/json.utils.mjs +11 -4
  170. package/esm2022/src/app/shared/file/uri.utils.mjs +1 -1
  171. package/esm2022/src/app/shared/focusable.mjs +1 -1
  172. package/esm2022/src/app/shared/form/field.component.mjs +69 -43
  173. package/esm2022/src/app/shared/form/field.model.mjs +4 -4
  174. package/esm2022/src/app/shared/form/loading-spinner.mjs +5 -5
  175. package/esm2022/src/app/shared/forms.mjs +116 -43
  176. package/esm2022/src/app/shared/functions.mjs +139 -71
  177. package/esm2022/src/app/shared/geolocation/geolocation.utils.mjs +14 -14
  178. package/esm2022/src/app/shared/gesture/gesture-config.mjs +10 -10
  179. package/esm2022/src/app/shared/gesture/hammer.utils.mjs +1 -1
  180. package/esm2022/src/app/shared/graph/colors.utils.mjs +14 -18
  181. package/esm2022/src/app/shared/graph/graph-colors.mjs +23 -29
  182. package/esm2022/src/app/shared/guard/component-dirty.guard.mjs +4 -4
  183. package/esm2022/src/app/shared/help/help.modal.mjs +6 -6
  184. package/esm2022/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.mjs +5 -5
  185. package/esm2022/src/app/shared/hotkeys/hotkeys.service.mjs +44 -17
  186. package/esm2022/src/app/shared/hotkeys/shared-hotkeys.module.mjs +9 -27
  187. package/esm2022/src/app/shared/http/http.utils.mjs +15 -11
  188. package/esm2022/src/app/shared/image/gallery/image-gallery.component.mjs +27 -27
  189. package/esm2022/src/app/shared/image/gallery/image-gallery.module.mjs +13 -10
  190. package/esm2022/src/app/shared/image/gallery/testing/gallegry.model.testing.mjs +1 -1
  191. package/esm2022/src/app/shared/image/gallery/testing/gallery.service.testing.mjs +14 -17
  192. package/esm2022/src/app/shared/image/gallery/testing/gallery.testing.mjs +9 -13
  193. package/esm2022/src/app/shared/image/gallery/testing/gallery.testing.module.mjs +14 -11
  194. package/esm2022/src/app/shared/image/image.model.mjs +1 -1
  195. package/esm2022/src/app/shared/image/image.module.mjs +8 -13
  196. package/esm2022/src/app/shared/image/image.service.mjs +14 -12
  197. package/esm2022/src/app/shared/inputs.mjs +52 -20
  198. package/esm2022/src/app/shared/interceptors/progess.interceptor.mjs +2 -3
  199. package/esm2022/src/app/shared/logging/log-level.model.mjs +1 -1
  200. package/esm2022/src/app/shared/logging/logger.model.mjs +2 -2
  201. package/esm2022/src/app/shared/logging/logging-service.class.mjs +17 -20
  202. package/esm2022/src/app/shared/logging/logging-service.module.mjs +6 -6
  203. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.config.mjs +7 -10
  204. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.mjs +348 -238
  205. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.module.mjs +13 -16
  206. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.utils.mjs +5 -4
  207. package/esm2022/src/app/shared/material/autocomplete/testing/autocomplete.test.mjs +51 -37
  208. package/esm2022/src/app/shared/material/badge/badge.directive.mjs +99 -57
  209. package/esm2022/src/app/shared/material/badge/badge.module.mjs +8 -20
  210. package/esm2022/src/app/shared/material/badge/badge.test.mjs +5 -5
  211. package/esm2022/src/app/shared/material/boolean/boolean.module.mjs +19 -20
  212. package/esm2022/src/app/shared/material/boolean/material.boolean.mjs +209 -104
  213. package/esm2022/src/app/shared/material/boolean/testing/boolean.test.page.mjs +15 -8
  214. package/esm2022/src/app/shared/material/chips/chips.module.mjs +12 -13
  215. package/esm2022/src/app/shared/material/chips/material.chips.mjs +228 -168
  216. package/esm2022/src/app/shared/material/chips/testing/chips.test.mjs +20 -21
  217. package/esm2022/src/app/shared/material/datetime/datetime.module.mjs +12 -27
  218. package/esm2022/src/app/shared/material/datetime/material.date.mjs +167 -92
  219. package/esm2022/src/app/shared/material/datetime/material.dateshort.mjs +128 -77
  220. package/esm2022/src/app/shared/material/datetime/material.datetime.mjs +297 -165
  221. package/esm2022/src/app/shared/material/datetime/testing/mat-date-time.test.mjs +34 -30
  222. package/esm2022/src/app/shared/material/datetime/testing/mat-date.test.mjs +31 -27
  223. package/esm2022/src/app/shared/material/datetime/testing/mat-dateshort.test.mjs +26 -23
  224. package/esm2022/src/app/shared/material/duration/duration.module.mjs +11 -16
  225. package/esm2022/src/app/shared/material/duration/duration.utils.mjs +3 -6
  226. package/esm2022/src/app/shared/material/duration/material.duration.mjs +35 -34
  227. package/esm2022/src/app/shared/material/duration/testing/mat-duration.test.mjs +23 -22
  228. package/esm2022/src/app/shared/material/latlong/latlong.utils.mjs +217 -170
  229. package/esm2022/src/app/shared/material/latlong/material.latlong.mjs +182 -241
  230. package/esm2022/src/app/shared/material/latlong/material.latlong.module.mjs +10 -15
  231. package/esm2022/src/app/shared/material/latlong/testing/latlong.test.mjs +19 -14
  232. package/esm2022/src/app/shared/material/material.animations.mjs +22 -22
  233. package/esm2022/src/app/shared/material/material.config.mjs +3 -0
  234. package/esm2022/src/app/shared/material/material.module.mjs +16 -16
  235. package/esm2022/src/app/shared/material/material.testing.module.mjs +50 -37
  236. package/esm2022/src/app/shared/material/paginator/material.paginator-i18n.mjs +12 -9
  237. package/esm2022/src/app/shared/material/stepper/material.stepper-i18n.mjs +4 -4
  238. package/esm2022/src/app/shared/material/swipe/material.swipe.mjs +26 -19
  239. package/esm2022/src/app/shared/material/swipe/swipe.module.mjs +7 -11
  240. package/esm2022/src/app/shared/material/swipe/testing/swipe.test.mjs +8 -8
  241. package/esm2022/src/app/shared/material/testing/common.test.mjs +30 -24
  242. package/esm2022/src/app/shared/material/text/testing/text-form.testing.mjs +30 -19
  243. package/esm2022/src/app/shared/material/text/text-form.component.mjs +128 -21
  244. package/esm2022/src/app/shared/material/text/text-form.module.mjs +8 -8
  245. package/esm2022/src/app/shared/modules.mjs +1 -1
  246. package/esm2022/src/app/shared/named-filter/named-filter-selector.component.mjs +118 -37
  247. package/esm2022/src/app/shared/named-filter/named-filter.model.mjs +1 -1
  248. package/esm2022/src/app/shared/named-filter/named-filter.module.mjs +5 -5
  249. package/esm2022/src/app/shared/named-filter/named-filter.service.mjs +8 -8
  250. package/esm2022/src/app/shared/named-filter/testing/named-filter-selector.testing.mjs +74 -0
  251. package/esm2022/src/app/shared/named-filter/testing/named-filter.testing.module.mjs +28 -0
  252. package/esm2022/src/app/shared/observables.mjs +14 -18
  253. package/esm2022/src/app/shared/pipes/arrays.pipe.mjs +53 -38
  254. package/esm2022/src/app/shared/pipes/badge.pipes.mjs +24 -0
  255. package/esm2022/src/app/shared/pipes/colors.pipe.mjs +8 -6
  256. package/esm2022/src/app/shared/pipes/date-diff-duration.pipe.mjs +8 -10
  257. package/esm2022/src/app/shared/pipes/date-format.pipe.mjs +15 -15
  258. package/esm2022/src/app/shared/pipes/date-from-now.pipe.mjs +6 -6
  259. package/esm2022/src/app/shared/pipes/duration.pipe.mjs +6 -6
  260. package/esm2022/src/app/shared/pipes/file-size.pipe.mjs +6 -13
  261. package/esm2022/src/app/shared/pipes/form.pipes.mjs +72 -47
  262. package/esm2022/src/app/shared/pipes/highlight.pipe.mjs +15 -15
  263. package/esm2022/src/app/shared/pipes/html.pipes.mjs +52 -0
  264. package/esm2022/src/app/shared/pipes/latlong-format.pipe.mjs +14 -14
  265. package/esm2022/src/app/shared/pipes/maps.pipe.mjs +17 -17
  266. package/esm2022/src/app/shared/pipes/maskito.pipe.mjs +37 -88
  267. package/esm2022/src/app/shared/pipes/math.pipes.mjs +16 -16
  268. package/esm2022/src/app/shared/pipes/ng-init.pipe.mjs +5 -5
  269. package/esm2022/src/app/shared/pipes/number-format.pipe.mjs +6 -6
  270. package/esm2022/src/app/shared/pipes/pipes.module.mjs +117 -137
  271. package/esm2022/src/app/shared/pipes/property.pipes.mjs +86 -47
  272. package/esm2022/src/app/shared/pipes/selection.pipes.mjs +179 -0
  273. package/esm2022/src/app/shared/pipes/string.pipes.mjs +50 -49
  274. package/esm2022/src/app/shared/pipes/translate-context.pipe.mjs +11 -11
  275. package/esm2022/src/app/shared/pipes/types.pipes.mjs +33 -17
  276. package/esm2022/src/app/shared/platforms.mjs +7 -5
  277. package/esm2022/src/app/shared/rx-state.module.mjs +7 -11
  278. package/esm2022/src/app/shared/services/entity-service.class.mjs +2 -2
  279. package/esm2022/src/app/shared/services/job.utils.mjs +7 -7
  280. package/esm2022/src/app/shared/services/memory-entity-service.class.mjs +43 -41
  281. package/esm2022/src/app/shared/services/progress-bar.service.mjs +4 -4
  282. package/esm2022/src/app/shared/services/startable-observable-service.class.mjs +11 -14
  283. package/esm2022/src/app/shared/services/startable-service.class.mjs +11 -17
  284. package/esm2022/src/app/shared/services/translate-context.service.mjs +18 -15
  285. package/esm2022/src/app/shared/services/validator-service.class.mjs +1 -1
  286. package/esm2022/src/app/shared/services.mjs +12 -12
  287. package/esm2022/src/app/shared/shared-routing.module.mjs +19 -18
  288. package/esm2022/src/app/shared/shared.module.mjs +29 -28
  289. package/esm2022/src/app/shared/shared.testing.module.mjs +18 -10
  290. package/esm2022/src/app/shared/storage/storage-explorer.component.mjs +39 -46
  291. package/esm2022/src/app/shared/storage/storage-explorer.module.mjs +8 -12
  292. package/esm2022/src/app/shared/storage/storage-explorer.testing-routing.module.mjs +9 -17
  293. package/esm2022/src/app/shared/storage/storage-explorer.testing.module.mjs +10 -18
  294. package/esm2022/src/app/shared/storage/storage.service.mjs +4 -4
  295. package/esm2022/src/app/shared/storage/storage.utils.mjs +2 -2
  296. package/esm2022/src/app/shared/testing/maskito.test.mjs +41 -0
  297. package/esm2022/src/app/shared/testing/observable.test.mjs +11 -13
  298. package/esm2022/src/app/shared/testing/tests.page.mjs +6 -6
  299. package/esm2022/src/app/shared/toast/toast.testing.mjs +11 -11
  300. package/esm2022/src/app/shared/toast/toast.testing.module.mjs +10 -25
  301. package/esm2022/src/app/shared/toast/toasts.mjs +9 -9
  302. package/esm2022/src/app/shared/toolbar/modal-toolbar.mjs +10 -8
  303. package/esm2022/src/app/shared/toolbar/toolbar.mjs +31 -32
  304. package/esm2022/src/app/shared/toolbar/toolbar.module.mjs +8 -39
  305. package/esm2022/src/app/shared/types.mjs +1 -1
  306. package/esm2022/src/app/shared/upload-file/testing/upload-file.testing.mjs +12 -12
  307. package/esm2022/src/app/shared/upload-file/testing/upload-file.testing.module.mjs +10 -25
  308. package/esm2022/src/app/shared/upload-file/upload-file-popover.component.mjs +7 -8
  309. package/esm2022/src/app/shared/upload-file/upload-file.component.mjs +21 -19
  310. package/esm2022/src/app/shared/upload-file/upload-file.model.mjs +2 -3
  311. package/esm2022/src/app/shared/validator/form-error-adapter.class.mjs +64 -56
  312. package/esm2022/src/app/shared/validator/validators.mjs +60 -39
  313. package/esm2022/src/app/shared/version/versions.mjs +2 -2
  314. package/esm2022/src/app/social/job/job.module.mjs +8 -27
  315. package/esm2022/src/app/social/job/progression/job-progression.component.mjs +9 -9
  316. package/esm2022/src/app/social/job/progression/job-progression.icon.mjs +49 -46
  317. package/esm2022/src/app/social/job/progression/job-progression.list.mjs +10 -13
  318. package/esm2022/src/app/social/job/progression/job-progression.model.mjs +1 -1
  319. package/esm2022/src/app/social/job/progression/job-progression.service.mjs +39 -21
  320. package/esm2022/src/app/social/job/testing/job-progression.testing.mjs +6 -11
  321. package/esm2022/src/app/social/job/testing/job-progression.testing.service.mjs +11 -30
  322. package/esm2022/src/app/social/job/testing/job.testing.module.mjs +8 -21
  323. package/esm2022/src/app/social/message/message.form.mjs +5 -5
  324. package/esm2022/src/app/social/message/message.modal.mjs +8 -8
  325. package/esm2022/src/app/social/message/message.model.mjs +8 -8
  326. package/esm2022/src/app/social/message/message.module.mjs +4 -4
  327. package/esm2022/src/app/social/message/message.service.mjs +7 -7
  328. package/esm2022/src/app/social/social.errors.mjs +2 -2
  329. package/esm2022/src/app/social/social.module.mjs +7 -32
  330. package/esm2022/src/app/social/social.testing.module.mjs +9 -20
  331. package/esm2022/src/app/social/user-event/notification/user-event-notification.icon.mjs +27 -23
  332. package/esm2022/src/app/social/user-event/notification/user-event-notification.list.mjs +19 -22
  333. package/esm2022/src/app/social/user-event/testing/user-event.testing.mjs +47 -23
  334. package/esm2022/src/app/social/user-event/testing/user-event.testing.model.mjs +8 -8
  335. package/esm2022/src/app/social/user-event/testing/user-event.testing.module.mjs +8 -21
  336. package/esm2022/src/app/social/user-event/testing/user-event.testing.service.mjs +27 -15
  337. package/esm2022/src/app/social/user-event/user-event.model.mjs +1 -1
  338. package/esm2022/src/app/social/user-event/user-event.module.mjs +8 -28
  339. package/esm2022/src/app/social/user-event/user-event.service.mjs +61 -64
  340. package/esm2022/src/environments/environment.class.mjs +9 -1
  341. package/esm2022/src/environments/environment.loader.mjs +5 -11
  342. package/esm2022/src/environments/environment.mjs +19 -11
  343. package/fesm2022/sumaris-net.ngx-components.mjs +16117 -14592
  344. package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
  345. package/package.json +36 -18
  346. package/public_api.d.ts +30 -22
  347. package/src/app/admin/services/filter/person.filter.d.ts +1 -1
  348. package/src/app/admin/users/users.d.ts +5 -6
  349. package/src/app/core/account/account.module.d.ts +10 -8
  350. package/src/app/core/account/account.page.d.ts +25 -15
  351. package/src/app/core/account/new-token.form.d.ts +29 -0
  352. package/src/app/core/account/new-token.modal.d.ts +9 -21
  353. package/src/app/core/account/password/change-password.form.d.ts +19 -0
  354. package/src/app/core/account/password/change-password.module.d.ts +11 -0
  355. package/src/app/core/account/password/change-password.page.d.ts +36 -0
  356. package/src/app/core/account/token.table.d.ts +7 -5
  357. package/src/app/core/auth/auth.form.d.ts +11 -9
  358. package/src/app/core/auth/auth.module.d.ts +6 -4
  359. package/src/app/core/auth/reset-password.modal.d.ts +26 -0
  360. package/src/app/core/core.module.d.ts +21 -24
  361. package/src/app/core/core.testing.module.d.ts +2 -1
  362. package/src/app/core/form/array/form-array.d.ts +136 -0
  363. package/src/app/core/form/array/testing/form-array-test.module.d.ts +12 -0
  364. package/src/app/core/form/array/testing/form-array.test.d.ts +26 -0
  365. package/src/app/core/form/buttons/form-buttons-bar.component.d.ts +2 -3
  366. package/src/app/core/form/entity/editor.class.d.ts +19 -179
  367. package/src/app/core/form/entity/entity-editor-modal.class.d.ts +10 -13
  368. package/src/app/core/form/entity/entity-editor.class.d.ts +12 -17
  369. package/src/app/core/form/entity/entity-metadata.component.d.ts +1 -1
  370. package/src/app/core/form/entity/tab-editor.class.d.ts +70 -0
  371. package/src/app/core/form/form-container.class.d.ts +126 -0
  372. package/src/app/core/form/form.class.d.ts +13 -26
  373. package/src/app/core/form/form.module.d.ts +2 -1
  374. package/src/app/core/form/form.utils.d.ts +60 -145
  375. package/src/app/core/form/list/list.form.d.ts +2 -2
  376. package/src/app/core/form/properties/properties.form.d.ts +34 -12
  377. package/src/app/core/form/properties/properties.table.d.ts +2 -2
  378. package/src/app/core/form/properties/properties.utils.d.ts +27 -0
  379. package/src/app/core/form/properties/property.validator.d.ts +9 -3
  380. package/src/app/core/form/text-popover/testing/text-popover.testing.d.ts +3 -1
  381. package/src/app/core/form/username/username.form.d.ts +19 -0
  382. package/src/app/core/form/username/username.module.d.ts +9 -0
  383. package/src/app/core/graphql/graphql.module.d.ts +1 -2
  384. package/src/app/core/graphql/graphql.service.d.ts +2 -4
  385. package/src/app/core/home/home.d.ts +26 -6
  386. package/src/app/core/menu/testing/menu-other.testing.d.ts +1 -1
  387. package/src/app/core/menu/testing/menu.testing.d.ts +11 -3
  388. package/src/app/core/peer/select-peer.modal.d.ts +13 -7
  389. package/src/app/core/peer/select-peer.module.d.ts +3 -4
  390. package/src/app/core/services/account.service.d.ts +9 -0
  391. package/src/app/core/services/base-entity-service.class.d.ts +1 -1
  392. package/src/app/core/services/config/core.config.d.ts +12 -1
  393. package/src/app/core/services/config.service.d.ts +4 -3
  394. package/src/app/core/services/errors.d.ts +11 -0
  395. package/src/app/core/services/local-settings.service.d.ts +8 -4
  396. package/src/app/core/services/model/entity.model.d.ts +6 -5
  397. package/src/app/core/services/model/filter.model.d.ts +1 -1
  398. package/src/app/core/services/model/peer.model.d.ts +1 -0
  399. package/src/app/core/services/model/person.model.d.ts +6 -2
  400. package/src/app/core/services/model/referential.model.d.ts +8 -3
  401. package/src/app/core/services/model/settings.model.d.ts +4 -2
  402. package/src/app/core/services/model/token.model.d.ts +1 -0
  403. package/src/app/core/services/model/tree-item-entity.model.d.ts +1 -1
  404. package/src/app/core/services/network.service.d.ts +11 -7
  405. package/src/app/core/services/pipes/department-to-string.pipe.d.ts +1 -1
  406. package/src/app/core/services/pipes/person-to-string.pipe.d.ts +3 -1
  407. package/src/app/core/services/pipes/pipes.module.d.ts +11 -0
  408. package/src/app/core/services/pipes/referential-to-string.pipe.d.ts +13 -0
  409. package/src/app/core/services/platform.service.d.ts +8 -3
  410. package/src/app/core/services/testing/referential-filter.model.d.ts +1 -1
  411. package/src/app/core/services/validator/local-settings.validator.d.ts +6 -2
  412. package/src/app/core/settings/settings.module.d.ts +2 -1
  413. package/src/app/core/settings/settings.page.d.ts +34 -21
  414. package/src/app/core/table/async-table.class.d.ts +22 -17
  415. package/src/app/core/table/column/actions-column.component.d.ts +59 -0
  416. package/src/app/core/table/column/nav-actions-column.component.d.ts +46 -0
  417. package/src/app/core/table/column/row-field.component.d.ts +40 -0
  418. package/src/app/core/table/entities-async-table-datasource.class.d.ts +1 -0
  419. package/src/app/core/table/entities-table-datasource.class.d.ts +1 -0
  420. package/src/app/core/table/table.class.d.ts +14 -11
  421. package/src/app/core/table/table.module.d.ts +8 -4
  422. package/src/app/core/table/table.pipes.d.ts +28 -0
  423. package/src/app/core/table/testing/table.testing.d.ts +12 -13
  424. package/src/app/core/table/testing/table2.testing.d.ts +13 -10
  425. package/src/app/shared/alerts.d.ts +4 -2
  426. package/src/app/shared/constants.d.ts +5 -0
  427. package/src/app/shared/dates.d.ts +12 -5
  428. package/src/app/shared/directives/autofocus.directive.d.ts +0 -1
  429. package/src/app/shared/events.d.ts +1 -1
  430. package/src/app/shared/file/csv.utils.d.ts +5 -0
  431. package/src/app/shared/file/images.utils.d.ts +17 -0
  432. package/src/app/shared/file/json.utils.d.ts +3 -0
  433. package/src/app/shared/form/field.component.d.ts +6 -3
  434. package/src/app/shared/forms.d.ts +32 -0
  435. package/src/app/shared/functions.d.ts +27 -8
  436. package/src/app/shared/graph/graph-colors.d.ts +1 -1
  437. package/src/app/shared/guard/component-dirty.guard.d.ts +1 -6
  438. package/src/app/shared/hotkeys/hotkeys.service.d.ts +17 -3
  439. package/src/app/shared/http/http.utils.d.ts +1 -0
  440. package/src/app/shared/image/gallery/image-gallery.component.d.ts +10 -10
  441. package/src/app/shared/image/gallery/image-gallery.module.d.ts +2 -1
  442. package/src/app/shared/image/gallery/testing/gallery.service.testing.d.ts +2 -2
  443. package/src/app/shared/image/gallery/testing/gallery.testing.module.d.ts +2 -1
  444. package/src/app/shared/inputs.d.ts +8 -6
  445. package/src/app/shared/material/autocomplete/material.autocomplete.config.d.ts +20 -1
  446. package/src/app/shared/material/autocomplete/material.autocomplete.d.ts +56 -16
  447. package/src/app/shared/material/autocomplete/material.autocomplete.module.d.ts +1 -1
  448. package/src/app/shared/material/autocomplete/material.autocomplete.utils.d.ts +2 -1
  449. package/src/app/shared/material/autocomplete/testing/autocomplete.test.d.ts +3 -2
  450. package/src/app/shared/material/badge/badge.directive.d.ts +10 -4
  451. package/src/app/shared/material/boolean/boolean.module.d.ts +15 -14
  452. package/src/app/shared/material/boolean/material.boolean.d.ts +51 -25
  453. package/src/app/shared/material/boolean/testing/boolean.test.page.d.ts +1 -0
  454. package/src/app/shared/material/chips/chips.module.d.ts +2 -1
  455. package/src/app/shared/material/chips/material.chips.d.ts +46 -21
  456. package/src/app/shared/material/chips/testing/chips.test.d.ts +1 -0
  457. package/src/app/shared/material/datetime/datetime.module.d.ts +1 -1
  458. package/src/app/shared/material/datetime/material.date.d.ts +33 -18
  459. package/src/app/shared/material/datetime/material.dateshort.d.ts +29 -16
  460. package/src/app/shared/material/datetime/material.datetime.d.ts +41 -28
  461. package/src/app/shared/material/datetime/testing/mat-date-time.test.d.ts +3 -3
  462. package/src/app/shared/material/duration/duration.module.d.ts +1 -1
  463. package/src/app/shared/material/duration/material.duration.d.ts +1 -1
  464. package/src/app/shared/material/latlong/latlong.utils.d.ts +9 -1
  465. package/src/app/shared/material/latlong/material.latlong.d.ts +29 -32
  466. package/src/app/shared/material/latlong/material.latlong.module.d.ts +1 -1
  467. package/src/app/shared/material/latlong/testing/latlong.test.d.ts +5 -1
  468. package/src/app/shared/material/material.config.d.ts +3 -0
  469. package/src/app/shared/material/material.module.d.ts +5 -6
  470. package/src/app/shared/material/material.testing.module.d.ts +8 -7
  471. package/src/app/shared/material/swipe/material.swipe.d.ts +4 -3
  472. package/src/app/shared/material/text/testing/text-form.testing.d.ts +10 -4
  473. package/src/app/shared/material/text/text-form.component.d.ts +42 -8
  474. package/src/app/shared/named-filter/named-filter-selector.component.d.ts +30 -14
  475. package/src/app/shared/named-filter/named-filter.service.d.ts +12 -6
  476. package/src/app/shared/named-filter/testing/named-filter-selector.testing.d.ts +34 -0
  477. package/src/app/shared/named-filter/testing/named-filter.testing.module.d.ts +10 -0
  478. package/src/app/shared/pipes/arrays.pipe.d.ts +5 -0
  479. package/src/app/shared/pipes/badge.pipes.d.ts +7 -0
  480. package/src/app/shared/pipes/date-format.pipe.d.ts +3 -2
  481. package/src/app/shared/pipes/form.pipes.d.ts +18 -8
  482. package/src/app/shared/pipes/html.pipes.d.ts +15 -0
  483. package/src/app/shared/pipes/maps.pipe.d.ts +4 -4
  484. package/src/app/shared/pipes/maskito.pipe.d.ts +7 -9
  485. package/src/app/shared/pipes/pipes.module.d.ts +7 -4
  486. package/src/app/shared/pipes/property.pipes.d.ts +24 -3
  487. package/src/app/shared/pipes/selection.pipes.d.ts +62 -0
  488. package/src/app/shared/pipes/string.pipes.d.ts +6 -6
  489. package/src/app/shared/pipes/types.pipes.d.ts +6 -1
  490. package/src/app/shared/services/entity-service.class.d.ts +0 -2
  491. package/src/app/shared/services/memory-entity-service.class.d.ts +6 -3
  492. package/src/app/shared/services.d.ts +1 -0
  493. package/src/app/shared/shared.testing.module.d.ts +2 -1
  494. package/src/app/shared/storage/storage-explorer.component.d.ts +4 -3
  495. package/src/app/shared/testing/maskito.test.d.ts +10 -0
  496. package/src/app/shared/toolbar/toolbar.d.ts +7 -2
  497. package/src/app/shared/types.d.ts +5 -0
  498. package/src/app/shared/upload-file/upload-file.component.d.ts +1 -0
  499. package/src/app/shared/validator/form-error-adapter.class.d.ts +17 -11
  500. package/src/app/shared/validator/validators.d.ts +20 -9
  501. package/src/app/social/job/progression/job-progression.icon.d.ts +4 -5
  502. package/src/app/social/job/progression/job-progression.list.d.ts +1 -3
  503. package/src/app/social/job/progression/job-progression.service.d.ts +3 -4
  504. package/src/app/social/job/testing/job-progression.testing.d.ts +0 -1
  505. package/src/app/social/job/testing/job-progression.testing.service.d.ts +3 -11
  506. package/src/app/social/message/message.modal.d.ts +2 -2
  507. package/src/app/social/message/message.model.d.ts +1 -1
  508. package/src/app/social/user-event/notification/user-event-notification.icon.d.ts +4 -4
  509. package/src/app/social/user-event/testing/user-event.testing.d.ts +1 -0
  510. package/src/app/social/user-event/testing/user-event.testing.model.d.ts +2 -3
  511. package/src/app/social/user-event/testing/user-event.testing.service.d.ts +1 -0
  512. package/src/assets/i18n/en-US.json +48 -19
  513. package/src/assets/i18n/en.json +48 -20
  514. package/src/assets/i18n/fr.json +50 -20
  515. package/src/assets/manifest.json +1 -1
  516. package/src/environments/environment.class.d.ts +10 -0
  517. package/src/environments/environment.d.ts +0 -1
  518. package/src/environments/environment.loader.d.ts +0 -2
  519. package/src/theme/_functions.scss +15 -0
  520. package/src/theme/_icons.scss +1 -1
  521. package/src/theme/_ionic.globals.scss +8 -2
  522. package/src/theme/_ionic.scss +10 -10
  523. package/src/theme/_material.globals.scss +16 -43
  524. package/src/theme/_material.scss +45 -32
  525. package/src/theme/_mixins.scss +99 -18
  526. package/src/theme/_ngx-components.forms.scss +354 -0
  527. package/src/theme/_ngx-components.globals.scss +20 -10
  528. package/src/theme/_ngx-components.scss +194 -400
  529. package/src/theme/_ngx-components.table.scss +200 -207
  530. package/src/theme/_ngx-components.tabs.scss +54 -0
  531. package/src/theme/_responsive.scss +0 -31
  532. package/src/theme/_theme.scss +2 -0
  533. package/src/theme/_theme.variables.scss +172 -0
  534. package/esm2022/src/app/core/table/actions-column.component.mjs +0 -115
  535. package/esm2022/src/app/shared/material/boolean/material-boolean2.mjs +0 -266
  536. package/esm2022/src/app/shared/material/numpad/numpad.append-to-input.directive.mjs +0 -104
  537. package/esm2022/src/app/shared/material/numpad/numpad.component.mjs +0 -83
  538. package/esm2022/src/app/shared/material/numpad/numpad.container.mjs +0 -203
  539. package/esm2022/src/app/shared/material/numpad/numpad.content.mjs +0 -19
  540. package/esm2022/src/app/shared/material/numpad/numpad.directive.mjs +0 -168
  541. package/esm2022/src/app/shared/material/numpad/numpad.dom-service.mjs +0 -36
  542. package/esm2022/src/app/shared/material/numpad/numpad.model.mjs +0 -16
  543. package/esm2022/src/app/shared/material/numpad/numpad.module.mjs +0 -60
  544. package/esm2022/src/app/shared/material/numpad/testing/numpad.test.mjs +0 -48
  545. package/src/app/core/table/actions-column.component.d.ts +0 -48
  546. package/src/app/shared/material/boolean/material-boolean2.d.ts +0 -66
  547. package/src/app/shared/material/numpad/numpad.append-to-input.directive.d.ts +0 -22
  548. package/src/app/shared/material/numpad/numpad.component.d.ts +0 -26
  549. package/src/app/shared/material/numpad/numpad.container.d.ts +0 -40
  550. package/src/app/shared/material/numpad/numpad.content.d.ts +0 -7
  551. package/src/app/shared/material/numpad/numpad.directive.d.ts +0 -35
  552. package/src/app/shared/material/numpad/numpad.dom-service.d.ts +0 -16
  553. package/src/app/shared/material/numpad/numpad.model.d.ts +0 -30
  554. package/src/app/shared/material/numpad/numpad.module.d.ts +0 -16
  555. package/src/app/shared/material/numpad/testing/numpad.test.d.ts +0 -13
@@ -11,6 +11,8 @@ import { fadeInAnimation, slideUpDownAnimation } from '../../shared/material/mat
11
11
  import { isNotNil, isNotNilOrBlank, toBoolean } from '../../shared/functions';
12
12
  import { ENVIRONMENT } from '../../../environments/environment.class';
13
13
  import { CORE_CONFIG_OPTIONS } from '../services/config/core.config';
14
+ import { RxState } from '@rx-angular/state';
15
+ import { ImagesUtils } from '../../shared/file/images.utils';
14
16
  import * as i0 from "@angular/core";
15
17
  import * as i1 from "../services/account.service";
16
18
  import * as i2 from "@ionic/angular";
@@ -27,15 +29,20 @@ import * as i12 from "@angular/material/menu";
27
29
  import * as i13 from "../../shared/toolbar/toolbar";
28
30
  import * as i14 from "@angular/router";
29
31
  import * as i15 from "../install/install-upgrade-card.component";
30
- import * as i16 from "../../shared/pipes/date-format.pipe";
31
- import * as i17 from "../../shared/pipes/date-from-now.pipe";
32
- import * as i18 from "../../../environments/environment.class";
33
- export const getRandomImage = (files) => {
34
- const imgIndex = Math.floor(Math.random() * files.length);
35
- return files[imgIndex];
36
- };
32
+ import * as i16 from "@rx-angular/template/push";
33
+ import * as i17 from "../../shared/pipes/date-format.pipe";
34
+ import * as i18 from "../../shared/pipes/date-from-now.pipe";
35
+ import * as i19 from "../../shared/pipes/arrays.pipe";
36
+ import * as i20 from "../../shared/pipes/string.pipes";
37
+ import * as i21 from "../../../environments/environment.class";
38
+ /**
39
+ * @param files
40
+ * @deprecated use `getRandomImageWithCredit()` instead
41
+ **/
42
+ export const getRandomImage = ImagesUtils.getRandomImage;
43
+ export const getRandomImageWithCredit = ImagesUtils.getRandomImageWithCredit;
37
44
  export const APP_HOME_BUTTONS = new InjectionToken('homeButton');
38
- export class HomePage {
45
+ export class HomePage extends RxState {
39
46
  accountService;
40
47
  modalCtrl;
41
48
  translate;
@@ -51,13 +58,12 @@ export class HomePage {
51
58
  _debug;
52
59
  _subscription = new Subscription();
53
60
  _config;
54
- loading = true;
61
+ pageHistory$ = this.select('pageHistory');
62
+ loading$ = this.select('loading');
55
63
  waitingNetwork = false;
56
- showSpinner = true;
57
64
  accountName = '';
58
65
  isLogin;
59
66
  $partners = new BehaviorSubject(null);
60
- loadingBanner = true;
61
67
  logo;
62
68
  description;
63
69
  appName;
@@ -65,15 +71,38 @@ export class HomePage {
65
71
  canRegister;
66
72
  contentStyle;
67
73
  contentCredits;
68
- pageHistory = [];
69
74
  offline;
70
75
  $filteredButtons = new BehaviorSubject(undefined);
71
76
  showAccountButton;
77
+ set pageHistory(value) {
78
+ this.set('pageHistory', () => value);
79
+ }
80
+ get pageHistory() {
81
+ return this.get('pageHistory');
82
+ }
83
+ set loading(value) {
84
+ this.set('loading', () => value);
85
+ }
86
+ get loading() {
87
+ return this.get('loading');
88
+ }
89
+ set showSpinner(value) {
90
+ this.set('showSpinner', () => value);
91
+ }
92
+ get showSpinner() {
93
+ return this.get('showSpinner');
94
+ }
95
+ set showPartnerBanner(value) {
96
+ this.set('showPartnerBanner', () => value);
97
+ }
98
+ get showPartnerBanner() {
99
+ return this.get('showPartnerBanner');
100
+ }
72
101
  get currentLocaleCode() {
73
- return this.loading ? '' :
74
- (this.translate.currentLang || this.translate.defaultLang || this.environment.defaultLocale)?.substring(0, 2);
102
+ return this.loading ? '' : (this.translate.currentLang || this.translate.defaultLang || this.environment.defaultLocale)?.substring(0, 2);
75
103
  }
76
104
  constructor(accountService, modalCtrl, translate, toastController, configService, platform, cd, network, settings, environment, locales, buttons) {
105
+ super();
77
106
  this.accountService = accountService;
78
107
  this.modalCtrl = modalCtrl;
79
108
  this.translate = translate;
@@ -86,8 +115,12 @@ export class HomePage {
86
115
  this.environment = environment;
87
116
  this.locales = locales;
88
117
  this.buttons = buttons;
118
+ this.set({
119
+ loading: true,
120
+ showPartnerBanner: false,
121
+ showSpinner: !this.platform.started,
122
+ });
89
123
  this._debug = !environment.production;
90
- this.showSpinner = !this.platform.started;
91
124
  this.platform.ready().then(() => this.start());
92
125
  this.showAccountButton = toBoolean(environment.account?.showAccountButton, true);
93
126
  }
@@ -96,14 +129,14 @@ export class HomePage {
96
129
  }
97
130
  async login() {
98
131
  const modal = await this.modalCtrl.create({
99
- component: AppAuthModal
132
+ component: AppAuthModal,
100
133
  });
101
134
  return modal.present();
102
135
  }
103
136
  async register() {
104
137
  const modal = await this.modalCtrl.create({
105
138
  component: RegisterModal,
106
- backdropDismiss: false
139
+ backdropDismiss: false,
107
140
  });
108
141
  return modal.present();
109
142
  }
@@ -115,8 +148,7 @@ export class HomePage {
115
148
  }
116
149
  }
117
150
  changeLanguage(locale) {
118
- this.settings.apply({ locale })
119
- .then(() => {
151
+ this.settings.apply({ locale }).then(() => {
120
152
  this.markForCheck();
121
153
  });
122
154
  }
@@ -126,10 +158,11 @@ export class HomePage {
126
158
  tryOnline() {
127
159
  this.waitingNetwork = true;
128
160
  this.markForCheck();
129
- this.network.tryOnline({
161
+ this.network
162
+ .tryOnline({
130
163
  showLoadingToast: false,
131
164
  showOnlineToast: true,
132
- showOfflineToast: false
165
+ showOfflineToast: false,
133
166
  })
134
167
  .then(() => {
135
168
  this.waitingNetwork = false;
@@ -145,25 +178,25 @@ export class HomePage {
145
178
  }
146
179
  this.offline = this.network.offline;
147
180
  // Listen login/logout events
148
- this._subscription.add(this.accountService.onLogin.subscribe(account => this.onLogin(account)));
181
+ this._subscription.add(this.accountService.onLogin.subscribe((account) => this.onLogin(account)));
149
182
  this._subscription.add(this.accountService.onLogout.subscribe(() => this.onLogout()));
150
183
  // Listen pod config
151
- this._subscription.add(this.configService.config.subscribe(config => this.onConfigLoaded(config)));
184
+ this._subscription.add(this.configService.config.subscribe((config) => this.onConfigLoaded(config)));
152
185
  // Listen settings changes
153
186
  this._subscription.add(this.settings.onChange
154
187
  .pipe(
155
188
  // Add a delay, to avoid to apply changes to often
156
- debounceTime(3000),
189
+ debounceTime(250),
157
190
  // Start with current settings
158
191
  startWith(await this.settings.ready()))
159
- .subscribe(res => this.onSettingsChanged(res)));
192
+ .subscribe((res) => this.onSettingsChanged(res)));
160
193
  // Listen network changes
161
194
  this._subscription.add(this.network.onNetworkStatusChanges
162
195
  .pipe(
163
196
  //debounceTime(450),
164
197
  //tap(() => this.waitingNetwork = false),
165
- map(connectionType => connectionType === 'none'), distinctUntilChanged())
166
- .subscribe(offline => {
198
+ map((connectionType) => connectionType === 'none'), distinctUntilChanged())
199
+ .subscribe((offline) => {
167
200
  this.offline = offline;
168
201
  this.markForCheck();
169
202
  }));
@@ -179,45 +212,38 @@ export class HomePage {
179
212
  this.description = config.name;
180
213
  this.isWeb = this.platform.isWeb();
181
214
  this.canRegister = config.getPropertyAsBoolean(CORE_CONFIG_OPTIONS.REGISTRATION_ENABLE);
182
- const partners = (config.partners || []).filter(p => p && p.logo);
215
+ const partners = (config.partners || []).filter((p) => p && p.logo);
183
216
  this.$partners.next(partners);
184
- this.loadingBanner = (partners.length === 0);
217
+ this.showPartnerBanner = partners.length > 0;
185
218
  // If not already set, compute the background image
186
219
  if (!this.contentStyle) {
187
220
  const backgroundImages = (config.backgroundImages || [])
188
221
  // Filter on not nil, because can occur if detected has not exists (see config-service.js)
189
- .filter(img => isNotNil(img)
222
+ .filter((img) => isNotNil(img) &&
190
223
  // If offline, filter on local dataURL image
191
- && (!this.offline || !img.startsWith('http')));
224
+ (!this.offline || !img.startsWith('http')));
192
225
  // Background image found: select one randomly
193
226
  if (backgroundImages.length) {
194
- const bgImage = getRandomImage(backgroundImages)?.split('|');
195
- this.contentStyle = bgImage?.[0] && { 'background-image': `url(${bgImage?.[0]})` } || {};
196
- this.contentCredits = bgImage?.[1];
227
+ const { image, credits } = getRandomImageWithCredit(backgroundImages);
228
+ this.contentStyle = image ? { 'background-image': `url(${image})` } : {};
229
+ this.contentCredits = credits || '';
197
230
  }
198
231
  // Use background color
199
232
  else {
200
- const primaryColor = config.properties && config.properties['sumaris.color.primary'] || 'var(--ion-color-primary)';
201
- this.contentStyle = primaryColor && { 'background-color': primaryColor } || {};
233
+ const primaryColor = config.getProperty(CORE_CONFIG_OPTIONS.COLOR_PRIMARY) || 'var(--ion-color-primary)';
234
+ this.contentStyle = (primaryColor && { 'background-color': primaryColor }) || {};
202
235
  }
203
236
  }
204
237
  this.refreshButtons();
205
238
  this.markForCheck();
206
239
  // If first load, hide the loading indicator
207
- if (this.loading) {
208
- setTimeout(() => {
209
- this.loading = false;
210
- this.cd.detectChanges();
211
- }, 500); // Add a delay, for animation
212
- }
240
+ this.loading = false;
213
241
  }
214
242
  onSettingsChanged(settings) {
215
243
  if (settings.pageHistory !== this.pageHistory) {
216
244
  console.debug('[home] Page history loaded');
217
245
  this.pageHistory = settings.pageHistory || [];
218
246
  }
219
- // Always force a refresh (same history array, but content may have changed)
220
- this.markForCheck();
221
247
  }
222
248
  onLogin(account) {
223
249
  if (!account)
@@ -245,9 +271,9 @@ export class HomePage {
245
271
  .filter((item) => MenuItems.checkIfVisible(item, account, this._config, {
246
272
  isLogin: this.isLogin,
247
273
  debug: this._debug,
248
- logPrefix: '[home]'
274
+ logPrefix: '[home]',
249
275
  }))
250
- .map(item => {
276
+ .map((item) => {
251
277
  // Replace title using properties
252
278
  if (isNotNilOrBlank(item.titleProperty) && this._config) {
253
279
  const title = this._config.properties[item.titleProperty];
@@ -258,16 +284,19 @@ export class HomePage {
258
284
  });
259
285
  this.$filteredButtons.next(filteredButtons);
260
286
  }
287
+ async removePageHistory(path) {
288
+ await this.settings.removePageHistory(path);
289
+ }
261
290
  markForCheck() {
262
291
  this.cd.markForCheck();
263
292
  }
264
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: HomePage, deps: [{ token: i1.AccountService }, { token: i2.ModalController }, { token: i3.TranslateService }, { token: i2.ToastController }, { token: i4.ConfigService }, { token: i5.PlatformService }, { token: i0.ChangeDetectorRef }, { token: i6.NetworkService }, { token: i7.LocalSettingsService }, { token: ENVIRONMENT }, { token: APP_LOCALES }, { token: APP_HOME_BUTTONS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
265
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: HomePage, selector: "app-page-home", ngImport: i0, template: "<app-toolbar [canGoBack]=\"false\"\n visible-xs visible-sm visible-mobile>\n\n <!-- change locale button -->\n <ion-button slot=\"end\" *ngIf=\"currentLocaleCode; let code\"\n [matMenuTriggerFor]=\"localeMenu\">\n <ion-label class=\"ion-text-uppercase\">&nbsp;{{ code }}</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n</app-toolbar>\n\n<!-- change locale menu -->\n<mat-menu #localeMenu=\"matMenu\">\n <button *ngFor=\"let item of locales\"\n mat-menu-item\n (click)=\"changeLanguage(item.key)\">\n <ion-label>{{item.value}}</ion-label>\n </button>\n</mat-menu>\n\n<ion-content [ngStyle]=\"contentStyle\" no-padding-xs>\n\n <span class=\"content-credits\"><ion-text>{{ contentCredits }}</ion-text></span>\n\n <!-- loading spinner -->\n <div class=\"loading-page\" [class.cdk-visually-hidden]=\"!loading\">\n <div class=\"spinner\" *ngIf=\"loading && showSpinner\">\n <p [innerHTML]=\"'COMMON.LOADING_DOTS'|translate\"></p>\n <div class=\"sk-cube1 sk-cube\"></div>\n <div class=\"sk-cube2 sk-cube\"></div>\n <div class=\"sk-cube4 sk-cube\"></div>\n <div class=\"sk-cube3 sk-cube\"></div>\n </div>\n </div>\n\n <!-- Desktop: translucent top toolbar -->\n <div hidden-xs hidden-sm hidden-mobile>\n <ion-toolbar translucent>\n <ion-buttons slot=\"start\">\n <ion-menu-toggle>\n <ion-button color=\"light\" fill=\"clear\">\n <ion-icon slot=\"icon-only\" name=\"menu\"></ion-icon>\n </ion-button>\n </ion-menu-toggle>\n </ion-buttons>\n\n <ion-buttons slot=\"end\">\n <!-- change locale button -->\n <ion-button color=\"secondary\" fill=\"solid\"\n *ngIf=\"currentLocaleCode; let code\"\n [matMenuTriggerFor]=\"localeMenu\">\n <ion-label class=\"ion-text-uppercase\">&nbsp;{{ code }}</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </div>\n\n <!-- Install (and upgrade) card -->\n <app-install-upgrade-card [isLogin]=\"isLogin\"\n [showInstallButton]=\"true\">\n </app-install-upgrade-card>\n\n <!-- Welcome card -->\n <ion-card *ngIf=\"!loading\"\n class=\"main welcome ion-padding ion-text-center ion-align-self-center\"\n @fadeInAnimation>\n <ion-card-header>\n <ion-card-title class=\"ion-text-center\">\n <span *ngIf=\"isWeb\" [innerHTML]=\"'HOME.WELCOME_WEB'|translate: {appName: appName}\"></span>\n <span *ngIf=\"!isWeb\" [innerHTML]=\"'HOME.WELCOME_APP'|translate: {appName: appName}\"></span>\n </ion-card-title>\n <ion-card-subtitle [innerHTML]=\"description\">\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content class=\"ion-no-padding\">\n <ion-text color=\"primary\">\n <img class=\"logo\" *ngIf=\"logo\" src=\"{{ logo }}\">\n </ion-text>\n <!-- register help text -->\n <ion-text *ngIf=\"!isLogin && canRegister\">\n <br/>\n <span translate>HOME.REGISTER_HELP</span>\n </ion-text>\n <div class=\"ion-padding-top\">\n\n <!-- If NOT login -->\n <ng-container *ngIf=\"!isLogin; else loginButtons;\">\n\n <ion-button *ngIf=\"canRegister\" expand=\"block\" color=\"tertiary\" (click)=\"register()\">\n <span translate>HOME.BTN_REGISTER</span>\n </ion-button>\n <ion-button expand=\"block\" color=\"light\" [routerLink]=\"['/']\" (click)=\"login()\">\n <span translate>AUTH.BTN_LOGIN</span>\n </ion-button>\n\n </ng-container>\n\n <!-- If user login -->\n <ng-template #loginButtons>\n\n <!-- Feature buttons -->\n <ng-container *rxIf=\"$filteredButtons; let buttons\">\n <ng-container *ngFor=\"let item of buttons\">\n <ion-button *ngIf=\"item.path\"\n expand=\"block\" color=\"tertiary\"\n [class]=\"item.cssClass\"\n [routerLink]=\"item.path\"\n routerDirection=\"root\">\n <ion-icon slot=\"start\" class=\"ion-float-start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" class=\"ion-float-start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-text>{{'HOME.BTN_DATA_ENTRY'|translate: {name: (item.title | translate) } }}</ion-text>\n </ion-button>\n\n <!-- divider -->\n <div *ngIf=\"!item.path && !item.action\" [class]=\"item.cssClass\">\n <ion-label translate>{{item.title}}&nbsp;</ion-label>\n </div>\n </ng-container>\n\n <!--<p *ngIf=\"buttons.length\" class=\"visible-mobile\">&nbsp;</p>-->\n </ng-container>\n\n <ion-button *ngIf=\"showAccountButton\" expand=\"block\" color=\"secondary\" [routerLink]=\"['/account']\">\n <ion-icon slot=\"start\" class=\"ion-float-start\" name=\"person-circle\"></ion-icon>\n <ion-text translate>HOME.BTN_MY_ACCOUNT</ion-text>\n </ion-button>\n\n <p hidden-xs hidden-sm hidden-mobile>\n <ion-text [innerHTML]=\"'HOME.NOT_THIS_ACCOUNT_QUESTION' | translate: {displayName: accountName }\"></ion-text>\n <br/>\n <ion-text>\n <a href=\"#\" (click)=\"logout($event)\">\n <span translate>HOME.BTN_DISCONNECT</span>\n </a>\n </ion-text>\n </p>\n\n\n </ng-template>\n\n </div>\n </ion-card-content>\n </ion-card>\n\n <!-- Page history -->\n <ion-grid *ngIf=\"!loading && isLogin && pageHistory.length; else bottomBanner\"\n class=\"history-container ion-align-self-center\">\n <ion-row>\n <ion-col size=\"12\" size-xl=\"\" *ngFor=\"let page of pageHistory; trackBy: getPagePath\"\n class=\"ion-text-center\">\n <ion-card class=\"ion-align-self-start ion-text-start\" @fadeInAnimation>\n <ion-card-header class=\"ion-no-padding\">\n <!-- top bar -->\n <ion-card-subtitle>\n <button type=\"button\" tabindex=\"-1\"\n (click)=\"settings.removePageHistory(page.path)\"\n mat-icon-button class=\"ion-float-start ion-no-margin\">\n <mat-icon>close</mat-icon>\n </button>\n <ion-label [innerHTML]=\"page.subtitle|translate\"></ion-label>\n <ion-text class=\"ion-float-end\" [title]=\"page.time|dateFormat:{time: true}\">\n <small><ion-icon name=\"time-outline\"></ion-icon>&nbsp;{{ page.time|dateFromNow }}</small>&nbsp;\n </ion-text>\n </ion-card-subtitle>\n\n <!-- main page -->\n <ion-card-title class=\"ion-no-margin ion-no-padding\">\n <ion-item detail=\"true\"\n tappable class=\"text-1x\"\n [routerLink]=\"page.path\"\n routerDirection=\"root\" lines=\"none\">\n <!-- page icon-->\n <ion-icon *ngIf=\"page.icon\" slot=\"start\" [name]=\"page.icon\"></ion-icon>\n <mat-icon *ngIf=\"page.matIcon\" slot=\"start\">{{page.matIcon}}</mat-icon>\n\n <ion-label color=\"primary\" [innerHTML]=\"page.title\"></ion-label>\n </ion-item>\n </ion-card-title>\n </ion-card-header>\n\n <!-- children pages -->\n <ion-card-content class=\"ion-no-padding ion-padding-start\" *ngIf=\"page.children?.length\">\n <ion-list class=\"ion-no-padding\">\n <ion-item detail=\"true\"\n *ngFor=\"let childPage of page.children\"\n tappable class=\"text-1x\"\n [routerLink]=\"childPage.path\"\n routerDirection=\"root\">\n <!-- page icon-->\n <ion-icon *ngIf=\"childPage.icon\" slot=\"start\" color=\"dark\" [name]=\"childPage.icon\"></ion-icon>\n <mat-icon *ngIf=\"childPage.matIcon\" slot=\"start\" color=\"dark\">{{childPage.matIcon}}</mat-icon>\n\n <ion-label color=\"dark\" [innerHTML]=\"childPage.title\"></ion-label>\n </ion-item>\n </ion-list>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Display configured Departments logos -->\n <ng-template #bottomBanner>\n <div class=\"bottom-banner ion-text-center ion-padding\" *ngIf=\"!loadingBanner\" @fadeInAnimation>\n <a href=\"{{ item.siteUrl }}\" *ngFor=\"let item of $partners | async \">\n <img class=\"logo\" src=\"{{ item.logo }}\" alt=\"{{item.label}}\" [title]=\"item.label\" />\n </a>\n </div>\n </ng-template>\n\n\n</ion-content>\n", styles: ["h1,h2,h3,h4,h5{white-space:normal}.center,ion-content ion-card.welcome img{text-align:center;display:inline-block}ion-content{--background: transparent;background-size:cover;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;display:inline-block;padding:15px;background-color:var(--ion-color-primary)}ion-content .loading-page{display:block;height:100%;width:100%;position:absolute;background-color:var(--ion-color-primary);z-index:5;transition:background .5s linear;-webkit-transition:background 1.5s linear}ion-content .loading-page.hidden{background-color:rgba(var(--ion-color-primary),0)}ion-content ion-card{z-index:9}ion-content ion-card ion-card-header{display:block}ion-content ion-card ion-card-header ion-card-subtitle,ion-content ion-card ion-card-header ion-card-title{display:block;width:100%}ion-content ion-card.main{min-width:240px;max-width:400px;margin-left:auto;margin-right:auto}ion-content ion-card.welcome{background-color:#ffffffb3}ion-content ion-card.welcome button{margin-top:16px}ion-content ion-card.welcome img{max-width:250px}ion-content .history-container{margin-left:auto;margin-right:auto}ion-content .history-container ion-card{display:inline-block;box-sizing:border-box;z-index:8;min-width:240px;max-width:400px;width:100%;margin-left:auto;margin-right:auto;background-color:#ffffffb3}ion-content .history-container ion-card ion-card-header ion-card-subtitle{height:40px}ion-content .history-container ion-card ion-card-header ion-card-subtitle button[float-start]{z-index:99;margin:0}ion-content .history-container ion-card ion-card-header ion-card-subtitle ion-label{line-height:40px}ion-content .history-container ion-card ion-card-header ion-card-subtitle ion-label[float-end]{padding-right:16px;font-weight:400}ion-content .history-container ion-card ion-card-header ion-card-title ion-item{--ion-item-background: $transparent;--ion-item-icon-color: var(--ion-color-primary);--ion-item-text-color: var(--ion-color-primary)}ion-content .history-container ion-card ion-card-header ion-card-title ion-item ion-icon[slot=start],ion-content .history-container ion-card ion-card-header ion-card-title ion-item mat-icon[slot=start]{margin-right:unset;margin-inline-end:16px!important;color:var(--ion-item-icon-color)!important;fill:currentColor;stroke:currentColor}ion-content .history-container ion-card ion-card-header ion-card-title ion-item ion-text,ion-content .history-container ion-card ion-card-header ion-card-title ion-item ion-label{color:var(--ion-item-text-color)!important;-webkit-text-size-adjust:100%;text-size-adjust:100%}ion-content .history-container ion-card ion-card-content ion-list{--ion-item-background: var(--ion-color-transparent)}ion-content .history-container ion-card ion-card-content ion-list ion-item{--ion-item-icon-color: var(--ion-color-dark);--ion-item-text-color: var(--ion-color-dark)}ion-content .history-container ion-card ion-card-content ion-list ion-item ion-icon[slot=start],ion-content .history-container ion-card ion-card-content ion-list ion-item mat-icon[slot=start]{color:var(--ion-item-icon-color)!important;fill:currentColor;stroke:currentColor;margin-right:unset;margin-inline-end:16px!important}ion-content .history-container ion-card ion-card-content ion-list ion-item ion-text,ion-content .history-container ion-card ion-card-content ion-list ion-item ion-label{color:var(--ion-item-text-color)!important}ion-content .bottom-banner{background-color:#ffffffb3;min-width:240px;z-index:0;position:absolute;left:16px;right:16px;bottom:16px}ion-content .bottom-banner img.logo{max-height:50px;margin-left:8px}ion-content ion-text{text-align:center}@media screen and (max-width: 575px){ion-content ion-card{min-width:160px;width:calc(100% - 20px);max-width:100%;margin-left:10px;margin-right:10px}ion-content ion-card h1{margin-top:0;font-size:20px}ion-content ion-card ion-card-content ion-button{margin-top:8px}ion-content .bottom-banner{display:block;position:unset}ion-content .bottom-banner img.logo{max-height:30px}}@media screen and (max-width: 767px) and (min-width: 576px){ion-content{min-height:555px}ion-content .bottom-banner img.logo{max-height:40px}}@media screen and (min-width: 768px){ion-content{min-height:calc(100% - 100px)}}.content-credits{position:absolute;right:5px;bottom:5px}\n"], dependencies: [{ kind: "directive", type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i8.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i2.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i2.IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonMenuToggle, selector: "ion-menu-toggle", inputs: ["autoHide", "menu"] }, { kind: "component", type: i2.IonRow, selector: "ion-row" }, { kind: "component", type: i2.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "directive", type: i2.RouterLinkDelegate, selector: ":not(a):not(area)[routerLink]" }, { kind: "directive", type: i3.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i9.RxIf, selector: "[rxIf]", inputs: ["rxIf", "rxIfStrategy", "rxIfElse", "rxIfThen", "rxIfSuspense", "rxIfComplete", "rxIfError", "rxIfContextTrigger", "rxIfNextTrigger", "rxIfSuspenseTrigger", "rxIfErrorTrigger", "rxIfCompleteTrigger", "rxIfParent", "rxIfPatchZone", "rxIfRenderCallback"] }, { kind: "component", type: i10.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i12.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i12.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i12.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i13.ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "directive", type: i14.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i15.AppInstallUpgradeCard, selector: "app-install-upgrade-card", inputs: ["isLogin", "showUpgradeWarning", "showOfflineWarning", "showInstallButton"] }, { kind: "pipe", type: i8.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "pipe", type: i16.DateFormatPipe, name: "dateFormat" }, { kind: "pipe", type: i17.DateFromNowPipe, name: "dateFromNow" }], animations: [fadeInAnimation, slideUpDownAnimation], changeDetection: i0.ChangeDetectionStrategy.OnPush });
293
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: HomePage, deps: [{ token: i1.AccountService }, { token: i2.ModalController }, { token: i3.TranslateService }, { token: i2.ToastController }, { token: i4.ConfigService }, { token: i5.PlatformService }, { token: i0.ChangeDetectorRef }, { token: i6.NetworkService }, { token: i7.LocalSettingsService }, { token: ENVIRONMENT }, { token: APP_LOCALES }, { token: APP_HOME_BUTTONS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
294
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.8", type: HomePage, selector: "app-page-home", usesInheritance: true, ngImport: i0, template: "<app-toolbar [canGoBack]=\"false\" visible-xs visible-sm visible-mobile>\n <!-- change locale button -->\n <ion-button slot=\"end\" *ngIf=\"currentLocaleCode; let code\" [matMenuTriggerFor]=\"localeMenu\">\n <ion-icon slot=\"icon-only\" name=\"language\"></ion-icon>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n</app-toolbar>\n\n<!-- change locale menu -->\n<mat-menu #localeMenu=\"matMenu\">\n <button *ngFor=\"let item of locales\" mat-menu-item (click)=\"changeLanguage(item.key)\">\n <ion-label>{{ item.value }}</ion-label>\n </button>\n</mat-menu>\n\n<ion-content [ngStyle]=\"contentStyle\" no-padding-xs>\n @if (contentCredits | isNotNilOrBlank) {\n <span class=\"content-credits\">\n <ion-text>{{ contentCredits }}</ion-text>\n </span>\n }\n\n <!-- loading spinner -->\n <div class=\"loading-page\" [class.cdk-visually-hidden]=\"!(loading$ | push)\">\n @if (showSpinner) {\n <div class=\"spinner\">\n <p [innerHTML]=\"'COMMON.LOADING_DOTS' | translate\"></p>\n <div class=\"sk-cube1 sk-cube\"></div>\n <div class=\"sk-cube2 sk-cube\"></div>\n <div class=\"sk-cube4 sk-cube\"></div>\n <div class=\"sk-cube3 sk-cube\"></div>\n </div>\n }\n </div>\n\n <!-- Desktop: translucent top toolbar -->\n <div hidden-xs hidden-sm hidden-mobile>\n <ion-toolbar translucent>\n <ion-buttons slot=\"start\">\n <ion-menu-toggle>\n <ion-button color=\"light\" fill=\"clear\">\n <ion-icon slot=\"icon-only\" name=\"menu\"></ion-icon>\n </ion-button>\n </ion-menu-toggle>\n </ion-buttons>\n\n <ion-buttons slot=\"end\">\n <!-- change locale button -->\n @if (currentLocaleCode; as code) {\n <ion-button\n color=\"secondary\"\n fill=\"solid\"\n [matMenuTriggerFor]=\"localeMenu\"\n [title]=\"'SETTINGS.LOCALE' | translate\"\n >\n <ion-icon slot=\"icon-only\" name=\"language\"></ion-icon>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n }\n </ion-buttons>\n </ion-toolbar>\n </div>\n\n <!-- Install (and upgrade) card -->\n <app-install-upgrade-card [isLogin]=\"isLogin\" [showInstallButton]=\"true\"></app-install-upgrade-card>\n\n @if (!(loading$ | push)) {\n <!-- Welcome card -->\n <ion-card class=\"main welcome ion-padding ion-text-center ion-align-self-center\" @fadeInAnimation>\n <ion-card-header>\n <ion-card-title class=\"ion-text-center\">\n <span *ngIf=\"isWeb\" [innerHTML]=\"'HOME.WELCOME_WEB' | translate: { appName: appName }\"></span>\n <span *ngIf=\"!isWeb\" [innerHTML]=\"'HOME.WELCOME_APP' | translate: { appName: appName }\"></span>\n </ion-card-title>\n <ion-card-subtitle [innerHTML]=\"description\"></ion-card-subtitle>\n </ion-card-header>\n <ion-card-content class=\"ion-no-padding\">\n <ion-text color=\"primary\">\n <img *ngIf=\"logo\" [attr.src]=\"logo\" alt=\"Logo\" />\n </ion-text>\n <!-- register help text -->\n <ion-text *ngIf=\"!isLogin && canRegister\">\n <br />\n <span translate>HOME.REGISTER_HELP</span>\n </ion-text>\n <div class=\"ion-padding-top\">\n <!-- If NOT login -->\n <ng-container *ngIf=\"!isLogin; else loginButtons\">\n <ion-button *ngIf=\"canRegister\" expand=\"block\" color=\"tertiary\" (click)=\"register()\">\n <span translate>HOME.BTN_REGISTER</span>\n </ion-button>\n <ion-button expand=\"block\" color=\"light\" [routerLink]=\"['/']\" (click)=\"login()\">\n <span translate>AUTH.BTN_LOGIN</span>\n </ion-button>\n </ng-container>\n\n <!-- If user login -->\n <ng-template #loginButtons>\n <!-- Feature buttons -->\n <ng-container *rxIf=\"$filteredButtons; let buttons\">\n <ng-container *ngFor=\"let item of buttons\">\n <ion-button\n *ngIf=\"item.path\"\n expand=\"block\"\n color=\"tertiary\"\n [class]=\"item.cssClass\"\n [routerLink]=\"item.path\"\n routerDirection=\"root\"\n >\n <ion-icon slot=\"start\" class=\"ion-float-start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" class=\"ion-float-start\" *ngIf=\"item.matIcon\">{{ item.matIcon }}</mat-icon>\n <ion-text>{{ 'HOME.BTN_DATA_ENTRY' | translate: { name: (item.title | translate) } }}</ion-text>\n </ion-button>\n\n <!-- divider -->\n <div *ngIf=\"!item.path && !item.action\" [class]=\"item.cssClass\">\n <ion-label translate>{{ item.title }}&nbsp;</ion-label>\n </div>\n </ng-container>\n\n <!--<p *ngIf=\"buttons.length\" class=\"visible-mobile\">&nbsp;</p>-->\n </ng-container>\n\n <ion-button *ngIf=\"showAccountButton\" expand=\"block\" color=\"secondary\" [routerLink]=\"['/account']\">\n <ion-icon slot=\"start\" class=\"ion-float-start\" name=\"person-circle\"></ion-icon>\n <ion-text translate>HOME.BTN_MY_ACCOUNT</ion-text>\n </ion-button>\n\n <p hidden-xs hidden-sm hidden-mobile>\n <ion-text\n [innerHTML]=\"'HOME.NOT_THIS_ACCOUNT_QUESTION' | translate: { displayName: accountName }\"\n ></ion-text>\n <br />\n <ion-text>\n <a href=\"#\" (click)=\"logout($event)\">\n <span translate>HOME.BTN_DISCONNECT</span>\n </a>\n </ion-text>\n </p>\n </ng-template>\n </div>\n </ion-card-content>\n </ion-card>\n\n <!-- Page history -->\n @if (isLogin && (pageHistory$ | push); as pageHistory) {\n <ion-grid class=\"history-container ion-align-self-center\">\n <ion-row>\n @for (page of pageHistory; track page.path) {\n <ion-col size=\"12\" size-xl=\"\" class=\"ion-text-center\">\n <ion-card class=\"ion-align-self-start ion-text-start\" @fadeInAnimation>\n <ion-card-header class=\"ion-no-padding\">\n <!-- top bar -->\n <ion-card-subtitle>\n <button\n type=\"button\"\n tabindex=\"-1\"\n (click)=\"removePageHistory(page.path)\"\n mat-icon-button\n class=\"ion-float-start ion-no-margin close-button\"\n >\n <mat-icon>close</mat-icon>\n </button>\n <ion-label [innerHTML]=\"page.subtitle | translate\"></ion-label>\n <ion-text class=\"ion-float-end\" [title]=\"page.time | dateFormat: { time: true }\">\n <small>\n <ion-icon name=\"time-outline\"></ion-icon>\n &nbsp;{{ page.time | dateFromNow }}\n </small>\n &nbsp;\n </ion-text>\n </ion-card-subtitle>\n\n <!-- main page -->\n <ion-card-title class=\"ion-no-margin ion-no-padding\">\n <ion-item\n detail=\"true\"\n tappable\n class=\"text-1x\"\n [routerLink]=\"page.path\"\n routerDirection=\"root\"\n lines=\"none\"\n >\n <!-- page icon-->\n <ion-icon *ngIf=\"page.icon\" slot=\"start\" [name]=\"page.icon\"></ion-icon>\n <mat-icon *ngIf=\"page.matIcon\" slot=\"start\">{{ page.matIcon }}</mat-icon>\n\n <ion-label color=\"primary\" [innerHTML]=\"page.title\"></ion-label>\n </ion-item>\n </ion-card-title>\n </ion-card-header>\n\n <!-- children pages -->\n @if (page.children | isNotEmptyArray) {\n <ion-card-content class=\"ion-no-padding ion-padding-start\">\n <ion-list class=\"ion-no-padding\">\n @for (childPage of page.children; track childPage.path) {\n <ion-item\n detail=\"true\"\n tappable\n class=\"text-1x\"\n [routerLink]=\"childPage.path\"\n routerDirection=\"root\"\n >\n <!-- page icon-->\n <ion-icon *ngIf=\"childPage.icon\" slot=\"start\" color=\"dark\" [name]=\"childPage.icon\"></ion-icon>\n <mat-icon *ngIf=\"childPage.matIcon\" slot=\"start\" color=\"dark\">\n {{ childPage.matIcon }}\n </mat-icon>\n\n <ion-label color=\"dark\" [innerHTML]=\"childPage.title\"></ion-label>\n </ion-item>\n }\n </ion-list>\n </ion-card-content>\n }\n </ion-card>\n </ion-col>\n }\n </ion-row>\n </ion-grid>\n } @else if (showPartnerBanner) {\n <!-- Display partners logos -->\n <div class=\"bottom-banner ion-text-center ion-padding\" @fadeInAnimation>\n @for (item of $partners | async; track $index) {\n <a href=\"{{ item.siteUrl }}\">\n <img class=\"logo\" src=\"{{ item.logo }}\" alt=\"{{ item.label }}\" [title]=\"item.label\" />\n </a>\n }\n </div>\n }\n }\n</ion-content>\n", styles: ["h1,h2,h3,h4,h5{white-space:normal}.center,ion-content ion-card.welcome img{text-align:center;display:inline-block}ion-content{--background: transparent;background-size:cover;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-color:var(--ion-background-color);display:inline-block;padding:15px}ion-content .loading-page{display:block;height:100%;width:100%;position:absolute;background-color:var(--ion-background-color);z-index:5;transition:background .5s linear;-webkit-transition:background 1.5s linear}ion-content .loading-page.hidden{background-color:rgba(var(--ion-color-primary),0)}ion-content ion-card{z-index:9}ion-content ion-card ion-card-header{display:block}ion-content ion-card ion-card-header ion-card-subtitle,ion-content ion-card ion-card-header ion-card-title{display:block;width:100%}ion-content ion-card.main{min-width:240px;max-width:400px;margin-left:auto;margin-right:auto}ion-content ion-card.welcome{background-color:var(--ion-card-background-color)}ion-content ion-card.welcome button{margin-top:16px}ion-content ion-card.welcome img{max-width:250px}ion-content .history-container{margin-left:auto;margin-right:auto}ion-content .history-container ion-card{display:inline-block;box-sizing:border-box;z-index:8;min-width:240px;max-width:400px;width:100%;margin-left:auto;margin-right:auto;background-color:var(--ion-card-background-color)}ion-content .history-container ion-card ion-card-header ion-card-subtitle{height:40px}ion-content .history-container ion-card ion-card-header ion-card-subtitle button[float-start]{--mdc-icon-button-state-layer-size: 40px;padding:8px;z-index:99;margin:0}ion-content .history-container ion-card ion-card-header ion-card-subtitle ion-label{line-height:40px}ion-content .history-container ion-card ion-card-header ion-card-subtitle ion-label[float-end]{padding-right:16px;font-weight:400}ion-content .history-container ion-card ion-card-header ion-card-title ion-item{width:100%;--ion-item-background: $transparent;--ion-item-icon-color: var(--ion-color-primary);--ion-item-text-color: var(--ion-color-primary)}ion-content .history-container ion-card ion-card-header ion-card-title ion-item ion-icon[slot=start],ion-content .history-container ion-card ion-card-header ion-card-title ion-item mat-icon[slot=start]{margin-right:unset;margin-inline-end:16px!important;color:var(--ion-item-icon-color)!important;fill:currentColor;stroke:currentColor}ion-content .history-container ion-card ion-card-header ion-card-title ion-item ion-text,ion-content .history-container ion-card ion-card-header ion-card-title ion-item ion-label{color:var(--ion-item-text-color)!important;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%}ion-content .history-container ion-card ion-card-content ion-list{--ion-item-background: var(--ion-color-transparent)}ion-content .history-container ion-card ion-card-content ion-list ion-item{--ion-item-icon-color: var(--ion-color-dark);--ion-item-text-color: var(--ion-color-dark)}ion-content .history-container ion-card ion-card-content ion-list ion-item ion-icon[slot=start],ion-content .history-container ion-card ion-card-content ion-list ion-item mat-icon[slot=start]{color:var(--ion-item-icon-color)!important;fill:currentColor;stroke:currentColor;margin-right:unset;margin-inline-end:16px!important}ion-content .history-container ion-card ion-card-content ion-list ion-item ion-text,ion-content .history-container ion-card ion-card-content ion-list ion-item ion-label{color:var(--ion-item-text-color)!important}ion-content .bottom-banner{background-color:var(--ion-card-background-color);min-width:240px;z-index:0;position:absolute;left:16px;right:16px;bottom:16px}ion-content .bottom-banner img.logo{max-height:50px;margin-left:8px}ion-content ion-text{text-align:center}@media screen and (max-width: 575px){ion-content ion-card{min-width:160px;width:calc(100% - 20px);max-width:100%;margin-left:10px;margin-right:10px}ion-content ion-card h1{margin-top:0;font-size:20px}ion-content ion-card ion-card-content ion-button{margin-top:8px}ion-content .bottom-banner{display:block;position:unset}ion-content .bottom-banner img.logo{max-height:30px}}@media screen and (max-width: 767px) and (min-width: 576px){ion-content{min-height:555px}ion-content .bottom-banner img.logo{max-height:40px}}@media screen and (min-width: 768px){ion-content{min-height:calc(100% - 100px)}}.content-credits{position:absolute;right:5px;bottom:5px}.content-credits ion-text{padding-inline-start:4px;padding-inline-end:4px;font-size:.8rem;background-color:var(--ion-background-color, white);color:var(--ion-text-color);opacity:.65}\n"], dependencies: [{ kind: "directive", type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i8.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i2.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i2.IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonMenuToggle, selector: "ion-menu-toggle", inputs: ["autoHide", "menu"] }, { kind: "component", type: i2.IonRow, selector: "ion-row" }, { kind: "component", type: i2.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "directive", type: i2.RouterLinkDelegate, selector: ":not(a):not(area)[routerLink]" }, { kind: "directive", type: i3.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i9.RxIf, selector: "[rxIf]", inputs: ["rxIf", "rxIfStrategy", "rxIfElse", "rxIfThen", "rxIfSuspense", "rxIfComplete", "rxIfError", "rxIfContextTrigger", "rxIfNextTrigger", "rxIfSuspenseTrigger", "rxIfErrorTrigger", "rxIfCompleteTrigger", "rxIfParent", "rxIfPatchZone", "rxIfRenderCallback"] }, { kind: "component", type: i10.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i12.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i12.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i12.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i13.ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "directive", type: i14.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i15.AppInstallUpgradeCard, selector: "app-install-upgrade-card", inputs: ["isLogin", "showUpgradeWarning", "showOfflineWarning", "showInstallButton"] }, { kind: "pipe", type: i8.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "pipe", type: i16.RxPush, name: "push" }, { kind: "pipe", type: i17.DateFormatPipe, name: "dateFormat" }, { kind: "pipe", type: i18.DateFromNowPipe, name: "dateFromNow" }, { kind: "pipe", type: i19.NotEmptyArrayPipe, name: "isNotEmptyArray" }, { kind: "pipe", type: i20.IsNotNilOrBlankPipe, name: "isNotNilOrBlank" }], animations: [fadeInAnimation, slideUpDownAnimation], changeDetection: i0.ChangeDetectionStrategy.OnPush });
266
295
  }
267
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: HomePage, decorators: [{
296
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: HomePage, decorators: [{
268
297
  type: Component,
269
- args: [{ selector: 'app-page-home', changeDetection: ChangeDetectionStrategy.OnPush, animations: [fadeInAnimation, slideUpDownAnimation], template: "<app-toolbar [canGoBack]=\"false\"\n visible-xs visible-sm visible-mobile>\n\n <!-- change locale button -->\n <ion-button slot=\"end\" *ngIf=\"currentLocaleCode; let code\"\n [matMenuTriggerFor]=\"localeMenu\">\n <ion-label class=\"ion-text-uppercase\">&nbsp;{{ code }}</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n</app-toolbar>\n\n<!-- change locale menu -->\n<mat-menu #localeMenu=\"matMenu\">\n <button *ngFor=\"let item of locales\"\n mat-menu-item\n (click)=\"changeLanguage(item.key)\">\n <ion-label>{{item.value}}</ion-label>\n </button>\n</mat-menu>\n\n<ion-content [ngStyle]=\"contentStyle\" no-padding-xs>\n\n <span class=\"content-credits\"><ion-text>{{ contentCredits }}</ion-text></span>\n\n <!-- loading spinner -->\n <div class=\"loading-page\" [class.cdk-visually-hidden]=\"!loading\">\n <div class=\"spinner\" *ngIf=\"loading && showSpinner\">\n <p [innerHTML]=\"'COMMON.LOADING_DOTS'|translate\"></p>\n <div class=\"sk-cube1 sk-cube\"></div>\n <div class=\"sk-cube2 sk-cube\"></div>\n <div class=\"sk-cube4 sk-cube\"></div>\n <div class=\"sk-cube3 sk-cube\"></div>\n </div>\n </div>\n\n <!-- Desktop: translucent top toolbar -->\n <div hidden-xs hidden-sm hidden-mobile>\n <ion-toolbar translucent>\n <ion-buttons slot=\"start\">\n <ion-menu-toggle>\n <ion-button color=\"light\" fill=\"clear\">\n <ion-icon slot=\"icon-only\" name=\"menu\"></ion-icon>\n </ion-button>\n </ion-menu-toggle>\n </ion-buttons>\n\n <ion-buttons slot=\"end\">\n <!-- change locale button -->\n <ion-button color=\"secondary\" fill=\"solid\"\n *ngIf=\"currentLocaleCode; let code\"\n [matMenuTriggerFor]=\"localeMenu\">\n <ion-label class=\"ion-text-uppercase\">&nbsp;{{ code }}</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </div>\n\n <!-- Install (and upgrade) card -->\n <app-install-upgrade-card [isLogin]=\"isLogin\"\n [showInstallButton]=\"true\">\n </app-install-upgrade-card>\n\n <!-- Welcome card -->\n <ion-card *ngIf=\"!loading\"\n class=\"main welcome ion-padding ion-text-center ion-align-self-center\"\n @fadeInAnimation>\n <ion-card-header>\n <ion-card-title class=\"ion-text-center\">\n <span *ngIf=\"isWeb\" [innerHTML]=\"'HOME.WELCOME_WEB'|translate: {appName: appName}\"></span>\n <span *ngIf=\"!isWeb\" [innerHTML]=\"'HOME.WELCOME_APP'|translate: {appName: appName}\"></span>\n </ion-card-title>\n <ion-card-subtitle [innerHTML]=\"description\">\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content class=\"ion-no-padding\">\n <ion-text color=\"primary\">\n <img class=\"logo\" *ngIf=\"logo\" src=\"{{ logo }}\">\n </ion-text>\n <!-- register help text -->\n <ion-text *ngIf=\"!isLogin && canRegister\">\n <br/>\n <span translate>HOME.REGISTER_HELP</span>\n </ion-text>\n <div class=\"ion-padding-top\">\n\n <!-- If NOT login -->\n <ng-container *ngIf=\"!isLogin; else loginButtons;\">\n\n <ion-button *ngIf=\"canRegister\" expand=\"block\" color=\"tertiary\" (click)=\"register()\">\n <span translate>HOME.BTN_REGISTER</span>\n </ion-button>\n <ion-button expand=\"block\" color=\"light\" [routerLink]=\"['/']\" (click)=\"login()\">\n <span translate>AUTH.BTN_LOGIN</span>\n </ion-button>\n\n </ng-container>\n\n <!-- If user login -->\n <ng-template #loginButtons>\n\n <!-- Feature buttons -->\n <ng-container *rxIf=\"$filteredButtons; let buttons\">\n <ng-container *ngFor=\"let item of buttons\">\n <ion-button *ngIf=\"item.path\"\n expand=\"block\" color=\"tertiary\"\n [class]=\"item.cssClass\"\n [routerLink]=\"item.path\"\n routerDirection=\"root\">\n <ion-icon slot=\"start\" class=\"ion-float-start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" class=\"ion-float-start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-text>{{'HOME.BTN_DATA_ENTRY'|translate: {name: (item.title | translate) } }}</ion-text>\n </ion-button>\n\n <!-- divider -->\n <div *ngIf=\"!item.path && !item.action\" [class]=\"item.cssClass\">\n <ion-label translate>{{item.title}}&nbsp;</ion-label>\n </div>\n </ng-container>\n\n <!--<p *ngIf=\"buttons.length\" class=\"visible-mobile\">&nbsp;</p>-->\n </ng-container>\n\n <ion-button *ngIf=\"showAccountButton\" expand=\"block\" color=\"secondary\" [routerLink]=\"['/account']\">\n <ion-icon slot=\"start\" class=\"ion-float-start\" name=\"person-circle\"></ion-icon>\n <ion-text translate>HOME.BTN_MY_ACCOUNT</ion-text>\n </ion-button>\n\n <p hidden-xs hidden-sm hidden-mobile>\n <ion-text [innerHTML]=\"'HOME.NOT_THIS_ACCOUNT_QUESTION' | translate: {displayName: accountName }\"></ion-text>\n <br/>\n <ion-text>\n <a href=\"#\" (click)=\"logout($event)\">\n <span translate>HOME.BTN_DISCONNECT</span>\n </a>\n </ion-text>\n </p>\n\n\n </ng-template>\n\n </div>\n </ion-card-content>\n </ion-card>\n\n <!-- Page history -->\n <ion-grid *ngIf=\"!loading && isLogin && pageHistory.length; else bottomBanner\"\n class=\"history-container ion-align-self-center\">\n <ion-row>\n <ion-col size=\"12\" size-xl=\"\" *ngFor=\"let page of pageHistory; trackBy: getPagePath\"\n class=\"ion-text-center\">\n <ion-card class=\"ion-align-self-start ion-text-start\" @fadeInAnimation>\n <ion-card-header class=\"ion-no-padding\">\n <!-- top bar -->\n <ion-card-subtitle>\n <button type=\"button\" tabindex=\"-1\"\n (click)=\"settings.removePageHistory(page.path)\"\n mat-icon-button class=\"ion-float-start ion-no-margin\">\n <mat-icon>close</mat-icon>\n </button>\n <ion-label [innerHTML]=\"page.subtitle|translate\"></ion-label>\n <ion-text class=\"ion-float-end\" [title]=\"page.time|dateFormat:{time: true}\">\n <small><ion-icon name=\"time-outline\"></ion-icon>&nbsp;{{ page.time|dateFromNow }}</small>&nbsp;\n </ion-text>\n </ion-card-subtitle>\n\n <!-- main page -->\n <ion-card-title class=\"ion-no-margin ion-no-padding\">\n <ion-item detail=\"true\"\n tappable class=\"text-1x\"\n [routerLink]=\"page.path\"\n routerDirection=\"root\" lines=\"none\">\n <!-- page icon-->\n <ion-icon *ngIf=\"page.icon\" slot=\"start\" [name]=\"page.icon\"></ion-icon>\n <mat-icon *ngIf=\"page.matIcon\" slot=\"start\">{{page.matIcon}}</mat-icon>\n\n <ion-label color=\"primary\" [innerHTML]=\"page.title\"></ion-label>\n </ion-item>\n </ion-card-title>\n </ion-card-header>\n\n <!-- children pages -->\n <ion-card-content class=\"ion-no-padding ion-padding-start\" *ngIf=\"page.children?.length\">\n <ion-list class=\"ion-no-padding\">\n <ion-item detail=\"true\"\n *ngFor=\"let childPage of page.children\"\n tappable class=\"text-1x\"\n [routerLink]=\"childPage.path\"\n routerDirection=\"root\">\n <!-- page icon-->\n <ion-icon *ngIf=\"childPage.icon\" slot=\"start\" color=\"dark\" [name]=\"childPage.icon\"></ion-icon>\n <mat-icon *ngIf=\"childPage.matIcon\" slot=\"start\" color=\"dark\">{{childPage.matIcon}}</mat-icon>\n\n <ion-label color=\"dark\" [innerHTML]=\"childPage.title\"></ion-label>\n </ion-item>\n </ion-list>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Display configured Departments logos -->\n <ng-template #bottomBanner>\n <div class=\"bottom-banner ion-text-center ion-padding\" *ngIf=\"!loadingBanner\" @fadeInAnimation>\n <a href=\"{{ item.siteUrl }}\" *ngFor=\"let item of $partners | async \">\n <img class=\"logo\" src=\"{{ item.logo }}\" alt=\"{{item.label}}\" [title]=\"item.label\" />\n </a>\n </div>\n </ng-template>\n\n\n</ion-content>\n", styles: ["h1,h2,h3,h4,h5{white-space:normal}.center,ion-content ion-card.welcome img{text-align:center;display:inline-block}ion-content{--background: transparent;background-size:cover;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;display:inline-block;padding:15px;background-color:var(--ion-color-primary)}ion-content .loading-page{display:block;height:100%;width:100%;position:absolute;background-color:var(--ion-color-primary);z-index:5;transition:background .5s linear;-webkit-transition:background 1.5s linear}ion-content .loading-page.hidden{background-color:rgba(var(--ion-color-primary),0)}ion-content ion-card{z-index:9}ion-content ion-card ion-card-header{display:block}ion-content ion-card ion-card-header ion-card-subtitle,ion-content ion-card ion-card-header ion-card-title{display:block;width:100%}ion-content ion-card.main{min-width:240px;max-width:400px;margin-left:auto;margin-right:auto}ion-content ion-card.welcome{background-color:#ffffffb3}ion-content ion-card.welcome button{margin-top:16px}ion-content ion-card.welcome img{max-width:250px}ion-content .history-container{margin-left:auto;margin-right:auto}ion-content .history-container ion-card{display:inline-block;box-sizing:border-box;z-index:8;min-width:240px;max-width:400px;width:100%;margin-left:auto;margin-right:auto;background-color:#ffffffb3}ion-content .history-container ion-card ion-card-header ion-card-subtitle{height:40px}ion-content .history-container ion-card ion-card-header ion-card-subtitle button[float-start]{z-index:99;margin:0}ion-content .history-container ion-card ion-card-header ion-card-subtitle ion-label{line-height:40px}ion-content .history-container ion-card ion-card-header ion-card-subtitle ion-label[float-end]{padding-right:16px;font-weight:400}ion-content .history-container ion-card ion-card-header ion-card-title ion-item{--ion-item-background: $transparent;--ion-item-icon-color: var(--ion-color-primary);--ion-item-text-color: var(--ion-color-primary)}ion-content .history-container ion-card ion-card-header ion-card-title ion-item ion-icon[slot=start],ion-content .history-container ion-card ion-card-header ion-card-title ion-item mat-icon[slot=start]{margin-right:unset;margin-inline-end:16px!important;color:var(--ion-item-icon-color)!important;fill:currentColor;stroke:currentColor}ion-content .history-container ion-card ion-card-header ion-card-title ion-item ion-text,ion-content .history-container ion-card ion-card-header ion-card-title ion-item ion-label{color:var(--ion-item-text-color)!important;-webkit-text-size-adjust:100%;text-size-adjust:100%}ion-content .history-container ion-card ion-card-content ion-list{--ion-item-background: var(--ion-color-transparent)}ion-content .history-container ion-card ion-card-content ion-list ion-item{--ion-item-icon-color: var(--ion-color-dark);--ion-item-text-color: var(--ion-color-dark)}ion-content .history-container ion-card ion-card-content ion-list ion-item ion-icon[slot=start],ion-content .history-container ion-card ion-card-content ion-list ion-item mat-icon[slot=start]{color:var(--ion-item-icon-color)!important;fill:currentColor;stroke:currentColor;margin-right:unset;margin-inline-end:16px!important}ion-content .history-container ion-card ion-card-content ion-list ion-item ion-text,ion-content .history-container ion-card ion-card-content ion-list ion-item ion-label{color:var(--ion-item-text-color)!important}ion-content .bottom-banner{background-color:#ffffffb3;min-width:240px;z-index:0;position:absolute;left:16px;right:16px;bottom:16px}ion-content .bottom-banner img.logo{max-height:50px;margin-left:8px}ion-content ion-text{text-align:center}@media screen and (max-width: 575px){ion-content ion-card{min-width:160px;width:calc(100% - 20px);max-width:100%;margin-left:10px;margin-right:10px}ion-content ion-card h1{margin-top:0;font-size:20px}ion-content ion-card ion-card-content ion-button{margin-top:8px}ion-content .bottom-banner{display:block;position:unset}ion-content .bottom-banner img.logo{max-height:30px}}@media screen and (max-width: 767px) and (min-width: 576px){ion-content{min-height:555px}ion-content .bottom-banner img.logo{max-height:40px}}@media screen and (min-width: 768px){ion-content{min-height:calc(100% - 100px)}}.content-credits{position:absolute;right:5px;bottom:5px}\n"] }]
270
- }], ctorParameters: () => [{ type: i1.AccountService }, { type: i2.ModalController }, { type: i3.TranslateService }, { type: i2.ToastController }, { type: i4.ConfigService }, { type: i5.PlatformService }, { type: i0.ChangeDetectorRef }, { type: i6.NetworkService }, { type: i7.LocalSettingsService }, { type: i18.Environment, decorators: [{
298
+ args: [{ selector: 'app-page-home', changeDetection: ChangeDetectionStrategy.OnPush, animations: [fadeInAnimation, slideUpDownAnimation], template: "<app-toolbar [canGoBack]=\"false\" visible-xs visible-sm visible-mobile>\n <!-- change locale button -->\n <ion-button slot=\"end\" *ngIf=\"currentLocaleCode; let code\" [matMenuTriggerFor]=\"localeMenu\">\n <ion-icon slot=\"icon-only\" name=\"language\"></ion-icon>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n</app-toolbar>\n\n<!-- change locale menu -->\n<mat-menu #localeMenu=\"matMenu\">\n <button *ngFor=\"let item of locales\" mat-menu-item (click)=\"changeLanguage(item.key)\">\n <ion-label>{{ item.value }}</ion-label>\n </button>\n</mat-menu>\n\n<ion-content [ngStyle]=\"contentStyle\" no-padding-xs>\n @if (contentCredits | isNotNilOrBlank) {\n <span class=\"content-credits\">\n <ion-text>{{ contentCredits }}</ion-text>\n </span>\n }\n\n <!-- loading spinner -->\n <div class=\"loading-page\" [class.cdk-visually-hidden]=\"!(loading$ | push)\">\n @if (showSpinner) {\n <div class=\"spinner\">\n <p [innerHTML]=\"'COMMON.LOADING_DOTS' | translate\"></p>\n <div class=\"sk-cube1 sk-cube\"></div>\n <div class=\"sk-cube2 sk-cube\"></div>\n <div class=\"sk-cube4 sk-cube\"></div>\n <div class=\"sk-cube3 sk-cube\"></div>\n </div>\n }\n </div>\n\n <!-- Desktop: translucent top toolbar -->\n <div hidden-xs hidden-sm hidden-mobile>\n <ion-toolbar translucent>\n <ion-buttons slot=\"start\">\n <ion-menu-toggle>\n <ion-button color=\"light\" fill=\"clear\">\n <ion-icon slot=\"icon-only\" name=\"menu\"></ion-icon>\n </ion-button>\n </ion-menu-toggle>\n </ion-buttons>\n\n <ion-buttons slot=\"end\">\n <!-- change locale button -->\n @if (currentLocaleCode; as code) {\n <ion-button\n color=\"secondary\"\n fill=\"solid\"\n [matMenuTriggerFor]=\"localeMenu\"\n [title]=\"'SETTINGS.LOCALE' | translate\"\n >\n <ion-icon slot=\"icon-only\" name=\"language\"></ion-icon>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n }\n </ion-buttons>\n </ion-toolbar>\n </div>\n\n <!-- Install (and upgrade) card -->\n <app-install-upgrade-card [isLogin]=\"isLogin\" [showInstallButton]=\"true\"></app-install-upgrade-card>\n\n @if (!(loading$ | push)) {\n <!-- Welcome card -->\n <ion-card class=\"main welcome ion-padding ion-text-center ion-align-self-center\" @fadeInAnimation>\n <ion-card-header>\n <ion-card-title class=\"ion-text-center\">\n <span *ngIf=\"isWeb\" [innerHTML]=\"'HOME.WELCOME_WEB' | translate: { appName: appName }\"></span>\n <span *ngIf=\"!isWeb\" [innerHTML]=\"'HOME.WELCOME_APP' | translate: { appName: appName }\"></span>\n </ion-card-title>\n <ion-card-subtitle [innerHTML]=\"description\"></ion-card-subtitle>\n </ion-card-header>\n <ion-card-content class=\"ion-no-padding\">\n <ion-text color=\"primary\">\n <img *ngIf=\"logo\" [attr.src]=\"logo\" alt=\"Logo\" />\n </ion-text>\n <!-- register help text -->\n <ion-text *ngIf=\"!isLogin && canRegister\">\n <br />\n <span translate>HOME.REGISTER_HELP</span>\n </ion-text>\n <div class=\"ion-padding-top\">\n <!-- If NOT login -->\n <ng-container *ngIf=\"!isLogin; else loginButtons\">\n <ion-button *ngIf=\"canRegister\" expand=\"block\" color=\"tertiary\" (click)=\"register()\">\n <span translate>HOME.BTN_REGISTER</span>\n </ion-button>\n <ion-button expand=\"block\" color=\"light\" [routerLink]=\"['/']\" (click)=\"login()\">\n <span translate>AUTH.BTN_LOGIN</span>\n </ion-button>\n </ng-container>\n\n <!-- If user login -->\n <ng-template #loginButtons>\n <!-- Feature buttons -->\n <ng-container *rxIf=\"$filteredButtons; let buttons\">\n <ng-container *ngFor=\"let item of buttons\">\n <ion-button\n *ngIf=\"item.path\"\n expand=\"block\"\n color=\"tertiary\"\n [class]=\"item.cssClass\"\n [routerLink]=\"item.path\"\n routerDirection=\"root\"\n >\n <ion-icon slot=\"start\" class=\"ion-float-start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" class=\"ion-float-start\" *ngIf=\"item.matIcon\">{{ item.matIcon }}</mat-icon>\n <ion-text>{{ 'HOME.BTN_DATA_ENTRY' | translate: { name: (item.title | translate) } }}</ion-text>\n </ion-button>\n\n <!-- divider -->\n <div *ngIf=\"!item.path && !item.action\" [class]=\"item.cssClass\">\n <ion-label translate>{{ item.title }}&nbsp;</ion-label>\n </div>\n </ng-container>\n\n <!--<p *ngIf=\"buttons.length\" class=\"visible-mobile\">&nbsp;</p>-->\n </ng-container>\n\n <ion-button *ngIf=\"showAccountButton\" expand=\"block\" color=\"secondary\" [routerLink]=\"['/account']\">\n <ion-icon slot=\"start\" class=\"ion-float-start\" name=\"person-circle\"></ion-icon>\n <ion-text translate>HOME.BTN_MY_ACCOUNT</ion-text>\n </ion-button>\n\n <p hidden-xs hidden-sm hidden-mobile>\n <ion-text\n [innerHTML]=\"'HOME.NOT_THIS_ACCOUNT_QUESTION' | translate: { displayName: accountName }\"\n ></ion-text>\n <br />\n <ion-text>\n <a href=\"#\" (click)=\"logout($event)\">\n <span translate>HOME.BTN_DISCONNECT</span>\n </a>\n </ion-text>\n </p>\n </ng-template>\n </div>\n </ion-card-content>\n </ion-card>\n\n <!-- Page history -->\n @if (isLogin && (pageHistory$ | push); as pageHistory) {\n <ion-grid class=\"history-container ion-align-self-center\">\n <ion-row>\n @for (page of pageHistory; track page.path) {\n <ion-col size=\"12\" size-xl=\"\" class=\"ion-text-center\">\n <ion-card class=\"ion-align-self-start ion-text-start\" @fadeInAnimation>\n <ion-card-header class=\"ion-no-padding\">\n <!-- top bar -->\n <ion-card-subtitle>\n <button\n type=\"button\"\n tabindex=\"-1\"\n (click)=\"removePageHistory(page.path)\"\n mat-icon-button\n class=\"ion-float-start ion-no-margin close-button\"\n >\n <mat-icon>close</mat-icon>\n </button>\n <ion-label [innerHTML]=\"page.subtitle | translate\"></ion-label>\n <ion-text class=\"ion-float-end\" [title]=\"page.time | dateFormat: { time: true }\">\n <small>\n <ion-icon name=\"time-outline\"></ion-icon>\n &nbsp;{{ page.time | dateFromNow }}\n </small>\n &nbsp;\n </ion-text>\n </ion-card-subtitle>\n\n <!-- main page -->\n <ion-card-title class=\"ion-no-margin ion-no-padding\">\n <ion-item\n detail=\"true\"\n tappable\n class=\"text-1x\"\n [routerLink]=\"page.path\"\n routerDirection=\"root\"\n lines=\"none\"\n >\n <!-- page icon-->\n <ion-icon *ngIf=\"page.icon\" slot=\"start\" [name]=\"page.icon\"></ion-icon>\n <mat-icon *ngIf=\"page.matIcon\" slot=\"start\">{{ page.matIcon }}</mat-icon>\n\n <ion-label color=\"primary\" [innerHTML]=\"page.title\"></ion-label>\n </ion-item>\n </ion-card-title>\n </ion-card-header>\n\n <!-- children pages -->\n @if (page.children | isNotEmptyArray) {\n <ion-card-content class=\"ion-no-padding ion-padding-start\">\n <ion-list class=\"ion-no-padding\">\n @for (childPage of page.children; track childPage.path) {\n <ion-item\n detail=\"true\"\n tappable\n class=\"text-1x\"\n [routerLink]=\"childPage.path\"\n routerDirection=\"root\"\n >\n <!-- page icon-->\n <ion-icon *ngIf=\"childPage.icon\" slot=\"start\" color=\"dark\" [name]=\"childPage.icon\"></ion-icon>\n <mat-icon *ngIf=\"childPage.matIcon\" slot=\"start\" color=\"dark\">\n {{ childPage.matIcon }}\n </mat-icon>\n\n <ion-label color=\"dark\" [innerHTML]=\"childPage.title\"></ion-label>\n </ion-item>\n }\n </ion-list>\n </ion-card-content>\n }\n </ion-card>\n </ion-col>\n }\n </ion-row>\n </ion-grid>\n } @else if (showPartnerBanner) {\n <!-- Display partners logos -->\n <div class=\"bottom-banner ion-text-center ion-padding\" @fadeInAnimation>\n @for (item of $partners | async; track $index) {\n <a href=\"{{ item.siteUrl }}\">\n <img class=\"logo\" src=\"{{ item.logo }}\" alt=\"{{ item.label }}\" [title]=\"item.label\" />\n </a>\n }\n </div>\n }\n }\n</ion-content>\n", styles: ["h1,h2,h3,h4,h5{white-space:normal}.center,ion-content ion-card.welcome img{text-align:center;display:inline-block}ion-content{--background: transparent;background-size:cover;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-color:var(--ion-background-color);display:inline-block;padding:15px}ion-content .loading-page{display:block;height:100%;width:100%;position:absolute;background-color:var(--ion-background-color);z-index:5;transition:background .5s linear;-webkit-transition:background 1.5s linear}ion-content .loading-page.hidden{background-color:rgba(var(--ion-color-primary),0)}ion-content ion-card{z-index:9}ion-content ion-card ion-card-header{display:block}ion-content ion-card ion-card-header ion-card-subtitle,ion-content ion-card ion-card-header ion-card-title{display:block;width:100%}ion-content ion-card.main{min-width:240px;max-width:400px;margin-left:auto;margin-right:auto}ion-content ion-card.welcome{background-color:var(--ion-card-background-color)}ion-content ion-card.welcome button{margin-top:16px}ion-content ion-card.welcome img{max-width:250px}ion-content .history-container{margin-left:auto;margin-right:auto}ion-content .history-container ion-card{display:inline-block;box-sizing:border-box;z-index:8;min-width:240px;max-width:400px;width:100%;margin-left:auto;margin-right:auto;background-color:var(--ion-card-background-color)}ion-content .history-container ion-card ion-card-header ion-card-subtitle{height:40px}ion-content .history-container ion-card ion-card-header ion-card-subtitle button[float-start]{--mdc-icon-button-state-layer-size: 40px;padding:8px;z-index:99;margin:0}ion-content .history-container ion-card ion-card-header ion-card-subtitle ion-label{line-height:40px}ion-content .history-container ion-card ion-card-header ion-card-subtitle ion-label[float-end]{padding-right:16px;font-weight:400}ion-content .history-container ion-card ion-card-header ion-card-title ion-item{width:100%;--ion-item-background: $transparent;--ion-item-icon-color: var(--ion-color-primary);--ion-item-text-color: var(--ion-color-primary)}ion-content .history-container ion-card ion-card-header ion-card-title ion-item ion-icon[slot=start],ion-content .history-container ion-card ion-card-header ion-card-title ion-item mat-icon[slot=start]{margin-right:unset;margin-inline-end:16px!important;color:var(--ion-item-icon-color)!important;fill:currentColor;stroke:currentColor}ion-content .history-container ion-card ion-card-header ion-card-title ion-item ion-text,ion-content .history-container ion-card ion-card-header ion-card-title ion-item ion-label{color:var(--ion-item-text-color)!important;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%}ion-content .history-container ion-card ion-card-content ion-list{--ion-item-background: var(--ion-color-transparent)}ion-content .history-container ion-card ion-card-content ion-list ion-item{--ion-item-icon-color: var(--ion-color-dark);--ion-item-text-color: var(--ion-color-dark)}ion-content .history-container ion-card ion-card-content ion-list ion-item ion-icon[slot=start],ion-content .history-container ion-card ion-card-content ion-list ion-item mat-icon[slot=start]{color:var(--ion-item-icon-color)!important;fill:currentColor;stroke:currentColor;margin-right:unset;margin-inline-end:16px!important}ion-content .history-container ion-card ion-card-content ion-list ion-item ion-text,ion-content .history-container ion-card ion-card-content ion-list ion-item ion-label{color:var(--ion-item-text-color)!important}ion-content .bottom-banner{background-color:var(--ion-card-background-color);min-width:240px;z-index:0;position:absolute;left:16px;right:16px;bottom:16px}ion-content .bottom-banner img.logo{max-height:50px;margin-left:8px}ion-content ion-text{text-align:center}@media screen and (max-width: 575px){ion-content ion-card{min-width:160px;width:calc(100% - 20px);max-width:100%;margin-left:10px;margin-right:10px}ion-content ion-card h1{margin-top:0;font-size:20px}ion-content ion-card ion-card-content ion-button{margin-top:8px}ion-content .bottom-banner{display:block;position:unset}ion-content .bottom-banner img.logo{max-height:30px}}@media screen and (max-width: 767px) and (min-width: 576px){ion-content{min-height:555px}ion-content .bottom-banner img.logo{max-height:40px}}@media screen and (min-width: 768px){ion-content{min-height:calc(100% - 100px)}}.content-credits{position:absolute;right:5px;bottom:5px}.content-credits ion-text{padding-inline-start:4px;padding-inline-end:4px;font-size:.8rem;background-color:var(--ion-background-color, white);color:var(--ion-text-color);opacity:.65}\n"] }]
299
+ }], ctorParameters: () => [{ type: i1.AccountService }, { type: i2.ModalController }, { type: i3.TranslateService }, { type: i2.ToastController }, { type: i4.ConfigService }, { type: i5.PlatformService }, { type: i0.ChangeDetectorRef }, { type: i6.NetworkService }, { type: i7.LocalSettingsService }, { type: i21.Environment, decorators: [{
271
300
  type: Inject,
272
301
  args: [ENVIRONMENT]
273
302
  }] }, { type: undefined, decorators: [{
@@ -279,4 +308,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImpor
279
308
  type: Inject,
280
309
  args: [APP_HOME_BUTTONS]
281
310
  }] }] });
282
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG9tZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS9ob21lL2hvbWUudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvcmUvaG9tZS9ob21lLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFxQixTQUFTLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBYSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbkksT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzNELE9BQU8sRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXJELE9BQU8sRUFBVyxlQUFlLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUczRSxPQUFPLEVBQUUsV0FBVyxFQUErQixNQUFNLGtDQUFrQyxDQUFDO0FBSzVGLE9BQU8sRUFBRSxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVsRCxPQUFPLEVBQWEsU0FBUyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDMUQsT0FBTyxFQUFvQixNQUFNLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRSxPQUFPLEVBQUUsZUFBZSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFDbEcsT0FBTyxFQUFFLFFBQVEsRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDOUUsT0FBTyxFQUFlLFdBQVcsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBRW5GLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVyRSxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcs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QUksQ0FBQyxNQUFNO1lBQ2xCLFNBQVMsRUFBRSxRQUFRO1NBQ3BCLENBQUMsQ0FBQzthQUNGLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUNWLGlDQUFpQztZQUNqQyxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtnQkFDdkQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUMxRCxJQUFJLEtBQUs7b0JBQUUsT0FBTyxFQUFFLEdBQUcsSUFBSSxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUMsaURBQWlEO2FBQ3ZGO1lBQ0QsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDLENBQUMsQ0FBQztRQUVMLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVTLFlBQVk7UUFDcEIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUN6QixDQUFDO3VHQWhRVSxRQUFRLDZTQXdDVCxXQUFXLGFBQ1gsV0FBVyxhQUNDLGdCQUFnQjsyRkExQzNCLFFBQVEscURDdENyQiwwMFJBcU5BLDQrU0RqTGMsQ0FBQyxlQUFlLEVBQUUsb0JBQW9CLENBQUM7OzJGQUV4QyxRQUFRO2tCQVBwQixTQUFTOytCQUNFLGVBQWUsbUJBR1IsdUJBQXVCLENBQUMsTUFBTSxjQUNuQyxDQUFDLGVBQWUsRUFBRSxvQkFBb0IsQ0FBQzs7MEJBMENoRCxNQUFNOzJCQUFDLFdBQVc7OzBCQUNsQixNQUFNOzJCQUFDLFdBQVc7OzBCQUNsQixRQUFROzswQkFBSSxNQUFNOzJCQUFDLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBJbmplY3QsIEluamVjdGlvblRva2VuLCBPbkRlc3Ryb3ksIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNb2RhbENvbnRyb2xsZXIsIFRvYXN0Q29udHJvbGxlciB9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7IFJlZ2lzdGVyTW9kYWwgfSBmcm9tICcuLi9yZWdpc3Rlci9yZWdpc3Rlci5tb2RhbCc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQWNjb3VudFNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9hY2NvdW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgQWNjb3VudCwgYWNjb3VudFRvU3RyaW5nIH0gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvYWNjb3VudC5tb2RlbCc7XG5pbXBvcnQgeyBDb25maWd1cmF0aW9uIH0gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvY29uZmlnLm1vZGVsJztcbmltcG9ydCB7IERlcGFydG1lbnQgfSBmcm9tICcuLi9zZXJ2aWNlcy9tb2RlbC9kZXBhcnRtZW50Lm1vZGVsJztcbmltcG9ydCB7IEFQUF9MT0NBTEVTLCBMb2NhbGVDb25maWcsIExvY2FsU2V0dGluZ3MgfSBmcm9tICcuLi9zZXJ2aWNlcy9tb2RlbC9zZXR0aW5ncy5tb2RlbCc7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvY29uZmlnLnNlcnZpY2UnO1xuaW1wb3J0IHsgUGxhdGZvcm1TZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvcGxhdGZvcm0uc2VydmljZSc7XG5pbXBvcnQgeyBMb2NhbFNldHRpbmdzU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2xvY2FsLXNldHRpbmdzLnNlcnZpY2UnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgbWFwLCBzdGFydFdpdGggfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBBcHBBdXRoTW9kYWwgfSBmcm9tICcuLi9hdXRoL2F1dGgubW9kYWwnO1xuaW1wb3J0IHsgTmV0d29ya1NlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9uZXR3b3JrLnNlcnZpY2UnO1xuaW1wb3J0IHsgSU1lbnVJdGVtLCBNZW51SXRlbXMgfSBmcm9tICcuLi9tZW51L21lbnUubW9kZWwnO1xuaW1wb3J0IHsgU2hvd1RvYXN0T3B0aW9ucywgVG9hc3RzIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3RvYXN0L3RvYXN0cyc7XG5pbXBvcnQgeyBmYWRlSW5BbmltYXRpb24sIHNsaWRlVXBEb3duQW5pbWF0aW9uIH0gZnJvbSAnLi4vLi4vc2hhcmVkL21hdGVyaWFsL21hdGVyaWFsLmFuaW1hdGlvbnMnO1xuaW1wb3J0IHsgaXNOb3ROaWwsIGlzTm90TmlsT3JCbGFuaywgdG9Cb29sZWFuIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Z1bmN0aW9ucyc7XG5pbXBvcnQgeyBFbnZpcm9ubWVudCwgRU5WSVJPTk1FTlQgfSBmcm9tICcuLi8uLi8uLi9lbnZpcm9ubWVudHMvZW52aXJvbm1lbnQuY2xhc3MnO1xuaW1wb3J0IHsgSGlzdG9yeVBhZ2VSZWZlcmVuY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9tb2RlbC9oaXN0b3J5Lm1vZGVsJztcbmltcG9ydCB7IENPUkVfQ09ORklHX09QVElPTlMgfSBmcm9tICcuLi9zZXJ2aWNlcy9jb25maWcvY29yZS5jb25maWcnO1xuXG5leHBvcnQgY29uc3QgZ2V0UmFuZG9tSW1hZ2UgPSAoZmlsZXM6IHN0cmluZ1tdKSA9PiB7XG4gIGNvbnN0IGltZ0luZGV4ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogZmlsZXMubGVuZ3RoKTtcbiAgcmV0dXJuIGZpbGVzW2ltZ0luZGV4XTtcbn07XG5cbmV4cG9ydCBjb25zdCBBUFBfSE9NRV9CVVRUT05TID0gbmV3IEluamVjdGlvblRva2VuPElNZW51SXRlbVtdPignaG9tZUJ1dHRvbicpO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtcGFnZS1ob21lJyxcbiAgdGVtcGxhdGVVcmw6ICdob21lLmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9ob21lLnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGFuaW1hdGlvbnM6IFtmYWRlSW5BbmltYXRpb24sIHNsaWRlVXBEb3duQW5pbWF0aW9uXVxufSlcbmV4cG9ydCBjbGFzcyBIb21lUGFnZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZGVidWc6IGJvb2xlYW47XG4gIHByaXZhdGUgX3N1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgcHJpdmF0ZSBfY29uZmlnOiBDb25maWd1cmF0aW9uO1xuXG4gIGxvYWRpbmcgPSB0cnVlO1xuICB3YWl0aW5nTmV0d29yayA9IGZhbHNlO1xuICBzaG93U3Bpbm5lciA9IHRydWU7XG4gIGFjY291bnROYW1lID0gJyc7XG4gIGlzTG9naW46IGJvb2xlYW47XG4gICRwYXJ0bmVycyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RGVwYXJ0bWVudFtdPihudWxsKTtcbiAgbG9hZGluZ0Jhbm5lciA9IHRydWU7XG4gIGxvZ286IHN0cmluZztcbiAgZGVzY3JpcHRpb246IHN0cmluZztcbiAgYXBwTmFtZTogc3RyaW5nO1xuICBpc1dlYjogYm9vbGVhbjtcbiAgY2FuUmVnaXN0ZXI6IGJvb2xlYW47XG4gIGNvbnRlbnRTdHlsZTogYW55O1xuICBjb250ZW50Q3JlZGl0czogc3RyaW5nO1xuICBwYWdlSGlzdG9yeTogSGlzdG9yeVBhZ2VSZWZlcmVuY2VbXSA9IFtdO1xuICBvZmZsaW5lOiBib29sZWFuO1xuICAkZmlsdGVyZWRCdXR0b25zID0gbmV3IEJlaGF2aW9yU3ViamVjdDxJTWVudUl0ZW1bXT4odW5kZWZpbmVkKTtcbiAgcmVhZG9ubHkgc2hvd0FjY291bnRCdXR0b246IGJvb2xlYW47XG5cbiAgZ2V0IGN1cnJlbnRMb2NhbGVDb2RlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMubG9hZGluZyA/ICcnIDpcbiAgICAodGhpcy50cmFuc2xhdGUuY3VycmVudExhbmcgfHwgdGhpcy50cmFuc2xhdGUuZGVmYXVsdExhbmcgfHwgdGhpcy5lbnZpcm9ubWVudC5kZWZhdWx0TG9jYWxlKT8uc3Vic3RyaW5nKDAsIDIpO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBhY2NvdW50U2VydmljZTogQWNjb3VudFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBtb2RhbEN0cmw6IE1vZGFsQ29udHJvbGxlcixcbiAgICBwcml2YXRlIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICBwcml2YXRlIHRvYXN0Q29udHJvbGxlcjogVG9hc3RDb250cm9sbGVyLFxuICAgIHByaXZhdGUgY29uZmlnU2VydmljZTogQ29uZmlnU2VydmljZSxcbiAgICBwcml2YXRlIHBsYXRmb3JtOiBQbGF0Zm9ybVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHVibGljIG5ldHdvcms6IE5ldHdvcmtTZXJ2aWNlLFxuICAgIHB1YmxpYyBzZXR0aW5nczogTG9jYWxTZXR0aW5nc1NlcnZpY2UsXG4gICAgQEluamVjdChFTlZJUk9OTUVOVCkgcHJvdGVjdGVkIGVudmlyb25tZW50OiBFbnZpcm9ubWVudCxcbiAgICBASW5qZWN0KEFQUF9MT0NBTEVTKSBwdWJsaWMgbG9jYWxlczogTG9jYWxlQ29uZmlnW10sXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChBUFBfSE9NRV9CVVRUT05TKSBwdWJsaWMgYnV0dG9uczogSU1lbnVJdGVtW11cbiAgKSB7XG5cbiAgICB0aGlzLl9kZWJ1ZyA9ICFlbnZpcm9ubWVudC5wcm9kdWN0aW9uO1xuICAgIHRoaXMuc2hvd1NwaW5uZXIgPSAhdGhpcy5wbGF0Zm9ybS5zdGFydGVkO1xuICAgIHRoaXMucGxhdGZvcm0ucmVhZHkoKS50aGVuKCgpID0+IHRoaXMuc3RhcnQoKSk7XG4gICAgdGhpcy5zaG93QWNjb3VudEJ1dHRvbiA9IHRvQm9vbGVhbihlbnZpcm9ubWVudC5hY2NvdW50Py5zaG93QWNjb3VudEJ1dHRvbiwgdHJ1ZSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIGFzeW5jIGxvZ2luKCkge1xuICAgIGNvbnN0IG1vZGFsID0gYXdhaXQgdGhpcy5tb2RhbEN0cmwuY3JlYXRlKHtcbiAgICAgIGNvbXBvbmVudDogQXBwQXV0aE1vZGFsXG4gICAgfSk7XG4gICAgcmV0dXJuIG1vZGFsLnByZXNlbnQoKTtcbiAgfVxuXG4gIGFzeW5jIHJlZ2lzdGVyKCkge1xuICAgIGNvbnN0IG1vZGFsID0gYXdhaXQgdGhpcy5tb2RhbEN0cmwuY3JlYXRlKHtcbiAgICAgIGNvbXBvbmVudDogUmVnaXN0ZXJNb2RhbCxcbiAgICAgIGJhY2tkcm9wRGlzbWlzczogZmFsc2VcbiAgICB9KTtcbiAgICByZXR1cm4gbW9kYWwucHJlc2VudCgpO1xuICB9XG5cbiAgYXN5bmMgbG9nb3V0KGV2ZW50OiBhbnkpIHtcbiAgICBhd2FpdCB0aGlzLmFjY291bnRTZXJ2aWNlLmxvZ291dCgpO1xuXG4gICAgLy8gSWYgd2FzIG9mZmxpbmUsIHRyeSB0byByZWNvbm5lY3QgKGJlY2F1c2UgY2FuIGJlIGEgZm9yY2VkIG9mZmxpbmUgbW9kZSlcbiAgICBpZiAodGhpcy5vZmZsaW5lKSB7XG4gICAgICBhd2FpdCB0aGlzLnRyeU9ubGluZSgpO1xuICAgIH1cbiAgfVxuXG4gIGNoYW5nZUxhbmd1YWdlKGxvY2FsZTogc3RyaW5nKSB7XG4gICAgdGhpcy5zZXR0aW5ncy5hcHBseSh7bG9jYWxlfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgZ2V0UGFnZVBhdGgoaW5kZXg6IG51bWJlciwgcGFnZTogSGlzdG9yeVBhZ2VSZWZlcmVuY2UpOiBzdHJpbmcge1xuICAgIHJldHVybiBwYWdlPy5wYXRoO1xuICB9XG5cblxuICB0cnlPbmxpbmUoKSB7XG4gICAgdGhpcy53YWl0aW5nTmV0d29yayA9IHRydWU7XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcblxuICAgIHRoaXMubmV0d29yay50cnlPbmxpbmUoe1xuICAgICAgc2hvd0xvYWRpbmdUb2FzdDogZmFsc2UsXG4gICAgICBzaG93T25saW5lVG9hc3Q6IHRydWUsXG4gICAgICBzaG93T2ZmbGluZVRvYXN0OiBmYWxzZVxuICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMud2FpdGluZ05ldHdvcmsgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuXG4gIH1cblxuICAvKiAtLSBwcm90ZWN0ZWQgbWV0aG9kICAtLSAqL1xuXG4gIHByb3RlY3RlZCBhc3luYyBzdGFydCgpIHtcbiAgICBhd2FpdCB0aGlzLmFjY291bnRTZXJ2aWNlLnJlYWR5KCk7XG5cbiAgICB0aGlzLmlzTG9naW4gPSB0aGlzLmFjY291bnRTZXJ2aWNlLmlzTG9naW4oKTtcbiAgICBpZiAodGhpcy5pc0xvZ2luKSB7XG4gICAgICB0aGlzLm9uTG9naW4odGhpcy5hY2NvdW50U2VydmljZS5hY2NvdW50KTtcbiAgICB9XG5cbiAgICB0aGlzLm9mZmxpbmUgPSB0aGlzLm5ldHdvcmsub2ZmbGluZTtcblxuICAgIC8vIExpc3RlbiBsb2dpbi9sb2dvdXQgZXZlbnRzXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZCh0aGlzLmFjY291bnRTZXJ2aWNlLm9uTG9naW4uc3Vic2NyaWJlKGFjY291bnQgPT4gdGhpcy5vbkxvZ2luKGFjY291bnQpKSk7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZCh0aGlzLmFjY291bnRTZXJ2aWNlLm9uTG9nb3V0LnN1YnNjcmliZSgoKSA9PiB0aGlzLm9uTG9nb3V0KCkpKTtcblxuICAgIC8vIExpc3RlbiBwb2QgY29uZmlnXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZCh0aGlzLmNvbmZpZ1NlcnZpY2UuY29uZmlnLnN1YnNjcmliZShjb25maWcgPT4gdGhpcy5vbkNvbmZpZ0xvYWRlZChjb25maWcpKSk7XG5cbiAgICAvLyBMaXN0ZW4gc2V0dGluZ3MgY2hhbmdlc1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbi5hZGQoXG4gICAgICB0aGlzLnNldHRpbmdzLm9uQ2hhbmdlXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIC8vIEFkZCBhIGRlbGF5LCB0byBhdm9pZCB0byBhcHBseSBjaGFuZ2VzIHRvIG9mdGVuXG4gICAgICAgICAgZGVib3VuY2VUaW1lKDMwMDApLFxuICAgICAgICAgIC8vIFN0YXJ0IHdpdGggY3VycmVudCBzZXR0aW5nc1xuICAgICAgICAgIHN0YXJ0V2l0aChhd2FpdCB0aGlzLnNldHRpbmdzLnJlYWR5KCkpXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZShyZXMgPT4gdGhpcy5vblNldHRpbmdzQ2hhbmdlZChyZXMpKSk7XG5cbiAgICAvLyBMaXN0ZW4gbmV0d29yayBjaGFuZ2VzXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgIHRoaXMubmV0d29yay5vbk5ldHdvcmtTdGF0dXNDaGFuZ2VzXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIC8vZGVib3VuY2VUaW1lKDQ1MCksXG4gICAgICAgICAgLy90YXAoKCkgPT4gdGhpcy53YWl0aW5nTmV0d29yayA9IGZhbHNlKSxcbiAgICAgICAgICBtYXAoY29ubmVjdGlvblR5cGUgPT4gY29ubmVjdGlvblR5cGUgPT09ICdub25lJyksXG4gICAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUob2ZmbGluZSA9PiB7XG4gICAgICAgICAgdGhpcy5vZmZsaW5lID0gb2ZmbGluZTtcbiAgICAgICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgc2hvd1RvYXN0KG9wdHM6IFNob3dUb2FzdE9wdGlvbnMpIHtcbiAgICBhd2FpdCBUb2FzdHMuc2hvdyh0aGlzLnRvYXN0Q29udHJvbGxlciwgdGhpcy50cmFuc2xhdGUsIG9wdHMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIG9uQ29uZmlnTG9hZGVkKGNvbmZpZzogQ29uZmlndXJhdGlvbikge1xuICAgIGNvbnNvbGUuZGVidWcoJ1tob21lXSBBcHBseWluZyBjb25maWd1cmF0aW9uJywgY29uZmlnKTtcbiAgICB0aGlzLl9jb25maWcgPSBjb25maWc7XG5cbiAgICB0aGlzLmFwcE5hbWUgPSBjb25maWcubGFiZWwgfHwgdGhpcy5lbnZpcm9ubWVudC5kZWZhdWx0QXBwTmFtZSB8fCAnU1VNQVJpUyc7XG4gICAgdGhpcy5sb2dvID0gY29uZmlnLmxhcmdlTG9nbyB8fCBjb25maWcuc21hbGxMb2dvIHx8IHVuZGVmaW5lZDtcbiAgICB0aGlzLmRlc2NyaXB0aW9uID0gY29uZmlnLm5hbWU7XG4gICAgdGhpcy5pc1dlYiA9IHRoaXMucGxhdGZvcm0uaXNXZWIoKTtcbiAgICB0aGlzLmNhblJlZ2lzdGVyID0gY29uZmlnLmdldFByb3BlcnR5QXNCb29sZWFuKENPUkVfQ09ORklHX09QVElPTlMuUkVHSVNUUkFUSU9OX0VOQUJMRSk7XG5cbiAgICBjb25zdCBwYXJ0bmVycyA9IChjb25maWcucGFydG5lcnMgfHwgW10pLmZpbHRlcihwID0+IHAgJiYgcC5sb2dvKTtcbiAgICB0aGlzLiRwYXJ0bmVycy5uZXh0KHBhcnRuZXJzKTtcbiAgICB0aGlzLmxvYWRpbmdCYW5uZXIgPSAocGFydG5lcnMubGVuZ3RoID09PSAwKTtcblxuICAgIC8vIElmIG5vdCBhbHJlYWR5IHNldCwgY29tcHV0ZSB0aGUgYmFja2dyb3VuZCBpbWFnZVxuICAgIGlmICghdGhpcy5jb250ZW50U3R5bGUpIHtcbiAgICAgIGNvbnN0IGJhY2tncm91bmRJbWFnZXMgPSAoY29uZmlnLmJhY2tncm91bmRJbWFnZXMgfHwgW10pXG4gICAgICAgIC8vIEZpbHRlciBvbiBub3QgbmlsLCBiZWNhdXNlIGNhbiBvY2N1ciBpZiBkZXRlY3RlZCBoYXMgbm90IGV4aXN0cyAoc2VlIGNvbmZpZy1zZXJ2aWNlLmpzKVxuICAgICAgICAuZmlsdGVyKGltZyA9PiBpc05vdE5pbChpbWcpXG4gICAgICAgICAgLy8gSWYgb2ZmbGluZSwgZmlsdGVyIG9uIGxvY2FsIGRhdGFVUkwgaW1hZ2VcbiAgICAgICAgICAmJiAoIXRoaXMub2ZmbGluZSB8fCAhaW1nLnN0YXJ0c1dpdGgoJ2h0dHAnKSkpO1xuXG4gICAgICAvLyBCYWNrZ3JvdW5kIGltYWdlIGZvdW5kOiBzZWxlY3Qgb25lIHJhbmRvbWx5XG4gICAgICBpZiAoYmFja2dyb3VuZEltYWdlcy5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgYmdJbWFnZSA9IGdldFJhbmRvbUltYWdlKGJhY2tncm91bmRJbWFnZXMpPy5zcGxpdCgnfCcpO1xuICAgICAgICB0aGlzLmNvbnRlbnRTdHlsZSA9IGJnSW1hZ2U/LlswXSAmJiB7J2JhY2tncm91bmQtaW1hZ2UnOiBgdXJsKCR7YmdJbWFnZT8uWzBdfSlgfSB8fCB7fTtcbiAgICAgICAgdGhpcy5jb250ZW50Q3JlZGl0cyA9IGJnSW1hZ2U/LlsxXTtcbiAgICAgIH1cblxuICAgICAgLy8gVXNlIGJhY2tncm91bmQgY29sb3JcbiAgICAgIGVsc2Uge1xuICAgICAgICBjb25zdCBwcmltYXJ5Q29sb3IgPSBjb25maWcucHJvcGVydGllcyAmJiBjb25maWcucHJvcGVydGllc1snc3VtYXJpcy5jb2xvci5wcmltYXJ5J10gfHwgJ3ZhcigtLWlvbi1jb2xvci1wcmltYXJ5KSc7XG4gICAgICAgIHRoaXMuY29udGVudFN0eWxlID0gcHJpbWFyeUNvbG9yICYmIHsnYmFja2dyb3VuZC1jb2xvcic6IHByaW1hcnlDb2xvcn0gfHwge307XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5yZWZyZXNoQnV0dG9ucygpO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG5cbiAgICAvLyBJZiBmaXJzdCBsb2FkLCBoaWRlIHRoZSBsb2FkaW5nIGluZGljYXRvclxuICAgIGlmICh0aGlzLmxvYWRpbmcpIHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9LCA1MDApOyAvLyBBZGQgYSBkZWxheSwgZm9yIGFuaW1hdGlvblxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBvblNldHRpbmdzQ2hhbmdlZChzZXR0aW5nczogTG9jYWxTZXR0aW5ncykge1xuICAgIGlmIChzZXR0aW5ncy5wYWdlSGlzdG9yeSAhPT0gdGhpcy5wYWdlSGlzdG9yeSkge1xuICAgICAgY29uc29sZS5kZWJ1ZygnW2hvbWVdIFBhZ2UgaGlzdG9yeSBsb2FkZWQnKTtcbiAgICAgIHRoaXMucGFnZUhpc3RvcnkgPSBzZXR0aW5ncy5wYWdlSGlzdG9yeSB8fCBbXTtcbiAgICB9XG4gICAgLy8gQWx3YXlzIGZvcmNlIGEgcmVmcmVzaCAoc2FtZSBoaXN0b3J5IGFycmF5LCBidXQgY29udGVudCBtYXkgaGF2ZSBjaGFuZ2VkKVxuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25Mb2dpbihhY2NvdW50OiBBY2NvdW50KSB7XG4gICAgaWYgKCFhY2NvdW50KSByZXR1cm47IC8vIFNraXBcbiAgICAvL2NvbnNvbGUuZGVidWcoJ1tob21lXSBMb2dnZWQgYWNjb3VudDogJywgYWNjb3VudCk7XG4gICAgdGhpcy5pc0xvZ2luID0gdHJ1ZTtcbiAgICB0aGlzLmFjY291bnROYW1lID0gYWNjb3VudFRvU3RyaW5nKGFjY291bnQpO1xuICAgIHRoaXMucmVmcmVzaEJ1dHRvbnMoYWNjb3VudCk7XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvbkxvZ291dCgpIHtcbiAgICB0aGlzLmlzTG9naW4gPSBmYWxzZTtcbiAgICB0aGlzLmFjY291bnROYW1lID0gJyc7XG4gICAgdGhpcy5wYWdlSGlzdG9yeSA9IFtdO1xuICAgIHRoaXMucmVmcmVzaEJ1dHRvbnMoKTtcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJlZnJlc2hCdXR0b25zKGFjY291bnQ/OiBBY2NvdW50KSB7XG4gICAgaWYgKCF0aGlzLl9jb25maWcpIHJldHVybjsgLy8gU2tpcCAod2FpdGluZyBjb25maWcgdG8gYmUgbG9hZGVkKVxuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZygnW2hvbWVdIFJlZnJlc2hpbmcgYnV0dG9ucy4uLicpO1xuXG4gICAgYWNjb3VudCA9IGFjY291bnQgfHwgdGhpcy5hY2NvdW50U2VydmljZS5hY2NvdW50O1xuICAgIGNvbnN0IGZpbHRlcmVkQnV0dG9ucyA9ICh0aGlzLmJ1dHRvbnMgfHwgW10pXG4gICAgICAuZmlsdGVyKChpdGVtKSA9PiBNZW51SXRlbXMuY2hlY2tJZlZpc2libGUoaXRlbSwgYWNjb3VudCwgdGhpcy5fY29uZmlnLCB7XG4gICAgICAgIGlzTG9naW46IHRoaXMuaXNMb2dpbixcbiAgICAgICAgZGVidWc6IHRoaXMuX2RlYnVnLFxuICAgICAgICBsb2dQcmVmaXg6ICdbaG9tZV0nXG4gICAgICB9KSlcbiAgICAgIC5tYXAoaXRlbSA9PiB7XG4gICAgICAgIC8vIFJlcGxhY2UgdGl0bGUgdXNpbmcgcHJvcGVydGllc1xuICAgICAgICBpZiAoaXNOb3ROaWxPckJsYW5rKGl0ZW0udGl0bGVQcm9wZXJ0eSkgJiYgdGhpcy5fY29uZmlnKSB7XG4gICAgICAgICAgY29uc3QgdGl0bGUgPSB0aGlzLl9jb25maWcucHJvcGVydGllc1tpdGVtLnRpdGxlUHJvcGVydHldO1xuICAgICAgICAgIGlmICh0aXRsZSkgcmV0dXJuIHsgLi4uaXRlbSwgdGl0bGV9OyAvLyBDcmVhdGUgYSBjb3B5LCB0byBrZWVwIHRoZSBvcmlnaW5hbCBpdGVtLnRpdGxlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZW07XG4gICAgICB9KTtcblxuICAgIHRoaXMuJGZpbHRlcmVkQnV0dG9ucy5uZXh0KGZpbHRlcmVkQnV0dG9ucyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgbWFya0ZvckNoZWNrKCkge1xuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuXG59XG4iLCI8YXBwLXRvb2xiYXIgW2NhbkdvQmFja109XCJmYWxzZVwiXG4gICAgICAgICAgICAgdmlzaWJsZS14cyB2aXNpYmxlLXNtIHZpc2libGUtbW9iaWxlPlxuXG4gIDwhLS0gY2hhbmdlIGxvY2FsZSBidXR0b24gLS0+XG4gIDxpb24tYnV0dG9uIHNsb3Q9XCJlbmRcIiAqbmdJZj1cImN1cnJlbnRMb2NhbGVDb2RlOyBsZXQgY29kZVwiXG4gICAgICAgICAgICAgIFttYXRNZW51VHJpZ2dlckZvcl09XCJsb2NhbGVNZW51XCI+XG4gICAgPGlvbi1sYWJlbCBjbGFzcz1cImlvbi10ZXh0LXVwcGVyY2FzZVwiPiZuYnNwO3t7IGNvZGUgfX08L2lvbi1sYWJlbD5cbiAgICA8bWF0LWljb24gc2xvdD1cImVuZFwiPmFycm93X2Ryb3BfZG93bjwvbWF0LWljb24+XG4gIDwvaW9uLWJ1dHRvbj5cbjwvYXBwLXRvb2xiYXI+XG5cbjwhLS0gY2hhbmdlIGxvY2FsZSBtZW51IC0tPlxuPG1hdC1tZW51ICNsb2NhbGVNZW51PVwibWF0TWVudVwiPlxuICA8YnV0dG9uICpuZ0Zvcj1cImxldCBpdGVtIG9mIGxvY2FsZXNcIlxuICAgICAgICAgIG1hdC1tZW51LWl0ZW1cbiAgICAgICAgICAoY2xpY2spPVwiY2hhbmdlTGFuZ3VhZ2UoaXRlbS5rZXkpXCI+XG4gICAgPGlvbi1sYWJlbD57e2l0ZW0udmFsdWV9fTwvaW9uLWxhYmVsPlxuICA8L2J1dHRvbj5cbjwvbWF0LW1lbnU+XG5cbjxpb24tY29udGVudCBbbmdTdHlsZV09XCJjb250ZW50U3R5bGVcIiBuby1wYWRkaW5nLXhzPlxuXG4gIDxzcGFuIGNsYXNzPVwiY29udGVudC1jcmVkaXRzXCI+PGlvbi10ZXh0Pnt7IGNvbnRlbnRDcmVkaXRzIH19PC9pb24tdGV4dD48L3NwYW4+XG5cbiAgPCEtLSBsb2FkaW5nIHNwaW5uZXIgLS0+XG4gIDxkaXYgY2xhc3M9XCJsb2FkaW5nLXBhZ2VcIiBbY2xhc3MuY2RrLXZpc3VhbGx5LWhpZGRlbl09XCIhbG9hZGluZ1wiPlxuICAgIDxkaXYgY2xhc3M9XCJzcGlubmVyXCIgKm5nSWY9XCJsb2FkaW5nICYmIHNob3dTcGlubmVyXCI+XG4gICAgICA8cCBbaW5uZXJIVE1MXT1cIidDT01NT04uTE9BRElOR19ET1RTJ3x0cmFuc2xhdGVcIj48L3A+XG4gICAgICA8ZGl2IGNsYXNzPVwic2stY3ViZTEgc2stY3ViZVwiPjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInNrLWN1YmUyIHNrLWN1YmVcIj48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJzay1jdWJlNCBzay1jdWJlXCI+PC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwic2stY3ViZTMgc2stY3ViZVwiPjwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8IS0tIERlc2t0b3A6IHRyYW5zbHVjZW50IHRvcCB0b29sYmFyIC0tPlxuICA8ZGl2IGhpZGRlbi14cyBoaWRkZW4tc20gaGlkZGVuLW1vYmlsZT5cbiAgICA8aW9uLXRvb2xiYXIgdHJhbnNsdWNlbnQ+XG4gICAgICA8aW9uLWJ1dHRvbnMgc2xvdD1cInN0YXJ0XCI+XG4gICAgICAgIDxpb24tbWVudS10b2dnbGU+XG4gICAgICAgICAgPGlvbi1idXR0b24gY29sb3I9XCJsaWdodFwiIGZpbGw9XCJjbGVhclwiPlxuICAgICAgICAgICAgPGlvbi1pY29uIHNsb3Q9XCJpY29uLW9ubHlcIiBuYW1lPVwibWVudVwiPjwvaW9uLWljb24+XG4gICAgICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgICA8L2lvbi1tZW51LXRvZ2dsZT5cbiAgICAgIDwvaW9uLWJ1dHRvbnM+XG5cbiAgICAgIDxpb24tYnV0dG9ucyBzbG90PVwiZW5kXCI+XG4gICAgICAgIDwhLS0gY2hhbmdlIGxvY2FsZSBidXR0b24gLS0+XG4gICAgICAgIDxpb24tYnV0dG9uIGNvbG9yPVwic2Vjb25kYXJ5XCIgZmlsbD1cInNvbGlkXCJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjdXJyZW50TG9jYWxlQ29kZTsgbGV0IGNvZGVcIlxuICAgICAgICAgICAgICAgICAgICBbbWF0TWVudVRyaWdnZXJGb3JdPVwibG9jYWxlTWVudVwiPlxuICAgICAgICAgIDxpb24tbGFiZWwgY2xhc3M9XCJpb24tdGV4dC11cHBlcmNhc2VcIj4mbmJzcDt7eyBjb2RlIH19PC9pb24tbGFiZWw+XG4gICAgICAgICAgPG1hdC1pY29uIHNsb3Q9XCJlbmRcIj5hcnJvd19kcm9wX2Rvd248L21hdC1pY29uPlxuICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICA8L2lvbi1idXR0b25zPlxuICAgIDwvaW9uLXRvb2xiYXI+XG4gIDwvZGl2PlxuXG4gIDwhLS0gSW5zdGFsbCAoYW5kIHVwZ3JhZGUpIGNhcmQgLS0+XG4gIDxhcHAtaW5zdGFsbC11cGdyYWRlLWNhcmQgW2lzTG9naW5dPVwiaXNMb2dpblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dJbnN0YWxsQnV0dG9uXT1cInRydWVcIj5cbiAgPC9hcHAtaW5zdGFsbC11cGdyYWRlLWNhcmQ+XG5cbiAgPCEtLSBXZWxjb21lIGNhcmQgLS0+XG4gIDxpb24tY2FyZCAqbmdJZj1cIiFsb2FkaW5nXCJcbiAgICAgICAgICAgIGNsYXNzPVwibWFpbiB3ZWxjb21lIGlvbi1wYWRkaW5nIGlvbi10ZXh0LWNlbnRlciBpb24tYWxpZ24tc2VsZi1jZW50ZXJcIlxuICAgICAgICAgICAgQGZhZGVJbkFuaW1hdGlvbj5cbiAgICA8aW9uLWNhcmQtaGVhZGVyPlxuICAgICAgPGlvbi1jYXJkLXRpdGxlIGNsYXNzPVwiaW9uLXRleHQtY2VudGVyXCI+XG4gICAgICAgIDxzcGFuICpuZ0lmPVwiaXNXZWJcIiBbaW5uZXJIVE1MXT1cIidIT01FLldFTENPTUVfV0VCJ3x0cmFuc2xhdGU6IHthcHBOYW1lOiBhcHBOYW1lfVwiPjwvc3Bhbj5cbiAgICAgICAgPHNwYW4gKm5nSWY9XCIhaXNXZWJcIiBbaW5uZXJIVE1MXT1cIidIT01FLldFTENPTUVfQVBQJ3x0cmFuc2xhdGU6IHthcHBOYW1lOiBhcHBOYW1lfVwiPjwvc3Bhbj5cbiAgICAgIDwvaW9uLWNhcmQtdGl0bGU+XG4gICAgICA8aW9uLWNhcmQtc3VidGl0bGUgW2lubmVySFRNTF09XCJkZXNjcmlwdGlvblwiPlxuICAgICAgPC9pb24tY2FyZC1zdWJ0aXRsZT5cbiAgICA8L2lvbi1jYXJkLWhlYWRlcj5cbiAgICA8aW9uLWNhcmQtY29udGVudCBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICA8aW9uLXRleHQgY29sb3I9XCJwcmltYXJ5XCI+XG4gICAgICAgIDxpbWcgY2xhc3M9XCJsb2dvXCIgKm5nSWY9XCJsb2dvXCIgc3JjPVwie3sgbG9nbyB9fVwiPlxuICAgICAgPC9pb24tdGV4dD5cbiAgICAgIDwhLS0gcmVnaXN0ZXIgaGVscCB0ZXh0IC0tPlxuICAgICAgPGlvbi10ZXh0ICpuZ0lmPVwiIWlzTG9naW4gJiYgY2FuUmVnaXN0ZXJcIj5cbiAgICAgICAgPGJyLz5cbiAgICAgICAgPHNwYW4gdHJhbnNsYXRlPkhPTUUuUkVHSVNURVJfSEVMUDwvc3Bhbj5cbiAgICAgIDwvaW9uLXRleHQ+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW9uLXBhZGRpbmctdG9wXCI+XG5cbiAgICAgICAgPCEtLSBJZiBOT1QgbG9naW4gLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNMb2dpbjsgZWxzZSBsb2dpbkJ1dHRvbnM7XCI+XG5cbiAgICAgICAgICA8aW9uLWJ1dHRvbiAqbmdJZj1cImNhblJlZ2lzdGVyXCIgZXhwYW5kPVwiYmxvY2tcIiBjb2xvcj1cInRlcnRpYXJ5XCIgKGNsaWNrKT1cInJlZ2lzdGVyKClcIj5cbiAgICAgICAgICAgIDxzcGFuIHRyYW5zbGF0ZT5IT01FLkJUTl9SRUdJU1RFUjwvc3Bhbj5cbiAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgICAgPGlvbi1idXR0b24gZXhwYW5kPVwiYmxvY2tcIiBjb2xvcj1cImxpZ2h0XCIgW3JvdXRlckxpbmtdPVwiWycvJ11cIiAoY2xpY2spPVwibG9naW4oKVwiPlxuICAgICAgICAgICAgPHNwYW4gdHJhbnNsYXRlPkFVVEguQlROX0xPR0lOPC9zcGFuPlxuICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cblxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIElmIHVzZXIgbG9naW4gLS0+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjbG9naW5CdXR0b25zPlxuXG4gICAgICAgICAgPCEtLSBGZWF0dXJlIGJ1dHRvbnMgLS0+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqcnhJZj1cIiRmaWx0ZXJlZEJ1dHRvbnM7IGxldCBidXR0b25zXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGJ1dHRvbnNcIj5cbiAgICAgICAgICAgICAgPGlvbi1idXR0b24gKm5nSWY9XCJpdGVtLnBhdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmQ9XCJibG9ja1wiIGNvbG9yPVwidGVydGlhcnlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3NdPVwiaXRlbS5jc3NDbGFzc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cIml0ZW0ucGF0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlckRpcmVjdGlvbj1cInJvb3RcIj5cbiAgICAgICAgICAgICAgICA8aW9uLWljb24gc2xvdD1cInN0YXJ0XCIgY2xhc3M9XCJpb24tZmxvYXQtc3RhcnRcIiAqbmdJZj1cIml0ZW0uaWNvblwiIFtuYW1lXT1cIml0ZW0uaWNvblwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uIHNsb3Q9XCJzdGFydFwiIGNsYXNzPVwiaW9uLWZsb2F0LXN0YXJ0XCIgKm5nSWY9XCJpdGVtLm1hdEljb25cIj57e2l0ZW0ubWF0SWNvbn19PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICA8aW9uLXRleHQ+e3snSE9NRS5CVE5fREFUQV9FTlRSWSd8dHJhbnNsYXRlOiB7bmFtZTogKGl0ZW0udGl0bGUgfCB0cmFuc2xhdGUpIH0gfX08L2lvbi10ZXh0PlxuICAgICAgICAgICAgICA8L2lvbi1idXR0b24+XG5cbiAgICAgICAgICAgICAgPCEtLSBkaXZpZGVyIC0tPlxuICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIWl0ZW0ucGF0aCAmJiAhaXRlbS5hY3Rpb25cIiBbY2xhc3NdPVwiaXRlbS5jc3NDbGFzc1wiPlxuICAgICAgICAgICAgICAgIDxpb24tbGFiZWwgdHJhbnNsYXRlPnt7aXRlbS50aXRsZX19Jm5ic3A7PC9pb24tbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDwhLS08cCAqbmdJZj1cImJ1dHRvbnMubGVuZ3RoXCIgY2xhc3M9XCJ2aXNpYmxlLW1vYmlsZVwiPiZuYnNwOzwvcD4tLT5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDxpb24tYnV0dG9uICpuZ0lmPVwic2hvd0FjY291bnRCdXR0b25cIiBleHBhbmQ9XCJibG9ja1wiIGNvbG9yPVwic2Vjb25kYXJ5XCIgW3JvdXRlckxpbmtdPVwiWycvYWNjb3VudCddXCI+XG4gICAgICAgICAgICA8aW9uLWljb24gc2xvdD1cInN0YXJ0XCIgY2xhc3M9XCJpb24tZmxvYXQtc3RhcnRcIiBuYW1lPVwicGVyc29uLWNpcmNsZVwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICA8aW9uLXRleHQgdHJhbnNsYXRlPkhPTUUuQlROX01ZX0FDQ09VTlQ8L2lvbi10ZXh0PlxuICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cblxuICAgICAgICAgIDxwIGhpZGRlbi14cyBoaWRkZW4tc20gaGlkZGVuLW1vYmlsZT5cbiAgICAgICAgICAgIDxpb24tdGV4dCBbaW5uZXJIVE1MXT1cIidIT01FLk5PVF9USElTX0FDQ09VTlRfUVVFU1RJT04nIHwgdHJhbnNsYXRlOiB7ZGlzcGxheU5hbWU6IGFjY291bnROYW1lIH1cIj48L2lvbi10ZXh0PlxuICAgICAgICAgICAgPGJyLz5cbiAgICAgICAgICAgIDxpb24tdGV4dD5cbiAgICAgICAgICAgICAgPGEgaHJlZj1cIiNcIiAoY2xpY2spPVwibG9nb3V0KCRldmVudClcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiB0cmFuc2xhdGU+SE9NRS5CVE5fRElTQ09OTkVDVDwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgPC9pb24tdGV4dD5cbiAgICAgICAgICA8L3A+XG5cblxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICA8L2Rpdj5cbiAgICA8L2lvbi1jYXJkLWNvbnRlbnQ+XG4gIDwvaW9uLWNhcmQ+XG5cbiAgPCEtLSBQYWdlIGhpc3RvcnkgLS0+XG4gIDxpb24tZ3JpZCAqbmdJZj1cIiFsb2FkaW5nICYmIGlzTG9naW4gJiYgcGFnZUhpc3RvcnkubGVuZ3RoOyBlbHNlIGJvdHRvbUJhbm5lclwiXG4gICAgICAgICAgICBjbGFzcz1cImhpc3RvcnktY29udGFpbmVyIGlvbi1hbGlnbi1zZWxmLWNlbnRlclwiPlxuICAgIDxpb24tcm93PlxuICAgICAgPGlvbi1jb2wgc2l6ZT1cIjEyXCIgc2l6ZS14bD1cIlwiICpuZ0Zvcj1cImxldCBwYWdlIG9mIHBhZ2VIaXN0b3J5OyB0cmFja0J5OiBnZXRQYWdlUGF0aFwiXG4gICAgICAgICAgICAgICBjbGFzcz1cImlvbi10ZXh0LWNlbnRlclwiPlxuICAgICAgICA8aW9uLWNhcmQgY2xhc3M9XCJpb24tYWxpZ24tc2VsZi1zdGFydCBpb24tdGV4dC1zdGFydFwiIEBmYWRlSW5BbmltYXRpb24+XG4gICAgICAgICAgPGlvbi1jYXJkLWhlYWRlciBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICAgICAgICA8IS0tIHRvcCBiYXIgLS0+XG4gICAgICAgICAgICA8aW9uLWNhcmQtc3VidGl0bGU+XG4gICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIHRhYmluZGV4PVwiLTFcIlxuICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzZXR0aW5ncy5yZW1vdmVQYWdlSGlzdG9yeShwYWdlLnBhdGgpXCJcbiAgICAgICAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b24gY2xhc3M9XCJpb24tZmxvYXQtc3RhcnQgaW9uLW5vLW1hcmdpblwiPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jbG9zZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8aW9uLWxhYmVsIFtpbm5lckhUTUxdPVwicGFnZS5zdWJ0aXRsZXx0cmFuc2xhdGVcIj48L2lvbi1sYWJlbD5cbiAgICAgICAgICAgICAgPGlvbi10ZXh0IGNsYXNzPVwiaW9uLWZsb2F0LWVuZFwiIFt0aXRsZV09XCJwYWdlLnRpbWV8ZGF0ZUZvcm1hdDp7dGltZTogdHJ1ZX1cIj5cbiAgICAgICAgICAgICAgICA8c21hbGw+PGlvbi1pY29uIG5hbWU9XCJ0aW1lLW91dGxpbmVcIj48L2lvbi1pY29uPiZuYnNwO3t7IHBhZ2UudGltZXxkYXRlRnJvbU5vdyB9fTwvc21hbGw+Jm5ic3A7XG4gICAgICAgICAgICAgIDwvaW9uLXRleHQ+XG4gICAgICAgICAgICA8L2lvbi1jYXJkLXN1YnRpdGxlPlxuXG4gICAgICAgICAgICA8IS0tIG1haW4gcGFnZSAtLT5cbiAgICAgICAgICAgIDxpb24tY2FyZC10aXRsZSBjbGFzcz1cImlvbi1uby1tYXJnaW4gaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgICAgICAgPGlvbi1pdGVtICBkZXRhaWw9XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICB0YXBwYWJsZSBjbGFzcz1cInRleHQtMXhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cInBhZ2UucGF0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVyRGlyZWN0aW9uPVwicm9vdFwiIGxpbmVzPVwibm9uZVwiPlxuICAgICAgICAgICAgICAgIDwhLS0gcGFnZSBpY29uLS0+XG4gICAgICAgICAgICAgICAgPGlvbi1pY29uICpuZ0lmPVwicGFnZS5pY29uXCIgICAgc2xvdD1cInN0YXJ0XCIgW25hbWVdPVwicGFnZS5pY29uXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJwYWdlLm1hdEljb25cIiBzbG90PVwic3RhcnRcIj57e3BhZ2UubWF0SWNvbn19PC9tYXQtaWNvbj5cblxuICAgICAgICAgICAgICAgIDxpb24tbGFiZWwgY29sb3I9XCJwcmltYXJ5XCIgW2lubmVySFRNTF09XCJwYWdlLnRpdGxlXCI+PC9pb24tbGFiZWw+XG4gICAgICAgICAgICAgIDwvaW9uLWl0ZW0+XG4gICAgICAgICAgICA8L2lvbi1jYXJkLXRpdGxlPlxuICAgICAgICAgIDwvaW9uLWNhcmQtaGVhZGVyPlxuXG4gICAgICAgICAgPCEtLSBjaGlsZHJlbiBwYWdlcyAtLT5cbiAgICAgICAgICA8aW9uLWNhcmQtY29udGVudCBjbGFzcz1cImlvbi1uby1wYWRkaW5nIGlvbi1wYWRkaW5nLXN0YXJ0XCIgKm5nSWY9XCJwYWdlLmNoaWxkcmVuPy5sZW5ndGhcIj5cbiAgICAgICAgICAgIDxpb24tbGlzdCBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICAgICAgICAgIDxpb24taXRlbSAgZGV0YWlsPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGNoaWxkUGFnZSBvZiBwYWdlLmNoaWxkcmVuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICB0YXBwYWJsZSBjbGFzcz1cInRleHQtMXhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3JvdXRlckxpbmtdPVwiY2hpbGRQYWdlLnBhdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVyRGlyZWN0aW9uPVwicm9vdFwiPlxuICAgICAgICAgICAgICAgIDwhLS0gcGFnZSBpY29uLS0+XG4gICAgICAgICAgICAgICAgPGlvbi1pY29uICpuZ0lmPVwiY2hpbGRQYWdlLmljb25cIiAgICBzbG90PVwic3RhcnRcIiBjb2xvcj1cImRhcmtcIiBbbmFtZV09XCJjaGlsZFBhZ2UuaWNvblwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiY2hpbGRQYWdlLm1hdEljb25cIiBzbG90PVwic3RhcnRcIiBjb2xvcj1cImRhcmtcIj57e2NoaWxkUGFnZS5tYXRJY29ufX08L21hdC1pY29uPlxuXG4gICAgICAgICAgICAgICAgPGlvbi1sYWJlbCBjb2xvcj1cImRhcmtcIiBbaW5uZXJIVE1MXT1cImNoaWxkUGFnZS50aXRsZVwiPjwvaW9uLWxhYmVsPlxuICAgICAgICAgICAgICA8L2lvbi1pdGVtPlxuICAgICAgICAgICAgPC9pb24tbGlzdD5cbiAgICAgICAgICA8L2lvbi1jYXJkLWNvbnRlbnQ+XG4gICAgICAgIDwvaW9uLWNhcmQ+XG4gICAgICA8L2lvbi1jb2w+XG4gICAgPC9pb24tcm93PlxuICA8L2lvbi1ncmlkPlxuXG4gIDwhLS0gRGlzcGxheSBjb25maWd1cmVkIERlcGFydG1lbnRzIGxvZ29zIC0tPlxuICA8bmctdGVtcGxhdGUgI2JvdHRvbUJhbm5lcj5cbiAgICA8ZGl2IGNsYXNzPVwiYm90dG9tLWJhbm5lciBpb24tdGV4dC1jZW50ZXIgaW9uLXBhZGRpbmdcIiAqbmdJZj1cIiFsb2FkaW5nQmFubmVyXCIgQGZhZGVJbkFuaW1hdGlvbj5cbiAgICAgIDxhIGhyZWY9XCJ7eyBpdGVtLnNpdGVVcmwgfX1cIiAqbmdGb3I9XCJsZXQgaXRlbSBvZiAkcGFydG5lcnMgfCBhc3luYyBcIj5cbiAgICAgICAgPGltZyBjbGFzcz1cImxvZ29cIiBzcmM9XCJ7eyBpdGVtLmxvZ28gfX1cIiBhbHQ9XCJ7e2l0ZW0ubGFiZWx9fVwiICBbdGl0bGVdPVwiaXRlbS5sYWJlbFwiIC8+XG4gICAgICA8L2E+XG4gICAgPC9kaXY+XG4gIDwvbmctdGVtcGxhdGU+XG5cblxuPC9pb24tY29udGVudD5cbiJdfQ==
311
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG9tZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS9ob21lL2hvbWUudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvcmUvaG9tZS9ob21lLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFxQixTQUFTLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBYSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbkksT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzNELE9BQU8sRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXJELE9BQU8sRUFBVyxlQUFlLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUczRSxPQUFPLEVBQUUsV0FBVyxFQUErQixNQUFNLGtDQUFrQyxDQUFDO0FBSzVGLE9BQU8sRUFBRSxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVsRCxPQUFPLEVBQWEsU0FBUyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDMUQsT0FBTyxFQUFvQixNQUFNLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRSxPQUFPLEVBQUUsZUFBZSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFDbEcsT0FBTyxFQUFFLFFBQVEsRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDOUUsT0FBTyxFQUFlLFdBQVcsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBRW5GLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM1QyxP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LENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQzFELElBQUksS0FBSztvQkFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxpREFBaUQ7WUFDekYsQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQyxDQUFDLENBQUM7UUFFTCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFUyxLQUFLLENBQUMsaUJBQWlCLENBQUMsSUFBWTtRQUM1QyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVTLFlBQVk7UUFDcEIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUN6QixDQUFDO3VHQWxTVSxRQUFRLDZTQW9FVCxXQUFXLGFBQ1gsV0FBVyxhQUNDLGdCQUFnQjsyRkF0RTNCLFFBQVEsNEVDaERyQixzeVRBeU9BLG9oVUQzTGMsQ0FBQyxlQUFlLEVBQUUsb0JBQW9CLENBQUM7OzJGQUV4QyxRQUFRO2tCQVBwQixTQUFTOytCQUNFLGVBQWUsbUJBR1IsdUJBQXVCLENBQUMsTUFBTSxjQUNuQyxDQUFDLGVBQWUsRUFBRSxvQkFBb0IsQ0FBQzs7MEJBc0VoRCxNQUFNOzJCQUFDLFdBQVc7OzBCQUNsQixNQUFNOzJCQUFDLFdBQVc7OzBCQUNsQixRQUFROzswQkFBSSxNQUFNOzJCQUFDLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBJbmplY3QsIEluamVjdGlvblRva2VuLCBPbkRlc3Ryb3ksIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNb2RhbENvbnRyb2xsZXIsIFRvYXN0Q29udHJvbGxlciB9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7IFJlZ2lzdGVyTW9kYWwgfSBmcm9tICcuLi9yZWdpc3Rlci9yZWdpc3Rlci5tb2RhbCc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQWNjb3VudFNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9hY2NvdW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgQWNjb3VudCwgYWNjb3VudFRvU3RyaW5nIH0gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvYWNjb3VudC5tb2RlbCc7XG5pbXBvcnQgeyBDb25maWd1cmF0aW9uIH0gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvY29uZmlnLm1vZGVsJztcbmltcG9ydCB7IERlcGFydG1lbnQgfSBmcm9tICcuLi9zZXJ2aWNlcy9tb2RlbC9kZXBhcnRtZW50Lm1vZGVsJztcbmltcG9ydCB7IEFQUF9MT0NBTEVTLCBMb2NhbGVDb25maWcsIExvY2FsU2V0dGluZ3MgfSBmcm9tICcuLi9zZXJ2aWNlcy9tb2RlbC9zZXR0aW5ncy5tb2RlbCc7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvY29uZmlnLnNlcnZpY2UnO1xuaW1wb3J0IHsgUGxhdGZvcm1TZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvcGxhdGZvcm0uc2VydmljZSc7XG5pbXBvcnQgeyBMb2NhbFNldHRpbmdzU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2xvY2FsLXNldHRpbmdzLnNlcnZpY2UnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgbWFwLCBzdGFydFdpdGggfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBBcHBBdXRoTW9kYWwgfSBmcm9tICcuLi9hdXRoL2F1dGgubW9kYWwnO1xuaW1wb3J0IHsgTmV0d29ya1NlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9uZXR3b3JrLnNlcnZpY2UnO1xuaW1wb3J0IHsgSU1lbnVJdGVtLCBNZW51SXRlbXMgfSBmcm9tICcuLi9tZW51L21lbnUubW9kZWwnO1xuaW1wb3J0IHsgU2hvd1RvYXN0T3B0aW9ucywgVG9hc3RzIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3RvYXN0L3RvYXN0cyc7XG5pbXBvcnQgeyBmYWRlSW5BbmltYXRpb24sIHNsaWRlVXBEb3duQW5pbWF0aW9uIH0gZnJvbSAnLi4vLi4vc2hhcmVkL21hdGVyaWFsL21hdGVyaWFsLmFuaW1hdGlvbnMnO1xuaW1wb3J0IHsgaXNOb3ROaWwsIGlzTm90TmlsT3JCbGFuaywgdG9Cb29sZWFuIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Z1bmN0aW9ucyc7XG5pbXBvcnQgeyBFbnZpcm9ubWVudCwgRU5WSVJPTk1FTlQgfSBmcm9tICcuLi8uLi8uLi9lbnZpcm9ubWVudHMvZW52aXJvbm1lbnQuY2xhc3MnO1xuaW1wb3J0IHsgSGlzdG9yeVBhZ2VSZWZlcmVuY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9tb2RlbC9oaXN0b3J5Lm1vZGVsJztcbmltcG9ydCB7IENPUkVfQ09ORklHX09QVElPTlMgfSBmcm9tICcuLi9zZXJ2aWNlcy9jb25maWcvY29yZS5jb25maWcnO1xuaW1wb3J0IHsgUnhTdGF0ZSB9IGZyb20gJ0ByeC1hbmd1bGFyL3N0YXRlJztcbmltcG9ydCB7IEltYWdlc1V0aWxzIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2ZpbGUvaW1hZ2VzLnV0aWxzJztcblxuLyoqXG4gKiBAcGFyYW0gZmlsZXNcbiAqIEBkZXByZWNhdGVkIHVzZSBgZ2V0UmFuZG9tSW1hZ2VXaXRoQ3JlZGl0KClgIGluc3RlYWRcbiAqKi9cbmV4cG9ydCBjb25zdCBnZXRSYW5kb21JbWFnZSA9IEltYWdlc1V0aWxzLmdldFJhbmRvbUltYWdlO1xuZXhwb3J0IGNvbnN0IGdldFJhbmRvbUltYWdlV2l0aENyZWRpdCA9IEltYWdlc1V0aWxzLmdldFJhbmRvbUltYWdlV2l0aENyZWRpdDtcblxuZXhwb3J0IGNvbnN0IEFQUF9IT01FX0JVVFRPTlMgPSBuZXcgSW5qZWN0aW9uVG9rZW48SU1lbnVJdGVtW10+KCdob21lQnV0dG9uJyk7XG5leHBvcnQgaW50ZXJmYWNlIEhvbWVQYWdlU3RhdGUge1xuICBsb2FkaW5nOiBib29sZWFuO1xuICBzaG93U3Bpbm5lcjogYm9vbGVhbjtcbiAgc2hvd1BhcnRuZXJCYW5uZXI6IGJvb2xlYW47XG4gIHBhZ2VIaXN0b3J5OiBIaXN0b3J5UGFnZVJlZmVyZW5jZVtdO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtcGFnZS1ob21lJyxcbiAgdGVtcGxhdGVVcmw6ICdob21lLmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9ob21lLnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGFuaW1hdGlvbnM6IFtmYWRlSW5BbmltYXRpb24sIHNsaWRlVXBEb3duQW5pbWF0aW9uXSxcbn0pXG5leHBvcnQgY2xhc3MgSG9tZVBhZ2UgZXh0ZW5kcyBSeFN0YXRlPEhvbWVQYWdlU3RhdGU+IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSByZWFkb25seSBfZGVidWc6IGJvb2xlYW47XG4gIHByaXZhdGUgX3N1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgcHJpdmF0ZSBfY29uZmlnOiBDb25maWd1cmF0aW9uO1xuXG4gIHByb3RlY3RlZCBwYWdlSGlzdG9yeSQgPSB0aGlzLnNlbGVjdCgncGFnZUhpc3RvcnknKTtcbiAgcHJvdGVjdGVkIGxvYWRpbmckID0gdGhpcy5zZWxlY3QoJ2xvYWRpbmcnKTtcblxuICB3YWl0aW5nTmV0d29yayA9IGZhbHNlO1xuICBhY2NvdW50TmFtZSA9ICcnO1xuICBpc0xvZ2luOiBib29sZWFuO1xuICAkcGFydG5lcnMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PERlcGFydG1lbnRbXT4obnVsbCk7XG4gIGxvZ286IHN0cmluZztcbiAgZGVzY3JpcHRpb246IHN0cmluZztcbiAgYXBwTmFtZTogc3RyaW5nO1xuICBpc1dlYjogYm9vbGVhbjtcbiAgY2FuUmVnaXN0ZXI6IGJvb2xlYW47XG4gIGNvbnRlbnRTdHlsZTogYW55O1xuICBjb250ZW50Q3JlZGl0czogc3RyaW5nO1xuXG4gIG9mZmxpbmU6IGJvb2xlYW47XG4gICRmaWx0ZXJlZEJ1dHRvbnMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PElNZW51SXRlbVtdPih1bmRlZmluZWQpO1xuICByZWFkb25seSBzaG93QWNjb3VudEJ1dHRvbjogYm9vbGVhbjtcblxuICBzZXQgcGFnZUhpc3RvcnkodmFsdWU6IEhpc3RvcnlQYWdlUmVmZXJlbmNlW10pIHtcbiAgICB0aGlzLnNldCgncGFnZUhpc3RvcnknLCAoKSA9PiB2YWx1ZSk7XG4gIH1cblxuICBnZXQgcGFnZUhpc3RvcnkoKTogSGlzdG9yeVBhZ2VSZWZlcmVuY2VbXSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCdwYWdlSGlzdG9yeScpO1xuICB9XG5cbiAgc2V0IGxvYWRpbmcodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLnNldCgnbG9hZGluZycsICgpID0+IHZhbHVlKTtcbiAgfVxuXG4gIGdldCBsb2FkaW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmdldCgnbG9hZGluZycpO1xuICB9XG5cbiAgc2V0IHNob3dTcGlubmVyKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5zZXQoJ3Nob3dTcGlubmVyJywgKCkgPT4gdmFsdWUpO1xuICB9XG4gIGdldCBzaG93U3Bpbm5lcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoJ3Nob3dTcGlubmVyJyk7XG4gIH1cblxuICBzZXQgc2hvd1BhcnRuZXJCYW5uZXIodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLnNldCgnc2hvd1BhcnRuZXJCYW5uZXInLCAoKSA9PiB2YWx1ZSk7XG4gIH1cbiAgZ2V0IHNob3dQYXJ0bmVyQmFubmVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmdldCgnc2hvd1BhcnRuZXJCYW5uZXInKTtcbiAgfVxuXG4gIGdldCBjdXJyZW50TG9jYWxlQ29kZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmxvYWRpbmcgPyAnJyA6ICh0aGlzLnRyYW5zbGF0ZS5jdXJyZW50TGFuZyB8fCB0aGlzLnRyYW5zbGF0ZS5kZWZhdWx0TGFuZyB8fCB0aGlzLmVudmlyb25tZW50LmRlZmF1bHRMb2NhbGUpPy5zdWJzdHJpbmcoMCwgMik7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGFjY291bnRTZXJ2aWNlOiBBY2NvdW50U2VydmljZSxcbiAgICBwcml2YXRlIG1vZGFsQ3RybDogTW9kYWxDb250cm9sbGVyLFxuICAgIHByaXZhdGUgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgdG9hc3RDb250cm9sbGVyOiBUb2FzdENvbnRyb2xsZXIsXG4gICAgcHJpdmF0ZSBjb25maWdTZXJ2aWNlOiBDb25maWdTZXJ2aWNlLFxuICAgIHByaXZhdGUgcGxhdGZvcm06IFBsYXRmb3JtU2VydmljZSxcbiAgICBwcml2YXRlIGNkOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwdWJsaWMgbmV0d29yazogTmV0d29ya1NlcnZpY2UsXG4gICAgcHVibGljIHNldHRpbmdzOiBMb2NhbFNldHRpbmdzU2VydmljZSxcbiAgICBASW5qZWN0KEVOVklST05NRU5UKSBwcm90ZWN0ZWQgZW52aXJvbm1lbnQ6IEVudmlyb25tZW50LFxuICAgIEBJbmplY3QoQVBQX0xPQ0FMRVMpIHB1YmxpYyBsb2NhbGVzOiBMb2NhbGVDb25maWdbXSxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEFQUF9IT01FX0JVVFRPTlMpIHB1YmxpYyBidXR0b25zOiBJTWVudUl0ZW1bXVxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuc2V0KDxQYXJ0aWFsPEhvbWVQYWdlU3RhdGU+PntcbiAgICAgIGxvYWRpbmc6IHRydWUsXG4gICAgICBzaG93UGFydG5lckJhbm5lcjogZmFsc2UsXG4gICAgICBzaG93U3Bpbm5lcjogIXRoaXMucGxhdGZvcm0uc3RhcnRlZCxcbiAgICB9KTtcblxuICAgIHRoaXMuX2RlYnVnID0gIWVudmlyb25tZW50LnByb2R1Y3Rpb247XG4gICAgdGhpcy5wbGF0Zm9ybS5yZWFkeSgpLnRoZW4oKCkgPT4gdGhpcy5zdGFydCgpKTtcbiAgICB0aGlzLnNob3dBY2NvdW50QnV0dG9uID0gdG9Cb29sZWFuKGVudmlyb25tZW50LmFjY291bnQ/LnNob3dBY2NvdW50QnV0dG9uLCB0cnVlKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgYXN5bmMgbG9naW4oKSB7XG4gICAgY29uc3QgbW9kYWwgPSBhd2FpdCB0aGlzLm1vZGFsQ3RybC5jcmVhdGUoe1xuICAgICAgY29tcG9uZW50OiBBcHBBdXRoTW9kYWwsXG4gICAgfSk7XG4gICAgcmV0dXJuIG1vZGFsLnByZXNlbnQoKTtcbiAgfVxuXG4gIGFzeW5jIHJlZ2lzdGVyKCkge1xuICAgIGNvbnN0IG1vZGFsID0gYXdhaXQgdGhpcy5tb2RhbEN0cmwuY3JlYXRlKHtcbiAgICAgIGNvbXBvbmVudDogUmVnaXN0ZXJNb2RhbCxcbiAgICAgIGJhY2tkcm9wRGlzbWlzczogZmFsc2UsXG4gICAgfSk7XG4gICAgcmV0dXJuIG1vZGFsLnByZXNlbnQoKTtcbiAgfVxuXG4gIGFzeW5jIGxvZ291dChldmVudDogYW55KSB7XG4gICAgYXdhaXQgdGhpcy5hY2NvdW50U2VydmljZS5sb2dvdXQoKTtcblxuICAgIC8vIElmIHdhcyBvZmZsaW5lLCB0cnkgdG8gcmVjb25uZWN0IChiZWNhdXNlIGNhbiBiZSBhIGZvcmNlZCBvZmZsaW5lIG1vZGUpXG4gICAgaWYgKHRoaXMub2ZmbGluZSkge1xuICAgICAgYXdhaXQgdGhpcy50cnlPbmxpbmUoKTtcbiAgICB9XG4gIH1cblxuICBjaGFuZ2VMYW5ndWFnZShsb2NhbGU6IHN0cmluZykge1xuICAgIHRoaXMuc2V0dGluZ3MuYXBwbHkoeyBsb2NhbGUgfSkudGhlbigoKSA9PiB7XG4gICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0UGFnZVBhdGgoaW5kZXg6IG51bWJlciwgcGFnZTogSGlzdG9yeVBhZ2VSZWZlcmVuY2UpOiBzdHJpbmcge1xuICAgIHJldHVybiBwYWdlPy5wYXRoO1xuICB9XG5cbiAgdHJ5T25saW5lKCkge1xuICAgIHRoaXMud2FpdGluZ05ldHdvcmsgPSB0cnVlO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG5cbiAgICB0aGlzLm5ldHdvcmtcbiAgICAgIC50cnlPbmxpbmUoe1xuICAgICAgICBzaG93TG9hZGluZ1RvYXN0OiBmYWxzZSxcbiAgICAgICAgc2hvd09ubGluZVRvYXN0OiB0cnVlLFxuICAgICAgICBzaG93T2ZmbGluZVRvYXN0OiBmYWxzZSxcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMud2FpdGluZ05ldHdvcmsgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyogLS0gcHJvdGVjdGVkIG1ldGhvZCAgLS0gKi9cblxuICBwcm90ZWN0ZWQgYXN5bmMgc3RhcnQoKSB7XG4gICAgYXdhaXQgdGhpcy5hY2NvdW50U2VydmljZS5yZWFkeSgpO1xuXG4gICAgdGhpcy5pc0xvZ2luID0gdGhpcy5hY2NvdW50U2VydmljZS5pc0xvZ2luKCk7XG4gICAgaWYgKHRoaXMuaXNMb2dpbikge1xuICAgICAgdGhpcy5vbkxvZ2luKHRoaXMuYWNjb3VudFNlcnZpY2UuYWNjb3VudCk7XG4gICAgfVxuXG4gICAgdGhpcy5vZmZsaW5lID0gdGhpcy5uZXR3b3JrLm9mZmxpbmU7XG5cbiAgICAvLyBMaXN0ZW4gbG9naW4vbG9nb3V0IGV2ZW50c1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbi5hZGQodGhpcy5hY2NvdW50U2VydmljZS5vbkxvZ2luLnN1YnNjcmliZSgoYWNjb3VudCkgPT4gdGhpcy5vbkxvZ2luKGFjY291bnQpKSk7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZCh0aGlzLmFjY291bnRTZXJ2aWNlLm9uTG9nb3V0LnN1YnNjcmliZSgoKSA9PiB0aGlzLm9uTG9nb3V0KCkpKTtcblxuICAgIC8vIExpc3RlbiBwb2QgY29uZmlnXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZCh0aGlzLmNvbmZpZ1NlcnZpY2UuY29uZmlnLnN1YnNjcmliZSgoY29uZmlnKSA9PiB0aGlzLm9uQ29uZmlnTG9hZGVkKGNvbmZpZykpKTtcblxuICAgIC8vIExpc3RlbiBzZXR0aW5ncyBjaGFuZ2VzXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgIHRoaXMuc2V0dGluZ3Mub25DaGFuZ2VcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgLy8gQWRkIGEgZGVsYXksIHRvIGF2b2lkIHRvIGFwcGx5IGNoYW5nZXMgdG8gb2Z0ZW5cbiAgICAgICAgICBkZWJvdW5jZVRpbWUoMjUwKSxcbiAgICAgICAgICAvLyBTdGFydCB3aXRoIGN1cnJlbnQgc2V0dGluZ3NcbiAgICAgICAgICBzdGFydFdpdGgoYXdhaXQgdGhpcy5zZXR0aW5ncy5yZWFkeSgpKVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKHJlcykgPT4gdGhpcy5vblNldHRpbmdzQ2hhbmdlZChyZXMpKVxuICAgICk7XG5cbiAgICAvLyBMaXN0ZW4gbmV0d29yayBjaGFuZ2VzXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgIHRoaXMubmV0d29yay5vbk5ldHdvcmtTdGF0dXNDaGFuZ2VzXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIC8vZGVib3VuY2VUaW1lKDQ1MCksXG4gICAgICAgICAgLy90YXAoKCkgPT4gdGhpcy53YWl0aW5nTmV0d29yayA9IGZhbHNlKSxcbiAgICAgICAgICBtYXAoKGNvbm5lY3Rpb25UeXBlKSA9PiBjb25uZWN0aW9uVHlwZSA9PT0gJ25vbmUnKSxcbiAgICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZSgob2ZmbGluZSkgPT4ge1xuICAgICAgICAgIHRoaXMub2ZmbGluZSA9IG9mZmxpbmU7XG4gICAgICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHNob3dUb2FzdChvcHRzOiBTaG93VG9hc3RPcHRpb25zKSB7XG4gICAgYXdhaXQgVG9hc3RzLnNob3codGhpcy50b2FzdENvbnRyb2xsZXIsIHRoaXMudHJhbnNsYXRlLCBvcHRzKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvbkNvbmZpZ0xvYWRlZChjb25maWc6IENvbmZpZ3VyYXRpb24pIHtcbiAgICBjb25zb2xlLmRlYnVnKCdbaG9tZV0gQXBwbHlpbmcgY29uZmlndXJhdGlvbicsIGNvbmZpZyk7XG4gICAgdGhpcy5fY29uZmlnID0gY29uZmlnO1xuXG4gICAgdGhpcy5hcHBOYW1lID0gY29uZmlnLmxhYmVsIHx8IHRoaXMuZW52aXJvbm1lbnQuZGVmYXVsdEFwcE5hbWUgfHwgJ1NVTUFSaVMnO1xuICAgIHRoaXMubG9nbyA9IGNvbmZpZy5sYXJnZUxvZ28gfHwgY29uZmlnLnNtYWxsTG9nbyB8fCB1bmRlZmluZWQ7XG4gICAgdGhpcy5kZXNjcmlwdGlvbiA9IGNvbmZpZy5uYW1lO1xuICAgIHRoaXMuaXNXZWIgPSB0aGlzLnBsYXRmb3JtLmlzV2ViKCk7XG4gICAgdGhpcy5jYW5SZWdpc3RlciA9IGNvbmZpZy5nZXRQcm9wZXJ0eUFzQm9vbGVhbihDT1JFX0NPTkZJR19PUFRJT05TLlJFR0lTVFJBVElPTl9FTkFCTEUpO1xuXG4gICAgY29uc3QgcGFydG5lcnMgPSAoY29uZmlnLnBhcnRuZXJzIHx8IFtdKS5maWx0ZXIoKHApID0+IHAgJiYgcC5sb2dvKTtcbiAgICB0aGlzLiRwYXJ0bmVycy5uZXh0KHBhcnRuZXJzKTtcbiAgICB0aGlzLnNob3dQYXJ0bmVyQmFubmVyID0gcGFydG5lcnMubGVuZ3RoID4gMDtcblxuICAgIC8vIElmIG5vdCBhbHJlYWR5IHNldCwgY29tcHV0ZSB0aGUgYmFja2dyb3VuZCBpbWFnZVxuICAgIGlmICghdGhpcy5jb250ZW50U3R5bGUpIHtcbiAgICAgIGNvbnN0IGJhY2tncm91bmRJbWFnZXMgPSAoY29uZmlnLmJhY2tncm91bmRJbWFnZXMgfHwgW10pXG4gICAgICAgIC8vIEZpbHRlciBvbiBub3QgbmlsLCBiZWNhdXNlIGNhbiBvY2N1ciBpZiBkZXRlY3RlZCBoYXMgbm90IGV4aXN0cyAoc2VlIGNvbmZpZy1zZXJ2aWNlLmpzKVxuICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgIChpbWcpID0+XG4gICAgICAgICAgICBpc05vdE5pbChpbWcpICYmXG4gICAgICAgICAgICAvLyBJZiBvZmZsaW5lLCBmaWx0ZXIgb24gbG9jYWwgZGF0YVVSTCBpbWFnZVxuICAgICAgICAgICAgKCF0aGlzLm9mZmxpbmUgfHwgIWltZy5zdGFydHNXaXRoKCdodHRwJykpXG4gICAgICAgICk7XG5cbiAgICAgIC8vIEJhY2tncm91bmQgaW1hZ2UgZm91bmQ6IHNlbGVjdCBvbmUgcmFuZG9tbHlcbiAgICAgIGlmIChiYWNrZ3JvdW5kSW1hZ2VzLmxlbmd0aCkge1xuICAgICAgICBjb25zdCB7IGltYWdlLCBjcmVkaXRzIH0gPSBnZXRSYW5kb21JbWFnZVdpdGhDcmVkaXQoYmFja2dyb3VuZEltYWdlcyk7XG4gICAgICAgIHRoaXMuY29udGVudFN0eWxlID0gaW1hZ2UgPyB7ICdiYWNrZ3JvdW5kLWltYWdlJzogYHVybCgke2ltYWdlfSlgIH0gOiB7fTtcbiAgICAgICAgdGhpcy5jb250ZW50Q3JlZGl0cyA9IGNyZWRpdHMgfHwgJyc7XG4gICAgICB9XG5cbiAgICAgIC8vIFVzZSBiYWNrZ3JvdW5kIGNvbG9yXG4gICAgICBlbHNlIHtcbiAgICAgICAgY29uc3QgcHJpbWFyeUNvbG9yID0gY29uZmlnLmdldFByb3BlcnR5KENPUkVfQ09ORklHX09QVElPTlMuQ09MT1JfUFJJTUFSWSkgfHwgJ3ZhcigtLWlvbi1jb2xvci1wcmltYXJ5KSc7XG4gICAgICAgIHRoaXMuY29udGVudFN0eWxlID0gKHByaW1hcnlDb2xvciAmJiB7ICdiYWNrZ3JvdW5kLWNvbG9yJzogcHJpbWFyeUNvbG9yIH0pIHx8IHt9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMucmVmcmVzaEJ1dHRvbnMoKTtcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgLy8gSWYgZmlyc3QgbG9hZCwgaGlkZSB0aGUgbG9hZGluZyBpbmRpY2F0b3JcbiAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblNldHRpbmdzQ2hhbmdlZChzZXR0aW5nczogTG9jYWxTZXR0aW5ncykge1xuICAgIGlmIChzZXR0aW5ncy5wYWdlSGlzdG9yeSAhPT0gdGhpcy5wYWdlSGlzdG9yeSkge1xuICAgICAgY29uc29sZS5kZWJ1ZygnW2hvbWVdIFBhZ2UgaGlzdG9yeSBsb2FkZWQnKTtcbiAgICAgIHRoaXMucGFnZUhpc3RvcnkgPSBzZXR0aW5ncy5wYWdlSGlzdG9yeSB8fCBbXTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgb25Mb2dpbihhY2NvdW50OiBBY2NvdW50KSB7XG4gICAgaWYgKCFhY2NvdW50KSByZXR1cm47IC8vIFNraXBcbiAgICAvL2NvbnNvbGUuZGVidWcoJ1tob21lXSBMb2dnZWQgYWNjb3VudDogJywgYWNjb3VudCk7XG4gICAgdGhpcy5pc0xvZ2luID0gdHJ1ZTtcbiAgICB0aGlzLmFjY291bnROYW1lID0gYWNjb3VudFRvU3RyaW5nKGFjY291bnQpO1xuICAgIHRoaXMucmVmcmVzaEJ1dHRvbnMoYWNjb3VudCk7XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvbkxvZ291dCgpIHtcbiAgICB0aGlzLmlzTG9naW4gPSBmYWxzZTtcbiAgICB0aGlzLmFjY291bnROYW1lID0gJyc7XG4gICAgdGhpcy5wYWdlSGlzdG9yeSA9IFtdO1xuICAgIHRoaXMucmVmcmVzaEJ1dHRvbnMoKTtcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJlZnJlc2hCdXR0b25zKGFjY291bnQ/OiBBY2NvdW50KSB7XG4gICAgaWYgKCF0aGlzLl9jb25maWcpIHJldHVybjsgLy8gU2tpcCAod2FpdGluZyBjb25maWcgdG8gYmUgbG9hZGVkKVxuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZygnW2hvbWVdIFJlZnJlc2hpbmcgYnV0dG9ucy4uLicpO1xuXG4gICAgYWNjb3VudCA9IGFjY291bnQgfHwgdGhpcy5hY2NvdW50U2VydmljZS5hY2NvdW50O1xuICAgIGNvbnN0IGZpbHRlcmVkQnV0dG9ucyA9ICh0aGlzLmJ1dHRvbnMgfHwgW10pXG4gICAgICAuZmlsdGVyKChpdGVtKSA9PlxuICAgICAgICBNZW51SXRlbXMuY2hlY2tJZlZpc2libGUoaXRlbSwgYWNjb3VudCwgdGhpcy5fY29uZmlnLCB7XG4gICAgICAgICAgaXNMb2dpbjogdGhpcy5pc0xvZ2luLFxuICAgICAgICAgIGRlYnVnOiB0aGlzLl9kZWJ1ZyxcbiAgICAgICAgICBsb2dQcmVmaXg6ICdbaG9tZV0nLFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLm1hcCgoaXRlbSkgPT4ge1xuICAgICAgICAvLyBSZXBsYWNlIHRpdGxlIHVzaW5nIHByb3BlcnRpZXNcbiAgICAgICAgaWYgKGlzTm90TmlsT3JCbGFuayhpdGVtLnRpdGxlUHJvcGVydHkpICYmIHRoaXMuX2NvbmZpZykge1xuICAgICAgICAgIGNvbnN0IHRpdGxlID0gdGhpcy5fY29uZmlnLnByb3BlcnRpZXNbaXRlbS50aXRsZVByb3BlcnR5XTtcbiAgICAgICAgICBpZiAodGl0bGUpIHJldHVybiB7IC4uLml0ZW0sIHRpdGxlIH07IC8vIENyZWF0ZSBhIGNvcHksIHRvIGtlZXAgdGhlIG9yaWdpbmFsIGl0ZW0udGl0bGVcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy4kZmlsdGVyZWRCdXR0b25zLm5leHQoZmlsdGVyZWRCdXR0b25zKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyByZW1vdmVQYWdlSGlzdG9yeShwYXRoOiBzdHJpbmcpIHtcbiAgICBhd2FpdCB0aGlzLnNldHRpbmdzLnJlbW92ZVBhZ2VIaXN0b3J5KHBhdGgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIG1hcmtGb3JDaGVjaygpIHtcbiAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICB9XG59XG4iLCI8YXBwLXRvb2xiYXIgW2NhbkdvQmFja109XCJmYWxzZVwiIHZpc2libGUteHMgdmlzaWJsZS1zbSB2aXNpYmxlLW1vYmlsZT5cbiAgPCEtLSBjaGFuZ2UgbG9jYWxlIGJ1dHRvbiAtLT5cbiAgPGlvbi1idXR0b24gc2xvdD1cImVuZFwiICpuZ0lmPVwiY3VycmVudExvY2FsZUNvZGU7IGxldCBjb2RlXCIgW21hdE1lbnVUcmlnZ2VyRm9yXT1cImxvY2FsZU1lbnVcIj5cbiAgICA8aW9uLWljb24gc2xvdD1cImljb24tb25seVwiIG5hbWU9XCJsYW5ndWFnZVwiPjwvaW9uLWljb24+XG4gICAgPG1hdC1pY29uIHNsb3Q9XCJlbmRcIj5hcnJvd19kcm9wX2Rvd248L21hdC1pY29uPlxuICA8L2lvbi1idXR0b24+XG48L2FwcC10b29sYmFyPlxuXG48IS0tIGNoYW5nZSBsb2NhbGUgbWVudSAtLT5cbjxtYXQtbWVudSAjbG9jYWxlTWVudT1cIm1hdE1lbnVcIj5cbiAgPGJ1dHRvbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBsb2NhbGVzXCIgbWF0LW1lbnUtaXRlbSAoY2xpY2spPVwiY2hhbmdlTGFuZ3VhZ2UoaXRlbS5rZXkpXCI+XG4gICAgPGlvbi1sYWJlbD57eyBpdGVtLnZhbHVlIH19PC9pb24tbGFiZWw+XG4gIDwvYnV0dG9uPlxuPC9tYXQtbWVudT5cblxuPGlvbi1jb250ZW50IFtuZ1N0eWxlXT1cImNvbnRlbnRTdHlsZVwiIG5vLXBhZGRpbmcteHM+XG4gIEBpZiAoY29udGVudENyZWRpdHMgfCBpc05vdE5pbE9yQmxhbmspIHtcbiAgICA8c3BhbiBjbGFzcz1cImNvbnRlbnQtY3JlZGl0c1wiPlxuICAgICAgPGlvbi10ZXh0Pnt7IGNvbnRlbnRDcmVkaXRzIH19PC9pb24tdGV4dD5cbiAgICA8L3NwYW4+XG4gIH1cblxuICA8IS0tIGxvYWRpbmcgc3Bpbm5lciAtLT5cbiAgPGRpdiBjbGFzcz1cImxvYWRpbmctcGFnZVwiIFtjbGFzcy5jZGstdmlzdWFsbHktaGlkZGVuXT1cIiEobG9hZGluZyQgfCBwdXNoKVwiPlxuICAgIEBpZiAoc2hvd1NwaW5uZXIpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJzcGlubmVyXCI+XG4gICAgICAgIDxwIFtpbm5lckhUTUxdPVwiJ0NPTU1PTi5MT0FESU5HX0RPVFMnIHwgdHJhbnNsYXRlXCI+PC9wPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2stY3ViZTEgc2stY3ViZVwiPjwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2stY3ViZTIgc2stY3ViZVwiPjwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2stY3ViZTQgc2stY3ViZVwiPjwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2stY3ViZTMgc2stY3ViZVwiPjwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgfVxuICA8L2Rpdj5cblxuICA8IS0tIERlc2t0b3A6IHRyYW5zbHVjZW50IHRvcCB0b29sYmFyIC0tPlxuICA8ZGl2IGhpZGRlbi14cyBoaWRkZW4tc20gaGlkZGVuLW1vYmlsZT5cbiAgICA8aW9uLXRvb2xiYXIgdHJhbnNsdWNlbnQ+XG4gICAgICA8aW9uLWJ1dHRvbnMgc2xvdD1cInN0YXJ0XCI+XG4gICAgICAgIDxpb24tbWVudS10b2dnbGU+XG4gICAgICAgICAgPGlvbi1idXR0b24gY29sb3I9XCJsaWdodFwiIGZpbGw9XCJjbGVhclwiPlxuICAgICAgICAgICAgPGlvbi1pY29uIHNsb3Q9XCJpY29uLW9ubHlcIiBuYW1lPVwibWVudVwiPjwvaW9uLWljb24+XG4gICAgICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgICA8L2lvbi1tZW51LXRvZ2dsZT5cbiAgICAgIDwvaW9uLWJ1dHRvbnM+XG5cbiAgICAgIDxpb24tYnV0dG9ucyBzbG90PVwiZW5kXCI+XG4gICAgICAgIDwhLS0gY2hhbmdlIGxvY2FsZSBidXR0b24gLS0+XG4gICAgICAgIEBpZiAoY3VycmVudExvY2FsZUNvZGU7IGFzIGNvZGUpIHtcbiAgICAgICAgICA8aW9uLWJ1dHRvblxuICAgICAgICAgICAgY29sb3I9XCJzZWNvbmRhcnlcIlxuICAgICAgICAgICAgZmlsbD1cInNvbGlkXCJcbiAgICAgICAgICAgIFttYXRNZW51VHJpZ2dlckZvcl09XCJsb2NhbGVNZW51XCJcbiAgICAgICAgICAgIFt0aXRsZV09XCInU0VUVElOR1MuTE9DQUxFJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGlvbi1pY29uIHNsb3Q9XCJpY29uLW9ubHlcIiBuYW1lPVwibGFuZ3VhZ2VcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgPG1hdC1pY29uIHNsb3Q9XCJlbmRcIj5hcnJvd19kcm9wX2Rvd248L21hdC1pY29uPlxuICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgICAgfVxuICAgICAgPC9pb24tYnV0dG9ucz5cbiAgICA8L2lvbi10b29sYmFyPlxuICA8L2Rpdj5cblxuICA8IS0tIEluc3RhbGwgKGFuZCB1cGdyYWRlKSBjYXJkIC0tPlxuICA8YXBwLWluc3RhbGwtdXBncmFkZS1jYXJkIFtpc0xvZ2luXT1cImlzTG9naW5cIiBbc2hvd0luc3RhbGxCdXR0b25dPVwidHJ1ZVwiPjwvYXBwLWluc3RhbGwtdXBncmFkZS1jYXJkPlxuXG4gIEBpZiAoIShsb2FkaW5nJCB8IHB1c2gpKSB7XG4gICAgPCEtLSBXZWxjb21lIGNhcmQgLS0+XG4gICAgPGlvbi1jYXJkIGNsYXNzPVwibWFpbiB3ZWxjb21lIGlvbi1wYWRkaW5nIGlvbi10ZXh0LWNlbnRlciBpb24tYWxpZ24tc2VsZi1jZW50ZXJcIiBAZmFkZUluQW5pbWF0aW9uPlxuICAgICAgPGlvbi1jYXJkLWhlYWRlcj5cbiAgICAgICAgPGlvbi1jYXJkLXRpdGxlIGNsYXNzPVwiaW9uLXRleHQtY2VudGVyXCI+XG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJpc1dlYlwiIFtpbm5lckhUTUxdPVwiJ0hPTUUuV0VMQ09NRV9XRUInIHwgdHJhbnNsYXRlOiB7IGFwcE5hbWU6IGFwcE5hbWUgfVwiPjwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiAqbmdJZj1cIiFpc1dlYlwiIFtpbm5lckhUTUxdPVwiJ0hPTUUuV0VMQ09NRV9BUFAnIHwgdHJhbnNsYXRlOiB7IGFwcE5hbWU6IGFwcE5hbWUgfVwiPjwvc3Bhbj5cbiAgICAgICAgPC9pb24tY2FyZC10aXRsZT5cbiAgICAgICAgPGlvbi1jYXJkLXN1YnRpdGxlIFtpbm5lckhUTUxdPVwiZGVzY3JpcHRpb25cIj48L2lvbi1jYXJkLXN1YnRpdGxlPlxuICAgICAgPC9pb24tY2FyZC1oZWFkZXI+XG4gICAgICA8aW9uLWNhcmQtY29udGVudCBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICAgIDxpb24tdGV4dCBjb2xvcj1cInByaW1hcnlcIj5cbiAgICAgICAgICA8aW1nICpuZ0lmPVwibG9nb1wiIFthdHRyLnNyY109XCJsb2dvXCIgYWx0PVwiTG9nb1wiIC8+XG4gICAgICAgIDwvaW9uLXRleHQ+XG4gICAgICAgIDwhLS0gcmVnaXN0ZXIgaGVscCB0ZXh0IC0tPlxuICAgICAgICA8aW9uLXRleHQgKm5nSWY9XCIhaXNMb2dpbiAmJiBjYW5SZWdpc3RlclwiPlxuICAgICAgICAgIDxiciAvPlxuICAgICAgICAgIDxzcGFuIHRyYW5zbGF0ZT5IT01FLlJFR0lTVEVSX0hFTFA8L3NwYW4+XG4gICAgICAgIDwvaW9uLXRleHQ+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJpb24tcGFkZGluZy10b3BcIj5cbiAgICAgICAgICA8IS0tIElmIE5PVCBsb2dpbiAtLT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzTG9naW47IGVsc2UgbG9naW5CdXR0b25zXCI+XG4gICAgICAgICAgICA8aW9uLWJ1dHRvbiAqbmdJZj1cImNhblJlZ2lzdGVyXCIgZXhwYW5kPVwiYmxvY2tcIiBjb2xvcj1cInRlcnRpYXJ5XCIgKGNsaWNrKT1cInJlZ2lzdGVyKClcIj5cbiAgICAgICAgICAgICAgPHNwYW4gdHJhbnNsYXRlPkhPTUUuQlROX1JFR0lTVEVSPC9zcGFuPlxuICAgICAgICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgICAgICAgPGlvbi1idXR0b24gZXhwYW5kPVwiYmxvY2tcIiBjb2xvcj1cImxpZ2h0XCIgW3JvdXRlckxpbmtdPVwiWycvJ11cIiAoY2xpY2spPVwibG9naW4oKVwiPlxuICAgICAgICAgICAgICA8c3BhbiB0cmFuc2xhdGU+QVVUSC5CVE5fTE9HSU48L3NwYW4+XG4gICAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICA8IS0tIElmIHVzZXIgbG9naW4gLS0+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNsb2dpbkJ1dHRvbnM+XG4gICAgICAgICAgICA8IS0tIEZlYXR1cmUgYnV0dG9ucyAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKnJ4SWY9XCIkZmlsdGVyZWRCdXR0b25zOyBsZXQgYnV0dG9uc1wiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGJ1dHRvbnNcIj5cbiAgICAgICAgICAgICAgICA8aW9uLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgKm5nSWY9XCJpdGVtLnBhdGhcIlxuICAgICAgICAgICAgICAgICAgZXhwYW5kPVwiYmxvY2tcIlxuICAgICAgICAgICAgICAgICAgY29sb3I9XCJ0ZXJ0aWFyeVwiXG4gICAgICAgICAgICAgICAgICBbY2xhc3NdPVwiaXRlbS5jc3NDbGFzc1wiXG4gICAgICAgICAgICAgICAgICBbcm91dGVyTGlua109XCJpdGVtLnBhdGhcIlxuICAgICAgICAgICAgICAgICAgcm91dGVyRGlyZWN0aW9uPVwicm9vdFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPGlvbi1pY29uIHNsb3Q9XCJzdGFydFwiIGNsYXNzPVwiaW9uLWZsb2F0LXN0YXJ0XCIgKm5nSWY9XCJpdGVtLmljb25cIiBbbmFtZV09XCJpdGVtLmljb25cIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIHNsb3Q9XCJzdGFydFwiIGNsYXNzPVwiaW9uLWZsb2F0LXN0YXJ0XCIgKm5nSWY9XCJpdGVtLm1hdEljb25cIj57eyBpdGVtLm1hdEljb24gfX08L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgPGlvbi10ZXh0Pnt7ICdIT01FLkJUTl9EQVRBX0VOVFJZJyB8IHRyYW5zbGF0ZTogeyBuYW1lOiAoaXRlbS50aXRsZSB8IHRyYW5zbGF0ZSkgfSB9fTwvaW9uLXRleHQ+XG4gICAgICAgICAgICAgICAgPC9pb24tYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgPCEtLSBkaXZpZGVyIC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhaXRlbS5wYXRoICYmICFpdGVtLmFjdGlvblwiIFtjbGFzc109XCJpdGVtLmNzc0NsYXNzXCI+XG4gICAgICAgICAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT57eyBpdGVtLnRpdGxlIH19Jm5ic3A7PC9pb24tbGFiZWw+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgIDwhLS08cCAqbmdJZj1cImJ1dHRvbnMubGVuZ3RoXCIgY2xhc3M9XCJ2aXNpYmxlLW1vYmlsZVwiPiZuYnNwOzwvcD4tLT5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8aW9uLWJ1dHRvbiAqbmdJZj1cInNob3dBY2NvdW50QnV0dG9uXCIgZXhwYW5kPVwiYmxvY2tcIiBjb2xvcj1cInNlY29uZGFyeVwiIFtyb3V0ZXJMaW5rXT1cIlsnL2FjY291bnQnXVwiPlxuICAgICAgICAgICAgICA8aW9uLWljb24gc2xvdD1cInN0YXJ0XCIgY2xhc3M9XCJpb24tZmxvYXQtc3RhcnRcIiBuYW1lPVwicGVyc29uLWNpcmNsZVwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgIDxpb24tdGV4dCB0cmFuc2xhdGU+SE9NRS5CVE5fTVlfQUNDT1VOVDwvaW9uLXRleHQ+XG4gICAgICAgICAgICA8L2lvbi1idXR0b24+XG5cbiAgICAgICAgICAgIDxwIGhpZGRlbi14cyBoaWRkZW4tc20gaGlkZGVuLW1vYmlsZT5cbiAgICAgICAgICAgICAgPGlvbi10ZXh0XG4gICAgICAgICAgICAgICAgW2lubmVySFRNTF09XCInSE9NRS5OT1RfVEhJU19BQ0NPVU5UX1FVRVNUSU9OJyB8IHRyYW5zbGF0ZTogeyBkaXNwbGF5TmFtZTogYWNjb3VudE5hbWUgfVwiXG4gICAgICAgICAgICAgID48L2lvbi10ZXh0PlxuICAgICAgICAgICAgICA8YnIgLz5cbiAgICAgICAgICAgICAgPGlvbi10ZXh0PlxuICAgICAgICAgICAgICAgIDxhIGhyZWY9XCIjXCIgKGNsaWNrKT1cImxvZ291dCgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiB0cmFuc2xhdGU+SE9NRS5CVE5fRElTQ09OTkVDVDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgIDwvaW9uLXRleHQ+XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2lvbi1jYXJkLWNvbnRlbnQ+XG4gICAgPC9pb24tY2FyZD5cblxuICAgIDwhLS0gUGFnZSBoaXN0b3J5IC0tPlxuICAgIEBpZiAoaXNMb2dpbiAmJiAocGFnZUhpc3RvcnkkIHwgcHVzaCk7IGFzIHBhZ2VIaXN0b3J5KSB7XG4gICAgICA8aW9uLWdyaWQgY2xhc3M9XCJoaXN0b3J5LWNvbnRhaW5lciBpb24tYWxpZ24tc2VsZi1jZW50ZXJcIj5cbiAgICAgICAgPGlvbi1yb3c+XG4gICAgICAgICAgQGZvciAocGFnZSBvZiBwYWdlSGlzdG9yeTsgdHJhY2sgcGFnZS5wYXRoKSB7XG4gICAgICAgICAgICA8aW9uLWNvbCBzaXplPVwiMTJcIiBzaXplLXhsPVwiXCIgY2xhc3M9XCJpb24tdGV4dC1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgPGlvbi1jYXJkIGNsYXNzPVwiaW9uLWFsaWduLXNlbGYtc3RhcnQgaW9uLXRleHQtc3RhcnRcIiBAZmFkZUluQW5pbWF0aW9uPlxuICAgICAgICAgICAgICAgIDxpb24tY2FyZC1oZWFkZXIgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuICAgICAgICAgICAgICAgICAgPCEtLSB0b3AgYmFyIC0tPlxuICAgICAgICAgICAgICAgICAgPGlvbi1jYXJkLXN1YnRpdGxlPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgdGFiaW5kZXg9XCItMVwiXG4gICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJlbW92ZVBhZ2VIaXN0b3J5KHBhZ2UucGF0aClcIlxuICAgICAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaW9uLWZsb2F0LXN0YXJ0IGlvbi1uby1tYXJnaW4gY2xvc2UtYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jbG9zZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWxhYmVsIFtpbm5lckhUTUxdPVwicGFnZS5zdWJ0aXRsZSB8IHRyYW5zbGF0ZVwiPjwvaW9uLWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLXRleHQgY2xhc3M9XCJpb24tZmxvYXQtZW5kXCIgW3RpdGxlXT1cInBhZ2UudGltZSB8IGRhdGVGb3JtYXQ6IHsgdGltZTogdHJ1ZSB9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHNtYWxsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1pY29uIG5hbWU9XCJ0aW1lLW91dGxpbmVcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgJm5ic3A7e3sgcGFnZS50aW1lIHwgZGF0ZUZyb21Ob3cgfX1cbiAgICAgICAgICAgICAgICAgICAgICA8L3NtYWxsPlxuICAgICAgICAgICAgICAgICAgICAgICZuYnNwO1xuICAgICAgICAgICAgICAgICAgICA8L2lvbi10ZXh0PlxuICAgICAgICAgICAgICAgICAgPC9pb24tY2FyZC1zdWJ0aXRsZT5cblxuICAgICAgICAgICAgICAgICAgPCEtLSBtYWluIHBhZ2UgLS0+XG4gICAgICAgICAgICAgICAgICA8aW9uLWNhcmQtdGl0bGUgY2xhc3M9XCJpb24tbm8tbWFyZ2luIGlvbi1uby1wYWRkaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgIDxpb24taXRlbVxuICAgICAgICAgICAgICAgICAgICAgIGRldGFpbD1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgIHRhcHBhYmxlXG4gICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LTF4XCJcbiAgICAgICAgICAgICAgICAgICAgICBbcm91dGVyTGlua109XCJwYWdlLnBhdGhcIlxuICAgICAgICAgICAgICAgICAgICAgIHJvdXRlckRpcmVjdGlvbj1cInJvb3RcIlxuICAgICAgICAgICAgICAgICAgICAgIGxpbmVzPVwibm9uZVwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICA8IS0tIHBhZ2UgaWNvbi0tPlxuICAgICAgICAgICAgICAgICAgICAgIDxpb24taWNvbiAqbmdJZj1cInBhZ2UuaWNvblwiIHNsb3Q9XCJzdGFydFwiIFtuYW1lXT1cInBhZ2UuaWNvblwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwicGFnZS5tYXRJY29uXCIgc2xvdD1cInN0YXJ0XCI+e3sgcGFnZS5tYXRJY29uIH19PC9tYXQtaWNvbj5cblxuICAgICAgICAgICAgICAgICAgICAgIDxpb24tbGFiZWwgY29sb3I9XCJwcmltYXJ5XCIgW2lubmVySFRNTF09XCJwYWdlLnRpdGxlXCI+PC9pb24tbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDwvaW9uLWl0ZW0+XG4gICAgICAgICAgICAgICAgICA8L2lvbi1jYXJkLXRpdGxlPlxuICAgICAgICAgICAgICAgIDwvaW9uLWNhcmQtaGVhZGVyPlxuXG4gICAgICAgICAgICAgICAgPCEtLSBjaGlsZHJlbiBwYWdlcyAtLT5cbiAgICAgICAgICAgICAgICBAaWYgKHBhZ2UuY2hpbGRyZW4gfCBpc05vdEVtcHR5QXJyYXkpIHtcbiAgICAgICAgICAgICAgICAgIDxpb24tY2FyZC1jb250ZW50IGNsYXNzPVwiaW9uLW5vLXBhZGRpbmcgaW9uLXBhZGRpbmctc3RhcnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGlvbi1saXN0IGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICBAZm9yIChjaGlsZFBhZ2Ugb2YgcGFnZS5jaGlsZHJlbjsgdHJhY2sgY2hpbGRQYWdlLnBhdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxpb24taXRlbVxuICAgICAgICAgICAgICAgICAgICAgICAgICBkZXRhaWw9XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGFwcGFibGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LTF4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW3JvdXRlckxpbmtdPVwiY2hpbGRQYWdlLnBhdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICByb3V0ZXJEaXJlY3Rpb249XCJyb290XCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBwYWdlIGljb24tLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1pY29uICpuZ0lmPVwiY2hpbGRQYWdlLmljb25cIiBzbG90PVwic3RhcnRcIiBjb2xvcj1cImRhcmtcIiBbbmFtZV09XCJjaGlsZFBhZ2UuaWNvblwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImNoaWxkUGFnZS5tYXRJY29uXCIgc2xvdD1cInN0YXJ0XCIgY29sb3I9XCJkYXJrXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY2hpbGRQYWdlLm1hdEljb24gfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtaWNvbj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICA8aW9uLWxhYmVsIGNvbG9yPVwiZGFya1wiIFtpbm5lckhUTUxdPVwiY2hpbGRQYWdlLnRpdGxlXCI+PC9pb24tbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2lvbi1pdGVtPlxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgPC9pb24tbGlzdD5cbiAgICAgICAgICAgICAgICAgIDwvaW9uLWNhcmQtY29udGVudD5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvaW9uLWNhcmQ+XG4gICAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgfVxuICAgICAgICA8L2lvbi1yb3c+XG4gICAgICA8L2lvbi1ncmlkPlxuICAgIH0gQGVsc2UgaWYgKHNob3dQYXJ0bmVyQmFubmVyKSB7XG4gICAgICA8IS0tIERpc3BsYXkgcGFydG5lcnMgbG9nb3MgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiYm90dG9tLWJhbm5lciBpb24tdGV4dC1jZW50ZXIgaW9uLXBhZGRpbmdcIiBAZmFkZUluQW5pbWF0aW9uPlxuICAgICAgICBAZm9yIChpdGVtIG9mICRwYXJ0bmVycyB8IGFzeW5jOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgICA8YSBocmVmPVwie3sgaXRlbS5zaXRlVXJsIH19XCI+XG4gICAgICAgICAgICA8aW1nIGNsYXNzPVwibG9nb1wiIHNyYz1cInt7IGl0ZW0ubG9nbyB9fVwiIGFsdD1cInt7IGl0ZW0ubGFiZWwgfX1cIiBbdGl0bGVdPVwiaXRlbS5sYWJlbFwiIC8+XG4gICAgICAgICAgPC9hPlxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICB9XG4gIH1cbjwvaW9uLWNvbnRlbnQ+XG4iXX0=