@sumaris-net/ngx-components 2.5.16 → 2.6.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 (329) hide show
  1. package/doc/changelog.md +86 -0
  2. package/esm2020/public_api.mjs +13 -3
  3. package/esm2020/src/app/admin/admin-routing.module.mjs +5 -5
  4. package/esm2020/src/app/admin/admin.module.mjs +5 -5
  5. package/esm2020/src/app/admin/services/person.service.mjs +4 -4
  6. package/esm2020/src/app/admin/services/validator/person.validator.mjs +4 -4
  7. package/esm2020/src/app/admin/users/users.mjs +6 -6
  8. package/esm2020/src/app/admin/users/users.module.mjs +5 -5
  9. package/esm2020/src/app/core/about/about.modal.mjs +4 -4
  10. package/esm2020/src/app/core/about/about.module.mjs +5 -5
  11. package/esm2020/src/app/core/account/account.module.mjs +5 -5
  12. package/esm2020/src/app/core/account/account.page.mjs +25 -26
  13. package/esm2020/src/app/core/account/new-token.modal.mjs +4 -4
  14. package/esm2020/src/app/core/account/token.table.mjs +5 -5
  15. package/esm2020/src/app/core/auth/auth.form.mjs +4 -4
  16. package/esm2020/src/app/core/auth/auth.modal.mjs +4 -4
  17. package/esm2020/src/app/core/auth/auth.module.mjs +5 -5
  18. package/esm2020/src/app/core/core.module.mjs +14 -14
  19. package/esm2020/src/app/core/core.testing.module.mjs +5 -5
  20. package/esm2020/src/app/core/form/buttons/form-buttons-bar.component.mjs +4 -4
  21. package/esm2020/src/app/core/form/buttons/form-buttons-bar.module.mjs +5 -5
  22. package/esm2020/src/app/core/form/entity/editor.class.mjs +19 -15
  23. package/esm2020/src/app/core/form/entity/entity-editor-modal.class.mjs +11 -9
  24. package/esm2020/src/app/core/form/entity/entity-editor.class.mjs +87 -68
  25. package/esm2020/src/app/core/form/entity/entity-metadata.component.mjs +4 -4
  26. package/esm2020/src/app/core/form/entity/entity.module.mjs +5 -5
  27. package/esm2020/src/app/core/form/form.class.mjs +6 -6
  28. package/esm2020/src/app/core/form/form.module.mjs +5 -5
  29. package/esm2020/src/app/core/form/form.utils.mjs +2 -2
  30. package/esm2020/src/app/core/form/list/list.form.mjs +4 -4
  31. package/esm2020/src/app/core/form/list/list.module.mjs +5 -5
  32. package/esm2020/src/app/core/form/properties/properties.form.mjs +9 -6
  33. package/esm2020/src/app/core/form/properties/properties.module.mjs +5 -5
  34. package/esm2020/src/app/core/form/properties/properties.table.mjs +8 -8
  35. package/esm2020/src/app/core/form/properties/property.validator.mjs +4 -4
  36. package/esm2020/src/app/core/form/properties/testing/properties-form.test.mjs +4 -4
  37. package/esm2020/src/app/core/form/properties/testing/properties-form.testing.module.mjs +5 -5
  38. package/esm2020/src/app/core/form/text-popover/testing/text-popover.testing.mjs +40 -7
  39. package/esm2020/src/app/core/form/text-popover/testing/text-popover.testing.module.mjs +5 -5
  40. package/esm2020/src/app/core/form/text-popover/text-form.component.mjs +5 -5
  41. package/esm2020/src/app/core/form/text-popover/text-popover.component.mjs +46 -5
  42. package/esm2020/src/app/core/form/text-popover/text-popover.module.mjs +5 -5
  43. package/esm2020/src/app/core/graphql/graphql.module.mjs +5 -5
  44. package/esm2020/src/app/core/graphql/graphql.service.mjs +20 -7
  45. package/esm2020/src/app/core/graphql/graphql.utils.mjs +1 -1
  46. package/esm2020/src/app/core/home/home.mjs +5 -5
  47. package/esm2020/src/app/core/home/home.module.mjs +5 -5
  48. package/esm2020/src/app/core/icon/icon.component.mjs +4 -4
  49. package/esm2020/src/app/core/icon/icon.module.mjs +5 -5
  50. package/esm2020/src/app/core/install/install-upgrade-card.component.mjs +17 -11
  51. package/esm2020/src/app/core/install/install-upgrade-card.module.mjs +5 -5
  52. package/esm2020/src/app/core/menu/menu.component.mjs +18 -19
  53. package/esm2020/src/app/core/menu/menu.module.mjs +5 -5
  54. package/esm2020/src/app/core/menu/menu.service.mjs +4 -4
  55. package/esm2020/src/app/core/offline/update-offline-mode-card.component.mjs +4 -4
  56. package/esm2020/src/app/core/offline/update-offline-mode-card.module.mjs +5 -5
  57. package/esm2020/src/app/core/peer/select-peer.modal.mjs +17 -9
  58. package/esm2020/src/app/core/peer/select-peer.module.mjs +5 -5
  59. package/esm2020/src/app/core/register/register-confirm.page.mjs +5 -5
  60. package/esm2020/src/app/core/register/register.form.mjs +4 -4
  61. package/esm2020/src/app/core/register/register.modal.mjs +4 -4
  62. package/esm2020/src/app/core/register/register.module.mjs +5 -5
  63. package/esm2020/src/app/core/services/account.service.mjs +28 -8
  64. package/esm2020/src/app/core/services/auth-guard.service.mjs +8 -8
  65. package/esm2020/src/app/core/services/base-entity-service.class.mjs +7 -4
  66. package/esm2020/src/app/core/services/base-graphql-service.class.mjs +4 -4
  67. package/esm2020/src/app/core/services/config.service.mjs +4 -4
  68. package/esm2020/src/app/core/services/crypto.service.mjs +4 -4
  69. package/esm2020/src/app/core/services/errors.mjs +2 -1
  70. package/esm2020/src/app/core/services/local-settings.service.mjs +15 -11
  71. package/esm2020/src/app/core/services/model/config.model.mjs +3 -3
  72. package/esm2020/src/app/core/services/model/entity.model.mjs +15 -4
  73. package/esm2020/src/app/core/services/model/referential.model.mjs +14 -3
  74. package/esm2020/src/app/core/services/network.service.mjs +35 -20
  75. package/esm2020/src/app/core/services/network.utils.mjs +10 -11
  76. package/esm2020/src/app/core/services/pipes/account.pipes.mjs +9 -9
  77. package/esm2020/src/app/core/services/pipes/department-to-string.pipe.mjs +5 -5
  78. package/esm2020/src/app/core/services/pipes/person-to-string.pipe.mjs +5 -5
  79. package/esm2020/src/app/core/services/pipes/usage-mode.pipes.mjs +12 -12
  80. package/esm2020/src/app/core/services/platform.service.mjs +37 -10
  81. package/esm2020/src/app/core/services/storage/entities-storage.service.mjs +8 -7
  82. package/esm2020/src/app/core/services/storage/entity-store.class.mjs +1 -1
  83. package/esm2020/src/app/core/services/testing/referential.validator.mjs +4 -4
  84. package/esm2020/src/app/core/services/validator/account.validator.mjs +4 -4
  85. package/esm2020/src/app/core/services/validator/base.validator.class.mjs +4 -4
  86. package/esm2020/src/app/core/services/validator/local-settings.validator.mjs +4 -4
  87. package/esm2020/src/app/core/services/validator/user-settings.validator.mjs +4 -4
  88. package/esm2020/src/app/core/services/validator/user-token.validator.mjs +4 -4
  89. package/esm2020/src/app/core/settings/settings.module.mjs +5 -5
  90. package/esm2020/src/app/core/settings/settings.page.mjs +46 -27
  91. package/esm2020/src/app/core/table/actions-column.component.mjs +11 -5
  92. package/esm2020/src/app/core/table/async-table.class.mjs +10 -6
  93. package/esm2020/src/app/core/table/entities-async-table-datasource.class.mjs +4 -4
  94. package/esm2020/src/app/core/table/entities-table-datasource.class.mjs +4 -4
  95. package/esm2020/src/app/core/table/memory-table.class.mjs +4 -4
  96. package/esm2020/src/app/core/table/table-select-columns.component.mjs +4 -4
  97. package/esm2020/src/app/core/table/table.class.mjs +79 -32
  98. package/esm2020/src/app/core/table/table.module.mjs +5 -5
  99. package/esm2020/src/app/core/table/table.utils.mjs +18 -1
  100. package/esm2020/src/app/core/table/testing/table-validator.service.mjs +27 -0
  101. package/esm2020/src/app/core/table/testing/table.testing.mjs +29 -14
  102. package/esm2020/src/app/core/table/testing/table.testing.module.mjs +5 -5
  103. package/esm2020/src/app/shared/alerts.mjs +3 -2
  104. package/esm2020/src/app/shared/audio/audio.mjs +62 -15
  105. package/esm2020/src/app/shared/audio/audio.testing.mjs +4 -4
  106. package/esm2020/src/app/shared/audio/audio.testing.module.mjs +5 -5
  107. package/esm2020/src/app/shared/capacitor/keyboard.mjs +4 -4
  108. package/esm2020/src/app/shared/dates.mjs +1 -1
  109. package/esm2020/src/app/shared/debug/debug-service.class.mjs +3 -0
  110. package/esm2020/src/app/shared/debug/debug.component.mjs +5 -5
  111. package/esm2020/src/app/shared/debug/debug.module.mjs +5 -5
  112. package/esm2020/src/app/shared/directives/autofocus.directive.mjs +4 -4
  113. package/esm2020/src/app/shared/directives/autotitle.directive.mjs +4 -4
  114. package/esm2020/src/app/shared/directives/directives.module.mjs +5 -5
  115. package/esm2020/src/app/shared/directives/drag-and-drop.directive.mjs +4 -4
  116. package/esm2020/src/app/shared/directives/ng-var.directive.mjs +4 -4
  117. package/esm2020/src/app/shared/directives/resizable/resizable.component.mjs +4 -4
  118. package/esm2020/src/app/shared/directives/resizable/resizable.directive.mjs +4 -4
  119. package/esm2020/src/app/shared/directives/resizable/resizable.module.mjs +5 -5
  120. package/esm2020/src/app/shared/file/file.service.mjs +4 -4
  121. package/esm2020/src/app/shared/file/json.utils.mjs +21 -3
  122. package/esm2020/src/app/shared/form/field.component.mjs +103 -40
  123. package/esm2020/src/app/shared/form/field.model.mjs +1 -1
  124. package/esm2020/src/app/shared/form/loading-spinner.mjs +4 -4
  125. package/esm2020/src/app/shared/functions.mjs +27 -12
  126. package/esm2020/src/app/shared/geolocation/geolocation.utils.mjs +46 -7
  127. package/esm2020/src/app/shared/gesture/gesture-config.mjs +4 -4
  128. package/esm2020/src/app/shared/graph/graph-colors.mjs +5 -1
  129. package/esm2020/src/app/shared/guard/component-dirty.guard.mjs +4 -4
  130. package/esm2020/src/app/shared/help/help.modal.mjs +4 -4
  131. package/esm2020/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.mjs +4 -4
  132. package/esm2020/src/app/shared/hotkeys/hotkeys.service.mjs +4 -4
  133. package/esm2020/src/app/shared/hotkeys/shared-hotkeys.module.mjs +5 -5
  134. package/esm2020/src/app/shared/http/http.utils.mjs +4 -4
  135. package/esm2020/src/app/shared/image/gallery/image-gallery.component.mjs +43 -33
  136. package/esm2020/src/app/shared/image/gallery/image-gallery.module.mjs +7 -6
  137. package/esm2020/src/app/shared/image/gallery/testing/gallery.service.testing.mjs +4 -4
  138. package/esm2020/src/app/shared/image/gallery/testing/gallery.testing.mjs +4 -4
  139. package/esm2020/src/app/shared/image/gallery/testing/gallery.testing.module.mjs +5 -5
  140. package/esm2020/src/app/shared/image/image.module.mjs +5 -5
  141. package/esm2020/src/app/shared/image/image.service.mjs +4 -4
  142. package/esm2020/src/app/shared/logging/log-level.model.mjs +48 -0
  143. package/esm2020/src/app/shared/logging/logger.model.mjs +47 -0
  144. package/esm2020/src/app/shared/logging/logging-service.class.mjs +121 -0
  145. package/esm2020/src/app/shared/logging/logging-service.config.mjs +2 -0
  146. package/esm2020/src/app/shared/logging/logging-service.module.mjs +30 -0
  147. package/esm2020/src/app/shared/material/autocomplete/material.autocomplete.mjs +15 -14
  148. package/esm2020/src/app/shared/material/autocomplete/material.autocomplete.module.mjs +5 -5
  149. package/esm2020/src/app/shared/material/autocomplete/testing/autocomplete.test.mjs +5 -5
  150. package/esm2020/src/app/shared/material/badge/badge.directive.mjs +130 -112
  151. package/esm2020/src/app/shared/material/badge/badge.module.mjs +5 -5
  152. package/esm2020/src/app/shared/material/badge/badge.test.mjs +27 -14
  153. package/esm2020/src/app/shared/material/boolean/boolean.module.mjs +5 -5
  154. package/esm2020/src/app/shared/material/boolean/material.boolean.mjs +6 -6
  155. package/esm2020/src/app/shared/material/chips/chips.module.mjs +5 -5
  156. package/esm2020/src/app/shared/material/chips/material.chips.mjs +4 -4
  157. package/esm2020/src/app/shared/material/chips/testing/chips.test.mjs +4 -4
  158. package/esm2020/src/app/shared/material/datetime/datetime.module.mjs +5 -5
  159. package/esm2020/src/app/shared/material/datetime/material.date.mjs +6 -6
  160. package/esm2020/src/app/shared/material/datetime/material.dateshort.mjs +6 -6
  161. package/esm2020/src/app/shared/material/datetime/material.datetime.mjs +96 -33
  162. package/esm2020/src/app/shared/material/datetime/testing/mat-date-time.test.mjs +4 -4
  163. package/esm2020/src/app/shared/material/datetime/testing/mat-date.test.mjs +4 -4
  164. package/esm2020/src/app/shared/material/datetime/testing/mat-dateshort.test.mjs +4 -4
  165. package/esm2020/src/app/shared/material/duration/duration.module.mjs +5 -5
  166. package/esm2020/src/app/shared/material/duration/material.duration.mjs +4 -4
  167. package/esm2020/src/app/shared/material/latlong/material.latlong.mjs +4 -4
  168. package/esm2020/src/app/shared/material/latlong/material.latlong.module.mjs +5 -5
  169. package/esm2020/src/app/shared/material/latlong/testing/latlong.test.mjs +4 -4
  170. package/esm2020/src/app/shared/material/material.module.mjs +5 -5
  171. package/esm2020/src/app/shared/material/material.testing.module.mjs +5 -5
  172. package/esm2020/src/app/shared/material/numpad/numpad.append-to-input.directive.mjs +4 -4
  173. package/esm2020/src/app/shared/material/numpad/numpad.component.mjs +4 -4
  174. package/esm2020/src/app/shared/material/numpad/numpad.container.mjs +4 -4
  175. package/esm2020/src/app/shared/material/numpad/numpad.content.mjs +4 -4
  176. package/esm2020/src/app/shared/material/numpad/numpad.directive.mjs +4 -4
  177. package/esm2020/src/app/shared/material/numpad/numpad.dom-service.mjs +4 -4
  178. package/esm2020/src/app/shared/material/numpad/numpad.module.mjs +5 -5
  179. package/esm2020/src/app/shared/material/numpad/testing/numpad.test.mjs +4 -4
  180. package/esm2020/src/app/shared/material/paginator/material.paginator-i18n.mjs +4 -4
  181. package/esm2020/src/app/shared/material/stepper/material.stepper-i18n.mjs +4 -4
  182. package/esm2020/src/app/shared/material/swipe/material.swipe.mjs +45 -35
  183. package/esm2020/src/app/shared/material/swipe/swipe.module.mjs +7 -6
  184. package/esm2020/src/app/shared/material/swipe/testing/swipe.test.mjs +4 -4
  185. package/esm2020/src/app/shared/pipes/arrays.pipe.mjs +47 -41
  186. package/esm2020/src/app/shared/pipes/colors.pipe.mjs +4 -4
  187. package/esm2020/src/app/shared/pipes/date-diff-duration.pipe.mjs +5 -5
  188. package/esm2020/src/app/shared/pipes/date-format.pipe.mjs +7 -7
  189. package/esm2020/src/app/shared/pipes/date-from-now.pipe.mjs +5 -5
  190. package/esm2020/src/app/shared/pipes/duration.pipe.mjs +6 -6
  191. package/esm2020/src/app/shared/pipes/file-size.pipe.mjs +4 -4
  192. package/esm2020/src/app/shared/pipes/form.pipes.mjs +19 -19
  193. package/esm2020/src/app/shared/pipes/highlight.pipe.mjs +5 -5
  194. package/esm2020/src/app/shared/pipes/latlong-format.pipe.mjs +10 -10
  195. package/esm2020/src/app/shared/pipes/maps.pipe.mjs +13 -13
  196. package/esm2020/src/app/shared/pipes/math.pipes.mjs +13 -13
  197. package/esm2020/src/app/shared/pipes/ng-init.pipe.mjs +4 -4
  198. package/esm2020/src/app/shared/pipes/number-format.pipe.mjs +5 -5
  199. package/esm2020/src/app/shared/pipes/pipes.module.mjs +22 -9
  200. package/esm2020/src/app/shared/pipes/property.pipes.mjs +8 -8
  201. package/esm2020/src/app/shared/pipes/string.pipes.mjs +28 -28
  202. package/esm2020/src/app/shared/pipes/translate-context.pipe.mjs +9 -9
  203. package/esm2020/src/app/shared/pipes/types.pipes.mjs +45 -0
  204. package/esm2020/src/app/shared/services/memory-entity-service.class.mjs +4 -4
  205. package/esm2020/src/app/shared/services/progress-bar.service.mjs +4 -4
  206. package/esm2020/src/app/shared/services/startable-service.class.mjs +6 -1
  207. package/esm2020/src/app/shared/services/translate-context.service.mjs +28 -4
  208. package/esm2020/src/app/shared/shared-routing.module.mjs +8 -8
  209. package/esm2020/src/app/shared/shared.module.mjs +7 -7
  210. package/esm2020/src/app/shared/shared.testing.module.mjs +20 -12
  211. package/esm2020/src/app/shared/storage/storage-explorer.component.mjs +268 -0
  212. package/esm2020/src/app/shared/storage/storage-explorer.module.mjs +60 -0
  213. package/esm2020/src/app/shared/storage/storage.service.mjs +132 -0
  214. package/esm2020/src/app/shared/storage/storage.utils.mjs +13 -0
  215. package/esm2020/src/app/shared/testing/observable.test.mjs +4 -4
  216. package/esm2020/src/app/shared/testing/tests.page.mjs +4 -4
  217. package/esm2020/src/app/shared/toast/toast.testing.mjs +6 -6
  218. package/esm2020/src/app/shared/toast/toast.testing.module.mjs +5 -5
  219. package/esm2020/src/app/shared/toolbar/modal-toolbar.mjs +4 -4
  220. package/esm2020/src/app/shared/toolbar/toolbar.mjs +14 -13
  221. package/esm2020/src/app/shared/toolbar/toolbar.module.mjs +5 -5
  222. package/esm2020/src/app/shared/upload-file/testing/upload-file.testing.mjs +4 -4
  223. package/esm2020/src/app/shared/upload-file/testing/upload-file.testing.module.mjs +5 -5
  224. package/esm2020/src/app/shared/upload-file/upload-file-popover.component.mjs +4 -4
  225. package/esm2020/src/app/shared/upload-file/upload-file.component.mjs +4 -4
  226. package/esm2020/src/app/shared/validator/form-error-adapter.class.mjs +4 -4
  227. package/esm2020/src/app/shared/validator/validators.mjs +32 -2
  228. package/esm2020/src/app/social/job/job.module.mjs +5 -5
  229. package/esm2020/src/app/social/job/progression/job-progression.component.mjs +4 -4
  230. package/esm2020/src/app/social/job/progression/job-progression.icon.mjs +4 -4
  231. package/esm2020/src/app/social/job/progression/job-progression.list.mjs +4 -4
  232. package/esm2020/src/app/social/job/progression/job-progression.service.mjs +4 -4
  233. package/esm2020/src/app/social/job/testing/job-progression.testing.mjs +4 -4
  234. package/esm2020/src/app/social/job/testing/job-progression.testing.service.mjs +4 -4
  235. package/esm2020/src/app/social/job/testing/job.testing.module.mjs +5 -5
  236. package/esm2020/src/app/social/message/message.form.mjs +4 -4
  237. package/esm2020/src/app/social/message/message.modal.mjs +4 -4
  238. package/esm2020/src/app/social/message/message.module.mjs +5 -5
  239. package/esm2020/src/app/social/message/message.service.mjs +4 -4
  240. package/esm2020/src/app/social/social.module.mjs +5 -5
  241. package/esm2020/src/app/social/social.testing.module.mjs +5 -5
  242. package/esm2020/src/app/social/user-event/notification/user-event-notification.icon.mjs +5 -5
  243. package/esm2020/src/app/social/user-event/notification/user-event-notification.list.mjs +4 -4
  244. package/esm2020/src/app/social/user-event/testing/user-event.testing.mjs +4 -6
  245. package/esm2020/src/app/social/user-event/testing/user-event.testing.module.mjs +5 -5
  246. package/esm2020/src/app/social/user-event/testing/user-event.testing.service.mjs +4 -4
  247. package/esm2020/src/app/social/user-event/user-event.module.mjs +5 -5
  248. package/esm2020/src/app/social/user-event/user-event.service.mjs +4 -4
  249. package/esm2020/src/environments/environment.class.mjs +1 -1
  250. package/esm2020/src/environments/environment.mjs +15 -7
  251. package/fesm2015/sumaris-net.ngx-components.mjs +2892 -1561
  252. package/fesm2015/sumaris-net.ngx-components.mjs.map +1 -1
  253. package/fesm2020/sumaris-net.ngx-components.mjs +2815 -1526
  254. package/fesm2020/sumaris-net.ngx-components.mjs.map +1 -1
  255. package/package.json +10 -10
  256. package/public_api.d.ts +12 -2
  257. package/src/app/core/account/account.page.d.ts +3 -3
  258. package/src/app/core/core.module.d.ts +1 -1
  259. package/src/app/core/form/entity/editor.class.d.ts +6 -4
  260. package/src/app/core/form/entity/entity-editor-modal.class.d.ts +0 -1
  261. package/src/app/core/form/entity/entity-editor.class.d.ts +37 -31
  262. package/src/app/core/form/form.class.d.ts +1 -1
  263. package/src/app/core/form/properties/properties.form.d.ts +1 -0
  264. package/src/app/core/form/text-popover/testing/text-popover.testing.d.ts +6 -2
  265. package/src/app/core/form/text-popover/text-popover.component.d.ts +27 -2
  266. package/src/app/core/graphql/graphql.service.d.ts +1 -1
  267. package/src/app/core/graphql/graphql.utils.d.ts +1 -1
  268. package/src/app/core/menu/menu.component.d.ts +3 -4
  269. package/src/app/core/peer/select-peer.modal.d.ts +5 -2
  270. package/src/app/core/services/account.service.d.ts +5 -0
  271. package/src/app/core/services/base-entity-service.class.d.ts +1 -0
  272. package/src/app/core/services/errors.d.ts +1 -0
  273. package/src/app/core/services/local-settings.service.d.ts +5 -2
  274. package/src/app/core/services/model/entity.model.d.ts +3 -0
  275. package/src/app/core/services/model/referential.model.d.ts +6 -1
  276. package/src/app/core/services/network.service.d.ts +5 -2
  277. package/src/app/core/services/network.utils.d.ts +6 -7
  278. package/src/app/core/services/pipes/usage-mode.pipes.d.ts +8 -8
  279. package/src/app/core/services/platform.service.d.ts +9 -5
  280. package/src/app/core/services/storage/entities-storage.service.d.ts +1 -1
  281. package/src/app/core/services/storage/entity-store.class.d.ts +1 -1
  282. package/src/app/core/settings/settings.page.d.ts +9 -6
  283. package/src/app/core/table/actions-column.component.d.ts +6 -1
  284. package/src/app/core/table/table.class.d.ts +11 -11
  285. package/src/app/core/table/table.utils.d.ts +4 -0
  286. package/src/app/core/table/testing/table-validator.service.d.ts +17 -0
  287. package/src/app/core/table/testing/table.testing.d.ts +2 -0
  288. package/src/app/shared/alerts.d.ts +2 -1
  289. package/src/app/shared/audio/audio.d.ts +1 -0
  290. package/src/app/shared/dates.d.ts +1 -1
  291. package/src/app/shared/debug/debug-service.class.d.ts +5 -0
  292. package/src/app/shared/file/file.utils.d.ts +1 -1
  293. package/src/app/shared/file/json.utils.d.ts +5 -0
  294. package/src/app/shared/form/field.component.d.ts +16 -4
  295. package/src/app/shared/form/field.model.d.ts +1 -1
  296. package/src/app/shared/functions.d.ts +10 -8
  297. package/src/app/shared/geolocation/geolocation.utils.d.ts +9 -1
  298. package/src/app/shared/image/gallery/image-gallery.component.d.ts +14 -17
  299. package/src/app/shared/logging/log-level.model.d.ts +38 -0
  300. package/src/app/shared/logging/logger.model.d.ts +68 -0
  301. package/src/app/shared/logging/logging-service.class.d.ts +39 -0
  302. package/src/app/shared/logging/logging-service.config.d.ts +25 -0
  303. package/src/app/shared/logging/logging-service.module.d.ts +9 -0
  304. package/src/app/shared/material/badge/badge.directive.d.ts +25 -18
  305. package/src/app/shared/material/badge/badge.test.d.ts +8 -0
  306. package/src/app/shared/material/datetime/material.datetime.d.ts +15 -5
  307. package/src/app/shared/material/swipe/material.swipe.d.ts +12 -12
  308. package/src/app/shared/pipes/arrays.pipe.d.ts +9 -9
  309. package/src/app/shared/pipes/duration.pipe.d.ts +2 -1
  310. package/src/app/shared/pipes/pipes.module.d.ts +5 -4
  311. package/src/app/shared/pipes/types.pipes.d.ts +18 -0
  312. package/src/app/shared/services/startable-service.class.d.ts +1 -0
  313. package/src/app/shared/services/translate-context.service.d.ts +2 -2
  314. package/src/app/shared/shared.testing.module.d.ts +2 -1
  315. package/src/app/shared/storage/storage-explorer.component.d.ts +58 -0
  316. package/src/app/shared/storage/storage-explorer.module.d.ts +16 -0
  317. package/src/app/shared/{services/storage → storage}/storage.service.d.ts +2 -2
  318. package/src/app/shared/toolbar/toolbar.d.ts +5 -4
  319. package/src/app/shared/validator/validators.d.ts +6 -0
  320. package/src/assets/i18n/en-US.json +23 -3
  321. package/src/assets/i18n/en.json +23 -3
  322. package/src/assets/i18n/fr.json +22 -8
  323. package/src/assets/manifest.json +1 -1
  324. package/src/environments/environment.class.d.ts +4 -0
  325. package/src/theme/_ionic.globals.scss +7 -2
  326. package/src/theme/_ngx-components.scss +13 -3
  327. package/esm2020/src/app/shared/services/storage/storage.service.mjs +0 -132
  328. package/esm2020/src/app/shared/services/storage/storage.utils.mjs +0 -13
  329. /package/src/app/shared/{services/storage → storage}/storage.utils.d.ts +0 -0
@@ -1,4 +1,4 @@
1
- import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, Inject, InjectionToken, Optional } from '@angular/core';
2
2
  import { EntityUtils } from '../services/model/entity.model';
3
3
  import { APP_LOCALES } from '../services/model/settings.model';
4
4
  import { Peer } from '../services/model/peer.model';
@@ -11,33 +11,34 @@ import { merge } from 'rxjs';
11
11
  import { Alerts } from '../../shared/alerts';
12
12
  import * as i0 from "@angular/core";
13
13
  import * as i1 from "../services/platform.service";
14
- import * as i2 from "@angular/router";
14
+ import * as i2 from "@ionic/angular";
15
15
  import * as i3 from "../services/validator/local-settings.validator";
16
- import * as i4 from "@ionic/angular";
17
- import * as i5 from "@ngx-translate/core";
18
- import * as i6 from "@angular/forms";
19
- import * as i7 from "../services/account.service";
20
- import * as i8 from "../services/local-settings.service";
21
- import * as i9 from "../services/network.service";
22
- import * as i10 from "@angular/common";
23
- import * as i11 from "@angular/material/form-field";
24
- import * as i12 from "@angular/material/input";
25
- import * as i13 from "@angular/material/checkbox";
26
- import * as i14 from "@angular/material/icon";
27
- import * as i15 from "@angular/material/button";
28
- import * as i16 from "@angular/material/menu";
29
- import * as i17 from "@angular/material/select";
30
- import * as i18 from "@angular/material/core";
16
+ import * as i4 from "@ngx-translate/core";
17
+ import * as i5 from "@angular/forms";
18
+ import * as i6 from "../services/account.service";
19
+ import * as i7 from "../services/local-settings.service";
20
+ import * as i8 from "../services/network.service";
21
+ import * as i9 from "@angular/common";
22
+ import * as i10 from "@angular/material/form-field";
23
+ import * as i11 from "@angular/material/input";
24
+ import * as i12 from "@angular/material/checkbox";
25
+ import * as i13 from "@angular/material/icon";
26
+ import * as i14 from "@angular/material/button";
27
+ import * as i15 from "@angular/material/menu";
28
+ import * as i16 from "@angular/material/select";
29
+ import * as i17 from "@angular/material/core";
30
+ import * as i18 from "@angular/material/divider";
31
31
  import * as i19 from "@angular/material/slide-toggle";
32
32
  import * as i20 from "../../shared/toolbar/toolbar";
33
33
  import * as i21 from "../../shared/form/field.component";
34
34
  import * as i22 from "../form/buttons/form-buttons-bar.component";
35
35
  import * as i23 from "../../shared/pipes/form.pipes";
36
+ export const APP_SETTINGS_MENU_ITEMS = new InjectionToken('settingsMenuItems');
36
37
  export class SettingsPage extends AppForm {
37
- constructor(injector, platform, router, validatorService, alertCtrl, translate, formBuilder, accountService, settings, cd, network, locales) {
38
+ constructor(injector, platform, navController, validatorService, alertCtrl, translate, formBuilder, accountService, settings, cd, network, locales, menuItems) {
38
39
  super(injector, validatorService.getFormGroup());
39
40
  this.platform = platform;
40
- this.router = router;
41
+ this.navController = navController;
41
42
  this.validatorService = validatorService;
42
43
  this.alertCtrl = alertCtrl;
43
44
  this.translate = translate;
@@ -55,6 +56,7 @@ export class SettingsPage extends AppForm {
55
56
  this.propertiesFormHelper = new FormArrayHelper(this.form.get('properties'), (value) => this.validatorService.getPropertyFormGroup(value), (v1, v2) => (!v1 && !v2) || (v1.key === v2.key), (value) => isNil(value) || (isNil(value.key) && isNil(value.value)), {
56
57
  allowEmptyArray: true
57
58
  });
59
+ this.menuItems = menuItems || [];
58
60
  this.mobile = this.platform.mobile;
59
61
  // By default, disable the form
60
62
  this._enable = false;
@@ -246,7 +248,7 @@ export class SettingsPage extends AppForm {
246
248
  if (this.saving)
247
249
  return;
248
250
  // Back to home
249
- return this.router.navigateByUrl('/', { replaceUrl: true }); // back to home
251
+ return this.navController.navigateRoot('/'); // back to home
250
252
  }
251
253
  async clearCache(event) {
252
254
  const confirm = await Alerts.askActionConfirmation(this.alertCtrl, this.translate, true, event);
@@ -255,6 +257,18 @@ export class SettingsPage extends AppForm {
255
257
  this.settings.removeOfflineFeatures();
256
258
  }
257
259
  }
260
+ async executeAction(event, item) {
261
+ if (!item)
262
+ return;
263
+ if (event?.defaultPrevented)
264
+ return;
265
+ if (item.path) {
266
+ await this.navController.navigateForward(item.path);
267
+ }
268
+ else {
269
+ console.error('[settings] Unknown item type (no path)', item);
270
+ }
271
+ }
258
272
  /* -- protected functions -- */
259
273
  async getValue() {
260
274
  const json = await this.getJsonValueToSave();
@@ -277,17 +291,22 @@ export class SettingsPage extends AppForm {
277
291
  this.cd.markForCheck();
278
292
  }
279
293
  }
280
- SettingsPage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SettingsPage, deps: [{ token: i0.Injector }, { token: i1.PlatformService }, { token: i2.Router }, { token: i3.LocalSettingsValidatorService }, { token: i4.AlertController }, { token: i5.TranslateService }, { token: i6.UntypedFormBuilder }, { token: i7.AccountService }, { token: i8.LocalSettingsService }, { token: i0.ChangeDetectorRef }, { token: i9.NetworkService }, { token: APP_LOCALES }], target: i0.ɵɵFactoryTarget.Component });
281
- SettingsPage.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: SettingsPage, selector: "page-settings", providers: [
294
+ SettingsPage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SettingsPage, deps: [{ token: i0.Injector }, { token: i1.PlatformService }, { token: i2.NavController }, { token: i3.LocalSettingsValidatorService }, { token: i2.AlertController }, { token: i4.TranslateService }, { token: i5.UntypedFormBuilder }, { token: i6.AccountService }, { token: i7.LocalSettingsService }, { token: i0.ChangeDetectorRef }, { token: i8.NetworkService }, { token: APP_LOCALES }, { token: APP_SETTINGS_MENU_ITEMS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
295
+ SettingsPage.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: SettingsPage, selector: "page-settings", providers: [
282
296
  { provide: ValidatorService, useExisting: LocalSettingsValidatorService },
283
- ], usesInheritance: true, ngImport: i0, template: "<app-toolbar [title]=\"'SETTINGS.TITLE'|translate\" color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\">\n\n <ion-buttons slot=\"end\">\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\"\n *ngIf=\"!saving\"\n [disabled]=\"saving\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item (click)=\"clearCache($event)\">\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item\n [disabled]=\"!dirty\"\n (click)=\"cancel($event)\">\n <ion-label>\n <mat-icon><ion-icon slot=\"start\" name=\"refresh\"></ion-icon></mat-icon>&nbsp;\n <span translate>COMMON.BTN_RESET</span>\n </ion-label>\n </button>\n</mat-menu>\n\n<ion-content>\n\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n\n <ion-grid class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"2\">&nbsp;\n </ion-col>\n\n <ion-col class=\"ion-padding\">\n\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <p [innerHTML]=\"'SETTINGS.DESCRIPTION'|translate\"></p>\n\n <!-- account inheritance (desktop) -->\n <mat-form-field [hidden]=\"!isLogin\" *ngIf=\"!mobile; else accountInheritanceMobile\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\">\n\n <!-- check box (if desktop) -->\n <mat-checkbox\n *ngIf=\"!mobile; else accountInheritanceMobile\"\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\">\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- account inheritance (if mobile) -->\n <ng-template #accountInheritanceMobile>\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\">\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\">\n\n </mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ng-template>\n\n <!-- locale -->\n <mat-form-field>\n <mat-select [placeholder]=\"'SETTINGS.LOCALE'|translate\" formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{item.value}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n\n <!-- Network entry -->\n <h3>\n <ion-text translate>SETTINGS.NETWORK_DIVIDER</ion-text>\n </h3>\n\n <!-- Peer address -->\n <mat-form-field>\n <input matInput type=\"text\" [placeholder]=\"'SETTINGS.PEER_URL'|translate\"\n formControlName=\"peerUrl\"\n required>\n\n <button mat-icon-button type=\"button\" matSuffix (click)=\"showSelectPeerModal()\" tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER'|translate\">\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\"\n translate>SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\"\n translate>SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n\n <!-- Offline mode (if mobile) -->\n <mat-form-field *ngIf=\"mobile\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\">\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\">\n\n </mat-slide-toggle>\n </mat-form-field>\n\n <!-- Data entry -->\n <h3>\n <ion-text translate>SETTINGS.DATA_ENTRY_DIVIDER</ion-text>\n </h3>\n\n <!-- Usage mode -->\n <mat-form-field>\n <mat-select [placeholder]=\"'SETTINGS.USAGE_MODE'|translate\" formControlName=\"usageMode\"\n required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{'SETTINGS.USAGE_MODES.'+item|translate}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- lat/long format-->\n <mat-form-field>\n <mat-select [placeholder]=\"'SETTINGS.LAT_LONG_FORMAT'|translate\" formControlName=\"latLongFormat\"\n required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{'COMMON.LAT_LONG.'+item+'_PLACEHOLDER'|translate}}\n </mat-option>\n </mat-select>\n <mat-error\n *ngIf=\"form.controls.latLongFormat.hasError('required')\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- fields options -->\n <ion-grid formArrayName=\"properties\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding ion-align-self-end\" size=\"12\">\n <span class=\"toolbar-spacer\"></span>\n\n <!-- Show more options -->\n <ion-button color=\"light\" *ngIf=\"propertiesForm?.length === 0\"\n [title]=\"'SETTINGS.BTN_SHOW_MORE_HELP'|translate\"\n (click)=\"propertiesFormHelper.add()\">\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n </ion-col>\n </ion-row>\n\n <!-- Fields options -->\n <ng-container *ngFor=\"let propertyForm of propertiesForm?.controls; let i=index\">\n <ion-row class=\"ion-no-padding\" [formGroupName]=\"i\">\n\n <!-- property key -->\n <ion-col class=\"ion-no-padding\">\n <mat-form-field>\n <mat-select formControlName=\"key\"\n [placeholder]=\" 'SETTINGS.PROPERTY_KEY'|translate\">\n <mat-option *ngFor=\"let item of propertyDefinitions\" [value]=\"item.key\">{{ item.label | translate }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n\n <!-- property value -->\n <ion-col class=\"ion-no-padding\" padding-left>\n <app-form-field *ngIf=\"getPropertyDefinition(i); let definition\"\n floatLabel=\"never\"\n [definition]=\"definition\"\n [formControl]=\"propertyForm|formGetControl:'value'\"\n [placeholder]=\"'SETTINGS.PROPERTY_VALUE' | translate\"\n [required]=\"true\">\n </app-form-field>\n </ion-col>\n <ion-col size=\"2\" class=\"ion-no-padding\">\n <button type=\"button\" mat-icon-button color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'COMMON.BTN_DELETE'|translate\"\n (click)=\"removePropertyAt(i)\">\n <mat-icon>close</mat-icon>\n </button>\n <button *ngIf=\"propertiesFormHelper.isLast(i)\"\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'SETTINGS.BTN_ADD_PROPERTY'|translate\"\n (click)=\"propertiesFormHelper.add()\">\n <mat-icon>add</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n </ng-container>\n </ion-grid>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"2\">&nbsp;\n </ion-col>\n </ion-row>\n </ion-grid>\n\n\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar (onCancel)=\"cancel()\" (onSave)=\"save($event)\" [disabled]=\"!form.dirty || saving\"></app-form-buttons-bar>\n</ion-footer>\n", dependencies: [{ kind: "directive", type: i10.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i10.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.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: i4.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i4.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: i4.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i4.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i4.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i4.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i4.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: i4.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i4.IonRow, selector: "ion-row" }, { kind: "component", type: i4.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i5.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i6.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i6.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i6.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i6.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i6.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: i11.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i11.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i11.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i12.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i13.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i14.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i15.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i16.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i16.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i16.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i17.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i18.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i19.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matSlideToggle"] }, { kind: "component", type: i20.ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: i21.AppFormField, selector: "app-form-field", inputs: ["definition", "required", "readonly", "disabled", "formControl", "formControlName", "placeholder", "compact", "floatLabel", "tabindex", "autofocus", "chipColor", "class"], outputs: ["keyup.enter"] }, { kind: "component", type: i22.FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "classList"], outputs: ["onCancel", "onSave", "onNext", "onBack"] }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "pipe", type: i23.FormGetControlPipe, name: "formGetControl" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
284
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SettingsPage, decorators: [{
297
+ ], usesInheritance: true, ngImport: i0, template: "<app-toolbar [title]=\"'SETTINGS.TITLE'|translate\" color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\">\n\n <ion-buttons slot=\"end\">\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\"\n *ngIf=\"!saving\"\n [disabled]=\"saving\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item (click)=\"clearCache($event)\">\n <mat-icon><ion-icon name=\"trash-outline\"></ion-icon></mat-icon>\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item\n [disabled]=\"!dirty\"\n (click)=\"cancel($event)\">\n <mat-icon><ion-icon name=\"refresh\"></ion-icon></mat-icon>\n <mat-label translate>COMMON.BTN_RESET</mat-label>\n </button>\n\n <!-- additional items -->\n <ng-container *ngIf=\"!loading\">\n <ng-container *ngFor=\"let item of menuItems\">\n <a *ngIf=\"item.path\"\n mat-menu-item\n class=\"{{item.cssClass}} {{item.color}}\"\n (click)=\"executeAction($event, item)\">\n <mat-icon *ngIf=\"item.icon\"><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-icon *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <mat-label translate>{{item.title}}</mat-label>\n </a>\n <!-- divider -->\n <mat-divider *ngIf=\"!item.path && !item.action\"\n class=\"{{item.cssClass}} {{item.color}}\">\n <mat-label translate>{{item.title}}</mat-label>\n </mat-divider>\n </ng-container>\n </ng-container>\n</mat-menu>\n\n<ion-content>\n\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n\n <ion-grid class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"2\">&nbsp;\n </ion-col>\n\n <ion-col class=\"ion-padding\">\n\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <p [innerHTML]=\"'SETTINGS.DESCRIPTION'|translate\"></p>\n\n <!-- account inheritance (desktop) -->\n <mat-form-field [hidden]=\"!isLogin\" *ngIf=\"!mobile; else accountInheritanceMobile\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\">\n\n <!-- check box (if desktop) -->\n <mat-checkbox\n *ngIf=\"!mobile; else accountInheritanceMobile\"\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\">\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- account inheritance (if mobile) -->\n <ng-template #accountInheritanceMobile>\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\">\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\">\n\n </mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ng-template>\n\n <!-- locale -->\n <mat-form-field>\n <mat-select [placeholder]=\"'SETTINGS.LOCALE'|translate\" formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{item.value}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n\n <!-- Network entry -->\n <h3>\n <ion-text translate>SETTINGS.NETWORK_DIVIDER</ion-text>\n </h3>\n\n <!-- Peer address -->\n <mat-form-field>\n <input matInput type=\"text\" [placeholder]=\"'SETTINGS.PEER_URL'|translate\"\n formControlName=\"peerUrl\"\n required>\n\n <button mat-icon-button type=\"button\" matSuffix (click)=\"showSelectPeerModal()\" tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER'|translate\">\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\"\n translate>SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\"\n translate>SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n\n <!-- Offline mode (if mobile) -->\n <mat-form-field *ngIf=\"mobile\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\">\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\">\n\n </mat-slide-toggle>\n </mat-form-field>\n\n <!-- Data entry -->\n <h3>\n <ion-text translate>SETTINGS.DATA_ENTRY_DIVIDER</ion-text>\n </h3>\n\n <!-- Usage mode -->\n <mat-form-field>\n <mat-select [placeholder]=\"'SETTINGS.USAGE_MODE'|translate\" formControlName=\"usageMode\"\n required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{'SETTINGS.USAGE_MODES.'+item|translate}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- lat/long format-->\n <mat-form-field>\n <mat-select [placeholder]=\"'SETTINGS.LAT_LONG_FORMAT'|translate\" formControlName=\"latLongFormat\"\n required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{'COMMON.LAT_LONG.'+item+'_PLACEHOLDER'|translate}}\n </mat-option>\n </mat-select>\n <mat-error\n *ngIf=\"form.controls.latLongFormat.hasError('required')\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- fields options -->\n <ion-grid formArrayName=\"properties\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding ion-align-self-end\" size=\"12\">\n <span class=\"toolbar-spacer\"></span>\n\n <!-- Show more options -->\n <ion-button color=\"light\" *ngIf=\"propertiesForm?.length === 0\"\n [title]=\"'SETTINGS.BTN_SHOW_MORE_HELP'|translate\"\n (click)=\"propertiesFormHelper.add()\">\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n </ion-col>\n </ion-row>\n\n <!-- Fields options -->\n <ng-container *ngFor=\"let propertyForm of propertiesForm?.controls; let i=index\">\n <ion-row class=\"ion-no-padding\" [formGroupName]=\"i\">\n\n <!-- property key -->\n <ion-col class=\"ion-no-padding\">\n <mat-form-field>\n <mat-select formControlName=\"key\"\n [placeholder]=\" 'SETTINGS.PROPERTY_KEY'|translate\">\n <mat-option *ngFor=\"let item of propertyDefinitions\" [value]=\"item.key\">{{ item.label | translate }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n\n <!-- property value -->\n <ion-col class=\"ion-no-padding\" padding-left>\n <app-form-field *ngIf=\"getPropertyDefinition(i); let definition\"\n floatLabel=\"never\"\n [definition]=\"definition\"\n [formControl]=\"propertyForm|formGetControl:'value'\"\n [placeholder]=\"'SETTINGS.PROPERTY_VALUE' | translate\"\n [required]=\"true\">\n </app-form-field>\n </ion-col>\n <ion-col size=\"2\" class=\"ion-no-padding\">\n <button type=\"button\" mat-icon-button color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'COMMON.BTN_DELETE'|translate\"\n (click)=\"removePropertyAt(i)\">\n <mat-icon>close</mat-icon>\n </button>\n <button *ngIf=\"propertiesFormHelper.isLast(i)\"\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'SETTINGS.BTN_ADD_PROPERTY'|translate\"\n (click)=\"propertiesFormHelper.add()\">\n <mat-icon>add</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n </ng-container>\n </ion-grid>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"2\">&nbsp;\n </ion-col>\n </ion-row>\n </ion-grid>\n\n\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar (onCancel)=\"cancel()\" (onSave)=\"save($event)\" [disabled]=\"!form.dirty || saving\"></app-form-buttons-bar>\n</ion-footer>\n", dependencies: [{ kind: "directive", type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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.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.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { 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.IonRow, selector: "ion-row" }, { kind: "component", type: i2.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i4.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i5.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i5.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: i10.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i11.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i12.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i13.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i14.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i15.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i15.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i15.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i16.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i17.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i18.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i19.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matSlideToggle"] }, { kind: "component", type: i20.ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: i21.AppFormField, selector: "app-form-field", inputs: ["definition", "required", "readonly", "disabled", "formControl", "formControlName", "placeholder", "compact", "floatLabel", "tabindex", "autofocus", "clearable", "chipColor", "debug", "class"], outputs: ["keyup.enter"] }, { kind: "component", type: i22.FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "classList"], outputs: ["onCancel", "onSave", "onNext", "onBack"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }, { kind: "pipe", type: i23.FormGetControlPipe, name: "formGetControl" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
298
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SettingsPage, decorators: [{
285
299
  type: Component,
286
300
  args: [{ selector: 'page-settings', providers: [
287
301
  { provide: ValidatorService, useExisting: LocalSettingsValidatorService },
288
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-toolbar [title]=\"'SETTINGS.TITLE'|translate\" color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\">\n\n <ion-buttons slot=\"end\">\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\"\n *ngIf=\"!saving\"\n [disabled]=\"saving\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item (click)=\"clearCache($event)\">\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item\n [disabled]=\"!dirty\"\n (click)=\"cancel($event)\">\n <ion-label>\n <mat-icon><ion-icon slot=\"start\" name=\"refresh\"></ion-icon></mat-icon>&nbsp;\n <span translate>COMMON.BTN_RESET</span>\n </ion-label>\n </button>\n</mat-menu>\n\n<ion-content>\n\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n\n <ion-grid class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"2\">&nbsp;\n </ion-col>\n\n <ion-col class=\"ion-padding\">\n\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <p [innerHTML]=\"'SETTINGS.DESCRIPTION'|translate\"></p>\n\n <!-- account inheritance (desktop) -->\n <mat-form-field [hidden]=\"!isLogin\" *ngIf=\"!mobile; else accountInheritanceMobile\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\">\n\n <!-- check box (if desktop) -->\n <mat-checkbox\n *ngIf=\"!mobile; else accountInheritanceMobile\"\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\">\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- account inheritance (if mobile) -->\n <ng-template #accountInheritanceMobile>\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\">\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\">\n\n </mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ng-template>\n\n <!-- locale -->\n <mat-form-field>\n <mat-select [placeholder]=\"'SETTINGS.LOCALE'|translate\" formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{item.value}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n\n <!-- Network entry -->\n <h3>\n <ion-text translate>SETTINGS.NETWORK_DIVIDER</ion-text>\n </h3>\n\n <!-- Peer address -->\n <mat-form-field>\n <input matInput type=\"text\" [placeholder]=\"'SETTINGS.PEER_URL'|translate\"\n formControlName=\"peerUrl\"\n required>\n\n <button mat-icon-button type=\"button\" matSuffix (click)=\"showSelectPeerModal()\" tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER'|translate\">\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\"\n translate>SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\"\n translate>SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n\n <!-- Offline mode (if mobile) -->\n <mat-form-field *ngIf=\"mobile\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\">\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\">\n\n </mat-slide-toggle>\n </mat-form-field>\n\n <!-- Data entry -->\n <h3>\n <ion-text translate>SETTINGS.DATA_ENTRY_DIVIDER</ion-text>\n </h3>\n\n <!-- Usage mode -->\n <mat-form-field>\n <mat-select [placeholder]=\"'SETTINGS.USAGE_MODE'|translate\" formControlName=\"usageMode\"\n required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{'SETTINGS.USAGE_MODES.'+item|translate}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- lat/long format-->\n <mat-form-field>\n <mat-select [placeholder]=\"'SETTINGS.LAT_LONG_FORMAT'|translate\" formControlName=\"latLongFormat\"\n required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{'COMMON.LAT_LONG.'+item+'_PLACEHOLDER'|translate}}\n </mat-option>\n </mat-select>\n <mat-error\n *ngIf=\"form.controls.latLongFormat.hasError('required')\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- fields options -->\n <ion-grid formArrayName=\"properties\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding ion-align-self-end\" size=\"12\">\n <span class=\"toolbar-spacer\"></span>\n\n <!-- Show more options -->\n <ion-button color=\"light\" *ngIf=\"propertiesForm?.length === 0\"\n [title]=\"'SETTINGS.BTN_SHOW_MORE_HELP'|translate\"\n (click)=\"propertiesFormHelper.add()\">\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n </ion-col>\n </ion-row>\n\n <!-- Fields options -->\n <ng-container *ngFor=\"let propertyForm of propertiesForm?.controls; let i=index\">\n <ion-row class=\"ion-no-padding\" [formGroupName]=\"i\">\n\n <!-- property key -->\n <ion-col class=\"ion-no-padding\">\n <mat-form-field>\n <mat-select formControlName=\"key\"\n [placeholder]=\" 'SETTINGS.PROPERTY_KEY'|translate\">\n <mat-option *ngFor=\"let item of propertyDefinitions\" [value]=\"item.key\">{{ item.label | translate }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n\n <!-- property value -->\n <ion-col class=\"ion-no-padding\" padding-left>\n <app-form-field *ngIf=\"getPropertyDefinition(i); let definition\"\n floatLabel=\"never\"\n [definition]=\"definition\"\n [formControl]=\"propertyForm|formGetControl:'value'\"\n [placeholder]=\"'SETTINGS.PROPERTY_VALUE' | translate\"\n [required]=\"true\">\n </app-form-field>\n </ion-col>\n <ion-col size=\"2\" class=\"ion-no-padding\">\n <button type=\"button\" mat-icon-button color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'COMMON.BTN_DELETE'|translate\"\n (click)=\"removePropertyAt(i)\">\n <mat-icon>close</mat-icon>\n </button>\n <button *ngIf=\"propertiesFormHelper.isLast(i)\"\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'SETTINGS.BTN_ADD_PROPERTY'|translate\"\n (click)=\"propertiesFormHelper.add()\">\n <mat-icon>add</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n </ng-container>\n </ion-grid>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"2\">&nbsp;\n </ion-col>\n </ion-row>\n </ion-grid>\n\n\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar (onCancel)=\"cancel()\" (onSave)=\"save($event)\" [disabled]=\"!form.dirty || saving\"></app-form-buttons-bar>\n</ion-footer>\n" }]
289
- }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.PlatformService }, { type: i2.Router }, { type: i3.LocalSettingsValidatorService }, { type: i4.AlertController }, { type: i5.TranslateService }, { type: i6.UntypedFormBuilder }, { type: i7.AccountService }, { type: i8.LocalSettingsService }, { type: i0.ChangeDetectorRef }, { type: i9.NetworkService }, { type: undefined, decorators: [{
302
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-toolbar [title]=\"'SETTINGS.TITLE'|translate\" color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\">\n\n <ion-buttons slot=\"end\">\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\"\n *ngIf=\"!saving\"\n [disabled]=\"saving\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item (click)=\"clearCache($event)\">\n <mat-icon><ion-icon name=\"trash-outline\"></ion-icon></mat-icon>\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item\n [disabled]=\"!dirty\"\n (click)=\"cancel($event)\">\n <mat-icon><ion-icon name=\"refresh\"></ion-icon></mat-icon>\n <mat-label translate>COMMON.BTN_RESET</mat-label>\n </button>\n\n <!-- additional items -->\n <ng-container *ngIf=\"!loading\">\n <ng-container *ngFor=\"let item of menuItems\">\n <a *ngIf=\"item.path\"\n mat-menu-item\n class=\"{{item.cssClass}} {{item.color}}\"\n (click)=\"executeAction($event, item)\">\n <mat-icon *ngIf=\"item.icon\"><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-icon *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <mat-label translate>{{item.title}}</mat-label>\n </a>\n <!-- divider -->\n <mat-divider *ngIf=\"!item.path && !item.action\"\n class=\"{{item.cssClass}} {{item.color}}\">\n <mat-label translate>{{item.title}}</mat-label>\n </mat-divider>\n </ng-container>\n </ng-container>\n</mat-menu>\n\n<ion-content>\n\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n\n <ion-grid class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"2\">&nbsp;\n </ion-col>\n\n <ion-col class=\"ion-padding\">\n\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <p [innerHTML]=\"'SETTINGS.DESCRIPTION'|translate\"></p>\n\n <!-- account inheritance (desktop) -->\n <mat-form-field [hidden]=\"!isLogin\" *ngIf=\"!mobile; else accountInheritanceMobile\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\">\n\n <!-- check box (if desktop) -->\n <mat-checkbox\n *ngIf=\"!mobile; else accountInheritanceMobile\"\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\">\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- account inheritance (if mobile) -->\n <ng-template #accountInheritanceMobile>\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\">\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\">\n\n </mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ng-template>\n\n <!-- locale -->\n <mat-form-field>\n <mat-select [placeholder]=\"'SETTINGS.LOCALE'|translate\" formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{item.value}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n\n <!-- Network entry -->\n <h3>\n <ion-text translate>SETTINGS.NETWORK_DIVIDER</ion-text>\n </h3>\n\n <!-- Peer address -->\n <mat-form-field>\n <input matInput type=\"text\" [placeholder]=\"'SETTINGS.PEER_URL'|translate\"\n formControlName=\"peerUrl\"\n required>\n\n <button mat-icon-button type=\"button\" matSuffix (click)=\"showSelectPeerModal()\" tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER'|translate\">\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\"\n translate>SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\"\n translate>SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n\n <!-- Offline mode (if mobile) -->\n <mat-form-field *ngIf=\"mobile\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\">\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\">\n\n </mat-slide-toggle>\n </mat-form-field>\n\n <!-- Data entry -->\n <h3>\n <ion-text translate>SETTINGS.DATA_ENTRY_DIVIDER</ion-text>\n </h3>\n\n <!-- Usage mode -->\n <mat-form-field>\n <mat-select [placeholder]=\"'SETTINGS.USAGE_MODE'|translate\" formControlName=\"usageMode\"\n required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{'SETTINGS.USAGE_MODES.'+item|translate}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- lat/long format-->\n <mat-form-field>\n <mat-select [placeholder]=\"'SETTINGS.LAT_LONG_FORMAT'|translate\" formControlName=\"latLongFormat\"\n required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{'COMMON.LAT_LONG.'+item+'_PLACEHOLDER'|translate}}\n </mat-option>\n </mat-select>\n <mat-error\n *ngIf=\"form.controls.latLongFormat.hasError('required')\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- fields options -->\n <ion-grid formArrayName=\"properties\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding ion-align-self-end\" size=\"12\">\n <span class=\"toolbar-spacer\"></span>\n\n <!-- Show more options -->\n <ion-button color=\"light\" *ngIf=\"propertiesForm?.length === 0\"\n [title]=\"'SETTINGS.BTN_SHOW_MORE_HELP'|translate\"\n (click)=\"propertiesFormHelper.add()\">\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n </ion-col>\n </ion-row>\n\n <!-- Fields options -->\n <ng-container *ngFor=\"let propertyForm of propertiesForm?.controls; let i=index\">\n <ion-row class=\"ion-no-padding\" [formGroupName]=\"i\">\n\n <!-- property key -->\n <ion-col class=\"ion-no-padding\">\n <mat-form-field>\n <mat-select formControlName=\"key\"\n [placeholder]=\" 'SETTINGS.PROPERTY_KEY'|translate\">\n <mat-option *ngFor=\"let item of propertyDefinitions\" [value]=\"item.key\">{{ item.label | translate }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n\n <!-- property value -->\n <ion-col class=\"ion-no-padding\" padding-left>\n <app-form-field *ngIf=\"getPropertyDefinition(i); let definition\"\n floatLabel=\"never\"\n [definition]=\"definition\"\n [formControl]=\"propertyForm|formGetControl:'value'\"\n [placeholder]=\"'SETTINGS.PROPERTY_VALUE' | translate\"\n [required]=\"true\">\n </app-form-field>\n </ion-col>\n <ion-col size=\"2\" class=\"ion-no-padding\">\n <button type=\"button\" mat-icon-button color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'COMMON.BTN_DELETE'|translate\"\n (click)=\"removePropertyAt(i)\">\n <mat-icon>close</mat-icon>\n </button>\n <button *ngIf=\"propertiesFormHelper.isLast(i)\"\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'SETTINGS.BTN_ADD_PROPERTY'|translate\"\n (click)=\"propertiesFormHelper.add()\">\n <mat-icon>add</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n </ng-container>\n </ion-grid>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"2\">&nbsp;\n </ion-col>\n </ion-row>\n </ion-grid>\n\n\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar (onCancel)=\"cancel()\" (onSave)=\"save($event)\" [disabled]=\"!form.dirty || saving\"></app-form-buttons-bar>\n</ion-footer>\n" }]
303
+ }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.PlatformService }, { type: i2.NavController }, { type: i3.LocalSettingsValidatorService }, { type: i2.AlertController }, { type: i4.TranslateService }, { type: i5.UntypedFormBuilder }, { type: i6.AccountService }, { type: i7.LocalSettingsService }, { type: i0.ChangeDetectorRef }, { type: i8.NetworkService }, { type: undefined, decorators: [{
290
304
  type: Inject,
291
305
  args: [APP_LOCALES]
306
+ }] }, { type: undefined, decorators: [{
307
+ type: Optional
308
+ }, {
309
+ type: Inject,
310
+ args: [APP_SETTINGS_MENU_ITEMS]
292
311
  }] }]; } });
293
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dGluZ3MucGFnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS9zZXR0aW5ncy9zZXR0aW5ncy5wYWdlLnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL3NldHRpbmdzL3NldHRpbmdzLnBhZ2UuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsdUJBQXVCLEVBQXFCLFNBQVMsRUFBRSxNQUFNLEVBQThCLE1BQU0sZUFBZSxDQUFDO0FBRXpILE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRCxPQUFPLEVBQUMsV0FBVyxFQUF5QyxNQUFNLGtDQUFrQyxDQUFDO0FBQ3JHLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQztBQUVsRCxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFDM0MsT0FBTyxFQUFDLFlBQVksRUFBRSxlQUFlLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQztBQUVqRSxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUMsNkJBQTZCLEVBQUMsTUFBTSxnREFBZ0QsQ0FBQztBQUc3RixPQUFPLEVBQUMsS0FBSyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQztBQUd0RSxPQUFPLEVBQUMsS0FBSyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBRTNCLE9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWMzQyxNQUFNLE9BQU8sWUFBYSxTQUFRLE9BQXNCO0lBMkJ0RCxZQUNFLFFBQWtCLEVBQ1IsUUFBeUIsRUFDekIsTUFBYyxFQUNkLGdCQUErQyxFQUMvQyxTQUEwQixFQUMxQixTQUEyQixFQUMzQixXQUErQixFQUMvQixjQUE4QixFQUM5QixR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QyxDQUFDO0lBQy9CLENBQUM7SUFFUyxZQUFZO1FBQ3BCLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDekIsQ0FBQzs7MEdBeFRVLFlBQVksOFdBdUNiLFdBQVc7OEZBdkNWLFlBQVksd0NBTFo7UUFDVCxFQUFDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsNkJBQTZCLEVBQUM7S0FDeEUsaURDN0JILHlxVUFzUEE7NEZEdE5hLFlBQVk7a0JBUnhCLFNBQVM7K0JBQ0UsZUFBZSxhQUVkO3dCQUNULEVBQUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSw2QkFBNkIsRUFBQztxQkFDeEUsbUJBQ2dCLHVCQUF1QixDQUFDLE1BQU07OzBCQXlDNUMsTUFBTTsyQkFBQyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgSW5qZWN0LCBJbmplY3RvciwgT25EZXN0cm95LCBPbkluaXR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtBY2NvdW50U2VydmljZX0gZnJvbSAnLi4vc2VydmljZXMvYWNjb3VudC5zZXJ2aWNlJztcbmltcG9ydCB7RW50aXR5VXRpbHN9IGZyb20gJy4uL3NlcnZpY2VzL21vZGVsL2VudGl0eS5tb2RlbCc7XG5pbXBvcnQge0FQUF9MT0NBTEVTLCBMb2NhbGVDb25maWcsIExvY2FsU2V0dGluZ3MsIFVzYWdlTW9kZX0gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvc2V0dGluZ3MubW9kZWwnO1xuaW1wb3J0IHtQZWVyfSBmcm9tICcuLi9zZXJ2aWNlcy9tb2RlbC9wZWVyLm1vZGVsJztcbmltcG9ydCB7VW50eXBlZEZvcm1BcnJheSwgVW50eXBlZEZvcm1CdWlsZGVyLCBVbnR5cGVkRm9ybUNvbnRyb2wsIFVudHlwZWRGb3JtR3JvdXB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7QXBwRm9ybX0gZnJvbSAnLi4vZm9ybS9mb3JtLmNsYXNzJztcbmltcG9ydCB7QXBwRm9ybVV0aWxzLCBGb3JtQXJyYXlIZWxwZXJ9IGZyb20gJy4uL2Zvcm0vZm9ybS51dGlscyc7XG5pbXBvcnQge1RyYW5zbGF0ZVNlcnZpY2V9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtWYWxpZGF0b3JTZXJ2aWNlfSBmcm9tICdAZS1pcy9uZ3gtbWF0ZXJpYWwtdGFibGUnO1xuaW1wb3J0IHtMb2NhbFNldHRpbmdzVmFsaWRhdG9yU2VydmljZX0gZnJvbSAnLi4vc2VydmljZXMvdmFsaWRhdG9yL2xvY2FsLXNldHRpbmdzLnZhbGlkYXRvcic7XG5pbXBvcnQge1BsYXRmb3JtU2VydmljZX0gZnJvbSAnLi4vc2VydmljZXMvcGxhdGZvcm0uc2VydmljZSc7XG5pbXBvcnQge05ldHdvcmtTZXJ2aWNlfSBmcm9tICcuLi9zZXJ2aWNlcy9uZXR3b3JrLnNlcnZpY2UnO1xuaW1wb3J0IHtpc05pbCwgaXNOaWxPckJsYW5rLCB0b0Jvb2xlYW59IGZyb20gJy4uLy4uL3NoYXJlZC9mdW5jdGlvbnMnO1xuaW1wb3J0IHtMb2NhbFNldHRpbmdzU2VydmljZX0gZnJvbSAnLi4vc2VydmljZXMvbG9jYWwtc2V0dGluZ3Muc2VydmljZSc7XG5pbXBvcnQge0Zvcm1GaWVsZERlZmluaXRpb24sIEZvcm1GaWVsZERlZmluaXRpb25NYXB9IGZyb20gJy4uLy4uL3NoYXJlZC9mb3JtL2ZpZWxkLm1vZGVsJztcbmltcG9ydCB7bWVyZ2V9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtBbGVydENvbnRyb2xsZXJ9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7QWxlcnRzfSBmcm9tICcuLi8uLi9zaGFyZWQvYWxlcnRzJztcbmltcG9ydCB7UHJvcGVydHl9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQge1JvdXRlcn0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7Q2FuTGVhdmV9IGZyb20gJy4uLy4uL3NoYXJlZC9ndWFyZC9jb21wb25lbnQtZGlydHkuZ3VhcmQnO1xuaW1wb3J0IHtJU2VsZWN0UGVlck1vZGFsT3B0aW9uc30gZnJvbSAnLi4vcGVlci9zZWxlY3QtcGVlci5tb2RhbCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3BhZ2Utc2V0dGluZ3MnLFxuICB0ZW1wbGF0ZVVybDogJ3NldHRpbmdzLnBhZ2UuaHRtbCcsXG4gIHByb3ZpZGVyczogW1xuICAgIHtwcm92aWRlOiBWYWxpZGF0b3JTZXJ2aWNlLCB1c2VFeGlzdGluZzogTG9jYWxTZXR0aW5nc1ZhbGlkYXRvclNlcnZpY2V9LFxuICBdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBTZXR0aW5nc1BhZ2UgZXh0ZW5kcyBBcHBGb3JtPExvY2FsU2V0dGluZ3M+IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIENhbkxlYXZlIHtcblxuICBwcml2YXRlIGRhdGE6IExvY2FsU2V0dGluZ3M7XG5cbiAgbW9iaWxlOiBib29sZWFuO1xuICBzYXZpbmcgPSBmYWxzZTtcbiAgdXNhZ2VNb2RlczogVXNhZ2VNb2RlW10gPSBbJ0ZJRUxEJywgJ0RFU0snXTtcblxuICBwcm9wZXJ0eURlZmluaXRpb25zOiBGb3JtRmllbGREZWZpbml0aW9uW107XG4gIHByb3BlcnR5RGVmaW5pdGlvbnNCeUtleTogRm9ybUZpZWxkRGVmaW5pdGlvbk1hcCA9IHt9O1xuICBwcm9wZXJ0eURlZmluaXRpb25zQnlJbmRleDogeyBbaW5kZXg6IG51bWJlcl06IEZvcm1GaWVsZERlZmluaXRpb24gfSA9IHt9O1xuICBwcm9wZXJ0aWVzRm9ybUhlbHBlcjogRm9ybUFycmF5SGVscGVyPFByb3BlcnR5PjtcblxuICBsYXRMb25nRm9ybWF0cyA9IFsnRERNTVNTJywgJ0RETU0nLCAnREQnXTtcblxuICBnZXQgYWNjb3VudEluaGVyaXRhbmNlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmZvcm0uY29udHJvbHNbJ2FjY291bnRJbmhlcml0YW5jZSddLnZhbHVlO1xuICB9XG5cbiAgZ2V0IGlzTG9naW4oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYWNjb3VudFNlcnZpY2UuaXNMb2dpbigpO1xuICB9XG5cbiAgZ2V0IHByb3BlcnRpZXNGb3JtKCk6IFVudHlwZWRGb3JtQXJyYXkge1xuICAgIHJldHVybiB0aGlzLmZvcm0uZ2V0KCdwcm9wZXJ0aWVzJykgYXMgVW50eXBlZEZvcm1BcnJheTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGluamVjdG9yOiBJbmplY3RvcixcbiAgICBwcm90ZWN0ZWQgcGxhdGZvcm06IFBsYXRmb3JtU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgcm91dGVyOiBSb3V0ZXIsXG4gICAgcHJvdGVjdGVkIHZhbGlkYXRvclNlcnZpY2U6IExvY2FsU2V0dGluZ3NWYWxpZGF0b3JTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBhbGVydEN0cmw6IEFsZXJ0Q29udHJvbGxlcixcbiAgICBwcm90ZWN0ZWQgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBmb3JtQnVpbGRlcjogVW50eXBlZEZvcm1CdWlsZGVyLFxuICAgIHByb3RlY3RlZCBhY2NvdW50U2VydmljZTogQWNjb3VudFNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIHNldHRpbmdzOiBMb2NhbFNldHRpbmdzU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHB1YmxpYyBuZXR3b3JrOiBOZXR3b3JrU2VydmljZSxcbiAgICBASW5qZWN0KEFQUF9MT0NBTEVTKSBwdWJsaWMgbG9jYWxlczogTG9jYWxlQ29uZmlnW11cbiAgKSB7XG4gICAgc3VwZXIoaW5qZWN0b3IsIHZhbGlkYXRvclNlcnZpY2UuZ2V0Rm9ybUdyb3VwKCkpO1xuXG4gICAgdGhpcy5wcm9wZXJ0aWVzRm9ybUhlbHBlciA9IG5ldyBGb3JtQXJyYXlIZWxwZXI8UHJvcGVydHk+KFxuICAgICAgdGhpcy5mb3JtLmdldCgncHJvcGVydGllcycpIGFzIFVudHlwZWRGb3JtQXJyYXksXG4gICAgICAodmFsdWUpID0+IHRoaXMudmFsaWRhdG9yU2VydmljZS5nZXRQcm9wZXJ0eUZvcm1Hcm91cCh2YWx1ZSksXG4gICAgICAodjEsIHYyKSA9PiAoIXYxICYmICF2MikgfHwgKHYxLmtleSA9PT0gdjIua2V5KSxcbiAgICAgICh2YWx1ZSkgPT4gIGlzTmlsKHZhbHVlKSB8fCAoaXNOaWwodmFsdWUua2V5KSAmJiBpc05pbCh2YWx1ZS52YWx1ZSkpLFxuICAgICAge1xuICAgICAgICBhbGxvd0VtcHR5QXJyYXk6IHRydWVcbiAgICAgIH1cbiAgICApO1xuXG4gICAgdGhpcy5tb2JpbGUgPSB0aGlzLnBsYXRmb3JtLm1vYmlsZTtcblxuICAgIC8vIEJ5IGRlZmF1bHQsIGRpc2FibGUgdGhlIGZvcm1cbiAgICB0aGlzLl9lbmFibGUgPSBmYWxzZTtcbiAgfVxuXG4gIGFzeW5jIG5nT25Jbml0KCkge1xuICAgIHN1cGVyLm5nT25Jbml0KCk7XG5cbiAgICAvLyBNYWtlIHN1cmUgcGxhdGZvcm0gaXMgcmVhZHlcbiAgICBhd2FpdCB0aGlzLnBsYXRmb3JtLnJlYWR5KCk7XG5cbiAgICB0aGlzLnByb3BlcnR5RGVmaW5pdGlvbnMgPSB0aGlzLnNldHRpbmdzLm9wdGlvbkRlZnMuc2xpY2UoKTsgLy8gY29weSBvcHRpb25zXG4gICAgdGhpcy5wcm9wZXJ0eURlZmluaXRpb25zLmZvckVhY2gobyA9PiB0aGlzLnByb3BlcnR5RGVmaW5pdGlvbnNCeUtleVtvLmtleV0gPSBvKTsgLy8gZmlsbCBtYXBcblxuICAgIC8vIExvYWQgc2V0dGluZ3NcbiAgICBhd2FpdCB0aGlzLmxvYWQoKTtcblxuICAgIHRoaXMucmVnaXN0ZXJTdWJzY3JpcHRpb24oXG4gICAgICBtZXJnZShcbiAgICAgICAgdGhpcy5hY2NvdW50U2VydmljZS5vbkxvZ2luLFxuICAgICAgICB0aGlzLmFjY291bnRTZXJ2aWNlLm9uTG9nb3V0XG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuc2V0QWNjb3VudEluaGVyaXRhbmNlKHRoaXMuYWNjb3VudEluaGVyaXRhbmNlKSkpO1xuICB9XG5cbiAgZ2V0UHJvcGVydHlEZWZpbml0aW9uKGluZGV4OiBudW1iZXIpOiBGb3JtRmllbGREZWZpbml0aW9uIHtcbiAgICBsZXQgZGVmaW5pdGlvbiA9IHRoaXMucHJvcGVydHlEZWZpbml0aW9uc0J5SW5kZXhbaW5kZXhdO1xuICAgIGlmICghZGVmaW5pdGlvbikge1xuICAgICAgZGVmaW5pdGlvbiA9IHRoaXMudXBkYXRlUHJvcGVydHlEZWZpbml0aW9uKGluZGV4KTtcbiAgICAgIHRoaXMucHJvcGVydHlEZWZpbml0aW9uc0J5SW5kZXhbaW5kZXhdID0gZGVmaW5pdGlvbjtcbiAgICB9XG4gICAgcmV0dXJuIGRlZmluaXRpb247XG4gIH1cblxuICB1cGRhdGVQcm9wZXJ0eURlZmluaXRpb24oaW5kZXg6IG51bWJlcik6IEZvcm1GaWVsZERlZmluaXRpb24ge1xuICAgIGNvbnN0IGtleSA9ICh0aGlzLnByb3BlcnRpZXNGb3JtLmF0KGluZGV4KSBhcyBVbnR5cGVkRm9ybUdyb3VwKS5jb250cm9scy5rZXkudmFsdWU7XG4gICAgY29uc3QgZGVmaW5pdGlvbiA9IGtleSAmJiB0aGlzLnByb3BlcnR5RGVmaW5pdGlvbnNCeUtleVtrZXldIHx8IG51bGw7XG4gICAgdGhpcy5wcm9wZXJ0eURlZmluaXRpb25zQnlJbmRleFtpbmRleF0gPSBkZWZpbml0aW9uOyAvLyB1cGRhdGUgbWFwIGJ5IGluZGV4XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICByZXR1cm4gZGVmaW5pdGlvbjtcbiAgfVxuXG4gIHJlbW92ZVByb3BlcnR5QXQoaW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMucHJvcGVydGllc0Zvcm1IZWxwZXIucmVtb3ZlQXQoaW5kZXgpO1xuICAgIHRoaXMucHJvcGVydHlEZWZpbml0aW9uc0J5SW5kZXggPSB7fTsgLy8gY2xlYXIgY2FjaGUgYnkgaW5kZXhcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgYXN5bmMgbG9hZCgpIHtcblxuICAgIHRoaXMubWFya0FzTG9hZGluZygpO1xuICAgIGNvbnNvbGUuZGVidWcoJ1tzZXR0aW5nc10gTG9hZGluZyBzZXR0aW5ncy4uLicpO1xuXG4gICAgY29uc3QgZGF0YSA9IHRoaXMuc2V0dGluZ3Muc2V0dGluZ3M7XG5cbiAgICAvLyBTZXQgZGVmYXVsdHNcbiAgICBkYXRhLmFjY291bnRJbmhlcml0YW5jZSA9IHRvQm9vbGVhbihkYXRhLmFjY291bnRJbmhlcml0YW5jZSwgdHJ1ZSk7XG4gICAgZGF0YS5sb2NhbGUgPSBkYXRhLmxvY2FsZSB8fCB0aGlzLnRyYW5zbGF0ZS5jdXJyZW50TGFuZyB8fCB0aGlzLnRyYW5zbGF0ZS5kZWZhdWx0TGFuZztcbiAgICBkYXRhLmxhdExvbmdGb3JtYXQgPSBkYXRhLmxhdExvbmdGb3JtYXQgfHwgJ0RETU1TUyc7XG4gICAgZGF0YS51c2FnZU1vZGUgPSBkYXRhLnVzYWdlTW9kZSB8fCAnREVTSyc7XG5cbiAgICAvLyBTZXQgcGVlclxuICAgIGlmIChpc05pbE9yQmxhbmsoZGF0YS5wZWVyVXJsKSkge1xuICAgICAgYXdhaXQgdGhpcy5uZXR3b3JrLnJlYWR5KCk7XG4gICAgICBjb25zdCBwZWVyID0gdGhpcy5uZXR3b3JrLnBlZXI7XG4gICAgICBkYXRhLnBlZXJVcmwgPSBwZWVyICYmIHBlZXIudXJsO1xuICAgIH1cblxuICAgIC8vIFJlbWVtYmVyIGRhdGFcbiAgICB0aGlzLnVwZGF0ZVZpZXcoZGF0YSk7XG4gIH1cblxuICB1cGRhdGVWaWV3KGRhdGE6IExvY2FsU2V0dGluZ3MpIHtcbiAgICBpZiAoIWRhdGEpIHJldHVybjsgLy9za2lwXG4gICAgdGhpcy5kYXRhID0gZGF0YTtcblxuICAgIGNvbnN0IGpzb246IGFueSA9IHsuLi5kYXRhfTtcblxuICAgIC8vIFRyYW5zZm9ybSBwcm9wZXJ0aWVzIG1hcCBpbnRvIGFycmF5XG4gICAganNvbi5wcm9wZXJ0aWVzID0gRW50aXR5VXRpbHMuZ2V0TWFwQXNBcnJheShkYXRhLnByb3BlcnRpZXMgfHwge30pO1xuICAgIHRoaXMucHJvcGVydGllc0Zvcm1IZWxwZXIucmVzaXplKGpzb24ucHJvcGVydGllcy5sZW5ndGgpO1xuXG4gICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUoanNvbiwge2VtaXRFdmVudDogZmFsc2V9KTtcbiAgICB0aGlzLm1hcmtBc1ByaXN0aW5lKCk7XG5cbiAgICB0aGlzLmVuYWJsZSh7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuXG4gICAgLy8gQXBwbHkgaW5oZXJpdGFuY2VcbiAgICB0aGlzLnNldEFjY291bnRJbmhlcml0YW5jZShkYXRhLmFjY291bnRJbmhlcml0YW5jZSwge2VtaXRFdmVudDogZmFsc2V9KTtcblxuICAgIHRoaXMubWFya0FzTG9hZGVkKCk7XG4gICAgdGhpcy5lcnJvciA9IG51bGw7XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIGFzeW5jIHNhdmUoZXZlbnQ/OiBFdmVudCwgb3B0aW9ucz86IGFueSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICh0aGlzLnNhdmluZykgcmV0dXJuOyAvLyBTa2lwXG5cbiAgICBpZiAoZXZlbnQpIGV2ZW50LnByZXZlbnREZWZhdWx0KClcblxuICAgIC8vIFJlbW92ZSBhbGwgZW1wdHkgY29udHJvbHNcbiAgICB0aGlzLnByb3BlcnRpZXNGb3JtSGVscGVyLnJlbW92ZUFsbEVtcHR5KCk7XG5cbiAgICBpZiAoIXRoaXMuZm9ybS52YWxpZCkge1xuICAgICAgYXdhaXQgQXBwRm9ybVV0aWxzLndhaXRXaGlsZVBlbmRpbmcodGhpcy5mb3JtKTtcblxuICAgICAgaWYgKHRoaXMuZm9ybS5pbnZhbGlkKSB7XG4gICAgICAgIEFwcEZvcm1VdGlscy5sb2dGb3JtRXJyb3JzKHRoaXMuZm9ybSk7XG4gICAgICAgIHRoaXMuZm9ybS5tYXJrQWxsQXNUb3VjaGVkKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zb2xlLmRlYnVnKCdbc2V0dGluZ3NdIFNhdmluZyBsb2NhbCBzZXR0aW5ncy4uLicpO1xuXG4gICAgdGhpcy5zYXZpbmcgPSB0cnVlO1xuICAgIHRoaXMuZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcblxuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLmdldFZhbHVlKCk7XG5cbiAgICAvLyBDaGVjayBwZWVyIGFsaXZlLCBiZWZvcmUgc2F2aW5nXG4gICAgY29uc3QgcGVlckNoYW5nZWQgPSB0aGlzLmZvcm0uZ2V0KCdwZWVyVXJsJykuZGlydHk7XG5cbiAgICAvLyBDbGVhbiBwYWdlIGhpc3RvcnksIHdoZW4gcGVlciBjaGFuZ2VkXG4gICAgaWYgKHBlZXJDaGFuZ2VkKSBkYXRhLnBhZ2VIaXN0b3J5ID0gW107XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5kaXNhYmxlKCk7XG5cbiAgICAgIGF3YWl0IHRoaXMuc2V0dGluZ3MuYXBwbHkoZGF0YSk7XG4gICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgICAgdGhpcy5tYXJrQXNQcmlzdGluZSgpO1xuXG4gICAgICAvLyBJZiBwZWVyIGNoYW5nZWRcbiAgICAgIGlmIChwZWVyQ2hhbmdlZCkge1xuICAgICAgICAvLyBSZXN0YXJ0IHRoZSBuZXR3b3JrXG4gICAgICAgIHRoaXMubmV0d29yay5wZWVyID0gUGVlci5wYXJzZVVybChkYXRhLnBlZXJVcmwpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgIHRoaXMuZXJyb3IgPSBlcnIgJiYgZXJyLm1lc3NhZ2UgfHwgZXJyO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmVuYWJsZSh7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuXG4gICAgICAvLyBBcHBseSBpbmhlcml0YW5jZVxuICAgICAgdGhpcy5zZXRBY2NvdW50SW5oZXJpdGFuY2UoZGF0YS5hY2NvdW50SW5oZXJpdGFuY2UsIHtlbWl0RXZlbnQ6IGZhbHNlfSk7XG5cbiAgICAgIC8vIEFkZCBhIGRlbGF5LCBiZWNhdXNlIG9mIG9wdGlvbiBtZW51IHRoYXQgaXMgYWx3YXlzIG9wZW5lZCBhZnRlciBzYXZlISFcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSwgNDAwKTtcbiAgICB9XG4gIH1cblxuXG4gIHNldEFjY291bnRJbmhlcml0YW5jZShlbmFibGU6IGJvb2xlYW4sIG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW4gfSkge1xuICAgIC8vIE1ha2Ugc3VyZSB0byB1cGRhdGUgdGhlIHZhbHVlIGluIGNvbnRyb2xcbiAgICB0aGlzLmZvcm0uY29udHJvbHNbJ2FjY291bnRJbmhlcml0YW5jZSddLnNldFZhbHVlKGVuYWJsZSwgb3B0cyk7XG4gICAgaWYgKHRoaXMuZGF0YS5hY2NvdW50SW5oZXJpdGFuY2UgIT09IGVuYWJsZSkge1xuICAgICAgdGhpcy5mb3JtLmNvbnRyb2xzWydhY2NvdW50SW5oZXJpdGFuY2UnXS5tYXJrQXNEaXJ0eSh7b25seVNlbGY6IGZhbHNlfSk7XG4gICAgfVxuXG4gICAgaWYgKGVuYWJsZSkge1xuICAgICAgaWYgKHRoaXMuaXNMb2dpbikge1xuICAgICAgICAvLyBGb3JjZSB1c2luZyBhY2NvdW50IHNldHRpbmdzXG4gICAgICAgIGNvbnN0IGFjY291bnQgPSB0aGlzLmFjY291bnRTZXJ2aWNlLmFjY291bnQ7XG5cbiAgICAgICAgLy8gQ29weSB2YWx1ZXNcbiAgICAgICAgaWYgKGFjY291bnQuc2V0dGluZ3MpIHtcbiAgICAgICAgICBpZiAoYWNjb3VudC5zZXR0aW5ncy5sb2NhbGUpIHRoaXMuZm9ybS5nZXQoJ2xvY2FsZScpLnNldFZhbHVlKGFjY291bnQuc2V0dGluZ3MubG9jYWxlLCBvcHRzKTtcbiAgICAgICAgICBpZiAoYWNjb3VudC5zZXR0aW5ncy5sYXRMb25nRm9ybWF0KSB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0Jykuc2V0VmFsdWUoYWNjb3VudC5zZXR0aW5ncy5sYXRMb25nRm9ybWF0LCBvcHRzKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBEaXNhYmxlIGZpZWxkc1xuICAgICAgICB0aGlzLmZvcm0uZ2V0KCdsb2NhbGUnKS5kaXNhYmxlKG9wdHMpO1xuICAgICAgICB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0JykuZGlzYWJsZShvcHRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEVuYWJsZSBmaWVsZHNcbiAgICAgICAgdGhpcy5mb3JtLmdldCgnbG9jYWxlJykuZW5hYmxlKG9wdHMpO1xuICAgICAgICB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0JykuZW5hYmxlKG9wdHMpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZXN0b3JlIHByZXZpb3VzIHZhbHVlc1xuICAgICAgdGhpcy5mb3JtLmdldCgnbG9jYWxlJykuc2V0VmFsdWUodGhpcy5kYXRhLmxvY2FsZSwgb3B0cyk7XG4gICAgICB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0Jykuc2V0VmFsdWUodGhpcy5kYXRhLmxhdExvbmdGb3JtYXQsIG9wdHMpO1xuXG4gICAgICAvLyBFbmFibGUgZmllbGRzXG4gICAgICB0aGlzLmZvcm0uZ2V0KCdsb2NhbGUnKS5lbmFibGUob3B0cyk7XG4gICAgICB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0JykuZW5hYmxlKG9wdHMpO1xuICAgIH1cblxuICAgIC8vIE1hcmsgZm9yIGNoZWNrLCBpZiBuZWVkXG4gICAgaWYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50KSB7XG4gICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNob3dTZWxlY3RQZWVyTW9kYWwob3B0cz86IFBhcnRpYWw8SVNlbGVjdFBlZXJNb2RhbE9wdGlvbnM+KSB7XG4gICAgY29uc3QgcGVlciA9IGF3YWl0IHRoaXMubmV0d29yay5zaG93U2VsZWN0UGVlck1vZGFsKHtcbiAgICAgIHNob3dTZXRNYW51YWxseUJ1dHRvbjogZmFsc2UsIC8vIE1ha2Ugbm8gc2Vuc2UgaGVyZSwgYmVjYXVzZSBzYW1lIGFzIGNhbmNlbCAoYWxyZWFkeSBpbnNpZGUgdGhlIHNldHRpbmdzIHBhZ2UpXG4gICAgICAuLi5vcHRzfSk7XG4gICAgaWYgKHBlZXI/LnVybCkge1xuICAgICAgY29uc3QgY29udHJvbCA9IHRoaXMuZm9ybS5nZXQoJ3BlZXJVcmwnKSBhcyBVbnR5cGVkRm9ybUNvbnRyb2w7XG4gICAgICBjb250cm9sLnNldFZhbHVlKHBlZXIudXJsLCB7ZW1pdEV2ZW50OiB0cnVlLCBvbmx5U2VsZjogZmFsc2V9KTtcbiAgICAgIGNvbnRyb2wubWFya0FzRGlydHkoe29ubHlTZWxmOiBmYWxzZX0pO1xuICAgICAgdGhpcy5tYXJrQXNEaXJ0eSgpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNhbmNlbChldmVudD86IEV2ZW50KSB7XG4gICAgYXdhaXQgdGhpcy5sb2FkKCk7XG4gIH1cblxuICBhc3luYyBjbG9zZShldmVudD86IEV2ZW50KSB7XG4gICAgaWYgKHRoaXMuc2F2aW5nKSByZXR1cm47XG5cbiAgICAvLyBCYWNrIHRvIGhvbWVcbiAgICByZXR1cm4gdGhpcy5yb3V0ZXIubmF2aWdhdGVCeVVybCgnLycsIHsgcmVwbGFjZVVybDogdHJ1ZSB9KTsgLy8gYmFjayB0byBob21lXG4gIH1cblxuICBhc3luYyBjbGVhckNhY2hlKGV2ZW50PzogRXZlbnQpIHtcbiAgICBjb25zdCBjb25maXJtID0gYXdhaXQgQWxlcnRzLmFza0FjdGlvbkNvbmZpcm1hdGlvbih0aGlzLmFsZXJ0Q3RybCwgdGhpcy50cmFuc2xhdGUsIHRydWUsIGV2ZW50KTtcbiAgICBpZiAoY29uZmlybSkge1xuICAgICAgYXdhaXQgdGhpcy5uZXR3b3JrLmNsZWFyQ2FjaGUoKTtcbiAgICAgIHRoaXMuc2V0dGluZ3MucmVtb3ZlT2ZmbGluZUZlYXR1cmVzKCk7XG4gICAgfVxuICB9XG5cbiAgLyogLS0gcHJvdGVjdGVkIGZ1bmN0aW9ucyAtLSAqL1xuXG4gIHByb3RlY3RlZCBhc3luYyBnZXRWYWx1ZSgpOiBQcm9taXNlPExvY2FsU2V0dGluZ3M+IHtcbiAgICBjb25zdCBqc29uID0gYXdhaXQgdGhpcy5nZXRKc29uVmFsdWVUb1NhdmUoKTtcblxuICAgIC8vIE92ZXJyaWRlIHByb3BlcnRpZXMgZnJvbSBhY2NvdW50XG4gICAgaWYgKGpzb24uYWNjb3VudEluaGVyaXRhbmNlICYmIHRoaXMuaXNMb2dpbikge1xuICAgICAgY29uc3QgYWNjb3VudCA9IHRoaXMuYWNjb3VudFNlcnZpY2UuYWNjb3VudDtcbiAgICAgIGNvbnN0IHVzZXJTZXR0aW5ncyA9IGFjY291bnQgJiYgYWNjb3VudC5zZXR0aW5ncztcbiAgICAgIGNvbnNvbGUuZGVidWcoYFtzZXR0aW5nc10gQXBwbHlpbmcgYWNjb3VudCBpbmhlcml0YW5jZSB7bG9jYWxlOiAnJHt1c2VyU2V0dGluZ3MubG9jYWxlfScsIGxhdExvbmdGb3JtYXQ6ICcke3VzZXJTZXR0aW5ncy5sYXRMb25nRm9ybWF0fSd9Li4uYCk7XG4gICAgICBqc29uLmxvY2FsZSA9IHVzZXJTZXR0aW5ncy5sb2NhbGUgfHwganNvbi5sb2NhbGU7XG4gICAgICBqc29uLmxhdExvbmdGb3JtYXQgPSB1c2VyU2V0dGluZ3MubGF0TG9uZ0Zvcm1hdCB8fCBqc29uLmxhdExvbmdGb3JtYXQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGpzb247XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0SnNvblZhbHVlVG9TYXZlKCk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QganNvbiA9IHRoaXMuZm9ybS52YWx1ZTtcbiAgICBqc29uLnByb3BlcnRpZXMgPSBFbnRpdHlVdGlscy5nZXRQcm9wZXJ0eUFycmF5QXNPYmplY3QoanNvbi5wcm9wZXJ0aWVzKTtcblxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoanNvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgbWFya0ZvckNoZWNrKCkge1xuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuXG59XG4iLCI8YXBwLXRvb2xiYXIgW3RpdGxlXT1cIidTRVRUSU5HUy5USVRMRSd8dHJhbnNsYXRlXCIgY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgICBbaGFzVmFsaWRhdGVdPVwiZGlydHkgJiYgIXNhdmluZ1wiXG4gICAgICAgICAgICAgW2hhc0Nsb3NlXT1cIiFkaXJ0eSAmJiAhc2F2aW5nXCJcbiAgICAgICAgICAgICAob25WYWxpZGF0ZSk9XCJzYXZlKCRldmVudClcIlxuICAgICAgICAgICAgIChvbkNsb3NlKT1cImNsb3NlKCRldmVudClcIj5cblxuICA8aW9uLWJ1dHRvbnMgc2xvdD1cImVuZFwiPlxuICAgIDwhLS0gb3B0aW9ucyBtZW51IC0tPlxuICAgIDxpb24tYnV0dG9uIFttYXRNZW51VHJpZ2dlckZvcl09XCJvcHRpb25zTWVudVwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCIhc2F2aW5nXCJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwic2F2aW5nXCI+XG4gICAgICA8bWF0LWljb24gc2xvdD1cImljb24tb25seVwiPm1vcmVfdmVydDwvbWF0LWljb24+XG4gICAgPC9pb24tYnV0dG9uPlxuICA8L2lvbi1idXR0b25zPlxuPC9hcHAtdG9vbGJhcj5cblxuPCEtLSBPcHRpb25zIG1lbnUgLS0+XG48bWF0LW1lbnUgI29wdGlvbnNNZW51PVwibWF0TWVudVwiPlxuICA8IS0tIENsZWFyIGNhY2hlIC0tPlxuICA8YnV0dG9uIG1hdC1tZW51LWl0ZW0gKGNsaWNrKT1cImNsZWFyQ2FjaGUoJGV2ZW50KVwiPlxuICAgIDxpb24tbGFiZWwgdHJhbnNsYXRlPlNFVFRJTkdTLkJUTl9DTEVBUl9DQUNIRTwvaW9uLWxhYmVsPlxuICA8L2J1dHRvbj5cblxuICA8IS0tIFJlc2V0IC0tPlxuICA8YnV0dG9uIG1hdC1tZW51LWl0ZW1cbiAgICAgICAgICBbZGlzYWJsZWRdPVwiIWRpcnR5XCJcbiAgICAgICAgICAoY2xpY2spPVwiY2FuY2VsKCRldmVudClcIj5cbiAgICA8aW9uLWxhYmVsPlxuICAgICAgPG1hdC1pY29uPjxpb24taWNvbiBzbG90PVwic3RhcnRcIiBuYW1lPVwicmVmcmVzaFwiPjwvaW9uLWljb24+PC9tYXQtaWNvbj4mbmJzcDtcbiAgICAgIDxzcGFuIHRyYW5zbGF0ZT5DT01NT04uQlROX1JFU0VUPC9zcGFuPlxuICAgIDwvaW9uLWxhYmVsPlxuICA8L2J1dHRvbj5cbjwvbWF0LW1lbnU+XG5cbjxpb24tY29udGVudD5cblxuICA8Zm9ybSBbZm9ybUdyb3VwXT1cImZvcm1cIiBub3ZhbGlkYXRlIChuZ1N1Ym1pdCk9XCJzYXZlKCRldmVudClcIiBjbGFzcz1cImZvcm0tY29udGFpbmVyXCI+XG5cbiAgICA8aW9uLWdyaWQgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuICAgICAgPGlvbi1yb3cgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuXG4gICAgICAgIDwhLS0gbGVmdCAgbWFyZ2luIC0tPlxuICAgICAgICA8aW9uLWNvbCBzaXplPVwiMFwiIHNpemUtbGc9XCIyXCI+Jm5ic3A7XG4gICAgICAgIDwvaW9uLWNvbD5cblxuICAgICAgICA8aW9uLWNvbCBjbGFzcz1cImlvbi1wYWRkaW5nXCI+XG5cbiAgICAgICAgICA8IS0tIGVycm9yIC0tPlxuICAgICAgICAgIDxpb24taXRlbSAqbmdJZj1cImVycm9yXCIgbGluZXM9XCJub25lXCI+XG4gICAgICAgICAgICA8aW9uLWljb24gY29sb3I9XCJkYW5nZXJcIiBzbG90PVwic3RhcnRcIiBuYW1lPVwiYWxlcnQtY2lyY2xlXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgIDxpb24tbGFiZWwgY29sb3I9XCJkYW5nZXJcIiBjbGFzcz1cImVycm9yXCIgW2lubmVySFRNTF09XCJlcnJvcnx0cmFuc2xhdGVcIj48L2lvbi1sYWJlbD5cbiAgICAgICAgICA8L2lvbi1pdGVtPlxuXG4gICAgICAgICAgPHAgW2lubmVySFRNTF09XCInU0VUVElOR1MuREVTQ1JJUFRJT04nfHRyYW5zbGF0ZVwiPjwvcD5cblxuICAgICAgICAgIDwhLS0gYWNjb3VudCBpbmhlcml0YW5jZSAoZGVza3RvcCkgLS0+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFtoaWRkZW5dPVwiIWlzTG9naW5cIiAqbmdJZj1cIiFtb2JpbGU7IGVsc2UgYWNjb3VudEluaGVyaXRhbmNlTW9iaWxlXCI+XG4gICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgaGlkZGVuIGZvcm1Db250cm9sTmFtZT1cImFjY291bnRJbmhlcml0YW5jZVwiIHR5cGU9XCJ0ZXh0XCI+XG5cbiAgICAgICAgICAgIDwhLS0gY2hlY2sgYm94IChpZiBkZXNrdG9wKSAtLT5cbiAgICAgICAgICAgIDxtYXQtY2hlY2tib3hcbiAgICAgICAgICAgICAgKm5nSWY9XCIhbW9iaWxlOyBlbHNlIGFjY291bnRJbmhlcml0YW5jZU1vYmlsZVwiXG4gICAgICAgICAgICAgIChjaGFuZ2UpPVwic2V0QWNjb3VudEluaGVyaXRhbmNlKCRldmVudC5jaGVja2VkKVwiXG4gICAgICAgICAgICAgIFtjaGVja2VkXT1cImFjY291bnRJbmhlcml0YW5jZVwiPlxuICAgICAgICAgICAgICA8c3BhbiB0cmFuc2xhdGU+U0VUVElOR1MuSU5IRVJJVF9GUk9NX0FDQ09VTlQ8L3NwYW4+XG4gICAgICAgICAgICA8L21hdC1jaGVja2JveD5cblxuICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZvcm0uY29udHJvbHMuYWNjb3VudEluaGVyaXRhbmNlLmhhc0Vycm9yKCdyZXF1aXJlZCcpXCIgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICAgICAgPCEtLSBhY2NvdW50IGluaGVyaXRhbmNlIChpZiBtb2JpbGUpIC0tPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjYWNjb3VudEluaGVyaXRhbmNlTW9iaWxlPlxuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFtoaWRkZW5dPVwiIWlzTG9naW5cIj5cbiAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IGhpZGRlbiBmb3JtQ29udHJvbE5hbWU9XCJhY2NvdW50SW5oZXJpdGFuY2VcIiB0eXBlPVwidGV4dFwiPlxuXG4gICAgICAgICAgICAgIDwhLS0gc2xpZGUgdG9nZ2xlICAtLT5cbiAgICAgICAgICAgICAgPGlvbi10ZXh0IHRyYW5zbGF0ZT5TRVRUSU5HUy5JTkhFUklUX0ZST01fQUNDT1VOVDwvaW9uLXRleHQ+XG4gICAgICAgICAgICAgIDxtYXQtc2xpZGUtdG9nZ2xlIG1hdFN1ZmZpeFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNldEFjY291bnRJbmhlcml0YW5jZSgkZXZlbnQuY2hlY2tlZClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJhY2NvdW50SW5oZXJpdGFuY2VcIj5cblxuICAgICAgICAgICAgICA8L21hdC1zbGlkZS10b2dnbGU+XG4gICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLmFjY291bnRJbmhlcml0YW5jZS5oYXNFcnJvcigncmVxdWlyZWQnKVwiIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRFxuICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgIDwhLS0gbG9jYWxlIC0tPlxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxtYXQtc2VsZWN0IFtwbGFjZWhvbGRlcl09XCInU0VUVElOR1MuTE9DQUxFJ3x0cmFuc2xhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJsb2NhbGVcIiByZXF1aXJlZD5cbiAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGl0ZW0gb2YgbG9jYWxlc1wiIFt2YWx1ZV09XCJpdGVtLmtleVwiPlxuICAgICAgICAgICAgICAgIHt7aXRlbS52YWx1ZX19XG4gICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLmxvY2FsZS5oYXNFcnJvcigncmVxdWlyZWQnKVwiIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRDwvbWF0LWVycm9yPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICA8IS0tIE5ldHdvcmsgZW50cnkgLS0+XG4gICAgICAgICAgPGgzPlxuICAgICAgICAgICAgPGlvbi10ZXh0IHRyYW5zbGF0ZT5TRVRUSU5HUy5ORVRXT1JLX0RJVklERVI8L2lvbi10ZXh0PlxuICAgICAgICAgIDwvaDM+XG5cbiAgICAgICAgICA8IS0tIFBlZXIgYWRkcmVzcyAtLT5cbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgdHlwZT1cInRleHRcIiBbcGxhY2Vob2xkZXJdPVwiJ1NFVFRJTkdTLlBFRVJfVVJMJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cInBlZXJVcmxcIlxuICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkPlxuXG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0U3VmZml4IChjbGljayk9XCJzaG93U2VsZWN0UGVlck1vZGFsKClcIiB0YWJpbmRleD1cIi0xXCJcbiAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidTRVRUSU5HUy5CVE5fQ0hBTkdFX1BFRVInfHRyYW5zbGF0ZVwiPlxuICAgICAgICAgICAgICA8bWF0LWljb24+c2VhcmNoPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5wZWVyVXJsLmhhc0Vycm9yKCdyZXF1aXJlZCcpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLnBlZXJVcmwuaGFzRXJyb3IoJ3BlZXJBbGl2ZScpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlPlNFVFRJTkdTLkVSUk9SLlBFRVJfTk9UX1JFQUNIQUJMRVxuICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5wZWVyVXJsLmhhc0Vycm9yKCdwZWVyTm90Q29tcGF0aWJsZScpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlPlNFVFRJTkdTLkVSUk9SLlBFRVJfTk9UX0NPTVBBVElCTEVcbiAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICA8IS0tIE9mZmxpbmUgbW9kZSAoaWYgbW9iaWxlKSAtLT5cbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nSWY9XCJtb2JpbGVcIj5cbiAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBoaWRkZW4gZm9ybUNvbnRyb2xOYW1lPVwiYWNjb3VudEluaGVyaXRhbmNlXCIgdHlwZT1cInRleHRcIj5cblxuICAgICAgICAgICAgPCEtLSBzbGlkZSB0b2dnbGUgIC0tPlxuICAgICAgICAgICAgPGlvbi10ZXh0IHRyYW5zbGF0ZT5TRVRUSU5HUy5PRkZMSU5FX01PREU8L2lvbi10ZXh0PlxuICAgICAgICAgICAgPG1hdC1zbGlkZS10b2dnbGUgbWF0U3VmZml4XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm5ldHdvcmsuc2V0Rm9yY2VPZmZsaW5lKCRldmVudC5jaGVja2VkKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJuZXR3b3JrLm9mZmxpbmVcIj5cblxuICAgICAgICAgICAgPC9tYXQtc2xpZGUtdG9nZ2xlPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICA8IS0tIERhdGEgZW50cnkgLS0+XG4gICAgICAgICAgPGgzPlxuICAgICAgICAgICAgPGlvbi10ZXh0IHRyYW5zbGF0ZT5TRVRUSU5HUy5EQVRBX0VOVFJZX0RJVklERVI8L2lvbi10ZXh0PlxuICAgICAgICAgIDwvaDM+XG5cbiAgICAgICAgICA8IS0tIFVzYWdlIG1vZGUgLS0+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPG1hdC1zZWxlY3QgW3BsYWNlaG9sZGVyXT1cIidTRVRUSU5HUy5VU0FHRV9NT0RFJ3x0cmFuc2xhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJ1c2FnZU1vZGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ+XG4gICAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBpdGVtIG9mIHVzYWdlTW9kZXNcIiBbdmFsdWVdPVwiaXRlbVwiPlxuICAgICAgICAgICAgICAgIHt7J1NFVFRJTkdTLlVTQUdFX01PREVTLicraXRlbXx0cmFuc2xhdGV9fVxuICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy51c2FnZU1vZGUuaGFzRXJyb3IoJ3JlcXVpcmVkJylcIlxuICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGU+RVJST1IuRklFTERfUkVRVUlSRURcbiAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICA8IS0tIGxhdC9sb25nIGZvcm1hdC0tPlxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxtYXQtc2VsZWN0IFtwbGFjZWhvbGRlcl09XCInU0VUVElOR1MuTEFUX0xPTkdfRk9STUFUJ3x0cmFuc2xhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJsYXRMb25nRm9ybWF0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkPlxuICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBsYXRMb25nRm9ybWF0c1wiIFt2YWx1ZV09XCJpdGVtXCI+XG4gICAgICAgICAgICAgICAge3snQ09NTU9OLkxBVF9MT05HLicraXRlbSsnX1BMQUNFSE9MREVSJ3x0cmFuc2xhdGV9fVxuICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICA8bWF0LWVycm9yXG4gICAgICAgICAgICAgICpuZ0lmPVwiZm9ybS5jb250cm9scy5sYXRMb25nRm9ybWF0Lmhhc0Vycm9yKCdyZXF1aXJlZCcpXCJcbiAgICAgICAgICAgICAgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICAgICAgPCEtLSBmaWVsZHMgb3B0aW9ucyAtLT5cbiAgICAgICAgICA8aW9uLWdyaWQgZm9ybUFycmF5TmFtZT1cInByb3BlcnRpZXNcIiBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICAgICAgICA8aW9uLXJvdyBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICAgICAgICAgIDxpb24tY29sIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmcgaW9uLWFsaWduLXNlbGYtZW5kXCIgc2l6ZT1cIjEyXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0b29sYmFyLXNwYWNlclwiPjwvc3Bhbj5cblxuICAgICAgICAgICAgICAgIDwhLS0gU2hvdyBtb3JlIG9wdGlvbnMgLS0+XG4gICAgICAgICAgICAgICAgPGlvbi1idXR0b24gY29sb3I9XCJsaWdodFwiICpuZ0lmPVwicHJvcGVydGllc0Zvcm0/Lmxlbmd0aCA9PT0gMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidTRVRUSU5HUy5CVE5fU0hPV19NT1JFX0hFTFAnfHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInByb3BlcnRpZXNGb3JtSGVscGVyLmFkZCgpXCI+XG4gICAgICAgICAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5DT01NT04uQlROX1NIT1dfTU9SRTwvaW9uLWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIHNsb3Q9XCJlbmRcIj5hcnJvd19kcm9wX2Rvd248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgPC9pb24tcm93PlxuXG4gICAgICAgICAgICA8IS0tIEZpZWxkcyBvcHRpb25zIC0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgcHJvcGVydHlGb3JtIG9mIHByb3BlcnRpZXNGb3JtPy5jb250cm9sczsgbGV0IGk9aW5kZXhcIj5cbiAgICAgICAgICAgICAgPGlvbi1yb3cgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiIFtmb3JtR3JvdXBOYW1lXT1cImlcIj5cblxuICAgICAgICAgICAgICAgIDwhLS0gcHJvcGVydHkga2V5IC0tPlxuICAgICAgICAgICAgICAgIDxpb24tY29sIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgZm9ybUNvbnRyb2xOYW1lPVwia2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIiAnU0VUVElOR1MuUFJPUEVSVFlfS0VZJ3x0cmFuc2xhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBwcm9wZXJ0eURlZmluaXRpb25zXCIgW3ZhbHVlXT1cIml0ZW0ua2V5XCI+e3sgaXRlbS5sYWJlbCB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8L2lvbi1jb2w+XG5cbiAgICAgICAgICAgICAgICA8IS0tIHByb3BlcnR5IHZhbHVlIC0tPlxuICAgICAgICAgICAgICAgIDxpb24tY29sIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIiBwYWRkaW5nLWxlZnQ+XG4gICAgICAgICAgICAgICAgICA8YXBwLWZvcm0tZmllbGQgKm5nSWY9XCJnZXRQcm9wZXJ0eURlZmluaXRpb24oaSk7IGxldCBkZWZpbml0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbG9hdExhYmVsPVwibmV2ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkZWZpbml0aW9uXT1cImRlZmluaXRpb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJwcm9wZXJ0eUZvcm18Zm9ybUdldENvbnRyb2w6J3ZhbHVlJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidTRVRUSU5HUy5QUk9QRVJUWV9WQUxVRScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZXF1aXJlZF09XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgICA8L2FwcC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICAgICAgICA8aW9uLWNvbCBzaXplPVwiMlwiIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiBjb2xvcj1cImxpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImxvYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiJ0NPTU1PTi5CVE5fREVMRVRFJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmVtb3ZlUHJvcGVydHlBdChpKVwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+Y2xvc2U8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwicHJvcGVydGllc0Zvcm1IZWxwZXIuaXNMYXN0KGkpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1cImxpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImxvYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidTRVRUSU5HUy5CVE5fQUREX1BST1BFUlRZJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicHJvcGVydGllc0Zvcm1IZWxwZXIuYWRkKClcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgICAgIDwvaW9uLXJvdz5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvaW9uLWdyaWQ+XG4gICAgICAgIDwvaW9uLWNvbD5cblxuICAgICAgICA8IS0tIHJpZ2h0IG1hcmdpbiAtLT5cbiAgICAgICAgPGlvbi1jb2wgc2l6ZT1cIjBcIiBzaXplLWxnPVwiMlwiPiZuYnNwO1xuICAgICAgICA8L2lvbi1jb2w+XG4gICAgICA8L2lvbi1yb3c+XG4gICAgPC9pb24tZ3JpZD5cblxuXG4gIDwvZm9ybT5cbjwvaW9uLWNvbnRlbnQ+XG5cbjxpb24tZm9vdGVyIGhpZGRlbi14cyBoaWRkZW4tc20gaGlkZGVuLW1vYmlsZT5cbiAgPGFwcC1mb3JtLWJ1dHRvbnMtYmFyIChvbkNhbmNlbCk9XCJjYW5jZWwoKVwiIChvblNhdmUpPVwic2F2ZSgkZXZlbnQpXCIgW2Rpc2FibGVkXT1cIiFmb3JtLmRpcnR5IHx8IHNhdmluZ1wiPjwvYXBwLWZvcm0tYnV0dG9ucy1iYXI+XG48L2lvbi1mb290ZXI+XG4iXX0=
312
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dGluZ3MucGFnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS9zZXR0aW5ncy9zZXR0aW5ncy5wYWdlLnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL3NldHRpbmdzL3NldHRpbmdzLnBhZ2UuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsdUJBQXVCLEVBQXFCLFNBQVMsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUErQixRQUFRLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFFbkosT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGdDQUFnQyxDQUFDO0FBQzNELE9BQU8sRUFBQyxXQUFXLEVBQXlDLE1BQU0sa0NBQWtDLENBQUM7QUFDckcsT0FBTyxFQUFDLElBQUksRUFBQyxNQUFNLDhCQUE4QixDQUFDO0FBRWxELE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQztBQUMzQyxPQUFPLEVBQUMsWUFBWSxFQUFFLGVBQWUsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBRWpFLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBQzFELE9BQU8sRUFBQyw2QkFBNkIsRUFBQyxNQUFNLGdEQUFnRCxDQUFDO0FBRzdGLE9BQU8sRUFBQyxLQUFLLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBQyxNQUFNLHdCQUF3QixDQUFDO0FBR3RFLE9BQU8sRUFBQyxLQUFLLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFFM0IsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLHFCQUFxQixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBTTNDLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLElBQUksY0FBYyxDQUFhLG1CQUFtQixDQUFDLENBQUM7QUFVM0YsTUFBTSxPQUFPLFlBQWEsU0FBUSxPQUFzQjtJQTRCdEQsWUFDRSxRQUFrQixFQUNS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QUFxRCxZQUFZLENBQUMsTUFBTSxzQkFBc0IsWUFBWSxDQUFDLGFBQWEsT0FBTyxDQUFDLENBQUM7WUFDL0ksSUFBSSxDQUFDLE1BQU0sR0FBRyxZQUFZLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDakQsSUFBSSxDQUFDLGFBQWEsR0FBRyxZQUFZLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUM7U0FDdkU7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFUyxrQkFBa0I7UUFDMUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDN0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxXQUFXLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRXhFLE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRVMsWUFBWTtRQUNwQixJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3pCLENBQUM7O3lHQXZVVSxZQUFZLHFYQXdDYixXQUFXLGFBQ0MsdUJBQXVCOzZGQXpDbEMsWUFBWSx3Q0FMWjtRQUNULEVBQUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSw2QkFBNkIsRUFBQztLQUN4RSxpREMvQkgscThWQXdRQTsyRkR0T2EsWUFBWTtrQkFSeEIsU0FBUzsrQkFDRSxlQUFlLGFBRWQ7d0JBQ1QsRUFBQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLDZCQUE2QixFQUFDO3FCQUN4RSxtQkFDZ0IsdUJBQXVCLENBQUMsTUFBTTs7MEJBMEM1QyxNQUFNOzJCQUFDLFdBQVc7OzBCQUNsQixRQUFROzswQkFBSSxNQUFNOzJCQUFDLHVCQUF1QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEluamVjdCwgSW5qZWN0aW9uVG9rZW4sIEluamVjdG9yLCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3B0aW9uYWx9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtBY2NvdW50U2VydmljZX0gZnJvbSAnLi4vc2VydmljZXMvYWNjb3VudC5zZXJ2aWNlJztcbmltcG9ydCB7RW50aXR5VXRpbHN9IGZyb20gJy4uL3NlcnZpY2VzL21vZGVsL2VudGl0eS5tb2RlbCc7XG5pbXBvcnQge0FQUF9MT0NBTEVTLCBMb2NhbGVDb25maWcsIExvY2FsU2V0dGluZ3MsIFVzYWdlTW9kZX0gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvc2V0dGluZ3MubW9kZWwnO1xuaW1wb3J0IHtQZWVyfSBmcm9tICcuLi9zZXJ2aWNlcy9tb2RlbC9wZWVyLm1vZGVsJztcbmltcG9ydCB7VW50eXBlZEZvcm1BcnJheSwgVW50eXBlZEZvcm1CdWlsZGVyLCBVbnR5cGVkRm9ybUNvbnRyb2wsIFVudHlwZWRGb3JtR3JvdXB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7QXBwRm9ybX0gZnJvbSAnLi4vZm9ybS9mb3JtLmNsYXNzJztcbmltcG9ydCB7QXBwRm9ybVV0aWxzLCBGb3JtQXJyYXlIZWxwZXJ9IGZyb20gJy4uL2Zvcm0vZm9ybS51dGlscyc7XG5pbXBvcnQge1RyYW5zbGF0ZVNlcnZpY2V9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtWYWxpZGF0b3JTZXJ2aWNlfSBmcm9tICdAZS1pcy9uZ3gtbWF0ZXJpYWwtdGFibGUnO1xuaW1wb3J0IHtMb2NhbFNldHRpbmdzVmFsaWRhdG9yU2VydmljZX0gZnJvbSAnLi4vc2VydmljZXMvdmFsaWRhdG9yL2xvY2FsLXNldHRpbmdzLnZhbGlkYXRvcic7XG5pbXBvcnQge1BsYXRmb3JtU2VydmljZX0gZnJvbSAnLi4vc2VydmljZXMvcGxhdGZvcm0uc2VydmljZSc7XG5pbXBvcnQge05ldHdvcmtTZXJ2aWNlfSBmcm9tICcuLi9zZXJ2aWNlcy9uZXR3b3JrLnNlcnZpY2UnO1xuaW1wb3J0IHtpc05pbCwgaXNOaWxPckJsYW5rLCB0b0Jvb2xlYW59IGZyb20gJy4uLy4uL3NoYXJlZC9mdW5jdGlvbnMnO1xuaW1wb3J0IHtMb2NhbFNldHRpbmdzU2VydmljZX0gZnJvbSAnLi4vc2VydmljZXMvbG9jYWwtc2V0dGluZ3Muc2VydmljZSc7XG5pbXBvcnQge0Zvcm1GaWVsZERlZmluaXRpb24sIEZvcm1GaWVsZERlZmluaXRpb25NYXB9IGZyb20gJy4uLy4uL3NoYXJlZC9mb3JtL2ZpZWxkLm1vZGVsJztcbmltcG9ydCB7bWVyZ2V9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtBbGVydENvbnRyb2xsZXIsIE5hdkNvbnRyb2xsZXJ9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7QWxlcnRzfSBmcm9tICcuLi8uLi9zaGFyZWQvYWxlcnRzJztcbmltcG9ydCB7UHJvcGVydHl9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQge0NhbkxlYXZlfSBmcm9tICcuLi8uLi9zaGFyZWQvZ3VhcmQvY29tcG9uZW50LWRpcnR5Lmd1YXJkJztcbmltcG9ydCB7SVNlbGVjdFBlZXJNb2RhbE9wdGlvbnN9IGZyb20gJy4uL3BlZXIvc2VsZWN0LXBlZXIubW9kYWwnO1xuaW1wb3J0IHtNZW51SXRlbX0gZnJvbSAnLi4vbWVudS9tZW51Lm1vZGVsJztcblxuZXhwb3J0IGNvbnN0IEFQUF9TRVRUSU5HU19NRU5VX0lURU1TID0gbmV3IEluamVjdGlvblRva2VuPE1lbnVJdGVtW10+KCdzZXR0aW5nc01lbnVJdGVtcycpO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdwYWdlLXNldHRpbmdzJyxcbiAgdGVtcGxhdGVVcmw6ICdzZXR0aW5ncy5wYWdlLmh0bWwnLFxuICBwcm92aWRlcnM6IFtcbiAgICB7cHJvdmlkZTogVmFsaWRhdG9yU2VydmljZSwgdXNlRXhpc3Rpbmc6IExvY2FsU2V0dGluZ3NWYWxpZGF0b3JTZXJ2aWNlfSxcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgU2V0dGluZ3NQYWdlIGV4dGVuZHMgQXBwRm9ybTxMb2NhbFNldHRpbmdzPiBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBDYW5MZWF2ZSB7XG5cbiAgcHJpdmF0ZSBkYXRhOiBMb2NhbFNldHRpbmdzO1xuXG4gIG1vYmlsZTogYm9vbGVhbjtcbiAgc2F2aW5nID0gZmFsc2U7XG4gIHVzYWdlTW9kZXM6IFVzYWdlTW9kZVtdID0gWydGSUVMRCcsICdERVNLJ107XG4gIG1lbnVJdGVtczogTWVudUl0ZW1bXTtcblxuICBwcm9wZXJ0eURlZmluaXRpb25zOiBGb3JtRmllbGREZWZpbml0aW9uW107XG4gIHByb3BlcnR5RGVmaW5pdGlvbnNCeUtleTogRm9ybUZpZWxkRGVmaW5pdGlvbk1hcCA9IHt9O1xuICBwcm9wZXJ0eURlZmluaXRpb25zQnlJbmRleDogeyBbaW5kZXg6IG51bWJlcl06IEZvcm1GaWVsZERlZmluaXRpb24gfSA9IHt9O1xuICBwcm9wZXJ0aWVzRm9ybUhlbHBlcjogRm9ybUFycmF5SGVscGVyPFByb3BlcnR5PjtcblxuICBsYXRMb25nRm9ybWF0cyA9IFsnRERNTVNTJywgJ0RETU0nLCAnREQnXTtcblxuICBnZXQgYWNjb3VudEluaGVyaXRhbmNlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmZvcm0uY29udHJvbHNbJ2FjY291bnRJbmhlcml0YW5jZSddLnZhbHVlO1xuICB9XG5cbiAgZ2V0IGlzTG9naW4oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYWNjb3VudFNlcnZpY2UuaXNMb2dpbigpO1xuICB9XG5cbiAgZ2V0IHByb3BlcnRpZXNGb3JtKCk6IFVudHlwZWRGb3JtQXJyYXkge1xuICAgIHJldHVybiB0aGlzLmZvcm0uZ2V0KCdwcm9wZXJ0aWVzJykgYXMgVW50eXBlZEZvcm1BcnJheTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGluamVjdG9yOiBJbmplY3RvcixcbiAgICBwcm90ZWN0ZWQgcGxhdGZvcm06IFBsYXRmb3JtU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgbmF2Q29udHJvbGxlcjogTmF2Q29udHJvbGxlcixcbiAgICBwcm90ZWN0ZWQgdmFsaWRhdG9yU2VydmljZTogTG9jYWxTZXR0aW5nc1ZhbGlkYXRvclNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIGFsZXJ0Q3RybDogQWxlcnRDb250cm9sbGVyLFxuICAgIHByb3RlY3RlZCB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIGZvcm1CdWlsZGVyOiBVbnR5cGVkRm9ybUJ1aWxkZXIsXG4gICAgcHJvdGVjdGVkIGFjY291bnRTZXJ2aWNlOiBBY2NvdW50U2VydmljZSxcbiAgICBwcm90ZWN0ZWQgc2V0dGluZ3M6IExvY2FsU2V0dGluZ3NTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHVibGljIG5ldHdvcms6IE5ldHdvcmtTZXJ2aWNlLFxuICAgIEBJbmplY3QoQVBQX0xPQ0FMRVMpIHB1YmxpYyBsb2NhbGVzOiBMb2NhbGVDb25maWdbXSxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEFQUF9TRVRUSU5HU19NRU5VX0lURU1TKSBtZW51SXRlbXM/OiBNZW51SXRlbVtdXG4gICkge1xuICAgIHN1cGVyKGluamVjdG9yLCB2YWxpZGF0b3JTZXJ2aWNlLmdldEZvcm1Hcm91cCgpKTtcblxuICAgIHRoaXMucHJvcGVydGllc0Zvcm1IZWxwZXIgPSBuZXcgRm9ybUFycmF5SGVscGVyPFByb3BlcnR5PihcbiAgICAgIHRoaXMuZm9ybS5nZXQoJ3Byb3BlcnRpZXMnKSBhcyBVbnR5cGVkRm9ybUFycmF5LFxuICAgICAgKHZhbHVlKSA9PiB0aGlzLnZhbGlkYXRvclNlcnZpY2UuZ2V0UHJvcGVydHlGb3JtR3JvdXAodmFsdWUpLFxuICAgICAgKHYxLCB2MikgPT4gKCF2MSAmJiAhdjIpIHx8ICh2MS5rZXkgPT09IHYyLmtleSksXG4gICAgICAodmFsdWUpID0+ICBpc05pbCh2YWx1ZSkgfHwgKGlzTmlsKHZhbHVlLmtleSkgJiYgaXNOaWwodmFsdWUudmFsdWUpKSxcbiAgICAgIHtcbiAgICAgICAgYWxsb3dFbXB0eUFycmF5OiB0cnVlXG4gICAgICB9XG4gICAgKTtcblxuICAgIHRoaXMubWVudUl0ZW1zID0gbWVudUl0ZW1zIHx8IFtdO1xuICAgIHRoaXMubW9iaWxlID0gdGhpcy5wbGF0Zm9ybS5tb2JpbGU7XG5cbiAgICAvLyBCeSBkZWZhdWx0LCBkaXNhYmxlIHRoZSBmb3JtXG4gICAgdGhpcy5fZW5hYmxlID0gZmFsc2U7XG4gIH1cblxuICBhc3luYyBuZ09uSW5pdCgpIHtcbiAgICBzdXBlci5uZ09uSW5pdCgpO1xuXG4gICAgLy8gTWFrZSBzdXJlIHBsYXRmb3JtIGlzIHJlYWR5XG4gICAgYXdhaXQgdGhpcy5wbGF0Zm9ybS5yZWFkeSgpO1xuXG4gICAgdGhpcy5wcm9wZXJ0eURlZmluaXRpb25zID0gdGhpcy5zZXR0aW5ncy5vcHRpb25EZWZzLnNsaWNlKCk7IC8vIGNvcHkgb3B0aW9uc1xuICAgIHRoaXMucHJvcGVydHlEZWZpbml0aW9ucy5mb3JFYWNoKG8gPT4gdGhpcy5wcm9wZXJ0eURlZmluaXRpb25zQnlLZXlbby5rZXldID0gbyk7IC8vIGZpbGwgbWFwXG5cbiAgICAvLyBMb2FkIHNldHRpbmdzXG4gICAgYXdhaXQgdGhpcy5sb2FkKCk7XG5cbiAgICB0aGlzLnJlZ2lzdGVyU3Vic2NyaXB0aW9uKFxuICAgICAgbWVyZ2UoXG4gICAgICAgIHRoaXMuYWNjb3VudFNlcnZpY2Uub25Mb2dpbixcbiAgICAgICAgdGhpcy5hY2NvdW50U2VydmljZS5vbkxvZ291dFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLnNldEFjY291bnRJbmhlcml0YW5jZSh0aGlzLmFjY291bnRJbmhlcml0YW5jZSkpKTtcbiAgfVxuXG4gIGdldFByb3BlcnR5RGVmaW5pdGlvbihpbmRleDogbnVtYmVyKTogRm9ybUZpZWxkRGVmaW5pdGlvbiB7XG4gICAgbGV0IGRlZmluaXRpb24gPSB0aGlzLnByb3BlcnR5RGVmaW5pdGlvbnNCeUluZGV4W2luZGV4XTtcbiAgICBpZiAoIWRlZmluaXRpb24pIHtcbiAgICAgIGRlZmluaXRpb24gPSB0aGlzLnVwZGF0ZVByb3BlcnR5RGVmaW5pdGlvbihpbmRleCk7XG4gICAgICB0aGlzLnByb3BlcnR5RGVmaW5pdGlvbnNCeUluZGV4W2luZGV4XSA9IGRlZmluaXRpb247XG4gICAgfVxuICAgIHJldHVybiBkZWZpbml0aW9uO1xuICB9XG5cbiAgdXBkYXRlUHJvcGVydHlEZWZpbml0aW9uKGluZGV4OiBudW1iZXIpOiBGb3JtRmllbGREZWZpbml0aW9uIHtcbiAgICBjb25zdCBrZXkgPSAodGhpcy5wcm9wZXJ0aWVzRm9ybS5hdChpbmRleCkgYXMgVW50eXBlZEZvcm1Hcm91cCkuY29udHJvbHMua2V5LnZhbHVlO1xuICAgIGNvbnN0IGRlZmluaXRpb24gPSBrZXkgJiYgdGhpcy5wcm9wZXJ0eURlZmluaXRpb25zQnlLZXlba2V5XSB8fCBudWxsO1xuICAgIHRoaXMucHJvcGVydHlEZWZpbml0aW9uc0J5SW5kZXhbaW5kZXhdID0gZGVmaW5pdGlvbjsgLy8gdXBkYXRlIG1hcCBieSBpbmRleFxuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gICAgcmV0dXJuIGRlZmluaXRpb247XG4gIH1cblxuICByZW1vdmVQcm9wZXJ0eUF0KGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLnByb3BlcnRpZXNGb3JtSGVscGVyLnJlbW92ZUF0KGluZGV4KTtcbiAgICB0aGlzLnByb3BlcnR5RGVmaW5pdGlvbnNCeUluZGV4ID0ge307IC8vIGNsZWFyIGNhY2hlIGJ5IGluZGV4XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIGFzeW5jIGxvYWQoKSB7XG5cbiAgICB0aGlzLm1hcmtBc0xvYWRpbmcoKTtcbiAgICBjb25zb2xlLmRlYnVnKCdbc2V0dGluZ3NdIExvYWRpbmcgc2V0dGluZ3MuLi4nKTtcblxuICAgIGNvbnN0IGRhdGEgPSB0aGlzLnNldHRpbmdzLnNldHRpbmdzO1xuXG4gICAgLy8gU2V0IGRlZmF1bHRzXG4gICAgZGF0YS5hY2NvdW50SW5oZXJpdGFuY2UgPSB0b0Jvb2xlYW4oZGF0YS5hY2NvdW50SW5oZXJpdGFuY2UsIHRydWUpO1xuICAgIGRhdGEubG9jYWxlID0gZGF0YS5sb2NhbGUgfHwgdGhpcy50cmFuc2xhdGUuY3VycmVudExhbmcgfHwgdGhpcy50cmFuc2xhdGUuZGVmYXVsdExhbmc7XG4gICAgZGF0YS5sYXRMb25nRm9ybWF0ID0gZGF0YS5sYXRMb25nRm9ybWF0IHx8ICdERE1NU1MnO1xuICAgIGRhdGEudXNhZ2VNb2RlID0gZGF0YS51c2FnZU1vZGUgfHwgJ0RFU0snO1xuXG4gICAgLy8gU2V0IHBlZXJcbiAgICBpZiAoaXNOaWxPckJsYW5rKGRhdGEucGVlclVybCkpIHtcbiAgICAgIGF3YWl0IHRoaXMubmV0d29yay5yZWFkeSgpO1xuICAgICAgY29uc3QgcGVlciA9IHRoaXMubmV0d29yay5wZWVyO1xuICAgICAgZGF0YS5wZWVyVXJsID0gcGVlciAmJiBwZWVyLnVybDtcbiAgICB9XG5cbiAgICAvLyBSZW1lbWJlciBkYXRhXG4gICAgdGhpcy51cGRhdGVWaWV3KGRhdGEpO1xuICB9XG5cbiAgdXBkYXRlVmlldyhkYXRhOiBMb2NhbFNldHRpbmdzKSB7XG4gICAgaWYgKCFkYXRhKSByZXR1cm47IC8vc2tpcFxuICAgIHRoaXMuZGF0YSA9IGRhdGE7XG5cbiAgICBjb25zdCBqc29uOiBhbnkgPSB7Li4uZGF0YX07XG5cbiAgICAvLyBUcmFuc2Zvcm0gcHJvcGVydGllcyBtYXAgaW50byBhcnJheVxuICAgIGpzb24ucHJvcGVydGllcyA9IEVudGl0eVV0aWxzLmdldE1hcEFzQXJyYXkoZGF0YS5wcm9wZXJ0aWVzIHx8IHt9KTtcbiAgICB0aGlzLnByb3BlcnRpZXNGb3JtSGVscGVyLnJlc2l6ZShqc29uLnByb3BlcnRpZXMubGVuZ3RoKTtcblxuICAgIHRoaXMuZm9ybS5wYXRjaFZhbHVlKGpzb24sIHtlbWl0RXZlbnQ6IGZhbHNlfSk7XG4gICAgdGhpcy5tYXJrQXNQcmlzdGluZSgpO1xuXG4gICAgdGhpcy5lbmFibGUoe2VtaXRFdmVudDogZmFsc2V9KTtcblxuICAgIC8vIEFwcGx5IGluaGVyaXRhbmNlXG4gICAgdGhpcy5zZXRBY2NvdW50SW5oZXJpdGFuY2UoZGF0YS5hY2NvdW50SW5oZXJpdGFuY2UsIHtlbWl0RXZlbnQ6IGZhbHNlfSk7XG5cbiAgICB0aGlzLm1hcmtBc0xvYWRlZCgpO1xuICAgIHRoaXMuZXJyb3IgPSBudWxsO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBhc3luYyBzYXZlKGV2ZW50PzogRXZlbnQsIG9wdGlvbnM/OiBhbnkpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAodGhpcy5zYXZpbmcpIHJldHVybjsgLy8gU2tpcFxuXG4gICAgaWYgKGV2ZW50KSBldmVudC5wcmV2ZW50RGVmYXVsdCgpXG5cbiAgICAvLyBSZW1vdmUgYWxsIGVtcHR5IGNvbnRyb2xzXG4gICAgdGhpcy5wcm9wZXJ0aWVzRm9ybUhlbHBlci5yZW1vdmVBbGxFbXB0eSgpO1xuXG4gICAgaWYgKCF0aGlzLmZvcm0udmFsaWQpIHtcbiAgICAgIGF3YWl0IEFwcEZvcm1VdGlscy53YWl0V2hpbGVQZW5kaW5nKHRoaXMuZm9ybSk7XG5cbiAgICAgIGlmICh0aGlzLmZvcm0uaW52YWxpZCkge1xuICAgICAgICBBcHBGb3JtVXRpbHMubG9nRm9ybUVycm9ycyh0aGlzLmZvcm0pO1xuICAgICAgICB0aGlzLmZvcm0ubWFya0FsbEFzVG91Y2hlZCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc29sZS5kZWJ1ZygnW3NldHRpbmdzXSBTYXZpbmcgbG9jYWwgc2V0dGluZ3MuLi4nKTtcblxuICAgIHRoaXMuc2F2aW5nID0gdHJ1ZTtcbiAgICB0aGlzLmVycm9yID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG5cbiAgICBjb25zdCBkYXRhID0gYXdhaXQgdGhpcy5nZXRWYWx1ZSgpO1xuXG4gICAgLy8gQ2hlY2sgcGVlciBhbGl2ZSwgYmVmb3JlIHNhdmluZ1xuICAgIGNvbnN0IHBlZXJDaGFuZ2VkID0gdGhpcy5mb3JtLmdldCgncGVlclVybCcpLmRpcnR5O1xuXG4gICAgLy8gQ2xlYW4gcGFnZSBoaXN0b3J5LCB3aGVuIHBlZXIgY2hhbmdlZFxuICAgIGlmIChwZWVyQ2hhbmdlZCkgZGF0YS5wYWdlSGlzdG9yeSA9IFtdO1xuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuZGlzYWJsZSgpO1xuXG4gICAgICBhd2FpdCB0aGlzLnNldHRpbmdzLmFwcGx5KGRhdGEpO1xuICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICAgIHRoaXMubWFya0FzUHJpc3RpbmUoKTtcblxuICAgICAgLy8gSWYgcGVlciBjaGFuZ2VkXG4gICAgICBpZiAocGVlckNoYW5nZWQpIHtcbiAgICAgICAgLy8gUmVzdGFydCB0aGUgbmV0d29ya1xuICAgICAgICB0aGlzLm5ldHdvcmsucGVlciA9IFBlZXIucGFyc2VVcmwoZGF0YS5wZWVyVXJsKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICB0aGlzLmVycm9yID0gZXJyICYmIGVyci5tZXNzYWdlIHx8IGVycjtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5lbmFibGUoe2VtaXRFdmVudDogZmFsc2V9KTtcblxuICAgICAgLy8gQXBwbHkgaW5oZXJpdGFuY2VcbiAgICAgIHRoaXMuc2V0QWNjb3VudEluaGVyaXRhbmNlKGRhdGEuYWNjb3VudEluaGVyaXRhbmNlLCB7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuXG4gICAgICAvLyBBZGQgYSBkZWxheSwgYmVjYXVzZSBvZiBvcHRpb24gbWVudSB0aGF0IGlzIGFsd2F5cyBvcGVuZWQgYWZ0ZXIgc2F2ZSEhXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0sIDQwMCk7XG4gICAgfVxuICB9XG5cblxuICBzZXRBY2NvdW50SW5oZXJpdGFuY2UoZW5hYmxlOiBib29sZWFuLCBvcHRzPzogeyBlbWl0RXZlbnQ/OiBib29sZWFuIH0pIHtcbiAgICAvLyBNYWtlIHN1cmUgdG8gdXBkYXRlIHRoZSB2YWx1ZSBpbiBjb250cm9sXG4gICAgdGhpcy5mb3JtLmNvbnRyb2xzWydhY2NvdW50SW5oZXJpdGFuY2UnXS5zZXRWYWx1ZShlbmFibGUsIG9wdHMpO1xuICAgIGlmICh0aGlzLmRhdGEuYWNjb3VudEluaGVyaXRhbmNlICE9PSBlbmFibGUpIHtcbiAgICAgIHRoaXMuZm9ybS5jb250cm9sc1snYWNjb3VudEluaGVyaXRhbmNlJ10ubWFya0FzRGlydHkoe29ubHlTZWxmOiBmYWxzZX0pO1xuICAgIH1cblxuICAgIGlmIChlbmFibGUpIHtcbiAgICAgIGlmICh0aGlzLmlzTG9naW4pIHtcbiAgICAgICAgLy8gRm9yY2UgdXNpbmcgYWNjb3VudCBzZXR0aW5nc1xuICAgICAgICBjb25zdCBhY2NvdW50ID0gdGhpcy5hY2NvdW50U2VydmljZS5hY2NvdW50O1xuXG4gICAgICAgIC8vIENvcHkgdmFsdWVzXG4gICAgICAgIGlmIChhY2NvdW50LnNldHRpbmdzKSB7XG4gICAgICAgICAgaWYgKGFjY291bnQuc2V0dGluZ3MubG9jYWxlKSB0aGlzLmZvcm0uZ2V0KCdsb2NhbGUnKS5zZXRWYWx1ZShhY2NvdW50LnNldHRpbmdzLmxvY2FsZSwgb3B0cyk7XG4gICAgICAgICAgaWYgKGFjY291bnQuc2V0dGluZ3MubGF0TG9uZ0Zvcm1hdCkgdGhpcy5mb3JtLmdldCgnbGF0TG9uZ0Zvcm1hdCcpLnNldFZhbHVlKGFjY291bnQuc2V0dGluZ3MubGF0TG9uZ0Zvcm1hdCwgb3B0cyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRGlzYWJsZSBmaWVsZHNcbiAgICAgICAgdGhpcy5mb3JtLmdldCgnbG9jYWxlJykuZGlzYWJsZShvcHRzKTtcbiAgICAgICAgdGhpcy5mb3JtLmdldCgnbGF0TG9uZ0Zvcm1hdCcpLmRpc2FibGUob3B0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBFbmFibGUgZmllbGRzXG4gICAgICAgIHRoaXMuZm9ybS5nZXQoJ2xvY2FsZScpLmVuYWJsZShvcHRzKTtcbiAgICAgICAgdGhpcy5mb3JtLmdldCgnbGF0TG9uZ0Zvcm1hdCcpLmVuYWJsZShvcHRzKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUmVzdG9yZSBwcmV2aW91cyB2YWx1ZXNcbiAgICAgIHRoaXMuZm9ybS5nZXQoJ2xvY2FsZScpLnNldFZhbHVlKHRoaXMuZGF0YS5sb2NhbGUsIG9wdHMpO1xuICAgICAgdGhpcy5mb3JtLmdldCgnbGF0TG9uZ0Zvcm1hdCcpLnNldFZhbHVlKHRoaXMuZGF0YS5sYXRMb25nRm9ybWF0LCBvcHRzKTtcblxuICAgICAgLy8gRW5hYmxlIGZpZWxkc1xuICAgICAgdGhpcy5mb3JtLmdldCgnbG9jYWxlJykuZW5hYmxlKG9wdHMpO1xuICAgICAgdGhpcy5mb3JtLmdldCgnbGF0TG9uZ0Zvcm1hdCcpLmVuYWJsZShvcHRzKTtcbiAgICB9XG5cbiAgICAvLyBNYXJrIGZvciBjaGVjaywgaWYgbmVlZFxuICAgIGlmICghb3B0cyB8fCBvcHRzLmVtaXRFdmVudCkge1xuICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzaG93U2VsZWN0UGVlck1vZGFsKG9wdHM/OiBQYXJ0aWFsPElTZWxlY3RQZWVyTW9kYWxPcHRpb25zPikge1xuICAgIGNvbnN0IHBlZXIgPSBhd2FpdCB0aGlzLm5ldHdvcmsuc2hvd1NlbGVjdFBlZXJNb2RhbCh7XG4gICAgICBzaG93U2V0TWFudWFsbHlCdXR0b246IGZhbHNlLCAvLyBNYWtlIG5vIHNlbnNlIGhlcmUsIGJlY2F1c2Ugc2FtZSBhcyBjYW5jZWwgKGFscmVhZHkgaW5zaWRlIHRoZSBzZXR0aW5ncyBwYWdlKVxuICAgICAgLi4ub3B0c30pO1xuICAgIGlmIChwZWVyPy51cmwpIHtcbiAgICAgIGNvbnN0IGNvbnRyb2wgPSB0aGlzLmZvcm0uZ2V0KCdwZWVyVXJsJykgYXMgVW50eXBlZEZvcm1Db250cm9sO1xuICAgICAgY29udHJvbC5zZXRWYWx1ZShwZWVyLnVybCwge2VtaXRFdmVudDogdHJ1ZSwgb25seVNlbGY6IGZhbHNlfSk7XG4gICAgICBjb250cm9sLm1hcmtBc0RpcnR5KHtvbmx5U2VsZjogZmFsc2V9KTtcbiAgICAgIHRoaXMubWFya0FzRGlydHkoKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjYW5jZWwoZXZlbnQ/OiBFdmVudCkge1xuICAgIGF3YWl0IHRoaXMubG9hZCgpO1xuICB9XG5cbiAgYXN5bmMgY2xvc2UoZXZlbnQ/OiBFdmVudCkge1xuICAgIGlmICh0aGlzLnNhdmluZykgcmV0dXJuO1xuXG4gICAgLy8gQmFjayB0byBob21lXG4gICAgcmV0dXJuIHRoaXMubmF2Q29udHJvbGxlci5uYXZpZ2F0ZVJvb3QoJy8nKTsgLy8gYmFjayB0byBob21lXG4gIH1cblxuICBhc3luYyBjbGVhckNhY2hlKGV2ZW50PzogRXZlbnQpIHtcbiAgICBjb25zdCBjb25maXJtID0gYXdhaXQgQWxlcnRzLmFza0FjdGlvbkNvbmZpcm1hdGlvbih0aGlzLmFsZXJ0Q3RybCwgdGhpcy50cmFuc2xhdGUsIHRydWUsIGV2ZW50KTtcbiAgICBpZiAoY29uZmlybSkge1xuICAgICAgYXdhaXQgdGhpcy5uZXR3b3JrLmNsZWFyQ2FjaGUoKTtcbiAgICAgIHRoaXMuc2V0dGluZ3MucmVtb3ZlT2ZmbGluZUZlYXR1cmVzKCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZXhlY3V0ZUFjdGlvbihldmVudDogRXZlbnQsIGl0ZW06IE1lbnVJdGVtKSB7XG4gICAgaWYgKCFpdGVtKSByZXR1cm47XG4gICAgaWYgKGV2ZW50Py5kZWZhdWx0UHJldmVudGVkKSByZXR1cm47XG5cbiAgICBpZiAoaXRlbS5wYXRoKSB7XG4gICAgICBhd2FpdCB0aGlzLm5hdkNvbnRyb2xsZXIubmF2aWdhdGVGb3J3YXJkKGl0ZW0ucGF0aCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcignW3NldHRpbmdzXSBVbmtub3duIGl0ZW0gdHlwZSAobm8gcGF0aCknLCBpdGVtKTtcbiAgICB9XG4gIH1cblxuICAvKiAtLSBwcm90ZWN0ZWQgZnVuY3Rpb25zIC0tICovXG5cbiAgcHJvdGVjdGVkIGFzeW5jIGdldFZhbHVlKCk6IFByb21pc2U8TG9jYWxTZXR0aW5ncz4ge1xuICAgIGNvbnN0IGpzb24gPSBhd2FpdCB0aGlzLmdldEpzb25WYWx1ZVRvU2F2ZSgpO1xuXG4gICAgLy8gT3ZlcnJpZGUgcHJvcGVydGllcyBmcm9tIGFjY291bnRcbiAgICBpZiAoanNvbi5hY2NvdW50SW5oZXJpdGFuY2UgJiYgdGhpcy5pc0xvZ2luKSB7XG4gICAgICBjb25zdCBhY2NvdW50ID0gdGhpcy5hY2NvdW50U2VydmljZS5hY2NvdW50O1xuICAgICAgY29uc3QgdXNlclNldHRpbmdzID0gYWNjb3VudCAmJiBhY2NvdW50LnNldHRpbmdzO1xuICAgICAgY29uc29sZS5kZWJ1ZyhgW3NldHRpbmdzXSBBcHBseWluZyBhY2NvdW50IGluaGVyaXRhbmNlIHtsb2NhbGU6ICcke3VzZXJTZXR0aW5ncy5sb2NhbGV9JywgbGF0TG9uZ0Zvcm1hdDogJyR7dXNlclNldHRpbmdzLmxhdExvbmdGb3JtYXR9J30uLi5gKTtcbiAgICAgIGpzb24ubG9jYWxlID0gdXNlclNldHRpbmdzLmxvY2FsZSB8fCBqc29uLmxvY2FsZTtcbiAgICAgIGpzb24ubGF0TG9uZ0Zvcm1hdCA9IHVzZXJTZXR0aW5ncy5sYXRMb25nRm9ybWF0IHx8IGpzb24ubGF0TG9uZ0Zvcm1hdDtcbiAgICB9XG5cbiAgICByZXR1cm4ganNvbjtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRKc29uVmFsdWVUb1NhdmUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBqc29uID0gdGhpcy5mb3JtLnZhbHVlO1xuICAgIGpzb24ucHJvcGVydGllcyA9IEVudGl0eVV0aWxzLmdldFByb3BlcnR5QXJyYXlBc09iamVjdChqc29uLnByb3BlcnRpZXMpO1xuXG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShqc29uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBtYXJrRm9yQ2hlY2soKSB7XG4gICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG5cbn1cbiIsIjxhcHAtdG9vbGJhciBbdGl0bGVdPVwiJ1NFVFRJTkdTLlRJVExFJ3x0cmFuc2xhdGVcIiBjb2xvcj1cInByaW1hcnlcIlxuICAgICAgICAgICAgIFtoYXNWYWxpZGF0ZV09XCJkaXJ0eSAmJiAhc2F2aW5nXCJcbiAgICAgICAgICAgICBbaGFzQ2xvc2VdPVwiIWRpcnR5ICYmICFzYXZpbmdcIlxuICAgICAgICAgICAgIChvblZhbGlkYXRlKT1cInNhdmUoJGV2ZW50KVwiXG4gICAgICAgICAgICAgKG9uQ2xvc2UpPVwiY2xvc2UoJGV2ZW50KVwiPlxuXG4gIDxpb24tYnV0dG9ucyBzbG90PVwiZW5kXCI+XG4gICAgPCEtLSBvcHRpb25zIG1lbnUgLS0+XG4gICAgPGlvbi1idXR0b24gW21hdE1lbnVUcmlnZ2VyRm9yXT1cIm9wdGlvbnNNZW51XCJcbiAgICAgICAgICAgICAgICAqbmdJZj1cIiFzYXZpbmdcIlxuICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJzYXZpbmdcIj5cbiAgICAgIDxtYXQtaWNvbiBzbG90PVwiaWNvbi1vbmx5XCI+bW9yZV92ZXJ0PC9tYXQtaWNvbj5cbiAgICA8L2lvbi1idXR0b24+XG4gIDwvaW9uLWJ1dHRvbnM+XG48L2FwcC10b29sYmFyPlxuXG48IS0tIE9wdGlvbnMgbWVudSAtLT5cbjxtYXQtbWVudSAjb3B0aW9uc01lbnU9XCJtYXRNZW51XCI+XG4gIDwhLS0gQ2xlYXIgY2FjaGUgLS0+XG4gIDxidXR0b24gbWF0LW1lbnUtaXRlbSAoY2xpY2spPVwiY2xlYXJDYWNoZSgkZXZlbnQpXCI+XG4gICAgPG1hdC1pY29uPjxpb24taWNvbiBuYW1lPVwidHJhc2gtb3V0bGluZVwiPjwvaW9uLWljb24+PC9tYXQtaWNvbj5cbiAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5TRVRUSU5HUy5CVE5fQ0xFQVJfQ0FDSEU8L2lvbi1sYWJlbD5cbiAgPC9idXR0b24+XG5cbiAgPCEtLSBSZXNldCAtLT5cbiAgPGJ1dHRvbiBtYXQtbWVudS1pdGVtXG4gICAgICAgICAgW2Rpc2FibGVkXT1cIiFkaXJ0eVwiXG4gICAgICAgICAgKGNsaWNrKT1cImNhbmNlbCgkZXZlbnQpXCI+XG4gICAgPG1hdC1pY29uPjxpb24taWNvbiBuYW1lPVwicmVmcmVzaFwiPjwvaW9uLWljb24+PC9tYXQtaWNvbj5cbiAgICA8bWF0LWxhYmVsIHRyYW5zbGF0ZT5DT01NT04uQlROX1JFU0VUPC9tYXQtbGFiZWw+XG4gIDwvYnV0dG9uPlxuXG4gIDwhLS0gYWRkaXRpb25hbCBpdGVtcyAtLT5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFsb2FkaW5nXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBtZW51SXRlbXNcIj5cbiAgICAgIDxhICpuZ0lmPVwiaXRlbS5wYXRoXCJcbiAgICAgICAgIG1hdC1tZW51LWl0ZW1cbiAgICAgICAgIGNsYXNzPVwie3tpdGVtLmNzc0NsYXNzfX0ge3tpdGVtLmNvbG9yfX1cIlxuICAgICAgICAgKGNsaWNrKT1cImV4ZWN1dGVBY3Rpb24oJGV2ZW50LCBpdGVtKVwiPlxuICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJpdGVtLmljb25cIj48aW9uLWljb24gW25hbWVdPVwiaXRlbS5pY29uXCI+PC9pb24taWNvbj48L21hdC1pY29uPlxuICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJpdGVtLm1hdEljb25cIj57e2l0ZW0ubWF0SWNvbn19PC9tYXQtaWNvbj5cbiAgICAgICAgPG1hdC1sYWJlbCB0cmFuc2xhdGU+e3tpdGVtLnRpdGxlfX08L21hdC1sYWJlbD5cbiAgICAgIDwvYT5cbiAgICAgIDwhLS0gZGl2aWRlciAtLT5cbiAgICAgIDxtYXQtZGl2aWRlciAqbmdJZj1cIiFpdGVtLnBhdGggJiYgIWl0ZW0uYWN0aW9uXCJcbiAgICAgICAgICAgICAgICAgICBjbGFzcz1cInt7aXRlbS5jc3NDbGFzc319IHt7aXRlbS5jb2xvcn19XCI+XG4gICAgICAgIDxtYXQtbGFiZWwgdHJhbnNsYXRlPnt7aXRlbS50aXRsZX19PC9tYXQtbGFiZWw+XG4gICAgICA8L21hdC1kaXZpZGVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbWF0LW1lbnU+XG5cbjxpb24tY29udGVudD5cblxuICA8Zm9ybSBbZm9ybUdyb3VwXT1cImZvcm1cIiBub3ZhbGlkYXRlIChuZ1N1Ym1pdCk9XCJzYXZlKCRldmVudClcIiBjbGFzcz1cImZvcm0tY29udGFpbmVyXCI+XG5cbiAgICA8aW9uLWdyaWQgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuICAgICAgPGlvbi1yb3cgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuXG4gICAgICAgIDwhLS0gbGVmdCAgbWFyZ2luIC0tPlxuICAgICAgICA8aW9uLWNvbCBzaXplPVwiMFwiIHNpemUtbGc9XCIyXCI+Jm5ic3A7XG4gICAgICAgIDwvaW9uLWNvbD5cblxuICAgICAgICA8aW9uLWNvbCBjbGFzcz1cImlvbi1wYWRkaW5nXCI+XG5cbiAgICAgICAgICA8IS0tIGVycm9yIC0tPlxuICAgICAgICAgIDxpb24taXRlbSAqbmdJZj1cImVycm9yXCIgbGluZXM9XCJub25lXCI+XG4gICAgICAgICAgICA8aW9uLWljb24gY29sb3I9XCJkYW5nZXJcIiBzbG90PVwic3RhcnRcIiBuYW1lPVwiYWxlcnQtY2lyY2xlXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgIDxpb24tbGFiZWwgY29sb3I9XCJkYW5nZXJcIiBjbGFzcz1cImVycm9yXCIgW2lubmVySFRNTF09XCJlcnJvcnx0cmFuc2xhdGVcIj48L2lvbi1sYWJlbD5cbiAgICAgICAgICA8L2lvbi1pdGVtPlxuXG4gICAgICAgICAgPHAgW2lubmVySFRNTF09XCInU0VUVElOR1MuREVTQ1JJUFRJT04nfHRyYW5zbGF0ZVwiPjwvcD5cblxuICAgICAgICAgIDwhLS0gYWNjb3VudCBpbmhlcml0YW5jZSAoZGVza3RvcCkgLS0+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFtoaWRkZW5dPVwiIWlzTG9naW5cIiAqbmdJZj1cIiFtb2JpbGU7IGVsc2UgYWNjb3VudEluaGVyaXRhbmNlTW9iaWxlXCI+XG4gICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgaGlkZGVuIGZvcm1Db250cm9sTmFtZT1cImFjY291bnRJbmhlcml0YW5jZVwiIHR5cGU9XCJ0ZXh0XCI+XG5cbiAgICAgICAgICAgIDwhLS0gY2hlY2sgYm94IChpZiBkZXNrdG9wKSAtLT5cbiAgICAgICAgICAgIDxtYXQtY2hlY2tib3hcbiAgICAgICAgICAgICAgKm5nSWY9XCIhbW9iaWxlOyBlbHNlIGFjY291bnRJbmhlcml0YW5jZU1vYmlsZVwiXG4gICAgICAgICAgICAgIChjaGFuZ2UpPVwic2V0QWNjb3VudEluaGVyaXRhbmNlKCRldmVudC5jaGVja2VkKVwiXG4gICAgICAgICAgICAgIFtjaGVja2VkXT1cImFjY291bnRJbmhlcml0YW5jZVwiPlxuICAgICAgICAgICAgICA8c3BhbiB0cmFuc2xhdGU+U0VUVElOR1MuSU5IRVJJVF9GUk9NX0FDQ09VTlQ8L3NwYW4+XG4gICAgICAgICAgICA8L21hdC1jaGVja2JveD5cblxuICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZvcm0uY29udHJvbHMuYWNjb3VudEluaGVyaXRhbmNlLmhhc0Vycm9yKCdyZXF1aXJlZCcpXCIgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICAgICAgPCEtLSBhY2NvdW50IGluaGVyaXRhbmNlIChpZiBtb2JpbGUpIC0tPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjYWNjb3VudEluaGVyaXRhbmNlTW9iaWxlPlxuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFtoaWRkZW5dPVwiIWlzTG9naW5cIj5cbiAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IGhpZGRlbiBmb3JtQ29udHJvbE5hbWU9XCJhY2NvdW50SW5oZXJpdGFuY2VcIiB0eXBlPVwidGV4dFwiPlxuXG4gICAgICAgICAgICAgIDwhLS0gc2xpZGUgdG9nZ2xlICAtLT5cbiAgICAgICAgICAgICAgPGlvbi10ZXh0IHRyYW5zbGF0ZT5TRVRUSU5HUy5JTkhFUklUX0ZST01fQUNDT1VOVDwvaW9uLXRleHQ+XG4gICAgICAgICAgICAgIDxtYXQtc2xpZGUtdG9nZ2xlIG1hdFN1ZmZpeFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNldEFjY291bnRJbmhlcml0YW5jZSgkZXZlbnQuY2hlY2tlZClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJhY2NvdW50SW5oZXJpdGFuY2VcIj5cblxuICAgICAgICAgICAgICA8L21hdC1zbGlkZS10b2dnbGU+XG4gICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLmFjY291bnRJbmhlcml0YW5jZS5oYXNFcnJvcigncmVxdWlyZWQnKVwiIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRFxuICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgIDwhLS0gbG9jYWxlIC0tPlxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxtYXQtc2VsZWN0IFtwbGFjZWhvbGRlcl09XCInU0VUVElOR1MuTE9DQUxFJ3x0cmFuc2xhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJsb2NhbGVcIiByZXF1aXJlZD5cbiAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGl0ZW0gb2YgbG9jYWxlc1wiIFt2YWx1ZV09XCJpdGVtLmtleVwiPlxuICAgICAgICAgICAgICAgIHt7aXRlbS52YWx1ZX19XG4gICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLmxvY2FsZS5oYXNFcnJvcigncmVxdWlyZWQnKVwiIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRDwvbWF0LWVycm9yPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICA8IS0tIE5ldHdvcmsgZW50cnkgLS0+XG4gICAgICAgICAgPGgzPlxuICAgICAgICAgICAgPGlvbi10ZXh0IHRyYW5zbGF0ZT5TRVRUSU5HUy5ORVRXT1JLX0RJVklERVI8L2lvbi10ZXh0PlxuICAgICAgICAgIDwvaDM+XG5cbiAgICAgICAgICA8IS0tIFBlZXIgYWRkcmVzcyAtLT5cbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgdHlwZT1cInRleHRcIiBbcGxhY2Vob2xkZXJdPVwiJ1NFVFRJTkdTLlBFRVJfVVJMJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cInBlZXJVcmxcIlxuICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkPlxuXG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0U3VmZml4IChjbGljayk9XCJzaG93U2VsZWN0UGVlck1vZGFsKClcIiB0YWJpbmRleD1cIi0xXCJcbiAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidTRVRUSU5HUy5CVE5fQ0hBTkdFX1BFRVInfHRyYW5zbGF0ZVwiPlxuICAgICAgICAgICAgICA8bWF0LWljb24+c2VhcmNoPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5wZWVyVXJsLmhhc0Vycm9yKCdyZXF1aXJlZCcpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLnBlZXJVcmwuaGFzRXJyb3IoJ3BlZXJBbGl2ZScpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlPlNFVFRJTkdTLkVSUk9SLlBFRVJfTk9UX1JFQUNIQUJMRVxuICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5wZWVyVXJsLmhhc0Vycm9yKCdwZWVyTm90Q29tcGF0aWJsZScpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlPlNFVFRJTkdTLkVSUk9SLlBFRVJfTk9UX0NPTVBBVElCTEVcbiAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICA8IS0tIE9mZmxpbmUgbW9kZSAoaWYgbW9iaWxlKSAtLT5cbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nSWY9XCJtb2JpbGVcIj5cbiAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBoaWRkZW4gZm9ybUNvbnRyb2xOYW1lPVwiYWNjb3VudEluaGVyaXRhbmNlXCIgdHlwZT1cInRleHRcIj5cblxuICAgICAgICAgICAgPCEtLSBzbGlkZSB0b2dnbGUgIC0tPlxuICAgICAgICAgICAgPGlvbi10ZXh0IHRyYW5zbGF0ZT5TRVRUSU5HUy5PRkZMSU5FX01PREU8L2lvbi10ZXh0PlxuICAgICAgICAgICAgPG1hdC1zbGlkZS10b2dnbGUgbWF0U3VmZml4XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm5ldHdvcmsuc2V0Rm9yY2VPZmZsaW5lKCRldmVudC5jaGVja2VkKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJuZXR3b3JrLm9mZmxpbmVcIj5cblxuICAgICAgICAgICAgPC9tYXQtc2xpZGUtdG9nZ2xlPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICA8IS0tIERhdGEgZW50cnkgLS0+XG4gICAgICAgICAgPGgzPlxuICAgICAgICAgICAgPGlvbi10ZXh0IHRyYW5zbGF0ZT5TRVRUSU5HUy5EQVRBX0VOVFJZX0RJVklERVI8L2lvbi10ZXh0PlxuICAgICAgICAgIDwvaDM+XG5cbiAgICAgICAgICA8IS0tIFVzYWdlIG1vZGUgLS0+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPG1hdC1zZWxlY3QgW3BsYWNlaG9sZGVyXT1cIidTRVRUSU5HUy5VU0FHRV9NT0RFJ3x0cmFuc2xhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJ1c2FnZU1vZGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ+XG4gICAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBpdGVtIG9mIHVzYWdlTW9kZXNcIiBbdmFsdWVdPVwiaXRlbVwiPlxuICAgICAgICAgICAgICAgIHt7J1NFVFRJTkdTLlVTQUdFX01PREVTLicraXRlbXx0cmFuc2xhdGV9fVxuICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy51c2FnZU1vZGUuaGFzRXJyb3IoJ3JlcXVpcmVkJylcIlxuICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGU+RVJST1IuRklFTERfUkVRVUlSRURcbiAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICA8IS0tIGxhdC9sb25nIGZvcm1hdC0tPlxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxtYXQtc2VsZWN0IFtwbGFjZWhvbGRlcl09XCInU0VUVElOR1MuTEFUX0xPTkdfRk9STUFUJ3x0cmFuc2xhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJsYXRMb25nRm9ybWF0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkPlxuICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBsYXRMb25nRm9ybWF0c1wiIFt2YWx1ZV09XCJpdGVtXCI+XG4gICAgICAgICAgICAgICAge3snQ09NTU9OLkxBVF9MT05HLicraXRlbSsnX1BMQUNFSE9MREVSJ3x0cmFuc2xhdGV9fVxuICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICA8bWF0LWVycm9yXG4gICAgICAgICAgICAgICpuZ0lmPVwiZm9ybS5jb250cm9scy5sYXRMb25nRm9ybWF0Lmhhc0Vycm9yKCdyZXF1aXJlZCcpXCJcbiAgICAgICAgICAgICAgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICAgICAgPCEtLSBmaWVsZHMgb3B0aW9ucyAtLT5cbiAgICAgICAgICA8aW9uLWdyaWQgZm9ybUFycmF5TmFtZT1cInByb3BlcnRpZXNcIiBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICAgICAgICA8aW9uLXJvdyBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICAgICAgICAgIDxpb24tY29sIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmcgaW9uLWFsaWduLXNlbGYtZW5kXCIgc2l6ZT1cIjEyXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0b29sYmFyLXNwYWNlclwiPjwvc3Bhbj5cblxuICAgICAgICAgICAgICAgIDwhLS0gU2hvdyBtb3JlIG9wdGlvbnMgLS0+XG4gICAgICAgICAgICAgICAgPGlvbi1idXR0b24gY29sb3I9XCJsaWdodFwiICpuZ0lmPVwicHJvcGVydGllc0Zvcm0/Lmxlbmd0aCA9PT0gMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidTRVRUSU5HUy5CVE5fU0hPV19NT1JFX0hFTFAnfHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInByb3BlcnRpZXNGb3JtSGVscGVyLmFkZCgpXCI+XG4gICAgICAgICAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5DT01NT04uQlROX1NIT1dfTU9SRTwvaW9uLWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIHNsb3Q9XCJlbmRcIj5hcnJvd19kcm9wX2Rvd248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgPC9pb24tcm93PlxuXG4gICAgICAgICAgICA8IS0tIEZpZWxkcyBvcHRpb25zIC0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgcHJvcGVydHlGb3JtIG9mIHByb3BlcnRpZXNGb3JtPy5jb250cm9sczsgbGV0IGk9aW5kZXhcIj5cbiAgICAgICAgICAgICAgPGlvbi1yb3cgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiIFtmb3JtR3JvdXBOYW1lXT1cImlcIj5cblxuICAgICAgICAgICAgICAgIDwhLS0gcHJvcGVydHkga2V5IC0tPlxuICAgICAgICAgICAgICAgIDxpb24tY29sIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgZm9ybUNvbnRyb2xOYW1lPVwia2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIiAnU0VUVElOR1MuUFJPUEVSVFlfS0VZJ3x0cmFuc2xhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBwcm9wZXJ0eURlZmluaXRpb25zXCIgW3ZhbHVlXT1cIml0ZW0ua2V5XCI+e3sgaXRlbS5sYWJlbCB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8L2lvbi1jb2w+XG5cbiAgICAgICAgICAgICAgICA8IS0tIHByb3BlcnR5IHZhbHVlIC0tPlxuICAgICAgICAgICAgICAgIDxpb24tY29sIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIiBwYWRkaW5nLWxlZnQ+XG4gICAgICAgICAgICAgICAgICA8YXBwLWZvcm0tZmllbGQgKm5nSWY9XCJnZXRQcm9wZXJ0eURlZmluaXRpb24oaSk7IGxldCBkZWZpbml0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbG9hdExhYmVsPVwibmV2ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkZWZpbml0aW9uXT1cImRlZmluaXRpb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJwcm9wZXJ0eUZvcm18Zm9ybUdldENvbnRyb2w6J3ZhbHVlJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidTRVRUSU5HUy5QUk9QRVJUWV9WQUxVRScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZXF1aXJlZF09XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgICA8L2FwcC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICAgICAgICA8aW9uLWNvbCBzaXplPVwiMlwiIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiBjb2xvcj1cImxpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImxvYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiJ0NPTU1PTi5CVE5fREVMRVRFJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmVtb3ZlUHJvcGVydHlBdChpKVwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+Y2xvc2U8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwicHJvcGVydGllc0Zvcm1IZWxwZXIuaXNMYXN0KGkpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1cImxpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImxvYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidTRVRUSU5HUy5CVE5fQUREX1BST1BFUlRZJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicHJvcGVydGllc0Zvcm1IZWxwZXIuYWRkKClcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgICAgIDwvaW9uLXJvdz5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvaW9uLWdyaWQ+XG4gICAgICAgIDwvaW9uLWNvbD5cblxuICAgICAgICA8IS0tIHJpZ2h0IG1hcmdpbiAtLT5cbiAgICAgICAgPGlvbi1jb2wgc2l6ZT1cIjBcIiBzaXplLWxnPVwiMlwiPiZuYnNwO1xuICAgICAgICA8L2lvbi1jb2w+XG4gICAgICA8L2lvbi1yb3c+XG4gICAgPC9pb24tZ3JpZD5cblxuXG4gIDwvZm9ybT5cbjwvaW9uLWNvbnRlbnQ+XG5cbjxpb24tZm9vdGVyIGhpZGRlbi14cyBoaWRkZW4tc20gaGlkZGVuLW1vYmlsZT5cbiAgPGFwcC1mb3JtLWJ1dHRvbnMtYmFyIChvbkNhbmNlbCk9XCJjYW5jZWwoKVwiIChvblNhdmUpPVwic2F2ZSgkZXZlbnQpXCIgW2Rpc2FibGVkXT1cIiFmb3JtLmRpcnR5IHx8IHNhdmluZ1wiPjwvYXBwLWZvcm0tYnV0dG9ucy1iYXI+XG48L2lvbi1mb290ZXI+XG4iXX0=