@sumaris-net/ngx-components 2.18.0-beta9 → 2.21.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 (715) hide show
  1. package/README.md +3 -0
  2. package/doc/build.md +14 -14
  3. package/doc/changelog.md +1386 -88
  4. package/doc/feed/feed-en.json +26 -0
  5. package/doc/feed/feed-fr.json +28 -0
  6. package/fesm2022/sumaris-net.ngx-components.mjs +32423 -22727
  7. package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
  8. package/package.json +42 -39
  9. package/src/assets/environments/environment-test.json +2 -2
  10. package/src/assets/i18n/en-US.json +143 -45
  11. package/src/assets/i18n/en.json +142 -43
  12. package/src/assets/i18n/fr.json +147 -47
  13. package/src/assets/manifest.json +1 -1
  14. package/src/theme/_icons.scss +8 -12
  15. package/src/theme/_ionic.globals.scss +8 -1
  16. package/src/theme/_markdown.scss +1 -1
  17. package/src/theme/_material.globals.scss +4 -1
  18. package/src/theme/_material.scss +60 -17
  19. package/src/theme/_mixins.scss +39 -4
  20. package/src/theme/_ngx-components.forms.scss +115 -89
  21. package/src/theme/_ngx-components.globals.scss +4 -1
  22. package/src/theme/_ngx-components.scss +162 -110
  23. package/src/theme/_ngx-components.table.scss +105 -44
  24. package/src/theme/_ngx-components.tabs.scss +46 -14
  25. package/src/theme/_responsive.scss +15 -0
  26. package/src/theme/_roboto.scss +3 -0
  27. package/src/theme/_theme.scss +11 -14
  28. package/src/theme/_theme.variables.scss +7 -3
  29. package/src/theme/ionic/ionic.functions.color.scss +13 -5
  30. package/src/theme/ionic/ionic.globals.scss +4 -4
  31. package/src/theme/ionic/ionic.theme.default.scss +2 -0
  32. package/types/sumaris-net.ngx-components.d.ts +14132 -0
  33. package/esm2022/public_api.mjs +0 -358
  34. package/esm2022/src/app/admin/admin-routing.module.mjs +0 -34
  35. package/esm2022/src/app/admin/admin.module.mjs +0 -32
  36. package/esm2022/src/app/admin/services/filter/person.filter.mjs +0 -69
  37. package/esm2022/src/app/admin/services/person.service.mjs +0 -174
  38. package/esm2022/src/app/admin/services/validator/person.validator.mjs +0 -72
  39. package/esm2022/src/app/admin/users/users.mjs +0 -267
  40. package/esm2022/src/app/admin/users/users.module.mjs +0 -56
  41. package/esm2022/src/app/core/about/about.modal.mjs +0 -84
  42. package/esm2022/src/app/core/about/about.module.mjs +0 -21
  43. package/esm2022/src/app/core/account/account.module.mjs +0 -68
  44. package/esm2022/src/app/core/account/account.page.mjs +0 -351
  45. package/esm2022/src/app/core/account/new-token.modal.mjs +0 -132
  46. package/esm2022/src/app/core/account/password/change-password.form.mjs +0 -60
  47. package/esm2022/src/app/core/account/password/change-password.module.mjs +0 -22
  48. package/esm2022/src/app/core/account/password/change-password.page.mjs +0 -144
  49. package/esm2022/src/app/core/account/token.table.mjs +0 -152
  50. package/esm2022/src/app/core/auth/auth.form.mjs +0 -159
  51. package/esm2022/src/app/core/auth/auth.modal.mjs +0 -76
  52. package/esm2022/src/app/core/auth/auth.module.mjs +0 -56
  53. package/esm2022/src/app/core/auth/reset-password.modal.mjs +0 -77
  54. package/esm2022/src/app/core/core.module.mjs +0 -151
  55. package/esm2022/src/app/core/core.testing.module.mjs +0 -107
  56. package/esm2022/src/app/core/form/array/form-array.mjs +0 -325
  57. package/esm2022/src/app/core/form/array/testing/form-array-test.module.mjs +0 -23
  58. package/esm2022/src/app/core/form/array/testing/form-array.test.mjs +0 -94
  59. package/esm2022/src/app/core/form/buttons/form-buttons-bar.component.mjs +0 -108
  60. package/esm2022/src/app/core/form/buttons/form-buttons-bar.module.mjs +0 -31
  61. package/esm2022/src/app/core/form/entity/editor.class.mjs +0 -265
  62. package/esm2022/src/app/core/form/entity/entity-editor-modal.class.mjs +0 -420
  63. package/esm2022/src/app/core/form/entity/entity-editor.class.mjs +0 -731
  64. package/esm2022/src/app/core/form/entity/entity-metadata.component.mjs +0 -24
  65. package/esm2022/src/app/core/form/entity/entity.module.mjs +0 -32
  66. package/esm2022/src/app/core/form/entity/tab-editor.class.mjs +0 -194
  67. package/esm2022/src/app/core/form/form-container.class.mjs +0 -327
  68. package/esm2022/src/app/core/form/form.class.mjs +0 -336
  69. package/esm2022/src/app/core/form/form.module.mjs +0 -70
  70. package/esm2022/src/app/core/form/form.utils.mjs +0 -197
  71. package/esm2022/src/app/core/form/list/list.form.mjs +0 -235
  72. package/esm2022/src/app/core/form/list/list.module.mjs +0 -31
  73. package/esm2022/src/app/core/form/properties/properties.form.mjs +0 -225
  74. package/esm2022/src/app/core/form/properties/properties.module.mjs +0 -37
  75. package/esm2022/src/app/core/form/properties/properties.table.mjs +0 -268
  76. package/esm2022/src/app/core/form/properties/properties.utils.mjs +0 -60
  77. package/esm2022/src/app/core/form/properties/property.validator.mjs +0 -38
  78. package/esm2022/src/app/core/form/properties/testing/properties-form.test.mjs +0 -95
  79. package/esm2022/src/app/core/form/properties/testing/properties-form.testing.module.mjs +0 -23
  80. package/esm2022/src/app/core/form/text-popover/testing/text-popover.testing.mjs +0 -73
  81. package/esm2022/src/app/core/form/text-popover/testing/text-popover.testing.module.mjs +0 -30
  82. package/esm2022/src/app/core/form/text-popover/text-popover.component.mjs +0 -152
  83. package/esm2022/src/app/core/form/text-popover/text-popover.module.mjs +0 -31
  84. package/esm2022/src/app/core/form/username/username.form.mjs +0 -52
  85. package/esm2022/src/app/core/form/username/username.module.mjs +0 -20
  86. package/esm2022/src/app/core/graphql/graphql.module.mjs +0 -14
  87. package/esm2022/src/app/core/graphql/graphql.service.mjs +0 -783
  88. package/esm2022/src/app/core/graphql/graphql.utils.mjs +0 -119
  89. package/esm2022/src/app/core/home/home.mjs +0 -311
  90. package/esm2022/src/app/core/home/home.module.mjs +0 -42
  91. package/esm2022/src/app/core/icon/icon.component.mjs +0 -40
  92. package/esm2022/src/app/core/icon/icon.module.mjs +0 -20
  93. package/esm2022/src/app/core/install/install-upgrade-card.component.mjs +0 -354
  94. package/esm2022/src/app/core/install/install-upgrade-card.module.mjs +0 -31
  95. package/esm2022/src/app/core/menu/menu.component.mjs +0 -263
  96. package/esm2022/src/app/core/menu/menu.model.mjs +0 -272
  97. package/esm2022/src/app/core/menu/menu.module.mjs +0 -47
  98. package/esm2022/src/app/core/menu/menu.service.mjs +0 -655
  99. package/esm2022/src/app/core/menu/sub-menu-tab.directive.mjs +0 -109
  100. package/esm2022/src/app/core/menu/testing/menu-other.testing.mjs +0 -49
  101. package/esm2022/src/app/core/menu/testing/menu.testing.mjs +0 -157
  102. package/esm2022/src/app/core/menu/testing/menu.testing.module.mjs +0 -60
  103. package/esm2022/src/app/core/offline/update-offline-mode-card.component.mjs +0 -28
  104. package/esm2022/src/app/core/offline/update-offline-mode-card.module.mjs +0 -31
  105. package/esm2022/src/app/core/peer/select-peer.modal.mjs +0 -203
  106. package/esm2022/src/app/core/peer/select-peer.module.mjs +0 -30
  107. package/esm2022/src/app/core/register/register-confirm.page.mjs +0 -90
  108. package/esm2022/src/app/core/register/register.form.mjs +0 -194
  109. package/esm2022/src/app/core/register/register.modal.mjs +0 -55
  110. package/esm2022/src/app/core/register/register.module.mjs +0 -23
  111. package/esm2022/src/app/core/services/account.service.mjs +0 -1346
  112. package/esm2022/src/app/core/services/auth-guard.service.mjs +0 -74
  113. package/esm2022/src/app/core/services/base-entity-service.class.mjs +0 -473
  114. package/esm2022/src/app/core/services/base-graphql-service.class.mjs +0 -230
  115. package/esm2022/src/app/core/services/base58.mjs +0 -83
  116. package/esm2022/src/app/core/services/config/core.config.mjs +0 -233
  117. package/esm2022/src/app/core/services/config.service.mjs +0 -384
  118. package/esm2022/src/app/core/services/crypto.service.mjs +0 -107
  119. package/esm2022/src/app/core/services/errors.mjs +0 -52
  120. package/esm2022/src/app/core/services/local-settings.service.mjs +0 -482
  121. package/esm2022/src/app/core/services/model/account.model.mjs +0 -150
  122. package/esm2022/src/app/core/services/model/config.model.mjs +0 -107
  123. package/esm2022/src/app/core/services/model/department.model.mjs +0 -35
  124. package/esm2022/src/app/core/services/model/entity.decorators.mjs +0 -97
  125. package/esm2022/src/app/core/services/model/entity.model.mjs +0 -224
  126. package/esm2022/src/app/core/services/model/filter.model.mjs +0 -93
  127. package/esm2022/src/app/core/services/model/history.model.mjs +0 -2
  128. package/esm2022/src/app/core/services/model/model.enum.mjs +0 -11
  129. package/esm2022/src/app/core/services/model/peer.model.mjs +0 -93
  130. package/esm2022/src/app/core/services/model/person.model.mjs +0 -114
  131. package/esm2022/src/app/core/services/model/referential.model.mjs +0 -202
  132. package/esm2022/src/app/core/services/model/settings.model.mjs +0 -4
  133. package/esm2022/src/app/core/services/model/token.model.mjs +0 -56
  134. package/esm2022/src/app/core/services/model/tree-item-entity.model.mjs +0 -195
  135. package/esm2022/src/app/core/services/network.service.mjs +0 -631
  136. package/esm2022/src/app/core/services/network.types.mjs +0 -20
  137. package/esm2022/src/app/core/services/network.utils.mjs +0 -15
  138. package/esm2022/src/app/core/services/pipes/account.pipes.mjs +0 -38
  139. package/esm2022/src/app/core/services/pipes/department-to-string.pipe.mjs +0 -23
  140. package/esm2022/src/app/core/services/pipes/person-to-string.pipe.mjs +0 -23
  141. package/esm2022/src/app/core/services/pipes/pipes.module.mjs +0 -54
  142. package/esm2022/src/app/core/services/pipes/referential-to-string.pipe.mjs +0 -21
  143. package/esm2022/src/app/core/services/pipes/usage-mode.pipes.mjs +0 -37
  144. package/esm2022/src/app/core/services/platform.service.mjs +0 -583
  145. package/esm2022/src/app/core/services/storage/entities-storage.service.mjs +0 -427
  146. package/esm2022/src/app/core/services/storage/entity-store.class.mjs +0 -449
  147. package/esm2022/src/app/core/services/testing/referential-filter.model.mjs +0 -25
  148. package/esm2022/src/app/core/services/testing/referential.validator.mjs +0 -46
  149. package/esm2022/src/app/core/services/validator/account.validator.mjs +0 -45
  150. package/esm2022/src/app/core/services/validator/base.validator.class.mjs +0 -49
  151. package/esm2022/src/app/core/services/validator/local-settings.validator.mjs +0 -81
  152. package/esm2022/src/app/core/services/validator/user-settings.validator.mjs +0 -27
  153. package/esm2022/src/app/core/services/validator/user-token.validator.mjs +0 -55
  154. package/esm2022/src/app/core/settings/settings.module.mjs +0 -22
  155. package/esm2022/src/app/core/settings/settings.page.mjs +0 -341
  156. package/esm2022/src/app/core/table/async-table.class.mjs +0 -1753
  157. package/esm2022/src/app/core/table/column/actions-column.component.mjs +0 -127
  158. package/esm2022/src/app/core/table/column/nav-actions-column.component.mjs +0 -117
  159. package/esm2022/src/app/core/table/column/row-field.component.mjs +0 -116
  160. package/esm2022/src/app/core/table/entities-async-table-datasource.class.mjs +0 -384
  161. package/esm2022/src/app/core/table/entities-table-datasource.class.mjs +0 -401
  162. package/esm2022/src/app/core/table/memory-table.class.mjs +0 -57
  163. package/esm2022/src/app/core/table/table-select-columns.component.mjs +0 -46
  164. package/esm2022/src/app/core/table/table.class.mjs +0 -1816
  165. package/esm2022/src/app/core/table/table.model.mjs +0 -16
  166. package/esm2022/src/app/core/table/table.module.mjs +0 -51
  167. package/esm2022/src/app/core/table/table.pipes.mjs +0 -77
  168. package/esm2022/src/app/core/table/table.utils.mjs +0 -31
  169. package/esm2022/src/app/core/table/testing/table-validator.service.mjs +0 -32
  170. package/esm2022/src/app/core/table/testing/table.testing.mjs +0 -329
  171. package/esm2022/src/app/core/table/testing/table.testing.module.mjs +0 -25
  172. package/esm2022/src/app/core/table/testing/table2-validator.service.mjs +0 -25
  173. package/esm2022/src/app/core/table/testing/table2.testing.mjs +0 -273
  174. package/esm2022/src/app/shared/alerts.mjs +0 -243
  175. package/esm2022/src/app/shared/audio/audio.mjs +0 -249
  176. package/esm2022/src/app/shared/audio/audio.testing.mjs +0 -32
  177. package/esm2022/src/app/shared/audio/audio.testing.module.mjs +0 -30
  178. package/esm2022/src/app/shared/capacitor/keyboard.mjs +0 -42
  179. package/esm2022/src/app/shared/capacitor/plugins.mjs +0 -9
  180. package/esm2022/src/app/shared/constants.mjs +0 -16
  181. package/esm2022/src/app/shared/dates.mjs +0 -151
  182. package/esm2022/src/app/shared/debug/debug-service.class.mjs +0 -3
  183. package/esm2022/src/app/shared/debug/debug.component.mjs +0 -40
  184. package/esm2022/src/app/shared/debug/debug.module.mjs +0 -23
  185. package/esm2022/src/app/shared/directives/autofocus.directive.mjs +0 -91
  186. package/esm2022/src/app/shared/directives/autotitle.directive.mjs +0 -32
  187. package/esm2022/src/app/shared/directives/directives.module.mjs +0 -22
  188. package/esm2022/src/app/shared/directives/drag-and-drop.directive.mjs +0 -52
  189. package/esm2022/src/app/shared/directives/ng-var.directive.mjs +0 -33
  190. package/esm2022/src/app/shared/directives/resizable/resizable.component.mjs +0 -62
  191. package/esm2022/src/app/shared/directives/resizable/resizable.directive.mjs +0 -45
  192. package/esm2022/src/app/shared/directives/resizable/resizable.module.mjs +0 -17
  193. package/esm2022/src/app/shared/events.mjs +0 -63
  194. package/esm2022/src/app/shared/file/csv.utils.mjs +0 -92
  195. package/esm2022/src/app/shared/file/file.service.mjs +0 -118
  196. package/esm2022/src/app/shared/file/file.utils.mjs +0 -115
  197. package/esm2022/src/app/shared/file/images.utils.mjs +0 -186
  198. package/esm2022/src/app/shared/file/json.utils.mjs +0 -58
  199. package/esm2022/src/app/shared/file/uri.utils.mjs +0 -24
  200. package/esm2022/src/app/shared/focusable.mjs +0 -6
  201. package/esm2022/src/app/shared/form/field.component.mjs +0 -379
  202. package/esm2022/src/app/shared/form/field.model.mjs +0 -25
  203. package/esm2022/src/app/shared/form/loading-spinner.mjs +0 -35
  204. package/esm2022/src/app/shared/forms.mjs +0 -480
  205. package/esm2022/src/app/shared/functions.mjs +0 -551
  206. package/esm2022/src/app/shared/geolocation/geolocation.utils.mjs +0 -82
  207. package/esm2022/src/app/shared/gesture/gesture-config.mjs +0 -46
  208. package/esm2022/src/app/shared/gesture/hammer.utils.mjs +0 -2
  209. package/esm2022/src/app/shared/graph/colors.utils.mjs +0 -60
  210. package/esm2022/src/app/shared/graph/graph-colors.mjs +0 -213
  211. package/esm2022/src/app/shared/guard/component-dirty.guard.mjs +0 -59
  212. package/esm2022/src/app/shared/help/help.modal.mjs +0 -63
  213. package/esm2022/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.mjs +0 -23
  214. package/esm2022/src/app/shared/hotkeys/hotkeys.service.mjs +0 -112
  215. package/esm2022/src/app/shared/hotkeys/shared-hotkeys.module.mjs +0 -24
  216. package/esm2022/src/app/shared/http/http.utils.mjs +0 -56
  217. package/esm2022/src/app/shared/image/gallery/image-gallery.component.mjs +0 -388
  218. package/esm2022/src/app/shared/image/gallery/image-gallery.module.mjs +0 -62
  219. package/esm2022/src/app/shared/image/gallery/testing/gallegry.model.testing.mjs +0 -26
  220. package/esm2022/src/app/shared/image/gallery/testing/gallery.service.testing.mjs +0 -87
  221. package/esm2022/src/app/shared/image/gallery/testing/gallery.testing.mjs +0 -37
  222. package/esm2022/src/app/shared/image/gallery/testing/gallery.testing.module.mjs +0 -59
  223. package/esm2022/src/app/shared/image/image.model.mjs +0 -2
  224. package/esm2022/src/app/shared/image/image.module.mjs +0 -24
  225. package/esm2022/src/app/shared/image/image.service.mjs +0 -106
  226. package/esm2022/src/app/shared/inputs.mjs +0 -263
  227. package/esm2022/src/app/shared/interceptors/progess.interceptor.mjs +0 -27
  228. package/esm2022/src/app/shared/logging/log-level.model.mjs +0 -48
  229. package/esm2022/src/app/shared/logging/logger.model.mjs +0 -47
  230. package/esm2022/src/app/shared/logging/logging-service.class.mjs +0 -125
  231. package/esm2022/src/app/shared/logging/logging-service.config.mjs +0 -2
  232. package/esm2022/src/app/shared/logging/logging-service.module.mjs +0 -30
  233. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.config.mjs +0 -46
  234. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.mjs +0 -1071
  235. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.module.mjs +0 -79
  236. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.utils.mjs +0 -18
  237. package/esm2022/src/app/shared/material/autocomplete/testing/autocomplete.test.mjs +0 -231
  238. package/esm2022/src/app/shared/material/badge/badge.directive.mjs +0 -251
  239. package/esm2022/src/app/shared/material/badge/badge.module.mjs +0 -20
  240. package/esm2022/src/app/shared/material/badge/badge.test.mjs +0 -42
  241. package/esm2022/src/app/shared/material/boolean/boolean.module.mjs +0 -71
  242. package/esm2022/src/app/shared/material/boolean/material.boolean.mjs +0 -376
  243. package/esm2022/src/app/shared/material/boolean/testing/boolean.test.page.mjs +0 -61
  244. package/esm2022/src/app/shared/material/chips/chips.module.mjs +0 -75
  245. package/esm2022/src/app/shared/material/chips/material.chips.mjs +0 -779
  246. package/esm2022/src/app/shared/material/chips/testing/chips.test.mjs +0 -147
  247. package/esm2022/src/app/shared/material/datetime/datetime.module.mjs +0 -76
  248. package/esm2022/src/app/shared/material/datetime/material.date.mjs +0 -471
  249. package/esm2022/src/app/shared/material/datetime/material.dateshort.mjs +0 -457
  250. package/esm2022/src/app/shared/material/datetime/material.datetime.mjs +0 -681
  251. package/esm2022/src/app/shared/material/datetime/testing/mat-date-time.test.mjs +0 -136
  252. package/esm2022/src/app/shared/material/datetime/testing/mat-date.test.mjs +0 -127
  253. package/esm2022/src/app/shared/material/datetime/testing/mat-dateshort.test.mjs +0 -118
  254. package/esm2022/src/app/shared/material/duration/duration.module.mjs +0 -65
  255. package/esm2022/src/app/shared/material/duration/duration.utils.mjs +0 -33
  256. package/esm2022/src/app/shared/material/duration/material.duration.mjs +0 -274
  257. package/esm2022/src/app/shared/material/duration/testing/mat-duration.test.mjs +0 -80
  258. package/esm2022/src/app/shared/material/latlong/latlong.utils.mjs +0 -313
  259. package/esm2022/src/app/shared/material/latlong/material.latlong.mjs +0 -381
  260. package/esm2022/src/app/shared/material/latlong/material.latlong.module.mjs +0 -67
  261. package/esm2022/src/app/shared/material/latlong/testing/latlong.test.mjs +0 -118
  262. package/esm2022/src/app/shared/material/material.animations.mjs +0 -143
  263. package/esm2022/src/app/shared/material/material.config.mjs +0 -3
  264. package/esm2022/src/app/shared/material/material.module.mjs +0 -229
  265. package/esm2022/src/app/shared/material/material.testing.module.mjs +0 -234
  266. package/esm2022/src/app/shared/material/paginator/material.paginator-i18n.mjs +0 -51
  267. package/esm2022/src/app/shared/material/stepper/material.stepper-i18n.mjs +0 -23
  268. package/esm2022/src/app/shared/material/swipe/material.swipe.mjs +0 -375
  269. package/esm2022/src/app/shared/material/swipe/swipe.module.mjs +0 -52
  270. package/esm2022/src/app/shared/material/swipe/testing/swipe.test.mjs +0 -67
  271. package/esm2022/src/app/shared/material/testing/common.test.mjs +0 -111
  272. package/esm2022/src/app/shared/material/text/testing/text-form.testing.mjs +0 -42
  273. package/esm2022/src/app/shared/material/text/text-form.component.mjs +0 -204
  274. package/esm2022/src/app/shared/material/text/text-form.module.mjs +0 -63
  275. package/esm2022/src/app/shared/modules.mjs +0 -12
  276. package/esm2022/src/app/shared/named-filter/named-filter-selector.component.mjs +0 -303
  277. package/esm2022/src/app/shared/named-filter/named-filter.model.mjs +0 -49
  278. package/esm2022/src/app/shared/named-filter/named-filter.module.mjs +0 -24
  279. package/esm2022/src/app/shared/named-filter/named-filter.service.mjs +0 -69
  280. package/esm2022/src/app/shared/named-filter/testing/named-filter-selector.testing.mjs +0 -74
  281. package/esm2022/src/app/shared/named-filter/testing/named-filter.testing.module.mjs +0 -28
  282. package/esm2022/src/app/shared/observables.mjs +0 -100
  283. package/esm2022/src/app/shared/pipes/arrays.pipe.mjs +0 -156
  284. package/esm2022/src/app/shared/pipes/badge.pipes.mjs +0 -24
  285. package/esm2022/src/app/shared/pipes/colors.pipe.mjs +0 -29
  286. package/esm2022/src/app/shared/pipes/date-diff-duration.pipe.mjs +0 -49
  287. package/esm2022/src/app/shared/pipes/date-format.pipe.mjs +0 -72
  288. package/esm2022/src/app/shared/pipes/date-from-now.pipe.mjs +0 -28
  289. package/esm2022/src/app/shared/pipes/duration.pipe.mjs +0 -36
  290. package/esm2022/src/app/shared/pipes/file-size.pipe.mjs +0 -53
  291. package/esm2022/src/app/shared/pipes/form.pipes.mjs +0 -219
  292. package/esm2022/src/app/shared/pipes/highlight.pipe.mjs +0 -48
  293. package/esm2022/src/app/shared/pipes/html.pipes.mjs +0 -52
  294. package/esm2022/src/app/shared/pipes/latlong-format.pipe.mjs +0 -42
  295. package/esm2022/src/app/shared/pipes/maps.pipe.mjs +0 -63
  296. package/esm2022/src/app/shared/pipes/maskito.pipe.mjs +0 -67
  297. package/esm2022/src/app/shared/pipes/math.pipes.mjs +0 -59
  298. package/esm2022/src/app/shared/pipes/ng-init.pipe.mjs +0 -19
  299. package/esm2022/src/app/shared/pipes/number-format.pipe.mjs +0 -30
  300. package/esm2022/src/app/shared/pipes/pipes.module.mjs +0 -236
  301. package/esm2022/src/app/shared/pipes/property.pipes.mjs +0 -136
  302. package/esm2022/src/app/shared/pipes/selection.pipes.mjs +0 -180
  303. package/esm2022/src/app/shared/pipes/string.pipes.mjs +0 -136
  304. package/esm2022/src/app/shared/pipes/translate-context.pipe.mjs +0 -44
  305. package/esm2022/src/app/shared/pipes/types.pipes.mjs +0 -74
  306. package/esm2022/src/app/shared/platforms.mjs +0 -45
  307. package/esm2022/src/app/shared/rx-state.module.mjs +0 -19
  308. package/esm2022/src/app/shared/services/entity-service.class.mjs +0 -7
  309. package/esm2022/src/app/shared/services/job.utils.mjs +0 -92
  310. package/esm2022/src/app/shared/services/memory-entity-service.class.mjs +0 -349
  311. package/esm2022/src/app/shared/services/progress-bar.service.mjs +0 -31
  312. package/esm2022/src/app/shared/services/startable-observable-service.class.mjs +0 -118
  313. package/esm2022/src/app/shared/services/startable-service.class.mjs +0 -107
  314. package/esm2022/src/app/shared/services/translate-context.service.mjs +0 -107
  315. package/esm2022/src/app/shared/services/validator-service.class.mjs +0 -2
  316. package/esm2022/src/app/shared/services.mjs +0 -62
  317. package/esm2022/src/app/shared/shared-routing.module.mjs +0 -72
  318. package/esm2022/src/app/shared/shared.module.mjs +0 -234
  319. package/esm2022/src/app/shared/shared.testing.module.mjs +0 -100
  320. package/esm2022/src/app/shared/storage/storage-explorer.component.mjs +0 -279
  321. package/esm2022/src/app/shared/storage/storage-explorer.module.mjs +0 -42
  322. package/esm2022/src/app/shared/storage/storage-explorer.testing-routing.module.mjs +0 -27
  323. package/esm2022/src/app/shared/storage/storage-explorer.testing.module.mjs +0 -25
  324. package/esm2022/src/app/shared/storage/storage.service.mjs +0 -134
  325. package/esm2022/src/app/shared/storage/storage.utils.mjs +0 -13
  326. package/esm2022/src/app/shared/testing/maskito.test.mjs +0 -41
  327. package/esm2022/src/app/shared/testing/observable.test.mjs +0 -94
  328. package/esm2022/src/app/shared/testing/tests.page.mjs +0 -37
  329. package/esm2022/src/app/shared/toast/toast.testing.mjs +0 -52
  330. package/esm2022/src/app/shared/toast/toast.testing.module.mjs +0 -30
  331. package/esm2022/src/app/shared/toast/toasts.mjs +0 -144
  332. package/esm2022/src/app/shared/toolbar/modal-toolbar.mjs +0 -62
  333. package/esm2022/src/app/shared/toolbar/toolbar.mjs +0 -263
  334. package/esm2022/src/app/shared/toolbar/toolbar.module.mjs +0 -26
  335. package/esm2022/src/app/shared/types.mjs +0 -2
  336. package/esm2022/src/app/shared/upload-file/testing/upload-file.testing.mjs +0 -59
  337. package/esm2022/src/app/shared/upload-file/testing/upload-file.testing.module.mjs +0 -30
  338. package/esm2022/src/app/shared/upload-file/upload-file-popover.component.mjs +0 -106
  339. package/esm2022/src/app/shared/upload-file/upload-file.component.mjs +0 -213
  340. package/esm2022/src/app/shared/upload-file/upload-file.model.mjs +0 -26
  341. package/esm2022/src/app/shared/validator/form-error-adapter.class.mjs +0 -114
  342. package/esm2022/src/app/shared/validator/validators.mjs +0 -601
  343. package/esm2022/src/app/shared/version/versions.mjs +0 -81
  344. package/esm2022/src/app/social/job/job.module.mjs +0 -23
  345. package/esm2022/src/app/social/job/progression/job-progression.component.mjs +0 -35
  346. package/esm2022/src/app/social/job/progression/job-progression.icon.mjs +0 -235
  347. package/esm2022/src/app/social/job/progression/job-progression.list.mjs +0 -47
  348. package/esm2022/src/app/social/job/progression/job-progression.model.mjs +0 -29
  349. package/esm2022/src/app/social/job/progression/job-progression.service.mjs +0 -91
  350. package/esm2022/src/app/social/job/testing/job-progression.testing.mjs +0 -38
  351. package/esm2022/src/app/social/job/testing/job-progression.testing.service.mjs +0 -34
  352. package/esm2022/src/app/social/job/testing/job.testing.module.mjs +0 -22
  353. package/esm2022/src/app/social/message/message.form.mjs +0 -140
  354. package/esm2022/src/app/social/message/message.modal.mjs +0 -110
  355. package/esm2022/src/app/social/message/message.model.mjs +0 -75
  356. package/esm2022/src/app/social/message/message.module.mjs +0 -22
  357. package/esm2022/src/app/social/message/message.service.mjs +0 -110
  358. package/esm2022/src/app/social/social.errors.mjs +0 -10
  359. package/esm2022/src/app/social/social.module.mjs +0 -22
  360. package/esm2022/src/app/social/social.testing.module.mjs +0 -40
  361. package/esm2022/src/app/social/user-event/notification/user-event-notification.icon.mjs +0 -127
  362. package/esm2022/src/app/social/user-event/notification/user-event-notification.list.mjs +0 -260
  363. package/esm2022/src/app/social/user-event/testing/user-event.testing.mjs +0 -257
  364. package/esm2022/src/app/social/user-event/testing/user-event.testing.model.mjs +0 -129
  365. package/esm2022/src/app/social/user-event/testing/user-event.testing.module.mjs +0 -22
  366. package/esm2022/src/app/social/user-event/testing/user-event.testing.service.mjs +0 -128
  367. package/esm2022/src/app/social/user-event/user-event.model.mjs +0 -2
  368. package/esm2022/src/app/social/user-event/user-event.module.mjs +0 -23
  369. package/esm2022/src/app/social/user-event/user-event.service.mjs +0 -509
  370. package/esm2022/src/environments/environment.class.mjs +0 -57
  371. package/esm2022/src/environments/environment.loader.mjs +0 -77
  372. package/esm2022/src/environments/environment.mjs +0 -105
  373. package/esm2022/sumaris-net.ngx-components.mjs +0 -5
  374. package/index.d.ts +0 -5
  375. package/public_api.d.ts +0 -322
  376. package/src/app/admin/admin-routing.module.d.ts +0 -9
  377. package/src/app/admin/admin.module.d.ts +0 -10
  378. package/src/app/admin/services/filter/person.filter.d.ts +0 -21
  379. package/src/app/admin/services/person.service.d.ts +0 -49
  380. package/src/app/admin/services/validator/person.validator.d.ts +0 -23
  381. package/src/app/admin/users/users.d.ts +0 -45
  382. package/src/app/admin/users/users.module.d.ts +0 -14
  383. package/src/app/core/about/about.modal.d.ts +0 -32
  384. package/src/app/core/about/about.module.d.ts +0 -10
  385. package/src/app/core/account/account.module.d.ts +0 -16
  386. package/src/app/core/account/account.page.d.ts +0 -80
  387. package/src/app/core/account/new-token.modal.d.ts +0 -41
  388. package/src/app/core/account/password/change-password.form.d.ts +0 -19
  389. package/src/app/core/account/password/change-password.module.d.ts +0 -11
  390. package/src/app/core/account/password/change-password.page.d.ts +0 -36
  391. package/src/app/core/account/token.table.d.ts +0 -27
  392. package/src/app/core/auth/auth.form.d.ts +0 -38
  393. package/src/app/core/auth/auth.modal.d.ts +0 -24
  394. package/src/app/core/auth/auth.module.d.ts +0 -13
  395. package/src/app/core/auth/reset-password.modal.d.ts +0 -26
  396. package/src/app/core/core.module.d.ts +0 -28
  397. package/src/app/core/core.testing.module.d.ts +0 -15
  398. package/src/app/core/form/array/form-array.d.ts +0 -136
  399. package/src/app/core/form/array/testing/form-array-test.module.d.ts +0 -12
  400. package/src/app/core/form/array/testing/form-array.test.d.ts +0 -26
  401. package/src/app/core/form/buttons/form-buttons-bar.component.d.ts +0 -37
  402. package/src/app/core/form/buttons/form-buttons-bar.module.d.ts +0 -9
  403. package/src/app/core/form/entity/editor.class.d.ts +0 -83
  404. package/src/app/core/form/entity/entity-editor-modal.class.d.ts +0 -126
  405. package/src/app/core/form/entity/entity-editor.class.d.ts +0 -204
  406. package/src/app/core/form/entity/entity-metadata.component.d.ts +0 -13
  407. package/src/app/core/form/entity/entity.module.d.ts +0 -10
  408. package/src/app/core/form/entity/tab-editor.class.d.ts +0 -70
  409. package/src/app/core/form/form-container.class.d.ts +0 -126
  410. package/src/app/core/form/form.class.d.ts +0 -144
  411. package/src/app/core/form/form.module.d.ts +0 -14
  412. package/src/app/core/form/form.utils.d.ts +0 -251
  413. package/src/app/core/form/list/list.form.d.ts +0 -81
  414. package/src/app/core/form/list/list.module.d.ts +0 -9
  415. package/src/app/core/form/properties/properties.form.d.ts +0 -66
  416. package/src/app/core/form/properties/properties.module.d.ts +0 -11
  417. package/src/app/core/form/properties/properties.table.d.ts +0 -78
  418. package/src/app/core/form/properties/properties.utils.d.ts +0 -27
  419. package/src/app/core/form/properties/property.validator.d.ts +0 -19
  420. package/src/app/core/form/properties/testing/properties-form.test.d.ts +0 -19
  421. package/src/app/core/form/properties/testing/properties-form.testing.module.d.ts +0 -12
  422. package/src/app/core/form/text-popover/testing/text-popover.testing.d.ts +0 -16
  423. package/src/app/core/form/text-popover/testing/text-popover.testing.module.d.ts +0 -11
  424. package/src/app/core/form/text-popover/text-popover.component.d.ts +0 -71
  425. package/src/app/core/form/text-popover/text-popover.module.d.ts +0 -9
  426. package/src/app/core/form/username/username.form.d.ts +0 -19
  427. package/src/app/core/form/username/username.module.d.ts +0 -9
  428. package/src/app/core/graphql/graphql.module.d.ts +0 -7
  429. package/src/app/core/graphql/graphql.service.d.ts +0 -147
  430. package/src/app/core/graphql/graphql.utils.d.ts +0 -42
  431. package/src/app/core/home/home.d.ts +0 -94
  432. package/src/app/core/home/home.module.d.ts +0 -13
  433. package/src/app/core/icon/icon.component.d.ts +0 -13
  434. package/src/app/core/icon/icon.module.d.ts +0 -9
  435. package/src/app/core/install/install-upgrade-card.component.d.ts +0 -64
  436. package/src/app/core/install/install-upgrade-card.module.d.ts +0 -9
  437. package/src/app/core/menu/menu.component.d.ts +0 -69
  438. package/src/app/core/menu/menu.model.d.ts +0 -144
  439. package/src/app/core/menu/menu.module.d.ts +0 -12
  440. package/src/app/core/menu/menu.service.d.ts +0 -94
  441. package/src/app/core/menu/sub-menu-tab.directive.d.ts +0 -29
  442. package/src/app/core/menu/testing/menu-other.testing.d.ts +0 -15
  443. package/src/app/core/menu/testing/menu.testing.d.ts +0 -51
  444. package/src/app/core/menu/testing/menu.testing.module.d.ts +0 -12
  445. package/src/app/core/offline/update-offline-mode-card.component.d.ts +0 -11
  446. package/src/app/core/offline/update-offline-mode-card.module.d.ts +0 -9
  447. package/src/app/core/peer/select-peer.modal.d.ts +0 -60
  448. package/src/app/core/peer/select-peer.module.d.ts +0 -10
  449. package/src/app/core/register/register-confirm.page.d.ts +0 -24
  450. package/src/app/core/register/register.form.d.ts +0 -49
  451. package/src/app/core/register/register.modal.d.ts +0 -14
  452. package/src/app/core/register/register.module.d.ts +0 -12
  453. package/src/app/core/services/account.service.d.ts +0 -205
  454. package/src/app/core/services/auth-guard.service.d.ts +0 -17
  455. package/src/app/core/services/base-entity-service.class.d.ts +0 -123
  456. package/src/app/core/services/base-graphql-service.class.d.ts +0 -77
  457. package/src/app/core/services/base58.d.ts +0 -7
  458. package/src/app/core/services/config/core.config.d.ts +0 -41
  459. package/src/app/core/services/config.service.d.ts +0 -63
  460. package/src/app/core/services/crypto.service.d.ts +0 -44
  461. package/src/app/core/services/errors.d.ts +0 -63
  462. package/src/app/core/services/local-settings.service.d.ts +0 -95
  463. package/src/app/core/services/model/account.model.d.ts +0 -41
  464. package/src/app/core/services/model/config.model.d.ts +0 -36
  465. package/src/app/core/services/model/department.model.d.ts +0 -11
  466. package/src/app/core/services/model/entity.decorators.d.ts +0 -17
  467. package/src/app/core/services/model/entity.model.d.ts +0 -87
  468. package/src/app/core/services/model/filter.model.d.ts +0 -37
  469. package/src/app/core/services/model/history.model.d.ts +0 -20
  470. package/src/app/core/services/model/model.enum.d.ts +0 -7
  471. package/src/app/core/services/model/peer.model.d.ts +0 -30
  472. package/src/app/core/services/model/person.model.d.ts +0 -37
  473. package/src/app/core/services/model/referential.model.d.ts +0 -83
  474. package/src/app/core/services/model/settings.model.d.ts +0 -28
  475. package/src/app/core/services/model/token.model.d.ts +0 -22
  476. package/src/app/core/services/model/tree-item-entity.model.d.ts +0 -53
  477. package/src/app/core/services/network.service.d.ts +0 -151
  478. package/src/app/core/services/network.types.d.ts +0 -5
  479. package/src/app/core/services/network.utils.d.ts +0 -31
  480. package/src/app/core/services/pipes/account.pipes.d.ts +0 -15
  481. package/src/app/core/services/pipes/department-to-string.pipe.d.ts +0 -9
  482. package/src/app/core/services/pipes/person-to-string.pipe.d.ts +0 -11
  483. package/src/app/core/services/pipes/pipes.module.d.ts +0 -11
  484. package/src/app/core/services/pipes/referential-to-string.pipe.d.ts +0 -13
  485. package/src/app/core/services/pipes/usage-mode.pipes.d.ts +0 -15
  486. package/src/app/core/services/platform.service.d.ts +0 -100
  487. package/src/app/core/services/storage/entities-storage.service.d.ts +0 -108
  488. package/src/app/core/services/storage/entity-store.class.d.ts +0 -113
  489. package/src/app/core/services/testing/referential-filter.model.d.ts +0 -9
  490. package/src/app/core/services/testing/referential.validator.d.ts +0 -22
  491. package/src/app/core/services/validator/account.validator.d.ts +0 -24
  492. package/src/app/core/services/validator/base.validator.class.d.ts +0 -21
  493. package/src/app/core/services/validator/local-settings.validator.d.ts +0 -22
  494. package/src/app/core/services/validator/user-settings.validator.d.ts +0 -10
  495. package/src/app/core/services/validator/user-token.validator.d.ts +0 -13
  496. package/src/app/core/settings/settings.module.d.ts +0 -11
  497. package/src/app/core/settings/settings.page.d.ts +0 -81
  498. package/src/app/core/table/async-table.class.d.ts +0 -389
  499. package/src/app/core/table/column/actions-column.component.d.ts +0 -59
  500. package/src/app/core/table/column/nav-actions-column.component.d.ts +0 -46
  501. package/src/app/core/table/column/row-field.component.d.ts +0 -40
  502. package/src/app/core/table/entities-async-table-datasource.class.d.ts +0 -81
  503. package/src/app/core/table/entities-table-datasource.class.d.ts +0 -95
  504. package/src/app/core/table/memory-table.class.d.ts +0 -25
  505. package/src/app/core/table/table-select-columns.component.d.ts +0 -22
  506. package/src/app/core/table/table.class.d.ts +0 -394
  507. package/src/app/core/table/table.model.d.ts +0 -26
  508. package/src/app/core/table/table.module.d.ts +0 -14
  509. package/src/app/core/table/table.pipes.d.ts +0 -28
  510. package/src/app/core/table/table.utils.d.ts +0 -11
  511. package/src/app/core/table/testing/table-validator.service.d.ts +0 -17
  512. package/src/app/core/table/testing/table.testing.d.ts +0 -54
  513. package/src/app/core/table/testing/table.testing.module.d.ts +0 -14
  514. package/src/app/core/table/testing/table2-validator.service.d.ts +0 -15
  515. package/src/app/core/table/testing/table2.testing.d.ts +0 -48
  516. package/src/app/shared/alerts.d.ts +0 -55
  517. package/src/app/shared/audio/audio.d.ts +0 -44
  518. package/src/app/shared/audio/audio.testing.d.ts +0 -13
  519. package/src/app/shared/audio/audio.testing.module.d.ts +0 -11
  520. package/src/app/shared/capacitor/keyboard.d.ts +0 -16
  521. package/src/app/shared/capacitor/plugins.d.ts +0 -7
  522. package/src/app/shared/constants.d.ts +0 -13
  523. package/src/app/shared/dates.d.ts +0 -48
  524. package/src/app/shared/debug/debug-service.class.d.ts +0 -5
  525. package/src/app/shared/debug/debug.component.d.ts +0 -13
  526. package/src/app/shared/debug/debug.module.d.ts +0 -12
  527. package/src/app/shared/directives/autofocus.directive.d.ts +0 -18
  528. package/src/app/shared/directives/autotitle.directive.d.ts +0 -10
  529. package/src/app/shared/directives/directives.module.d.ts +0 -12
  530. package/src/app/shared/directives/drag-and-drop.directive.d.ts +0 -17
  531. package/src/app/shared/directives/ng-var.directive.d.ts +0 -12
  532. package/src/app/shared/directives/resizable/resizable.component.d.ts +0 -21
  533. package/src/app/shared/directives/resizable/resizable.directive.d.ts +0 -12
  534. package/src/app/shared/directives/resizable/resizable.module.d.ts +0 -8
  535. package/src/app/shared/events.d.ts +0 -28
  536. package/src/app/shared/file/csv.utils.d.ts +0 -24
  537. package/src/app/shared/file/file.service.d.ts +0 -23
  538. package/src/app/shared/file/file.utils.d.ts +0 -20
  539. package/src/app/shared/file/images.utils.d.ts +0 -36
  540. package/src/app/shared/file/json.utils.d.ts +0 -19
  541. package/src/app/shared/file/uri.utils.d.ts +0 -8
  542. package/src/app/shared/focusable.d.ts +0 -4
  543. package/src/app/shared/form/field.component.d.ts +0 -74
  544. package/src/app/shared/form/field.model.d.ts +0 -39
  545. package/src/app/shared/form/loading-spinner.d.ts +0 -8
  546. package/src/app/shared/forms.d.ts +0 -118
  547. package/src/app/shared/functions.d.ts +0 -152
  548. package/src/app/shared/geolocation/geolocation.utils.d.ts +0 -19
  549. package/src/app/shared/gesture/gesture-config.d.ts +0 -15
  550. package/src/app/shared/gesture/hammer.utils.d.ts +0 -16
  551. package/src/app/shared/graph/colors.utils.d.ts +0 -17
  552. package/src/app/shared/graph/graph-colors.d.ts +0 -63
  553. package/src/app/shared/guard/component-dirty.guard.d.ts +0 -14
  554. package/src/app/shared/help/help.modal.d.ts +0 -33
  555. package/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.d.ts +0 -8
  556. package/src/app/shared/hotkeys/hotkeys.service.d.ts +0 -42
  557. package/src/app/shared/hotkeys/shared-hotkeys.module.d.ts +0 -11
  558. package/src/app/shared/http/http.utils.d.ts +0 -28
  559. package/src/app/shared/image/gallery/image-gallery.component.d.ts +0 -98
  560. package/src/app/shared/image/gallery/image-gallery.module.d.ts +0 -15
  561. package/src/app/shared/image/gallery/testing/gallegry.model.testing.d.ts +0 -12
  562. package/src/app/shared/image/gallery/testing/gallery.service.testing.d.ts +0 -33
  563. package/src/app/shared/image/gallery/testing/gallery.testing.d.ts +0 -16
  564. package/src/app/shared/image/gallery/testing/gallery.testing.module.d.ts +0 -13
  565. package/src/app/shared/image/image.model.d.ts +0 -5
  566. package/src/app/shared/image/image.module.d.ts +0 -8
  567. package/src/app/shared/image/image.service.d.ts +0 -32
  568. package/src/app/shared/inputs.d.ts +0 -34
  569. package/src/app/shared/interceptors/progess.interceptor.d.ts +0 -8
  570. package/src/app/shared/logging/log-level.model.d.ts +0 -38
  571. package/src/app/shared/logging/logger.model.d.ts +0 -68
  572. package/src/app/shared/logging/logging-service.class.d.ts +0 -39
  573. package/src/app/shared/logging/logging-service.config.d.ts +0 -25
  574. package/src/app/shared/logging/logging-service.module.d.ts +0 -9
  575. package/src/app/shared/material/autocomplete/material.autocomplete.config.d.ts +0 -55
  576. package/src/app/shared/material/autocomplete/material.autocomplete.d.ts +0 -180
  577. package/src/app/shared/material/autocomplete/material.autocomplete.module.d.ts +0 -22
  578. package/src/app/shared/material/autocomplete/material.autocomplete.utils.d.ts +0 -5
  579. package/src/app/shared/material/autocomplete/testing/autocomplete.test.d.ts +0 -46
  580. package/src/app/shared/material/badge/badge.directive.d.ts +0 -43
  581. package/src/app/shared/material/badge/badge.module.d.ts +0 -10
  582. package/src/app/shared/material/badge/badge.test.d.ts +0 -21
  583. package/src/app/shared/material/boolean/boolean.module.d.ts +0 -21
  584. package/src/app/shared/material/boolean/material.boolean.d.ts +0 -93
  585. package/src/app/shared/material/boolean/testing/boolean.test.page.d.ts +0 -22
  586. package/src/app/shared/material/chips/chips.module.d.ts +0 -22
  587. package/src/app/shared/material/chips/material.chips.d.ts +0 -150
  588. package/src/app/shared/material/chips/testing/chips.test.d.ts +0 -32
  589. package/src/app/shared/material/datetime/datetime.module.d.ts +0 -24
  590. package/src/app/shared/material/datetime/material.date.d.ts +0 -90
  591. package/src/app/shared/material/datetime/material.dateshort.d.ts +0 -89
  592. package/src/app/shared/material/datetime/material.datetime.d.ts +0 -121
  593. package/src/app/shared/material/datetime/testing/mat-date-time.test.d.ts +0 -37
  594. package/src/app/shared/material/datetime/testing/mat-date.test.d.ts +0 -32
  595. package/src/app/shared/material/datetime/testing/mat-dateshort.test.d.ts +0 -31
  596. package/src/app/shared/material/duration/duration.module.d.ts +0 -19
  597. package/src/app/shared/material/duration/duration.utils.d.ts +0 -3
  598. package/src/app/shared/material/duration/material.duration.d.ts +0 -58
  599. package/src/app/shared/material/duration/testing/mat-duration.test.d.ts +0 -22
  600. package/src/app/shared/material/latlong/latlong.utils.d.ts +0 -21
  601. package/src/app/shared/material/latlong/material.latlong.d.ts +0 -70
  602. package/src/app/shared/material/latlong/material.latlong.module.d.ts +0 -20
  603. package/src/app/shared/material/latlong/testing/latlong.test.d.ts +0 -27
  604. package/src/app/shared/material/material.animations.d.ts +0 -6
  605. package/src/app/shared/material/material.config.d.ts +0 -3
  606. package/src/app/shared/material/material.module.d.ts +0 -45
  607. package/src/app/shared/material/material.testing.module.d.ts +0 -31
  608. package/src/app/shared/material/paginator/material.paginator-i18n.d.ts +0 -12
  609. package/src/app/shared/material/stepper/material.stepper-i18n.d.ts +0 -10
  610. package/src/app/shared/material/swipe/material.swipe.d.ts +0 -90
  611. package/src/app/shared/material/swipe/swipe.module.d.ts +0 -16
  612. package/src/app/shared/material/swipe/testing/swipe.test.d.ts +0 -22
  613. package/src/app/shared/material/testing/common.test.d.ts +0 -25
  614. package/src/app/shared/material/text/testing/text-form.testing.d.ts +0 -19
  615. package/src/app/shared/material/text/text-form.component.d.ts +0 -66
  616. package/src/app/shared/material/text/text-form.module.d.ts +0 -16
  617. package/src/app/shared/modules.d.ts +0 -9
  618. package/src/app/shared/named-filter/named-filter-selector.component.d.ts +0 -60
  619. package/src/app/shared/named-filter/named-filter.model.d.ts +0 -32
  620. package/src/app/shared/named-filter/named-filter.module.d.ts +0 -13
  621. package/src/app/shared/named-filter/named-filter.service.d.ts +0 -32
  622. package/src/app/shared/named-filter/testing/named-filter-selector.testing.d.ts +0 -34
  623. package/src/app/shared/named-filter/testing/named-filter.testing.module.d.ts +0 -10
  624. package/src/app/shared/observables.d.ts +0 -30
  625. package/src/app/shared/pipes/arrays.pipe.d.ts +0 -59
  626. package/src/app/shared/pipes/badge.pipes.d.ts +0 -7
  627. package/src/app/shared/pipes/colors.pipe.d.ts +0 -9
  628. package/src/app/shared/pipes/date-diff-duration.pipe.d.ts +0 -23
  629. package/src/app/shared/pipes/date-format.pipe.d.ts +0 -35
  630. package/src/app/shared/pipes/date-from-now.pipe.d.ts +0 -12
  631. package/src/app/shared/pipes/duration.pipe.d.ts +0 -13
  632. package/src/app/shared/pipes/file-size.pipe.d.ts +0 -30
  633. package/src/app/shared/pipes/form.pipes.d.ts +0 -69
  634. package/src/app/shared/pipes/highlight.pipe.d.ts +0 -11
  635. package/src/app/shared/pipes/html.pipes.d.ts +0 -15
  636. package/src/app/shared/pipes/latlong-format.pipe.d.ts +0 -20
  637. package/src/app/shared/pipes/maps.pipe.d.ts +0 -22
  638. package/src/app/shared/pipes/maskito.pipe.d.ts +0 -14
  639. package/src/app/shared/pipes/math.pipes.d.ts +0 -20
  640. package/src/app/shared/pipes/ng-init.pipe.d.ts +0 -8
  641. package/src/app/shared/pipes/number-format.pipe.d.ts +0 -10
  642. package/src/app/shared/pipes/pipes.module.d.ts +0 -31
  643. package/src/app/shared/pipes/property.pipes.d.ts +0 -47
  644. package/src/app/shared/pipes/selection.pipes.d.ts +0 -62
  645. package/src/app/shared/pipes/string.pipes.d.ts +0 -53
  646. package/src/app/shared/pipes/translate-context.pipe.d.ts +0 -17
  647. package/src/app/shared/pipes/types.pipes.d.ts +0 -30
  648. package/src/app/shared/platforms.d.ts +0 -8
  649. package/src/app/shared/rx-state.module.d.ts +0 -10
  650. package/src/app/shared/services/entity-service.class.d.ts +0 -71
  651. package/src/app/shared/services/job.utils.d.ts +0 -20
  652. package/src/app/shared/services/memory-entity-service.class.d.ts +0 -78
  653. package/src/app/shared/services/progress-bar.service.d.ts +0 -20
  654. package/src/app/shared/services/startable-observable-service.class.d.ts +0 -36
  655. package/src/app/shared/services/startable-service.class.d.ts +0 -37
  656. package/src/app/shared/services/translate-context.service.d.ts +0 -29
  657. package/src/app/shared/services/validator-service.class.d.ts +0 -11
  658. package/src/app/shared/services.d.ts +0 -10
  659. package/src/app/shared/shared-routing.module.d.ts +0 -23
  660. package/src/app/shared/shared.module.d.ts +0 -34
  661. package/src/app/shared/shared.testing.module.d.ts +0 -19
  662. package/src/app/shared/storage/storage-explorer.component.d.ts +0 -59
  663. package/src/app/shared/storage/storage-explorer.module.d.ts +0 -13
  664. package/src/app/shared/storage/storage-explorer.testing-routing.module.d.ts +0 -9
  665. package/src/app/shared/storage/storage-explorer.testing.module.d.ts +0 -10
  666. package/src/app/shared/storage/storage.service.d.ts +0 -22
  667. package/src/app/shared/storage/storage.utils.d.ts +0 -19
  668. package/src/app/shared/testing/maskito.test.d.ts +0 -10
  669. package/src/app/shared/testing/observable.test.d.ts +0 -25
  670. package/src/app/shared/testing/tests.page.d.ts +0 -20
  671. package/src/app/shared/toast/toast.testing.d.ts +0 -15
  672. package/src/app/shared/toast/toast.testing.module.d.ts +0 -11
  673. package/src/app/shared/toast/toasts.d.ts +0 -17
  674. package/src/app/shared/toolbar/modal-toolbar.d.ts +0 -21
  675. package/src/app/shared/toolbar/toolbar.d.ts +0 -68
  676. package/src/app/shared/toolbar/toolbar.module.d.ts +0 -16
  677. package/src/app/shared/types.d.ts +0 -31
  678. package/src/app/shared/upload-file/testing/upload-file.testing.d.ts +0 -21
  679. package/src/app/shared/upload-file/testing/upload-file.testing.module.d.ts +0 -11
  680. package/src/app/shared/upload-file/upload-file-popover.component.d.ts +0 -39
  681. package/src/app/shared/upload-file/upload-file.component.d.ts +0 -49
  682. package/src/app/shared/upload-file/upload-file.model.d.ts +0 -30
  683. package/src/app/shared/validator/form-error-adapter.class.d.ts +0 -33
  684. package/src/app/shared/validator/validators.d.ts +0 -130
  685. package/src/app/shared/version/versions.d.ts +0 -26
  686. package/src/app/social/job/job.module.d.ts +0 -12
  687. package/src/app/social/job/progression/job-progression.component.d.ts +0 -23
  688. package/src/app/social/job/progression/job-progression.icon.d.ts +0 -62
  689. package/src/app/social/job/progression/job-progression.list.d.ts +0 -19
  690. package/src/app/social/job/progression/job-progression.model.d.ts +0 -10
  691. package/src/app/social/job/progression/job-progression.service.d.ts +0 -33
  692. package/src/app/social/job/testing/job-progression.testing.d.ts +0 -13
  693. package/src/app/social/job/testing/job-progression.testing.service.d.ts +0 -9
  694. package/src/app/social/job/testing/job.testing.module.d.ts +0 -11
  695. package/src/app/social/message/message.form.d.ts +0 -36
  696. package/src/app/social/message/message.modal.d.ts +0 -43
  697. package/src/app/social/message/message.model.d.ts +0 -33
  698. package/src/app/social/message/message.module.d.ts +0 -12
  699. package/src/app/social/message/message.service.d.ts +0 -32
  700. package/src/app/social/social.errors.d.ts +0 -9
  701. package/src/app/social/social.module.d.ts +0 -20
  702. package/src/app/social/social.testing.module.d.ts +0 -13
  703. package/src/app/social/user-event/notification/user-event-notification.icon.d.ts +0 -32
  704. package/src/app/social/user-event/notification/user-event-notification.list.d.ts +0 -71
  705. package/src/app/social/user-event/testing/user-event.testing.d.ts +0 -35
  706. package/src/app/social/user-event/testing/user-event.testing.model.d.ts +0 -42
  707. package/src/app/social/user-event/testing/user-event.testing.module.d.ts +0 -11
  708. package/src/app/social/user-event/testing/user-event.testing.service.d.ts +0 -42
  709. package/src/app/social/user-event/user-event.model.d.ts +0 -44
  710. package/src/app/social/user-event/user-event.module.d.ts +0 -13
  711. package/src/app/social/user-event/user-event.service.d.ts +0 -129
  712. package/src/environments/environment.class.d.ts +0 -68
  713. package/src/environments/environment.d.ts +0 -2
  714. package/src/environments/environment.loader.d.ts +0 -24
  715. package/src/theme/_globals.scss +0 -5
@@ -1,1346 +0,0 @@
1
- import { Inject, Injectable, InjectionToken, Optional } from '@angular/core';
2
- import { CryptoService } from './crypto.service';
3
- import { Account, AccountUtils, UserSettings } from './model/account.model';
4
- import { PersonUtils } from './model/person.model';
5
- import { BehaviorSubject, from, Subject, Subscription } from 'rxjs';
6
- import { gql } from '@apollo/client/core';
7
- import { isEmptyArray, isNil, sleep, toNumber } from '../../shared/functions';
8
- import { BaseGraphqlService } from './base-graphql-service.class';
9
- import { ErrorCodes, ServerErrorCodes } from './errors';
10
- import { MINIFY_ENTITY_FOR_POD, ReferentialUtils } from './model/referential.model';
11
- import { StatusIds } from './model/model.enum';
12
- import { Base58 } from './base58';
13
- import { ENVIRONMENT } from '../../../environments/environment.class';
14
- import { fromDateISOString } from '../../shared/dates';
15
- import { firstNotNilPromise } from '../../shared/observables';
16
- import { debounceTime, filter, map, switchMap } from 'rxjs/operators';
17
- import { Toasts } from '../../shared/toast/toasts';
18
- import { UserToken } from './model/token.model';
19
- import * as i0 from "@angular/core";
20
- import * as i1 from "./network.service";
21
- import * as i2 from "../graphql/graphql.service";
22
- import * as i3 from "./local-settings.service";
23
- import * as i4 from "@ionic/storage-angular";
24
- import * as i5 from "../../shared/file/file.service";
25
- import * as i6 from "@ngx-translate/core";
26
- import * as i7 from "@ionic/angular";
27
- import * as i8 from "../../../environments/environment.class";
28
- const TOKEN_STORAGE_KEY = 'token';
29
- const PUBKEY_STORAGE_KEY = 'pubkey';
30
- const SECKEY_STORAGE_KEY = 'seckey';
31
- const ACCOUNT_STORAGE_KEY = 'account';
32
- const DEFAULT_AVATAR_IMAGE = 'assets/img/person.png';
33
- export const APP_USER_SETTINGS_OPTIONS = new InjectionToken('UserSettingsOptions');
34
- export const APP_USER_TOKEN_SCOPES = new InjectionToken('UserTokenScopes');
35
- /* ------------------------------------
36
- * GraphQL queries
37
- * ------------------------------------*/
38
- const Fragments = {
39
- account: gql `
40
- fragment AccountFragment on AccountVO {
41
- id
42
- firstName
43
- lastName
44
- email
45
- pubkey
46
- avatar
47
- statusId
48
- updateDate
49
- creationDate
50
- profiles
51
- settings {
52
- ...UserSettingsFragment
53
- }
54
- department {
55
- id
56
- label
57
- name
58
- __typename
59
- }
60
- __typename
61
- }
62
- `,
63
- settings: gql `
64
- fragment UserSettingsFragment on UserSettingsVO {
65
- id
66
- locale
67
- latLongFormat
68
- content
69
- nonce
70
- updateDate
71
- __typename
72
- }
73
- `,
74
- token: gql `
75
- fragment UserTokenFragment on UserTokenVO {
76
- id
77
- pubkey
78
- name
79
- flags
80
- expirationDate
81
- lastUsedDate
82
- creationDate
83
- updateDate
84
- __typename
85
- }
86
- `,
87
- };
88
- // Account queries
89
- const Queries = {
90
- load: gql `
91
- query Account {
92
- data: account {
93
- ...AccountFragment
94
- }
95
- }
96
- ${Fragments.account}
97
- ${Fragments.settings}
98
- `,
99
- loadWithTokens: gql `
100
- query AccountWithToken {
101
- data: account {
102
- ...AccountFragment
103
- tokens {
104
- ...UserTokenFragment
105
- }
106
- }
107
- }
108
- ${Fragments.account}
109
- ${Fragments.settings}
110
- ${Fragments.token}
111
- `,
112
- };
113
- // Check email query
114
- const IsEmailExistsQuery = gql `
115
- query IsEmailExists($email: String, $hash: String) {
116
- isEmailExists(email: $email, hash: $hash)
117
- }
118
- `;
119
- // Account mutations
120
- const Mutations = {
121
- save: gql `
122
- mutation SaveAccount($data: AccountVOInput) {
123
- data: saveAccount(account: $data) {
124
- ...AccountFragment
125
- }
126
- }
127
- ${Fragments.account}
128
- ${Fragments.settings}
129
- `,
130
- saveWithTokens: gql `
131
- mutation SaveAccountWithTokens($data: AccountVOInput) {
132
- data: saveAccount(account: $data) {
133
- ...AccountFragment
134
- tokens {
135
- ...UserTokenFragment
136
- }
137
- }
138
- }
139
- ${Fragments.account}
140
- ${Fragments.settings}
141
- ${Fragments.token}
142
- `,
143
- create: gql `
144
- mutation CreateAccount($data: AccountVOInput) {
145
- data: createAccount(account: $data) {
146
- ...AccountFragment
147
- }
148
- }
149
- ${Fragments.account}
150
- ${Fragments.settings}
151
- `,
152
- saveSettings: gql `
153
- mutation SaveSettings($data: UserSettingsVOInput) {
154
- data: saveSettings(settings: $data) {
155
- ...UserSettingsFragment
156
- }
157
- }
158
- ${Fragments.settings}
159
- `,
160
- };
161
- // Sent confirmation email
162
- const SendConfirmEmailQuery = gql `
163
- query sendAccountConfirmationEmail($email: String, $locale: String) {
164
- data: sendAccountConfirmationEmail(email: $email, locale: $locale)
165
- }
166
- `;
167
- // Confirm account email
168
- const ConfirmEmailQuery = gql `
169
- query confirmAccountEmail($email: String, $code: String) {
170
- data: confirmAccountEmail(email: $email, code: $code)
171
- }
172
- `;
173
- // Send email to reset password
174
- const SendResetPasswordEmailQuery = gql `
175
- query SendResetPasswordEmail($username: String!, $locale: String!) {
176
- sendResetPasswordEmail(username: $username, locale: $locale)
177
- }
178
- `;
179
- const ResetAccountPubkeyQuery = gql `
180
- query ResetPubkey($username: String!, $token: String!) {
181
- data: resetAccountPubkey(username: $username, token: $token)
182
- }
183
- `;
184
- const UpdatePubKeyQuery = gql `
185
- query UpdateAccountPubkey($pubkey: String!) {
186
- data: updateAccountPubkey(pubkey: $pubkey)
187
- }
188
- `;
189
- // Authentication query
190
- const AuthQuery = gql `
191
- query Auth($token: String) {
192
- authenticate(token: $token)
193
- }
194
- `;
195
- // New auth challenge query
196
- const AuthChallengeQuery = gql `
197
- query AuthChallenge {
198
- authChallenge {
199
- challenge
200
- pubkey
201
- signature
202
- }
203
- }
204
- `;
205
- const AccountSubscriptions = {
206
- listenChanges: gql `
207
- subscription updateAccount($interval: Int) {
208
- data: updateAccount(interval: $interval) {
209
- id
210
- updateDate
211
- }
212
- }
213
- `,
214
- };
215
- export class AccountService extends BaseGraphqlService {
216
- network;
217
- graphql;
218
- settings;
219
- storage;
220
- file;
221
- translate;
222
- toastController;
223
- environment;
224
- onLogin = new Subject();
225
- onWillLogout = new Subject();
226
- onLogout = new Subject();
227
- onChange = new Subject();
228
- onAuthTokenChange = new BehaviorSubject(undefined);
229
- onAuthBasicChange = new BehaviorSubject(undefined);
230
- _listenChangesSubscription = null;
231
- _enableListenChanges;
232
- _listenIntervalInSeconds;
233
- _cache = {
234
- loaded: false,
235
- keypair: null,
236
- authToken: null,
237
- authBasic: null,
238
- pubkey: null,
239
- mainProfile: null,
240
- person: null,
241
- department: null,
242
- };
243
- _optionDefs;
244
- _$additionalFields = new BehaviorSubject([]);
245
- _tokenType$ = new BehaviorSubject(undefined);
246
- _apiTokenEnabled = true;
247
- get account() {
248
- return this._cache.loaded ? this._data : undefined;
249
- }
250
- get person() {
251
- if (this._cache.loaded && !this._cache.person) {
252
- this._cache.person = this._cache.loaded ? this._data.asPerson() : undefined;
253
- }
254
- return this._cache.person;
255
- }
256
- get department() {
257
- if (this._cache.loaded && !this._cache.department) {
258
- this._cache.department = this._cache.loaded ? this._data.asPerson().department : undefined;
259
- }
260
- return this._cache.department;
261
- }
262
- get tokenType() {
263
- return this._tokenType$.value;
264
- }
265
- set tokenType(value) {
266
- if (this._tokenType$.value !== value) {
267
- console.info('[account] Using authentication token type: ' + value);
268
- this._tokenType$.next(value);
269
- // Reset values
270
- this._cache.authToken = undefined;
271
- this.onAuthTokenChange.next(undefined);
272
- this._cache.authBasic = undefined;
273
- this.onAuthBasicChange.next(undefined);
274
- }
275
- }
276
- get apiTokenEnabled() {
277
- return this._apiTokenEnabled;
278
- }
279
- set apiTokenEnabled(value) {
280
- this._apiTokenEnabled = value;
281
- }
282
- constructor(network, graphql, settings, storage, file, translate, toastController, environment, options) {
283
- super(graphql, environment);
284
- this.network = network;
285
- this.graphql = graphql;
286
- this.settings = settings;
287
- this.storage = storage;
288
- this.file = file;
289
- this.translate = translate;
290
- this.toastController = toastController;
291
- this.environment = environment;
292
- this._enableListenChanges = !environment.account || environment.account.enableListenChanges !== false; // True by default
293
- this._listenIntervalInSeconds = toNumber(environment.account && environment.account.listenIntervalInSeconds, 0); // no timer by default
294
- this._debug = !environment.production;
295
- if (this._debug)
296
- console.debug('[account-service] Creating service');
297
- this._optionDefs = Object.values(options?.options || {});
298
- this.resetData();
299
- // Send auth token to the graphql layer, when changed
300
- this.onAuthTokenChange.subscribe((token) => this.graphql.setAuthToken(token));
301
- this.onAuthBasicChange.subscribe((basic) => this.graphql.setAuthBasic(basic));
302
- // Force network to wait account service, after getting connection to the peer
303
- this.registerSubscription(this.network.on('beforeTryOnlineFinish', async (online) => {
304
- // If online, wait a full restart, because it can force offline mode
305
- if (online && (!this.started || this.isLogin())) {
306
- console.debug('[account] Force networkService.tryOnline() to wait, that graphql and account service is restarted...');
307
- await sleep(500); // wait graphql service to be restarted
308
- if (!this.started)
309
- await this.ready();
310
- }
311
- }));
312
- }
313
- async ngOnStart() {
314
- await Promise.all([
315
- this.settings.ready(),
316
- // Wait token type to be set
317
- firstNotNilPromise(this._tokenType$),
318
- ]);
319
- // Listen graphql start (or restart)
320
- this.registerSubscription(this.graphql.stopSubject.subscribe(() => {
321
- if (this.started && this.isLogin()) {
322
- console.debug('[account] Restarting, to retry to authenticate...');
323
- this.restart();
324
- }
325
- }));
326
- await this.restoreLocally();
327
- await this.listenSettings();
328
- return this._data;
329
- }
330
- async ngOnStop() {
331
- const hadAuthToken = this._cache.authToken && true;
332
- const hadAuthBasic = this._cache.authBasic && true;
333
- const hadAuth = hadAuthToken || hadAuthBasic;
334
- this.resetData();
335
- if (hadAuth) {
336
- this.onLogout.next();
337
- this.onChange.next(undefined);
338
- if (hadAuthToken)
339
- this.onAuthTokenChange.next(undefined);
340
- if (hadAuthBasic)
341
- this.onAuthBasicChange.next(undefined);
342
- }
343
- }
344
- isLogin() {
345
- return !!(this._cache.pubkey && this._cache.loaded);
346
- }
347
- isAuth() {
348
- return !!(this._cache.pubkey && this._cache.keypair && this._cache.keypair.secretKey);
349
- }
350
- hasMinProfile(userProfile) {
351
- // should be login, and status ENABLE or TEMPORARY
352
- if (!this._data || !this._data.pubkey || (this._data.statusId !== StatusIds.ENABLE && this._data.statusId !== StatusIds.TEMPORARY)) {
353
- return false;
354
- }
355
- return PersonUtils.hasUpperOrEqualsProfile(this._data.profiles, userProfile);
356
- }
357
- hasExactProfile(label) {
358
- return AccountUtils.hasExactProfile(this._data, label);
359
- }
360
- hasProfileAndIsEnable(userProfile) {
361
- return AccountUtils.hasProfileAndIsEnable(this._data, userProfile);
362
- }
363
- isAdmin() {
364
- return this.hasProfileAndIsEnable('ADMIN');
365
- }
366
- isSupervisor() {
367
- return this.hasProfileAndIsEnable('SUPERVISOR');
368
- }
369
- isUser() {
370
- return this.hasProfileAndIsEnable('USER');
371
- }
372
- /**
373
- * @deprecated
374
- * @param mode
375
- */
376
- isUsageMode(mode) {
377
- return this.settings.isUsageMode(mode);
378
- }
379
- isOnlyGuest() {
380
- // Should be login, and status ENABLE or TEMPORARY
381
- if (!this._data || !this._data.pubkey || (this._data.statusId !== StatusIds.ENABLE && this._data.statusId !== StatusIds.TEMPORARY))
382
- return false;
383
- // Profile less then user
384
- return !PersonUtils.hasUpperOrEqualsProfile(this._data.profiles, 'USER');
385
- }
386
- /**
387
- *
388
- * @param recorderDepartment
389
- * @deprecated use ProgramRefService.canUserWriteEntity() instead
390
- */
391
- canUserWriteDataForDepartment(recorderDepartment) {
392
- if (ReferentialUtils.isEmpty(recorderDepartment)) {
393
- return this.isAdmin();
394
- }
395
- // Should be login, and status ENABLE
396
- if (!this._data || !this._data.pubkey || this._data.statusId !== StatusIds.ENABLE)
397
- return false;
398
- if (!this._data.department || !this._data.department.id) {
399
- console.warn('User account has no department ! Unable to check write right against recorderDepartment');
400
- return false;
401
- }
402
- // Same recorder department: OK, user can write
403
- if (this._data.department.id === recorderDepartment.id)
404
- return true;
405
- // Cannot write
406
- return false;
407
- }
408
- async register(data) {
409
- if (this.isLogin()) {
410
- throw new Error('User already login. Please logout before register.');
411
- }
412
- if (!data.username || !data.password)
413
- throw new Error('Missing required username or password');
414
- if (this._debug)
415
- console.debug('[account] Register new user account...', data.account);
416
- this._cache.loaded = false;
417
- const now = Date.now();
418
- try {
419
- const keypair = await CryptoService.scryptKeypair(data.username, data.password);
420
- data.account.pubkey = Base58.encode(keypair.publicKey);
421
- // Default values
422
- data.account.settings = data.account.settings || new UserSettings();
423
- data.account.settings.locale = this.settings.locale;
424
- data.account.settings.latLongFormat = this.settings.latLongFormat;
425
- data.account.settings.content = data.account.settings.content || {};
426
- data.account.department.id = data.account.department.id || this.environment.defaultDepartmentId;
427
- this._cache.keypair = keypair;
428
- const account = await this.saveRemotely(data.account, keypair);
429
- // Default values
430
- account.avatar = account.avatar || this.environment.baseUrl + DEFAULT_AVATAR_IMAGE;
431
- this._cache.mainProfile = PersonUtils.getMainProfile(account.profiles);
432
- this._data = account;
433
- this._cache.pubkey = account.pubkey;
434
- // Try to auth on pod
435
- await this.authenticate(data);
436
- this._cache.loaded = true;
437
- await this.saveLocally();
438
- console.debug(`[account] Account successfully registered in ${Date.now() - now}ms`);
439
- // Emit events
440
- this.onLogin.next(this._data);
441
- this.onChange.next(this._data);
442
- // Listen remote changes
443
- if (this._enableListenChanges)
444
- this.startListenRemoteChanges();
445
- return this._data;
446
- }
447
- catch (error) {
448
- console.error((error && error.message) || error);
449
- this.resetData();
450
- throw error;
451
- }
452
- }
453
- async authenticate(data) {
454
- // Wait the auth token, then continue
455
- const tokenType = await firstNotNilPromise(this._tokenType$);
456
- // Basic auth
457
- if (tokenType === 'basic' || tokenType === 'basic-and-token') {
458
- // Generate the authBasic, if used
459
- if (!this._cache.authBasic) {
460
- // Skip if token already provided
461
- if (!(this._cache.authToken && tokenType === 'basic-and-token')) {
462
- if (!data || !data.username || !data.password)
463
- throw new Error('Missing username and password');
464
- this._cache.authBasic = CryptoService.encodeBase64(`${data.username}:${data.password}`);
465
- }
466
- }
467
- this.onAuthBasicChange.next(this._cache.authBasic);
468
- }
469
- // Generate the authToken, if used
470
- if (tokenType === 'token' || tokenType === 'basic-and-token') {
471
- try {
472
- this._cache.authToken = await this.authenticateAndGetToken(this._cache.authToken);
473
- }
474
- catch (error) {
475
- // Never authenticate, or not ready for offline mode => exit
476
- console.error(error);
477
- this.resetData();
478
- throw error;
479
- }
480
- }
481
- // Forget authBasic, to switch to authToken
482
- if (tokenType === 'basic-and-token') {
483
- this._cache.authBasic = undefined;
484
- this.onAuthBasicChange.next(undefined);
485
- }
486
- }
487
- async login(data) {
488
- if (!data || !data.username || !data.password)
489
- throw new Error('Missing required username or password');
490
- console.debug('[account] Login...');
491
- let keypair;
492
- try {
493
- keypair = await CryptoService.scryptKeypair(data.username, data.password);
494
- }
495
- catch (error) {
496
- console.error(error);
497
- this.resetData();
498
- throw { code: ErrorCodes.UNKNOWN_ERROR, message: 'ERROR.SCRYPT_ERROR' };
499
- }
500
- // Store pubkey+keypair
501
- this._cache.pubkey = Base58.encode(keypair.publicKey);
502
- this._cache.keypair = keypair;
503
- // Try to load previous token
504
- let previousToken = await this.storage.get(TOKEN_STORAGE_KEY);
505
- previousToken = (previousToken && previousToken.startsWith(this._cache.pubkey) && previousToken) || null;
506
- // Offline mode
507
- const offline = this.settings.hasOfflineFeature() && (this.network.offline || data.offline === true);
508
- if (offline) {
509
- this._cache.authToken = previousToken;
510
- // Make sure network if set as offline
511
- this.network.setForceOffline(true, { showToast: false });
512
- console.info(`[account] Login [OK] {pubkey: ${this._cache.pubkey.substr(0, 8)}}, {offline: true}`);
513
- }
514
- // Online mode: try to auth on pod
515
- else {
516
- try {
517
- await this.authenticate(data);
518
- }
519
- catch (error) {
520
- // Never authenticate, or not ready for offline mode => exit
521
- console.error(error);
522
- this.resetData();
523
- throw error;
524
- }
525
- }
526
- // Load account data
527
- try {
528
- await this.loadData({ offline, fetchPolicy: 'network-only' });
529
- }
530
- catch (err) {
531
- // If account not found, check if email is valid
532
- if (err && +err.code === ErrorCodes.LOAD_ACCOUNT_ERROR) {
533
- // Check email exists
534
- if (data.username.indexOf('@') !== -1) {
535
- let isEmailExists;
536
- try {
537
- isEmailExists = await this.isEmailExists(data.username);
538
- }
539
- catch (otherError) {
540
- throw err; // resend the first error
541
- }
542
- // Email not exists (no account)
543
- if (!isEmailExists) {
544
- throw { code: ErrorCodes.UNKNOWN_ACCOUNT_EMAIL, message: 'ERROR.UNKNOWN_ACCOUNT_EMAIL' };
545
- }
546
- }
547
- // Email exists, so error = 'bad password'
548
- throw { code: ErrorCodes.BAD_PASSWORD, message: 'ERROR.BAD_PASSWORD' };
549
- }
550
- throw err; // resend the first error
551
- }
552
- try {
553
- // Store to local storage
554
- await this.saveLocally();
555
- }
556
- catch (error) {
557
- console.error(error);
558
- this.resetData();
559
- throw error;
560
- }
561
- // Emit event to observers
562
- this.onLogin.next(this._data);
563
- this.onChange.next(this._data);
564
- if (this._enableListenChanges)
565
- this.startListenRemoteChanges();
566
- return this._data;
567
- }
568
- async reload(opts) {
569
- if (!this._cache.pubkey)
570
- throw new Error('User not logged');
571
- if (this.network.offline)
572
- throw new Error('Cannot check account in offline mode');
573
- const now = Date.now();
574
- console.debug(`[account] Reloading account...`);
575
- const wasLogin = this.isLogin();
576
- try {
577
- await this.loadData();
578
- await this.saveLocally();
579
- console.debug(`[account] Reloading account [OK] in ${Date.now() - now}ms`);
580
- // Emit login event to subscribers
581
- this.onLogin.next(this._data);
582
- this.onChange.next(this._data);
583
- // Display toast (without await, because not need to wait toast close event)
584
- if (!opts || opts.showToast !== false) {
585
- this.showToast({ message: 'ACCOUNT.INFO.RELOADED', type: 'info' });
586
- }
587
- return this._data;
588
- }
589
- catch (error) {
590
- // Cannot reload but was login: force to logout
591
- if (wasLogin && !this.isLogin()) {
592
- console.error(`[account] Reloading account failed. Will force logout...`, error);
593
- await this.logout();
594
- }
595
- else {
596
- throw error;
597
- }
598
- }
599
- }
600
- /**
601
- * Create or update an user account, to the remote storage
602
- *
603
- * @param account
604
- */
605
- async save(account) {
606
- if (!this._cache.pubkey)
607
- return Promise.reject('User not logged');
608
- if (this._cache.pubkey !== account.pubkey)
609
- return Promise.reject('Not user account');
610
- account = await this.saveRemotely(account, this._cache.keypair);
611
- // Set defaults
612
- account.avatar = account.avatar || this.environment.baseUrl + DEFAULT_AVATAR_IMAGE;
613
- this._cache.mainProfile = PersonUtils.getMainProfile(account.profiles);
614
- this._data = account;
615
- // Update cache
616
- this._cache.person = account.asPerson();
617
- this._cache.department = this._cache.person.department;
618
- this._cache.loaded = true;
619
- // Save locally (in storage)
620
- await this.saveLocally();
621
- // Send event
622
- this.onLogin.next(this._data);
623
- this.onChange.next(this._data);
624
- return this._data;
625
- }
626
- async logout() {
627
- const hadAuthToken = this._cache.authToken && true;
628
- const hadAuthBasic = this._cache.authBasic && true;
629
- const pubkey = this._cache && this._cache.pubkey;
630
- // Notify observers
631
- this.onWillLogout.next(this.account);
632
- this.resetData();
633
- if (!this.settings.hasOfflineFeature()) {
634
- // Remove all data from the local storage
635
- await Promise.all([
636
- this.storage.remove(PUBKEY_STORAGE_KEY),
637
- this.storage.remove(TOKEN_STORAGE_KEY),
638
- this.storage.remove(ACCOUNT_STORAGE_KEY),
639
- (pubkey && this.storage.remove(ACCOUNT_STORAGE_KEY + '#' + pubkey)) || Promise.resolve(),
640
- this.storage.remove(SECKEY_STORAGE_KEY),
641
- ]);
642
- }
643
- // Offline features enable: need to keep some data
644
- else {
645
- // Always remove only secret key
646
- // But keep:
647
- // - account by pubkey
648
- // - auth token
649
- await Promise.all([this.storage.remove(PUBKEY_STORAGE_KEY), this.storage.remove(ACCOUNT_STORAGE_KEY), this.storage.remove(SECKEY_STORAGE_KEY)]);
650
- }
651
- // Clean page history, in local settings
652
- await this.settings.clearPageHistory();
653
- // Notify observers
654
- this.onLogout.next();
655
- if (hadAuthToken)
656
- this.onAuthTokenChange.next(undefined);
657
- if (hadAuthBasic)
658
- this.onAuthBasicChange.next(undefined);
659
- this.onChange.next(undefined);
660
- }
661
- /**
662
- * Load a account
663
- *
664
- * @param opts
665
- */
666
- async load(opts) {
667
- const now = this._debug && Date.now();
668
- if (this._debug)
669
- console.debug(`[account] Loading account...`);
670
- let json;
671
- // Load locally
672
- const offline = (this.network.offline && (!opts || (opts.fetchPolicy !== 'network-only' && opts.fetchPolicy !== 'no-cache'))) ||
673
- (opts && opts.offline === true);
674
- if (offline) {
675
- json = await this.storage.get(ACCOUNT_STORAGE_KEY);
676
- json = (json && typeof json === 'string' && JSON.parse(json)) || json;
677
- json = (json && this._cache.pubkey && json.pubkey === this._cache.pubkey && json) || null;
678
- if (!json && this._cache.pubkey) {
679
- json = await this.storage.get(ACCOUNT_STORAGE_KEY + '#' + this._cache.pubkey);
680
- json = (json && typeof json === 'string' && JSON.parse(json)) || json;
681
- }
682
- }
683
- // Load remotely
684
- else {
685
- const query = opts?.query || (this.apiTokenEnabled ? Queries.loadWithTokens : Queries.load);
686
- const { data } = await this.graphql.query({
687
- query,
688
- error: { code: ErrorCodes.LOAD_ACCOUNT_ERROR, message: 'ERROR.LOAD_ACCOUNT_ERROR' },
689
- fetchPolicy: (opts && opts.fetchPolicy) || 'no-cache' || undefined,
690
- });
691
- json = data;
692
- }
693
- if (json) {
694
- const account = Account.fromObject(json);
695
- if (this._debug)
696
- console.debug(`[account] Account loaded in ${Date.now() - now}ms`, account);
697
- return account;
698
- }
699
- else {
700
- console.warn(`[account] Account not found !`);
701
- return undefined;
702
- }
703
- }
704
- async generateToken(flags) {
705
- const now = this._debug && Date.now();
706
- if (this._debug)
707
- console.debug(`[account] Generate token...`);
708
- const authChallenge = await this.getAuthChallenge();
709
- // Add Flags to challenge
710
- const challenge = `${authChallenge.challenge}:${flags}`;
711
- const signature = await CryptoService.sign(challenge, this._cache.keypair);
712
- const newToken = `${this._cache.pubkey}:${challenge}|${signature}`;
713
- if (newToken) {
714
- if (this._debug)
715
- console.debug(`[account] Token generated in ${Date.now() - now}ms`);
716
- }
717
- else {
718
- console.warn(`[account] Token generation failed !`);
719
- }
720
- return newToken;
721
- }
722
- /**
723
- * Check if email is available for new account registration.
724
- * Throw an error if not available
725
- *
726
- * @param email
727
- */
728
- async checkEmailAvailable(email) {
729
- const isEmailExists = await this.isEmailExists(email);
730
- if (isEmailExists) {
731
- throw { code: ErrorCodes.EMAIL_ALREADY_REGISTERED, message: 'ERROR.EMAIL_ALREADY_REGISTERED' };
732
- }
733
- }
734
- /**
735
- * Check if email is exists in server.
736
- *
737
- * @param email
738
- */
739
- async isEmailExists(email) {
740
- if (this._debug)
741
- console.debug('[account] Checking if {' + email + '} exists...');
742
- const data = await this.graphql.query({
743
- query: IsEmailExistsQuery,
744
- variables: {
745
- email,
746
- hash: undefined,
747
- },
748
- });
749
- if (this._debug)
750
- console.debug('[account] Email exist: ' + (data && data.isEmailExists));
751
- return data && data.isEmailExists;
752
- }
753
- async sendConfirmationEmail(email, locale) {
754
- locale = locale || this.settings.locale;
755
- console.debug('[account] Sending confirmation email to {' + email + '} with locale {' + locale + '}...');
756
- const { data } = await this.graphql.query({
757
- query: SendConfirmEmailQuery,
758
- variables: {
759
- email,
760
- locale,
761
- },
762
- error: {
763
- code: ErrorCodes.SENT_CONFIRMATION_EMAIL_FAILED,
764
- message: 'ERROR.SENT_ACCOUNT_CONFIRMATION_EMAIL_FAILED',
765
- },
766
- });
767
- return data;
768
- }
769
- async confirmEmail(email, code) {
770
- console.debug('[account] Sending confirm request for email {' + email + '} with code {' + code + '}...');
771
- const { data } = await this.graphql.query({
772
- query: ConfirmEmailQuery,
773
- variables: {
774
- email,
775
- code,
776
- },
777
- error: {
778
- code: ErrorCodes.CONFIRM_EMAIL_FAILED,
779
- message: 'ERROR.CONFIRM_ACCOUNT_EMAIL_FAILED',
780
- },
781
- });
782
- return data;
783
- }
784
- async sendResetPasswordEmail(username, locale) {
785
- locale = locale || this.settings.locale;
786
- console.debug(`[account] Sending change password email to {${username}} with locale {${locale}}...`);
787
- const { data: isOk } = await this.graphql.query({
788
- query: SendResetPasswordEmailQuery,
789
- variables: {
790
- username,
791
- locale,
792
- },
793
- error: {
794
- code: ErrorCodes.AUTH_UPDATE_PUBKEY_ERROR,
795
- message: 'ACCOUNT.ERROR.CHANGE_PUBKEY_ERROR',
796
- },
797
- fetchPolicy: 'no-cache',
798
- });
799
- return isOk;
800
- }
801
- async updatePubkey(data) {
802
- if (!data.username || !data.password)
803
- throw new Error('Missing required username or password');
804
- if (!this.isLogin())
805
- throw new Error('Should be login');
806
- const keypair = await CryptoService.scryptKeypair(data.username, data.password);
807
- const pubkey = Base58.encode(keypair.publicKey);
808
- console.debug(`[account] Updating account pubkey to ${pubkey} ...`);
809
- const { data: res } = await this.graphql.query({
810
- query: UpdatePubKeyQuery,
811
- variables: { pubkey },
812
- error: {
813
- code: ErrorCodes.AUTH_UPDATE_PUBKEY_ERROR,
814
- message: 'ERROR.ACCOUNT.UPDATE_PUBKEY_ERROR',
815
- },
816
- fetchPolicy: 'no-cache',
817
- });
818
- console.debug(`[account] Updating account pubkey response`, res);
819
- if (res) {
820
- await this.logout();
821
- await this.login(data);
822
- }
823
- return res;
824
- }
825
- async resetPubkey(data, token) {
826
- if (this.isLogin()) {
827
- await this.logout();
828
- }
829
- // Parse challenge
830
- const challenge = token.split('|', 2)[0].split(':', 2)[1];
831
- const keypair = await CryptoService.scryptKeypair(data.username, data.password);
832
- const pubkey = Base58.encode(keypair.publicKey);
833
- const signature = await CryptoService.sign(challenge, keypair);
834
- const newToken = `${pubkey}:${challenge}|${signature}`;
835
- console.debug(`[account] Resetting account pubkey, using token: `, newToken);
836
- const { data: res } = await this.graphql.query({
837
- query: ResetAccountPubkeyQuery,
838
- variables: { token: newToken, username: data.username },
839
- error: {
840
- code: ErrorCodes.AUTH_UPDATE_PUBKEY_ERROR,
841
- message: 'ERROR.ACCOUNT.UPDATE_PUBKEY_ERROR',
842
- },
843
- fetchPolicy: 'no-cache',
844
- });
845
- // Login
846
- if (res) {
847
- await this.login(data);
848
- }
849
- return res;
850
- }
851
- listenChanges(opts) {
852
- if (this._enableListenChanges)
853
- return new Subscription(); // Already started: skip
854
- return this.startListenRemoteChanges(opts);
855
- }
856
- get additionalFields() {
857
- return this._$additionalFields.getValue();
858
- }
859
- get $additionalFields() {
860
- return this._$additionalFields.asObservable();
861
- }
862
- getAdditionalField(key) {
863
- return this._$additionalFields.getValue().find((f) => f.key === key);
864
- }
865
- registerAdditionalField(field) {
866
- const values = this._$additionalFields.getValue();
867
- if (values.some((f) => f.key === field.key)) {
868
- throw new Error(`Additional account field {key: ${field.key}} already define.`);
869
- }
870
- if (this._debug)
871
- console.debug(`[account] Found additional account's field {key: ${field.key}}`);
872
- this._$additionalFields.next(values.concat(field));
873
- }
874
- get optionDefs() {
875
- return this._optionDefs;
876
- }
877
- registerOption(def) {
878
- if (this._optionDefs.findIndex((f) => f.key === def.key) !== -1) {
879
- throw new Error(`Additional option {${def.key}} already define.`);
880
- }
881
- if (this._debug)
882
- console.debug(`[account] Adding additional option {${def.key}}`, def);
883
- this._optionDefs.push(def);
884
- }
885
- registerOptions(defs) {
886
- (defs || []).forEach((def) => this.registerOption(def));
887
- }
888
- /* -- protected method -- */
889
- resetData() {
890
- this.stopListenRemoteChanges();
891
- this._cache.loaded = false;
892
- this._cache.keypair = null;
893
- this._cache.authToken = null;
894
- this._cache.authBasic = null;
895
- this._cache.pubkey = null;
896
- this._cache.mainProfile = null;
897
- this._cache.person = null;
898
- this._cache.department = null;
899
- this._data = new Account();
900
- }
901
- async loadData(opts) {
902
- if (!this._cache.pubkey)
903
- throw new Error('User not logged');
904
- this._cache.loaded = false;
905
- try {
906
- const account = (await this.load(opts)) || new Account();
907
- // Set defaults
908
- account.avatar = account.avatar || this.environment.baseUrl + DEFAULT_AVATAR_IMAGE;
909
- account.settings = account.settings || new UserSettings();
910
- account.settings.locale = account.settings.locale || this.settings.locale;
911
- account.settings.latLongFormat = account.settings.latLongFormat || this.settings.latLongFormat || 'DDMM';
912
- account.settings.content = account.settings.content || {};
913
- // Read main profile
914
- this._cache.mainProfile = PersonUtils.getMainProfile(account.profiles);
915
- // Update, instead of replace it
916
- if (this._data) {
917
- this._data.fromObject(account);
918
- }
919
- else {
920
- this._data = account;
921
- }
922
- this._cache.loaded = true;
923
- // Apply settings, found in remote account
924
- if (account.settings) {
925
- const settings = {
926
- ...this.settings.settings,
927
- ...account.settings.asLocalSettings(),
928
- };
929
- await this.settings.apply(settings);
930
- }
931
- return this._data;
932
- }
933
- catch (error) {
934
- this.resetData();
935
- if (error.code && error.message)
936
- throw error;
937
- console.error(error);
938
- throw {
939
- code: ErrorCodes.LOAD_ACCOUNT_ERROR,
940
- message: 'ERROR.LOAD_ACCOUNT_ERROR',
941
- };
942
- }
943
- }
944
- async listenSettings() {
945
- // When settings changed: save it remotely
946
- this.registerSubscription(this.settings.onChange
947
- .pipe(debounceTime(1000), filter(() => this.isLogin() && this.network.online))
948
- .subscribe((settings) => this.saveLocalSettingsRemotely(settings)));
949
- }
950
- async restoreLocally() {
951
- // Restore from storage
952
- const values = await Promise.all([
953
- this.storage.get(PUBKEY_STORAGE_KEY),
954
- this.storage.get(TOKEN_STORAGE_KEY),
955
- this.storage.get(SECKEY_STORAGE_KEY),
956
- ]);
957
- let pubkey = values[0];
958
- let token = values[1];
959
- const seckey = values[2];
960
- // DEV only - auth by token
961
- if (!this.environment.production && this.environment.defaultAuthValues?.token) {
962
- token = token || this.environment.defaultAuthValues.token;
963
- pubkey = pubkey || token?.split(':', 2)[0];
964
- }
965
- // Quit if no pubkey (not logged)
966
- if (!pubkey)
967
- return;
968
- // Quit if could not auth on pod
969
- const canRemoteAuth = token || seckey || false;
970
- if (!canRemoteAuth)
971
- return;
972
- if (this._debug)
973
- console.debug(`[account] Account restoration...`);
974
- this._cache.authToken = token;
975
- this._cache.pubkey = pubkey;
976
- this._cache.keypair =
977
- (seckey && {
978
- publicKey: Base58.decode(pubkey),
979
- secretKey: Base58.decode(seckey),
980
- }) ||
981
- null;
982
- // Online mode: try to connect to pod
983
- if (this.network.online) {
984
- try {
985
- await this.authenticate();
986
- if (!this._cache.authToken && !this._cache.authBasic)
987
- throw new Error('Authentication failed');
988
- }
989
- catch (error) {
990
- // Offline feature are enable: continue in offline mode
991
- if (this.settings.hasOfflineFeature()) {
992
- console.warn('[account] Unable to authenticate on pod: forcing offline mode');
993
- this.network.setForceOffline(true, { showToast: false });
994
- // Continue
995
- }
996
- // No offline features enable (=offline mode not allowed)
997
- else {
998
- console.error(error);
999
- this.logout();
1000
- return;
1001
- }
1002
- }
1003
- }
1004
- // Get the account, from pubkey
1005
- let jsonAccount = await this.storage.get(`${ACCOUNT_STORAGE_KEY}#${pubkey}`);
1006
- if (!jsonAccount) {
1007
- // Try using the old storage key
1008
- const accountStr = await this.storage.get(ACCOUNT_STORAGE_KEY);
1009
- jsonAccount = accountStr && ((typeof accountStr === 'string' && JSON.parse(jsonAccount)) || accountStr);
1010
- }
1011
- // Invalid account: do not use it
1012
- if (!jsonAccount || jsonAccount.pubkey !== pubkey) {
1013
- // DEV only: create a fake account with given username
1014
- if (!this.environment.production && this.environment.defaultAuthValues.username) {
1015
- const username = this.environment.defaultAuthValues.username;
1016
- jsonAccount = { pubkey, username, firstName: username, lastName: username };
1017
- }
1018
- else {
1019
- return;
1020
- }
1021
- }
1022
- // Transform to entity
1023
- const account = Account.fromObject(jsonAccount);
1024
- // Update data
1025
- this._data = account;
1026
- this._cache.mainProfile = PersonUtils.getMainProfile(account.profiles);
1027
- this._cache.loaded = true;
1028
- // Emit event
1029
- this.onLogin.next(this._data);
1030
- this.onChange.next(this._data);
1031
- if (this._enableListenChanges)
1032
- this.startListenRemoteChanges();
1033
- if (this._debug)
1034
- console.debug(`[account] Account restoration [OK] {pubkey: ${pubkey.substr(0, 8)}}, {profile: ${this._cache.mainProfile}}`);
1035
- return account;
1036
- }
1037
- /**
1038
- * Save account into the local storage
1039
- */
1040
- async saveLocally() {
1041
- if (!this._cache.pubkey)
1042
- throw new Error('User not logged');
1043
- if (this._debug)
1044
- console.debug(`[account] Saving account {${this._cache.pubkey.substring(0, 6)}} in local storage...`);
1045
- // Convert account to json
1046
- const json = this._data.asObject({ keepTypename: true });
1047
- const seckey = (this._cache.keypair && this._cache.keypair.secretKey && Base58.encode(this._cache.keypair.secretKey)) || null;
1048
- // Convert avatar URL to dataUrl (e.g. 'data:image/png:<base64 content>')
1049
- const hasAvatarUrl = json.avatar && !json.avatar.endsWith(DEFAULT_AVATAR_IMAGE) && (json.avatar.startsWith('http://') || json.avatar.startsWith('https://'));
1050
- if (hasAvatarUrl && this.network.online) {
1051
- await this.file
1052
- .getImage(json.avatar, {
1053
- thumbnail: true,
1054
- outputType: 'dataUrl',
1055
- })
1056
- .then((dataUrl) => {
1057
- if (dataUrl && this._debug)
1058
- console.debug('[account] Image fetched: ', dataUrl.substring(0, 50));
1059
- // TODO: make sure to display Base64 image in the menu top header
1060
- //jsonAccount.avatar = dataUrl;
1061
- })
1062
- .catch((err) => {
1063
- console.error(`[account] Error while fetching image: ${json.avatar}: ${err}`);
1064
- });
1065
- }
1066
- try {
1067
- await Promise.all([
1068
- this.storage.set(PUBKEY_STORAGE_KEY, this._cache.pubkey),
1069
- this.storage.set(TOKEN_STORAGE_KEY, this._cache.authToken),
1070
- this.storage.set(`${ACCOUNT_STORAGE_KEY}#${this._cache.pubkey}`, json),
1071
- // Secret key (optional)
1072
- (seckey && this.storage.set(SECKEY_STORAGE_KEY, seckey)) || this.storage.remove(SECKEY_STORAGE_KEY),
1073
- // Remove old storage key
1074
- this.storage.remove(ACCOUNT_STORAGE_KEY),
1075
- ]);
1076
- if (this._debug)
1077
- console.debug('[account] Account saved in local storage');
1078
- }
1079
- catch (err) {
1080
- console.error('[account] Error while saving account locally: ' + ((err && err.message) || err), err);
1081
- }
1082
- }
1083
- async saveLocalSettingsRemotely(source) {
1084
- if (!source || !this.isLogin() || source.accountInheritance === false)
1085
- return; // Skip
1086
- const account = this.account;
1087
- // Merge local settings into account's settings
1088
- const settings = UserSettings.fromObject(account.settings) || new UserSettings();
1089
- const changed = settings.merge(source, ['locale', 'latLongFormat', 'properties']);
1090
- if (!changed)
1091
- return; // Skip if unchanged
1092
- // Save remotely
1093
- this.account.settings = settings;
1094
- await this.saveSettingsRemotely(settings);
1095
- }
1096
- /**
1097
- * Create or update an user account
1098
- *
1099
- * @param account
1100
- * @param keyPair
1101
- */
1102
- async saveRemotely(account, keyPair) {
1103
- account.pubkey = account.pubkey || (keyPair && Base58.encode(keyPair.publicKey));
1104
- if (!account.pubkey)
1105
- throw new Error('Missing account pubkey');
1106
- const now = this._debug && Date.now();
1107
- if (this._debug)
1108
- console.debug(`[account] Saving account remotely...`);
1109
- const isNew = isNil(account.id);
1110
- // If this is an update: get existing account's updateDate, to avoid 'version error' when saving
1111
- if (!isNew) {
1112
- const existingAccount = await this.load({ fetchPolicy: 'network-only' });
1113
- if (!existingAccount || !existingAccount.updateDate) {
1114
- throw { code: ErrorCodes.ACCOUNT_NOT_EXISTS, message: 'ERROR.ACCOUNT_NOT_EXISTS' };
1115
- }
1116
- this.copyIdAndUpdateDate(existingAccount, account);
1117
- }
1118
- // Merging settings
1119
- account.settings.content['pages'] = this.settings.settings.pages;
1120
- account.settings.content['pageHistory'] = this.settings.settings.pageHistory;
1121
- // Convert to json
1122
- const json = account.asObject(MINIFY_ENTITY_FOR_POD);
1123
- // User not allow to change his profiles
1124
- delete json.profiles;
1125
- const mutation = isNew ? Mutations.create : this._apiTokenEnabled ? Mutations.saveWithTokens : Mutations.save;
1126
- // Execute mutation
1127
- const { data } = await this.graphql.mutate({
1128
- mutation,
1129
- variables: { data: json },
1130
- error: {
1131
- code: ErrorCodes.SAVE_ACCOUNT_ERROR,
1132
- message: 'ERROR.SAVE_ACCOUNT_ERROR',
1133
- },
1134
- });
1135
- // Copy update properties
1136
- this.copyIdAndUpdateDate(data, account);
1137
- if (this._debug)
1138
- console.debug(`[account] Account remotely saved in ${Date.now() - now}ms`);
1139
- return account;
1140
- }
1141
- /**
1142
- * Create or update user settings
1143
- *
1144
- * @param settings
1145
- */
1146
- async saveSettingsRemotely(settings) {
1147
- const now = this._debug && Date.now();
1148
- if (this._debug)
1149
- console.debug(`[account] Saving settings remotely...`);
1150
- const json = settings.asObject(MINIFY_ENTITY_FOR_POD);
1151
- // Execute mutation
1152
- const { data } = await this.graphql.mutate({
1153
- mutation: Mutations.saveSettings,
1154
- variables: { data: json },
1155
- error: {
1156
- code: ErrorCodes.SAVE_SETTINGS_ERROR,
1157
- message: 'ERROR.SAVE_SETTINGS_ERROR',
1158
- },
1159
- });
1160
- // Copy update properties
1161
- this.copyIdAndUpdateDateSettings(data, settings);
1162
- if (this._debug)
1163
- console.debug(`[account] Settings remotely saved in ${Date.now() - now}ms`);
1164
- // Save into account
1165
- if (this.account)
1166
- this.account.settings = settings;
1167
- }
1168
- async authenticateAndGetToken(token, counter) {
1169
- if (!this._cache.pubkey)
1170
- throw new Error('User not logged');
1171
- if (!counter)
1172
- console.info('[account] Authentication on pod...');
1173
- if (counter > 4) {
1174
- if (this._debug)
1175
- console.debug(`[account] Failed to authentication on pod (after ${counter} attempts)`);
1176
- throw { code: ErrorCodes.AUTH_SERVER_ERROR, message: 'ERROR.AUTH_SERVER_ERROR' };
1177
- }
1178
- // Check if valid
1179
- if (token) {
1180
- const data = await this.graphql.query({
1181
- query: AuthQuery,
1182
- variables: {
1183
- token,
1184
- },
1185
- error: {
1186
- code: ErrorCodes.UNAUTHORIZED,
1187
- message: 'ERROR.UNAUTHORIZED',
1188
- },
1189
- fetchPolicy: 'no-cache',
1190
- });
1191
- // Token is accepted by the server
1192
- if (data && data.authenticate) {
1193
- // Store the token
1194
- this.onAuthTokenChange.next(token);
1195
- console.info(`[account] Authentication on pod [OK] {pubkey: '${this._cache.pubkey.substr(0, 8)}'}`);
1196
- return token; // return the token
1197
- }
1198
- // Continue (will retry with another challenge)
1199
- }
1200
- // Generate a new token
1201
- const authChallenge = await this.getAuthChallenge();
1202
- // TODO: check server pubkey as a valid certificate
1203
- // Do the challenge
1204
- const signature = await CryptoService.sign(authChallenge.challenge, this._cache.keypair);
1205
- const newToken = `${this._cache.pubkey}:${authChallenge.challenge}|${signature}`;
1206
- // iterate with the new token
1207
- return await this.authenticateAndGetToken(newToken, (counter || 1) + 1 /* increment */);
1208
- }
1209
- async getAuthChallenge() {
1210
- const challengeError = {
1211
- code: ErrorCodes.AUTH_CHALLENGE_ERROR,
1212
- message: 'ERROR.AUTH_CHALLENGE_ERROR',
1213
- };
1214
- const { authChallenge } = await this.graphql.query({
1215
- query: AuthChallengeQuery,
1216
- variables: {},
1217
- error: challengeError,
1218
- fetchPolicy: 'network-only',
1219
- });
1220
- // Check challenge
1221
- if (!authChallenge)
1222
- throw challengeError; // Should never occur
1223
- // Check server signature
1224
- const signatureOK = await CryptoService.verify(authChallenge.challenge, authChallenge.signature, authChallenge.pubkey);
1225
- if (!signatureOK) {
1226
- console.warn('FIXME: Bad peer signature on auth challenge !', authChallenge);
1227
- }
1228
- return authChallenge;
1229
- }
1230
- startListenRemoteChanges(opts) {
1231
- if (this._listenChangesSubscription)
1232
- this.stopListenRemoteChanges(); // Stop previous subscription
1233
- if (this.network.offline)
1234
- return new Subscription(); // Offline: skip
1235
- this._listenChangesSubscription = this.watchChanges(opts).subscribe({
1236
- next: (data) => {
1237
- console.debug(`[account] Remote update detected at ${data.updateDate}`);
1238
- this.reload();
1239
- },
1240
- error: (err) => {
1241
- if (err && +err.code === ServerErrorCodes.NOT_FOUND) {
1242
- console.info('[account] [WS] Account not exists anymore: force user to logout...', err);
1243
- this.logout();
1244
- }
1245
- else if (err && +err.code === ServerErrorCodes.UNAUTHORIZED) {
1246
- console.info('[account] [WS] Account not authorized: force user to logout...', err);
1247
- this.logout();
1248
- }
1249
- else {
1250
- console.warn('[account] [WS] Received error:', err);
1251
- }
1252
- },
1253
- });
1254
- this._listenChangesSubscription.add(() => {
1255
- console.debug(`[account] Stop watching remote changes`);
1256
- this._listenChangesSubscription = null;
1257
- });
1258
- return this._listenChangesSubscription;
1259
- }
1260
- stopListenRemoteChanges() {
1261
- this._listenChangesSubscription?.unsubscribe();
1262
- }
1263
- watchChanges(opts) {
1264
- if (!this.started) {
1265
- // Wait service ready, then loop
1266
- return from(this.ready()).pipe(switchMap(() => this.watchChanges(opts)));
1267
- }
1268
- if (!this._cache.pubkey)
1269
- throw new Error('Not logged in');
1270
- if (this.network.offline)
1271
- throw new Error('Cannot watch account changes: network is offline.');
1272
- const variables = {
1273
- interval: toNumber(opts && opts.intervalInSeconds, this._listenIntervalInSeconds),
1274
- };
1275
- console.debug(`[account] Watching remote changes, every ${variables.interval}s`);
1276
- return this.graphql
1277
- .subscribe({
1278
- query: AccountSubscriptions.listenChanges,
1279
- variables,
1280
- error: {
1281
- code: ErrorCodes.SUBSCRIBE_ACCOUNT_ERROR,
1282
- message: 'ERROR.ACCOUNT.SUBSCRIBE_ERROR',
1283
- },
1284
- })
1285
- .pipe(map(({ data }) => data),
1286
- // Keep only if newer
1287
- filter((data) => {
1288
- const currentUpdateDate = fromDateISOString(this._data?.updateDate);
1289
- const remoteUpdateDate = fromDateISOString(data?.updateDate);
1290
- return remoteUpdateDate && (!currentUpdateDate || !remoteUpdateDate.isSame(currentUpdateDate, 'millisecond'));
1291
- }));
1292
- }
1293
- copyIdAndUpdateDate(source, target) {
1294
- if (!source)
1295
- return;
1296
- target.id = source.id || target.id;
1297
- target.updateDate = source.updateDate || target.updateDate;
1298
- // Update settings
1299
- this.copyIdAndUpdateDateSettings(source.settings, target.settings);
1300
- // Update tokens
1301
- if (this._apiTokenEnabled) {
1302
- this.copyIdAndUpdateDateToken(source.tokens, target.tokens);
1303
- }
1304
- }
1305
- copyIdAndUpdateDateSettings(source, target) {
1306
- if (!source)
1307
- return;
1308
- target.id = source.id || target.id;
1309
- target.updateDate = source.updateDate || target.updateDate;
1310
- }
1311
- copyIdAndUpdateDateToken(sources, targets) {
1312
- if (isEmptyArray(sources))
1313
- return;
1314
- sources.forEach((source) => {
1315
- const target = targets.find((value) => UserToken.equals(value, source));
1316
- if (target) {
1317
- target.id = source.id || target.id;
1318
- target.creationDate = source.creationDate || target.creationDate;
1319
- target.updateDate = source.updateDate || target.updateDate;
1320
- target.token = undefined;
1321
- }
1322
- });
1323
- }
1324
- showToast(opts) {
1325
- return Toasts.show(this.toastController, this.translate, opts);
1326
- }
1327
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AccountService, deps: [{ token: i1.NetworkService }, { token: i2.GraphqlService }, { token: i3.LocalSettingsService }, { token: i4.Storage }, { token: i5.FileService }, { token: i6.TranslateService, optional: true }, { token: i7.ToastController, optional: true }, { token: ENVIRONMENT }, { token: APP_USER_SETTINGS_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
1328
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AccountService, providedIn: 'root' });
1329
- }
1330
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AccountService, decorators: [{
1331
- type: Injectable,
1332
- args: [{ providedIn: 'root', deps: [ENVIRONMENT] }]
1333
- }], ctorParameters: () => [{ type: i1.NetworkService }, { type: i2.GraphqlService }, { type: i3.LocalSettingsService }, { type: i4.Storage }, { type: i5.FileService }, { type: i6.TranslateService, decorators: [{
1334
- type: Optional
1335
- }] }, { type: i7.ToastController, decorators: [{
1336
- type: Optional
1337
- }] }, { type: i8.Environment, decorators: [{
1338
- type: Inject,
1339
- args: [ENVIRONMENT]
1340
- }] }, { type: undefined, decorators: [{
1341
- type: Optional
1342
- }, {
1343
- type: Inject,
1344
- args: [APP_USER_SETTINGS_OPTIONS]
1345
- }] }] });
1346
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjb3VudC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL3NlcnZpY2VzL2FjY291bnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdFLE9BQU8sRUFBRSxhQUFhLEVBQVcsTUFBTSxrQkFBa0IsQ0FBQztBQUUxRCxPQUFPLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM1RSxPQUFPLEVBQVUsV0FBVyxFQUFvQixNQUFNLHNCQUFzQixDQUFDO0FBRTdFLE9BQU8sRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFjLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDaEYsT0FBTyxFQUFlLEdBQUcsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBR3ZELE9BQU8sRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM5RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsVUFBVSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBT3hELE9BQU8sRUFBRSxxQkFBcUIsRUFBZSxnQkFBZ0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2pHLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ2xDLE9BQU8sRUFBZSxXQUFXLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNuRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RCxPQUFPLEVB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QTdFcEMsY0FBYyxjQURELE1BQU07OzJGQUNuQixjQUFjO2tCQUQxQixVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxXQUFXLENBQUMsRUFBRTs7MEJBMkVsRCxRQUFROzswQkFDUixRQUFROzswQkFDUixNQUFNOzJCQUFDLFdBQVc7OzBCQUNsQixRQUFROzswQkFBSSxNQUFNOzJCQUFDLHlCQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSwgSW5qZWN0aW9uVG9rZW4sIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDcnlwdG9TZXJ2aWNlLCBLZXlwYWlyIH0gZnJvbSAnLi9jcnlwdG8uc2VydmljZSc7XG5pbXBvcnQgeyBEZXBhcnRtZW50IH0gZnJvbSAnLi9tb2RlbC9kZXBhcnRtZW50Lm1vZGVsJztcbmltcG9ydCB7IEFjY291bnQsIEFjY291bnRVdGlscywgVXNlclNldHRpbmdzIH0gZnJvbSAnLi9tb2RlbC9hY2NvdW50Lm1vZGVsJztcbmltcG9ydCB7IFBlcnNvbiwgUGVyc29uVXRpbHMsIFVzZXJQcm9maWxlTGFiZWwgfSBmcm9tICcuL21vZGVsL3BlcnNvbi5tb2RlbCc7XG5pbXBvcnQgeyBMb2NhbFNldHRpbmdzLCBVc2FnZU1vZGUgfSBmcm9tICcuL21vZGVsL3NldHRpbmdzLm1vZGVsJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgZnJvbSwgT2JzZXJ2YWJsZSwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBGZXRjaFBvbGljeSwgZ3FsIH0gZnJvbSAnQGFwb2xsby9jbGllbnQvY29yZSc7XG5pbXBvcnQgeyBTdG9yYWdlIH0gZnJvbSAnQGlvbmljL3N0b3JhZ2UtYW5ndWxhcic7XG5cbmltcG9ydCB7IGlzRW1wdHlBcnJheSwgaXNOaWwsIHNsZWVwLCB0b051bWJlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9mdW5jdGlvbnMnO1xuaW1wb3J0IHsgQmFzZUdyYXBocWxTZXJ2aWNlIH0gZnJvbSAnLi9iYXNlLWdyYXBocWwtc2VydmljZS5jbGFzcyc7XG5pbXBvcnQgeyBFcnJvckNvZGVzLCBTZXJ2ZXJFcnJvckNvZGVzIH0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHsgR3JhcGhxbFNlcnZpY2UgfSBmcm9tICcuLi9ncmFwaHFsL2dyYXBocWwuc2VydmljZSc7XG5pbXBvcnQgeyBMb2NhbFNldHRpbmdzU2VydmljZSB9IGZyb20gJy4vbG9jYWwtc2V0dGluZ3Muc2VydmljZSc7XG5pbXBvcnQgeyBGb3JtRmllbGREZWZpbml0aW9uLCBGb3JtRmllbGREZWZpbml0aW9uTWFwIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Zvcm0vZmllbGQubW9kZWwnO1xuaW1wb3J0IHsgTmV0d29ya1NlcnZpY2UgfSBmcm9tICcuL25ldHdvcmsuc2VydmljZSc7XG5pbXBvcnQgeyBBdXRoVG9rZW5UeXBlIH0gZnJvbSAnLi9uZXR3b3JrLnR5cGVzJztcbmltcG9ydCB7IEZpbGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2ZpbGUvZmlsZS5zZXJ2aWNlJztcbmltcG9ydCB7IE1JTklGWV9FTlRJVFlfRk9SX1BPRCwgUmVmZXJlbnRpYWwsIFJlZmVyZW50aWFsVXRpbHMgfSBmcm9tICcuL21vZGVsL3JlZmVyZW50aWFsLm1vZGVsJztcbmltcG9ydCB7IFN0YXR1c0lkcyB9IGZyb20gJy4vbW9kZWwvbW9kZWwuZW51bSc7XG5pbXBvcnQgeyBCYXNlNTggfSBmcm9tICcuL2Jhc2U1OCc7XG5pbXBvcnQgeyBFbnZpcm9ubWVudCwgRU5WSVJPTk1FTlQgfSBmcm9tICcuLi8uLi8uLi9lbnZpcm9ubWVudHMvZW52aXJvbm1lbnQuY2xhc3MnO1xuaW1wb3J0IHsgZnJvbURhdGVJU09TdHJpbmcgfSBmcm9tICcuLi8uLi9zaGFyZWQvZGF0ZXMnO1xuaW1wb3J0IHsgZmlyc3ROb3ROaWxQcm9taXNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL29ic2VydmFibGVzJztcbmltcG9ydCB7IGRlYm91bmNlVGltZSwgZmlsdGVyLCBtYXAsIHN3aXRjaE1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEJhc2VFbnRpdHlHcmFwaHFsTXV0YXRpb25zLCBCYXNlRW50aXR5R3JhcGhxbFF1ZXJpZXMsIEJhc2VFbnRpdHlHcmFwaHFsU3Vic2NyaXB0aW9ucyB9IGZyb20gJy4vYmFzZS1lbnRpdHktc2VydmljZS5jbGFzcyc7XG5pbXBvcnQgeyBNb21lbnQgfSBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHsgU2hvd1RvYXN0T3B0aW9ucywgVG9hc3RzIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3RvYXN0L3RvYXN0cyc7XG5pbXBvcnQgeyBPdmVybGF5RXZlbnREZXRhaWwgfSBmcm9tICdAaW9uaWMvY29yZSc7XG5pbXBvcnQgeyBUb2FzdENvbnRyb2xsZXIgfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBUb2tlblNjb3BlLCBVc2VyVG9rZW4gfSBmcm9tICcuL21vZGVsL3Rva2VuLm1vZGVsJztcblxuZXhwb3J0IGRlY2xhcmUgaW50ZXJmYWNlIEFjY291bnREZXRhaWxzIHtcbiAgbG9hZGVkOiBib29sZWFuO1xuICBrZXlwYWlyOiBLZXlwYWlyO1xuICBhdXRoVG9rZW46IHN0cmluZztcbiAgYXV0aEJhc2ljPzogc3RyaW5nO1xuICBwdWJrZXk6IHN0cmluZztcbiAgcGVyc29uOiBQZXJzb247XG4gIGRlcGFydG1lbnQ6IERlcGFydG1lbnQ7XG4gIG1haW5Qcm9maWxlOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXV0aERhdGEge1xuICB1c2VybmFtZTogc3RyaW5nO1xuICBwYXNzd29yZDogc3RyaW5nO1xuICBvZmZsaW5lPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWdpc3RlckRhdGEgZXh0ZW5kcyBBdXRoRGF0YSB7XG4gIGFjY291bnQ6IEFjY291bnQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhbmdlUGFzc3dvcmREYXRhIHtcbiAgcGFzc3dvcmQ6IHN0cmluZztcbiAgY29uZmlybVBhc3N3b3JkOiBzdHJpbmc7XG4gIGVtYWlsOiBzdHJpbmc7XG59XG5cbmNvbnN0IFRPS0VOX1NUT1JBR0VfS0VZID0gJ3Rva2VuJztcbmNvbnN0IFBVQktFWV9TVE9SQUdFX0tFWSA9ICdwdWJrZXknO1xuY29uc3QgU0VDS0VZX1NUT1JBR0VfS0VZID0gJ3NlY2tleSc7XG5jb25zdCBBQ0NPVU5UX1NUT1JBR0VfS0VZID0gJ2FjY291bnQnO1xuXG5jb25zdCBERUZBVUxUX0FWQVRBUl9JTUFHRSA9ICdhc3NldHMvaW1nL3BlcnNvbi5wbmcnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFVzZXJTZXR0aW5nc09wdGlvbnMge1xuICBvcHRpb25zOiBGb3JtRmllbGREZWZpbml0aW9uTWFwO1xufVxuXG5leHBvcnQgY29uc3QgQVBQX1VTRVJfU0VUVElOR1NfT1BUSU9OUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxVc2VyU2V0dGluZ3NPcHRpb25zPignVXNlclNldHRpbmdzT3B0aW9ucycpO1xuZXhwb3J0IGNvbnN0IEFQUF9VU0VSX1RPS0VOX1NDT1BFUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxUb2tlblNjb3BlW10+KCdVc2VyVG9rZW5TY29wZXMnKTtcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBHcmFwaFFMIHF1ZXJpZXNcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5jb25zdCBGcmFnbWVudHMgPSB7XG4gIGFjY291bnQ6IGdxbGBcbiAgICBmcmFnbWVudCBBY2NvdW50RnJhZ21lbnQgb24gQWNjb3VudFZPIHtcbiAgICAgIGlkXG4gICAgICBmaXJzdE5hbWVcbiAgICAgIGxhc3ROYW1lXG4gICAgICBlbWFpbFxuICAgICAgcHVia2V5XG4gICAgICBhdmF0YXJcbiAgICAgIHN0YXR1c0lkXG4gICAgICB1cGRhdGVEYXRlXG4gICAgICBjcmVhdGlvbkRhdGVcbiAgICAgIHByb2ZpbGVzXG4gICAgICBzZXR0aW5ncyB7XG4gICAgICAgIC4uLlVzZXJTZXR0aW5nc0ZyYWdtZW50XG4gICAgICB9XG4gICAgICBkZXBhcnRtZW50IHtcbiAgICAgICAgaWRcbiAgICAgICAgbGFiZWxcbiAgICAgICAgbmFtZVxuICAgICAgICBfX3R5cGVuYW1lXG4gICAgICB9XG4gICAgICBfX3R5cGVuYW1lXG4gICAgfVxuICBgLFxuXG4gIHNldHRpbmdzOiBncWxgXG4gICAgZnJhZ21lbnQgVXNlclNldHRpbmdzRnJhZ21lbnQgb24gVXNlclNldHRpbmdzVk8ge1xuICAgICAgaWRcbiAgICAgIGxvY2FsZVxuICAgICAgbGF0TG9uZ0Zvcm1hdFxuICAgICAgY29udGVudFxuICAgICAgbm9uY2VcbiAgICAgIHVwZGF0ZURhdGVcbiAgICAgIF9fdHlwZW5hbWVcbiAgICB9XG4gIGAsXG5cbiAgdG9rZW46IGdxbGBcbiAgICBmcmFnbWVudCBVc2VyVG9rZW5GcmFnbWVudCBvbiBVc2VyVG9rZW5WTyB7XG4gICAgICBpZFxuICAgICAgcHVia2V5XG4gICAgICBuYW1lXG4gICAgICBmbGFnc1xuICAgICAgZXhwaXJhdGlvbkRhdGVcbiAgICAgIGxhc3RVc2VkRGF0ZVxuICAgICAgY3JlYXRpb25EYXRlXG4gICAgICB1cGRhdGVEYXRlXG4gICAgICBfX3R5cGVuYW1lXG4gICAgfVxuICBgLFxufTtcblxuLy8gQWNjb3VudCBxdWVyaWVzXG5jb25zdCBRdWVyaWVzOiBQYXJ0aWFsPEJhc2VFbnRpdHlHcmFwaHFsUXVlcmllcz4gJiB7IGxvYWRXaXRoVG9rZW5zOiBhbnkgfSA9IHtcbiAgbG9hZDogZ3FsYFxuICAgIHF1ZXJ5IEFjY291bnQge1xuICAgICAgZGF0YTogYWNjb3VudCB7XG4gICAgICAgIC4uLkFjY291bnRGcmFnbWVudFxuICAgICAgfVxuICAgIH1cbiAgICAke0ZyYWdtZW50cy5hY2NvdW50fVxuICAgICR7RnJhZ21lbnRzLnNldHRpbmdzfVxuICBgLFxuXG4gIGxvYWRXaXRoVG9rZW5zOiBncWxgXG4gICAgcXVlcnkgQWNjb3VudFdpdGhUb2tlbiB7XG4gICAgICBkYXRhOiBhY2NvdW50IHtcbiAgICAgICAgLi4uQWNjb3VudEZyYWdtZW50XG4gICAgICAgIHRva2VucyB7XG4gICAgICAgICAgLi4uVXNlclRva2VuRnJhZ21lbnRcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAke0ZyYWdtZW50cy5hY2NvdW50fVxuICAgICR7RnJhZ21lbnRzLnNldHRpbmdzfVxuICAgICR7RnJhZ21lbnRzLnRva2VufVxuICBgLFxufTtcblxuLy8gQ2hlY2sgZW1haWwgcXVlcnlcbmNvbnN0IElzRW1haWxFeGlzdHNRdWVyeTogYW55ID0gZ3FsYFxuICBxdWVyeSBJc0VtYWlsRXhpc3RzKCRlbWFpbDogU3RyaW5nLCAkaGFzaDogU3RyaW5nKSB7XG4gICAgaXNFbWFpbEV4aXN0cyhlbWFpbDogJGVtYWlsLCBoYXNoOiAkaGFzaClcbiAgfVxuYDtcblxuZXhwb3J0IGRlY2xhcmUgaW50ZXJmYWNlIElzRW1haWxFeGlzdHNWYXJpYWJsZXMge1xuICBlbWFpbDogc3RyaW5nO1xuICBoYXNoOiBzdHJpbmc7XG59XG5cbi8vIEFjY291bnQgbXV0YXRpb25zXG5jb25zdCBNdXRhdGlvbnM6IFBhcnRpYWw8QmFzZUVudGl0eUdyYXBocWxNdXRhdGlvbnM+ICYgeyBzYXZlV2l0aFRva2VuczogYW55OyBzYXZlU2V0dGluZ3M6IGFueTsgY3JlYXRlOiBhbnkgfSA9IHtcbiAgc2F2ZTogZ3FsYFxuICAgIG11dGF0aW9uIFNhdmVBY2NvdW50KCRkYXRhOiBBY2NvdW50Vk9JbnB1dCkge1xuICAgICAgZGF0YTogc2F2ZUFjY291bnQoYWNjb3VudDogJGRhdGEpIHtcbiAgICAgICAgLi4uQWNjb3VudEZyYWdtZW50XG4gICAgICB9XG4gICAgfVxuICAgICR7RnJhZ21lbnRzLmFjY291bnR9XG4gICAgJHtGcmFnbWVudHMuc2V0dGluZ3N9XG4gIGAsXG5cbiAgc2F2ZVdpdGhUb2tlbnM6IGdxbGBcbiAgICBtdXRhdGlvbiBTYXZlQWNjb3VudFdpdGhUb2tlbnMoJGRhdGE6IEFjY291bnRWT0lucHV0KSB7XG4gICAgICBkYXRhOiBzYXZlQWNjb3VudChhY2NvdW50OiAkZGF0YSkge1xuICAgICAgICAuLi5BY2NvdW50RnJhZ21lbnRcbiAgICAgICAgdG9rZW5zIHtcbiAgICAgICAgICAuLi5Vc2VyVG9rZW5GcmFnbWVudFxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgICR7RnJhZ21lbnRzLmFjY291bnR9XG4gICAgJHtGcmFnbWVudHMuc2V0dGluZ3N9XG4gICAgJHtGcmFnbWVudHMudG9rZW59XG4gIGAsXG5cbiAgY3JlYXRlOiBncWxgXG4gICAgbXV0YXRpb24gQ3JlYXRlQWNjb3VudCgkZGF0YTogQWNjb3VudFZPSW5wdXQpIHtcbiAgICAgIGRhdGE6IGNyZWF0ZUFjY291bnQoYWNjb3VudDogJGRhdGEpIHtcbiAgICAgICAgLi4uQWNjb3VudEZyYWdtZW50XG4gICAgICB9XG4gICAgfVxuICAgICR7RnJhZ21lbnRzLmFjY291bnR9XG4gICAgJHtGcmFnbWVudHMuc2V0dGluZ3N9XG4gIGAsXG5cbiAgc2F2ZVNldHRpbmdzOiBncWxgXG4gICAgbXV0YXRpb24gU2F2ZVNldHRpbmdzKCRkYXRhOiBVc2VyU2V0dGluZ3NWT0lucHV0KSB7XG4gICAgICBkYXRhOiBzYXZlU2V0dGluZ3Moc2V0dGluZ3M6ICRkYXRhKSB7XG4gICAgICAgIC4uLlVzZXJTZXR0aW5nc0ZyYWdtZW50XG4gICAgICB9XG4gICAgfVxuICAgICR7RnJhZ21lbnRzLnNldHRpbmdzfVxuICBgLFxufTtcblxuLy8gU2VudCBjb25maXJtYXRpb24gZW1haWxcbmNvbnN0IFNlbmRDb25maXJtRW1haWxRdWVyeTogYW55ID0gZ3FsYFxuICBxdWVyeSBzZW5kQWNjb3VudENvbmZpcm1hdGlvbkVtYWlsKCRlbWFpbDogU3RyaW5nLCAkbG9jYWxlOiBTdHJpbmcpIHtcbiAgICBkYXRhOiBzZW5kQWNjb3VudENvbmZpcm1hdGlvbkVtYWlsKGVtYWlsOiAkZW1haWwsIGxvY2FsZTogJGxvY2FsZSlcbiAgfVxuYDtcblxuLy8gQ29uZmlybSBhY2NvdW50IGVtYWlsXG5jb25zdCBDb25maXJtRW1haWxRdWVyeTogYW55ID0gZ3FsYFxuICBxdWVyeSBjb25maXJtQWNjb3VudEVtYWlsKCRlbWFpbDogU3RyaW5nLCAkY29kZTogU3RyaW5nKSB7XG4gICAgZGF0YTogY29uZmlybUFjY291bnRFbWFpbChlbWFpbDogJGVtYWlsLCBjb2RlOiAkY29kZSlcbiAgfVxuYDtcblxuLy8gU2VuZCBlbWFpbCB0byByZXNldCBwYXNzd29yZFxuY29uc3QgU2VuZFJlc2V0UGFzc3dvcmRFbWFpbFF1ZXJ5OiBhbnkgPSBncWxgXG4gIHF1ZXJ5IFNlbmRSZXNldFBhc3N3b3JkRW1haWwoJHVzZXJuYW1lOiBTdHJpbmchLCAkbG9jYWxlOiBTdHJpbmchKSB7XG4gICAgc2VuZFJlc2V0UGFzc3dvcmRFbWFpbCh1c2VybmFtZTogJHVzZXJuYW1lLCBsb2NhbGU6ICRsb2NhbGUpXG4gIH1cbmA7XG5cbmNvbnN0IFJlc2V0QWNjb3VudFB1YmtleVF1ZXJ5OiBhbnkgPSBncWxgXG4gIHF1ZXJ5IFJlc2V0UHVia2V5KCR1c2VybmFtZTogU3RyaW5nISwgJHRva2VuOiBTdHJpbmchKSB7XG4gICAgZGF0YTogcmVzZXRBY2NvdW50UHVia2V5KHVzZXJuYW1lOiAkdXNlcm5hbWUsIHRva2VuOiAkdG9rZW4pXG4gIH1cbmA7XG5cbmNvbnN0IFVwZGF0ZVB1YktleVF1ZXJ5OiBhbnkgPSBncWxgXG4gIHF1ZXJ5IFVwZGF0ZUFjY291bnRQdWJrZXkoJHB1YmtleTogU3RyaW5nISkge1xuICAgIGRhdGE6IHVwZGF0ZUFjY291bnRQdWJrZXkocHVia2V5OiAkcHVia2V5KVxuICB9XG5gO1xuXG4vLyBBdXRoZW50aWNhdGlvbiAgcXVlcnlcbmNvbnN0IEF1dGhRdWVyeTogYW55ID0gZ3FsYFxuICBxdWVyeSBBdXRoKCR0b2tlbjogU3RyaW5nKSB7XG4gICAgYXV0aGVudGljYXRlKHRva2VuOiAkdG9rZW4pXG4gIH1cbmA7XG5cbi8vIE5ldyBhdXRoIGNoYWxsZW5nZSBxdWVyeVxuY29uc3QgQXV0aENoYWxsZW5nZVF1ZXJ5OiBhbnkgPSBncWxgXG4gIHF1ZXJ5IEF1dGhDaGFsbGVuZ2Uge1xuICAgIGF1dGhDaGFsbGVuZ2Uge1xuICAgICAgY2hhbGxlbmdlXG4gICAgICBwdWJrZXlcbiAgICAgIHNpZ25hdHVyZVxuICAgIH1cbiAgfVxuYDtcblxuaW50ZXJmYWNlIElBdXRoQ2hhbGxlbmdlIHtcbiAgcHVia2V5OiBzdHJpbmc7XG4gIGNoYWxsZW5nZTogc3RyaW5nO1xuICBzaWduYXR1cmU6IHN0cmluZztcbn1cblxuY29uc3QgQWNjb3VudFN1YnNjcmlwdGlvbnM6IEJhc2VFbnRpdHlHcmFwaHFsU3Vic2NyaXB0aW9ucyA9IHtcbiAgbGlzdGVuQ2hhbmdlczogZ3FsYFxuICAgIHN1YnNjcmlwdGlvbiB1cGRhdGVBY2NvdW50KCRpbnRlcnZhbDogSW50KSB7XG4gICAgICBkYXRhOiB1cGRhdGVBY2NvdW50KGludGVydmFsOiAkaW50ZXJ2YWwpIHtcbiAgICAgICAgaWRcbiAgICAgICAgdXBkYXRlRGF0ZVxuICAgICAgfVxuICAgIH1cbiAgYCxcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWNjb3VudFdhdGNoT3B0aW9ucyB7XG4gIGludGVydmFsSW5TZWNvbmRzPzogbnVtYmVyO1xufVxuXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JywgZGVwczogW0VOVklST05NRU5UXSB9KVxuZXhwb3J0IGNsYXNzIEFjY291bnRTZXJ2aWNlIGV4dGVuZHMgQmFzZUdyYXBocWxTZXJ2aWNlPEFjY291bnQsIGFueSwgbnVtYmVyLCBBY2NvdW50PiB7XG4gIG9uTG9naW4gPSBuZXcgU3ViamVjdDxBY2NvdW50PigpO1xuICBvbldpbGxMb2dvdXQgPSBuZXcgU3ViamVjdDxBY2NvdW50PigpO1xuICBvbkxvZ291dCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIG9uQ2hhbmdlID0gbmV3IFN1YmplY3Q8QWNjb3VudD4oKTtcbiAgb25BdXRoVG9rZW5DaGFuZ2UgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZyB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgb25BdXRoQmFzaWNDaGFuZ2UgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZyB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcblxuICBwcml2YXRlIF9saXN0ZW5DaGFuZ2VzU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gPSBudWxsO1xuICBwcml2YXRlIHJlYWRvbmx5IF9lbmFibGVMaXN0ZW5DaGFuZ2VzOiBib29sZWFuO1xuICBwcml2YXRlIHJlYWRvbmx5IF9saXN0ZW5JbnRlcnZhbEluU2Vjb25kczogbnVtYmVyO1xuICBwcml2YXRlIF9jYWNoZTogQWNjb3VudERldGFpbHMgPSB7XG4gICAgbG9hZGVkOiBmYWxzZSxcbiAgICBrZXlwYWlyOiBudWxsLFxuICAgIGF1dGhUb2tlbjogbnVsbCxcbiAgICBhdXRoQmFzaWM6IG51bGwsXG4gICAgcHVia2V5OiBudWxsLFxuICAgIG1haW5Qcm9maWxlOiBudWxsLFxuICAgIHBlcnNvbjogbnVsbCxcbiAgICBkZXBhcnRtZW50OiBudWxsLFxuICB9O1xuICBwcml2YXRlIHJlYWRvbmx5IF9vcHRpb25EZWZzOiBGb3JtRmllbGREZWZpbml0aW9uW107XG4gIHByaXZhdGUgXyRhZGRpdGlvbmFsRmllbGRzID0gbmV3IEJlaGF2aW9yU3ViamVjdDxGb3JtRmllbGREZWZpbml0aW9uW10+KFtdKTtcbiAgcHJpdmF0ZSBfdG9rZW5UeXBlJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8QXV0aFRva2VuVHlwZT4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSBfYXBpVG9rZW5FbmFibGVkID0gdHJ1ZTtcblxuICBnZXQgYWNjb3VudCgpOiBBY2NvdW50IHtcbiAgICByZXR1cm4gdGhpcy5fY2FjaGUubG9hZGVkID8gdGhpcy5fZGF0YSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGdldCBwZXJzb24oKTogUGVyc29uIHtcbiAgICBpZiAodGhpcy5fY2FjaGUubG9hZGVkICYmICF0aGlzLl9jYWNoZS5wZXJzb24pIHtcbiAgICAgIHRoaXMuX2NhY2hlLnBlcnNvbiA9IHRoaXMuX2NhY2hlLmxvYWRlZCA/IHRoaXMuX2RhdGEuYXNQZXJzb24oKSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NhY2hlLnBlcnNvbjtcbiAgfVxuXG4gIGdldCBkZXBhcnRtZW50KCk6IERlcGFydG1lbnQge1xuICAgIGlmICh0aGlzLl9jYWNoZS5sb2FkZWQgJiYgIXRoaXMuX2NhY2hlLmRlcGFydG1lbnQpIHtcbiAgICAgIHRoaXMuX2NhY2hlLmRlcGFydG1lbnQgPSB0aGlzLl9jYWNoZS5sb2FkZWQgPyB0aGlzLl9kYXRhLmFzUGVyc29uKCkuZGVwYXJ0bWVudCA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NhY2hlLmRlcGFydG1lbnQ7XG4gIH1cblxuICBnZXQgdG9rZW5UeXBlKCk6IEF1dGhUb2tlblR5cGUge1xuICAgIHJldHVybiB0aGlzLl90b2tlblR5cGUkLnZhbHVlO1xuICB9XG5cbiAgc2V0IHRva2VuVHlwZSh2YWx1ZTogQXV0aFRva2VuVHlwZSkge1xuICAgIGlmICh0aGlzLl90b2tlblR5cGUkLnZhbHVlICE9PSB2YWx1ZSkge1xuICAgICAgY29uc29sZS5pbmZvKCdbYWNjb3VudF0gVXNpbmcgYXV0aGVudGljYXRpb24gdG9rZW4gdHlwZTogJyArIHZhbHVlKTtcbiAgICAgIHRoaXMuX3Rva2VuVHlwZSQubmV4dCh2YWx1ZSk7XG4gICAgICAvLyBSZXNldCB2YWx1ZXNcbiAgICAgIHRoaXMuX2NhY2hlLmF1dGhUb2tlbiA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMub25BdXRoVG9rZW5DaGFuZ2UubmV4dCh1bmRlZmluZWQpO1xuICAgICAgdGhpcy5fY2FjaGUuYXV0aEJhc2ljID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5vbkF1dGhCYXNpY0NoYW5nZS5uZXh0KHVuZGVmaW5lZCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGFwaVRva2VuRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fYXBpVG9rZW5FbmFibGVkO1xuICB9XG5cbiAgc2V0IGFwaVRva2VuRW5hYmxlZCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2FwaVRva2VuRW5hYmxlZCA9IHZhbHVlO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIG5ldHdvcms6IE5ldHdvcmtTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBncmFwaHFsOiBHcmFwaHFsU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgc2V0dGluZ3M6IExvY2FsU2V0dGluZ3NTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBzdG9yYWdlOiBTdG9yYWdlLFxuICAgIHByb3RlY3RlZCBmaWxlOiBGaWxlU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIHRvYXN0Q29udHJvbGxlcjogVG9hc3RDb250cm9sbGVyLFxuICAgIEBJbmplY3QoRU5WSVJPTk1FTlQpIHByb3RlY3RlZCBlbnZpcm9ubWVudDogRW52aXJvbm1lbnQsXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChBUFBfVVNFUl9TRVRUSU5HU19PUFRJT05TKSBvcHRpb25zOiBVc2VyU2V0dGluZ3NPcHRpb25zXG4gICkge1xuICAgIHN1cGVyKGdyYXBocWwsIGVudmlyb25tZW50KTtcbiAgICB0aGlzLl9lbmFibGVMaXN0ZW5DaGFuZ2VzID0gIWVudmlyb25tZW50LmFjY291bnQgfHwgZW52aXJvbm1lbnQuYWNjb3VudC5lbmFibGVMaXN0ZW5DaGFuZ2VzICE9PSBmYWxzZTsgLy8gVHJ1ZSBieSBkZWZhdWx0XG4gICAgdGhpcy5fbGlzdGVuSW50ZXJ2YWxJblNlY29uZHMgPSB0b051bWJlcihlbnZpcm9ubWVudC5hY2NvdW50ICYmIGVudmlyb25tZW50LmFjY291bnQubGlzdGVuSW50ZXJ2YWxJblNlY29uZHMsIDApOyAvLyBubyB0aW1lciBieSBkZWZhdWx0XG5cbiAgICB0aGlzLl9kZWJ1ZyA9ICFlbnZpcm9ubWVudC5wcm9kdWN0aW9uO1xuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZygnW2FjY291bnQtc2VydmljZV0gQ3JlYXRpbmcgc2VydmljZScpO1xuICAgIHRoaXMuX29wdGlvbkRlZnMgPSBPYmplY3QudmFsdWVzKG9wdGlvbnM/Lm9wdGlvbnMgfHwge30pO1xuXG4gICAgdGhpcy5yZXNldERhdGEoKTtcblxuICAgIC8vIFNlbmQgYXV0aCB0b2tlbiB0byB0aGUgZ3JhcGhxbCBsYXllciwgd2hlbiBjaGFuZ2VkXG4gICAgdGhpcy5vbkF1dGhUb2tlbkNoYW5nZS5zdWJzY3JpYmUoKHRva2VuKSA9PiB0aGlzLmdyYXBocWwuc2V0QXV0aFRva2VuKHRva2VuKSk7XG4gICAgdGhpcy5vbkF1dGhCYXNpY0NoYW5nZS5zdWJzY3JpYmUoKGJhc2ljKSA9PiB0aGlzLmdyYXBocWwuc2V0QXV0aEJhc2ljKGJhc2ljKSk7XG5cbiAgICAvLyBGb3JjZSBuZXR3b3JrIHRvIHdhaXQgYWNjb3VudCBzZXJ2aWNlLCBhZnRlciBnZXR0aW5nIGNvbm5lY3Rpb24gdG8gdGhlIHBlZXJcbiAgICB0aGlzLnJlZ2lzdGVyU3Vic2NyaXB0aW9uKFxuICAgICAgdGhpcy5uZXR3b3JrLm9uKCdiZWZvcmVUcnlPbmxpbmVGaW5pc2gnLCBhc3luYyAob25saW5lKSA9PiB7XG4gICAgICAgIC8vIElmIG9ubGluZSwgd2FpdCBhIGZ1bGwgcmVzdGFydCwgYmVjYXVzZSBpdCBjYW4gZm9yY2Ugb2ZmbGluZSBtb2RlXG4gICAgICAgIGlmIChvbmxpbmUgJiYgKCF0aGlzLnN0YXJ0ZWQgfHwgdGhpcy5pc0xvZ2luKCkpKSB7XG4gICAgICAgICAgY29uc29sZS5kZWJ1ZygnW2FjY291bnRdIEZvcmNlIG5ldHdvcmtTZXJ2aWNlLnRyeU9ubGluZSgpIHRvIHdhaXQsIHRoYXQgZ3JhcGhxbCBhbmQgYWNjb3VudCBzZXJ2aWNlIGlzIHJlc3RhcnRlZC4uLicpO1xuICAgICAgICAgIGF3YWl0IHNsZWVwKDUwMCk7IC8vIHdhaXQgZ3JhcGhxbCBzZXJ2aWNlIHRvIGJlIHJlc3RhcnRlZFxuICAgICAgICAgIGlmICghdGhpcy5zdGFydGVkKSBhd2FpdCB0aGlzLnJlYWR5KCk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIG5nT25TdGFydCgpOiBQcm9taXNlPEFjY291bnQ+IHtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICB0aGlzLnNldHRpbmdzLnJlYWR5KCksXG4gICAgICAvLyBXYWl0IHRva2VuIHR5cGUgdG8gYmUgc2V0XG4gICAgICBmaXJzdE5vdE5pbFByb21pc2UodGhpcy5fdG9rZW5UeXBlJCksXG4gICAgXSk7XG5cbiAgICAvLyBMaXN0ZW4gZ3JhcGhxbCBzdGFydCAob3IgcmVzdGFydClcbiAgICB0aGlzLnJlZ2lzdGVyU3Vic2NyaXB0aW9uKFxuICAgICAgdGhpcy5ncmFwaHFsLnN0b3BTdWJqZWN0LnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLnN0YXJ0ZWQgJiYgdGhpcy5pc0xvZ2luKCkpIHtcbiAgICAgICAgICBjb25zb2xlLmRlYnVnKCdbYWNjb3VudF0gUmVzdGFydGluZywgdG8gcmV0cnkgdG8gYXV0aGVudGljYXRlLi4uJyk7XG4gICAgICAgICAgdGhpcy5yZXN0YXJ0KCk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcblxuICAgIGF3YWl0IHRoaXMucmVzdG9yZUxvY2FsbHkoKTtcbiAgICBhd2FpdCB0aGlzLmxpc3RlblNldHRpbmdzKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fZGF0YTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBuZ09uU3RvcCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBoYWRBdXRoVG9rZW4gPSB0aGlzLl9jYWNoZS5hdXRoVG9rZW4gJiYgdHJ1ZTtcbiAgICBjb25zdCBoYWRBdXRoQmFzaWMgPSB0aGlzLl9jYWNoZS5hdXRoQmFzaWMgJiYgdHJ1ZTtcbiAgICBjb25zdCBoYWRBdXRoID0gaGFkQXV0aFRva2VuIHx8IGhhZEF1dGhCYXNpYztcbiAgICB0aGlzLnJlc2V0RGF0YSgpO1xuICAgIGlmIChoYWRBdXRoKSB7XG4gICAgICB0aGlzLm9uTG9nb3V0Lm5leHQoKTtcbiAgICAgIHRoaXMub25DaGFuZ2UubmV4dCh1bmRlZmluZWQpO1xuICAgICAgaWYgKGhhZEF1dGhUb2tlbikgdGhpcy5vbkF1dGhUb2tlbkNoYW5nZS5uZXh0KHVuZGVmaW5lZCk7XG4gICAgICBpZiAoaGFkQXV0aEJhc2ljKSB0aGlzLm9uQXV0aEJhc2ljQ2hhbmdlLm5leHQodW5kZWZpbmVkKTtcbiAgICB9XG4gIH1cblxuICBpc0xvZ2luKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhISh0aGlzLl9jYWNoZS5wdWJrZXkgJiYgdGhpcy5fY2FjaGUubG9hZGVkKTtcbiAgfVxuXG4gIGlzQXV0aCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISEodGhpcy5fY2FjaGUucHVia2V5ICYmIHRoaXMuX2NhY2hlLmtleXBhaXIgJiYgdGhpcy5fY2FjaGUua2V5cGFpci5zZWNyZXRLZXkpO1xuICB9XG5cbiAgaGFzTWluUHJvZmlsZSh1c2VyUHJvZmlsZTogVXNlclByb2ZpbGVMYWJlbCk6IGJvb2xlYW4ge1xuICAgIC8vIHNob3VsZCBiZSBsb2dpbiwgYW5kIHN0YXR1cyBFTkFCTEUgb3IgVEVNUE9SQVJZXG4gICAgaWYgKCF0aGlzLl9kYXRhIHx8ICF0aGlzLl9kYXRhLnB1YmtleSB8fCAodGhpcy5fZGF0YS5zdGF0dXNJZCAhPT0gU3RhdHVzSWRzLkVOQUJMRSAmJiB0aGlzLl9kYXRhLnN0YXR1c0lkICE9PSBTdGF0dXNJZHMuVEVNUE9SQVJZKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gUGVyc29uVXRpbHMuaGFzVXBwZXJPckVxdWFsc1Byb2ZpbGUodGhpcy5fZGF0YS5wcm9maWxlcywgdXNlclByb2ZpbGUpO1xuICB9XG5cbiAgaGFzRXhhY3RQcm9maWxlKGxhYmVsOiBVc2VyUHJvZmlsZUxhYmVsKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIEFjY291bnRVdGlscy5oYXNFeGFjdFByb2ZpbGUodGhpcy5fZGF0YSwgbGFiZWwpO1xuICB9XG5cbiAgaGFzUHJvZmlsZUFuZElzRW5hYmxlKHVzZXJQcm9maWxlOiBVc2VyUHJvZmlsZUxhYmVsKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIEFjY291bnRVdGlscy5oYXNQcm9maWxlQW5kSXNFbmFibGUodGhpcy5fZGF0YSwgdXNlclByb2ZpbGUpO1xuICB9XG5cbiAgaXNBZG1pbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5oYXNQcm9maWxlQW5kSXNFbmFibGUoJ0FETUlOJyk7XG4gIH1cblxuICBpc1N1cGVydmlzb3IoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaGFzUHJvZmlsZUFuZElzRW5hYmxlKCdTVVBFUlZJU09SJyk7XG4gIH1cblxuICBpc1VzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaGFzUHJvZmlsZUFuZElzRW5hYmxlKCdVU0VSJyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWRcbiAgICogQHBhcmFtIG1vZGVcbiAgICovXG4gIGlzVXNhZ2VNb2RlKG1vZGU6IFVzYWdlTW9kZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNldHRpbmdzLmlzVXNhZ2VNb2RlKG1vZGUpO1xuICB9XG5cbiAgaXNPbmx5R3Vlc3QoKTogYm9vbGVhbiB7XG4gICAgLy8gU2hvdWxkIGJlIGxvZ2luLCBhbmQgc3RhdHVzIEVOQUJMRSBvciBURU1QT1JBUllcbiAgICBpZiAoIXRoaXMuX2RhdGEgfHwgIXRoaXMuX2RhdGEucHVia2V5IHx8ICh0aGlzLl9kYXRhLnN0YXR1c0lkICE9PSBTdGF0dXNJZHMuRU5BQkxFICYmIHRoaXMuX2RhdGEuc3RhdHVzSWQgIT09IFN0YXR1c0lkcy5URU1QT1JBUlkpKSByZXR1cm4gZmFsc2U7XG4gICAgLy8gUHJvZmlsZSBsZXNzIHRoZW4gdXNlclxuICAgIHJldHVybiAhUGVyc29uVXRpbHMuaGFzVXBwZXJPckVxdWFsc1Byb2ZpbGUodGhpcy5fZGF0YS5wcm9maWxlcywgJ1VTRVInKTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0gcmVjb3JkZXJEZXBhcnRtZW50XG4gICAqIEBkZXByZWNhdGVkIHVzZSBQcm9ncmFtUmVmU2VydmljZS5jYW5Vc2VyV3JpdGVFbnRpdHkoKSBpbnN0ZWFkXG4gICAqL1xuICBjYW5Vc2VyV3JpdGVEYXRhRm9yRGVwYXJ0bWVudChyZWNvcmRlckRlcGFydG1lbnQ6IFJlZmVyZW50aWFsIHwgYW55KTogYm9vbGVhbiB7XG4gICAgaWYgKFJlZmVyZW50aWFsVXRpbHMuaXNFbXB0eShyZWNvcmRlckRlcGFydG1lbnQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5pc0FkbWluKCk7XG4gICAgfVxuXG4gICAgLy8gU2hvdWxkIGJlIGxvZ2luLCBhbmQgc3RhdHVzIEVOQUJMRVxuICAgIGlmICghdGhpcy5fZGF0YSB8fCAhdGhpcy5fZGF0YS5wdWJrZXkgfHwgdGhpcy5fZGF0YS5zdGF0dXNJZCAhPT0gU3RhdHVzSWRzLkVOQUJMRSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKCF0aGlzLl9kYXRhLmRlcGFydG1lbnQgfHwgIXRoaXMuX2RhdGEuZGVwYXJ0bWVudC5pZCkge1xuICAgICAgY29uc29sZS53YXJuKCdVc2VyIGFjY291bnQgaGFzIG5vIGRlcGFydG1lbnQgISBVbmFibGUgdG8gY2hlY2sgd3JpdGUgcmlnaHQgYWdhaW5zdCByZWNvcmRlckRlcGFydG1lbnQnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBTYW1lIHJlY29yZGVyIGRlcGFydG1lbnQ6IE9LLCB1c2VyIGNhbiB3cml0ZVxuICAgIGlmICh0aGlzLl9kYXRhLmRlcGFydG1lbnQuaWQgPT09IHJlY29yZGVyRGVwYXJ0bWVudC5pZCkgcmV0dXJuIHRydWU7XG5cbiAgICAvLyBDYW5ub3Qgd3JpdGVcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBhc3luYyByZWdpc3RlcihkYXRhOiBSZWdpc3RlckRhdGEpOiBQcm9taXNlPEFjY291bnQ+IHtcbiAgICBpZiAodGhpcy5pc0xvZ2luKCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVXNlciBhbHJlYWR5IGxvZ2luLiBQbGVhc2UgbG9nb3V0IGJlZm9yZSByZWdpc3Rlci4nKTtcbiAgICB9XG4gICAgaWYgKCFkYXRhLnVzZXJuYW1lIHx8ICFkYXRhLnBhc3N3b3JkKSB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgcmVxdWlyZWQgdXNlcm5hbWUgb3IgcGFzc3dvcmQnKTtcblxuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZygnW2FjY291bnRdIFJlZ2lzdGVyIG5ldyB1c2VyIGFjY291bnQuLi4nLCBkYXRhLmFjY291bnQpO1xuICAgIHRoaXMuX2NhY2hlLmxvYWRlZCA9IGZhbHNlO1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3Qga2V5cGFpciA9IGF3YWl0IENyeXB0b1NlcnZpY2Uuc2NyeXB0S2V5cGFpcihkYXRhLnVzZXJuYW1lLCBkYXRhLnBhc3N3b3JkKTtcbiAgICAgIGRhdGEuYWNjb3VudC5wdWJrZXkgPSBCYXNlNTguZW5jb2RlKGtleXBhaXIucHVibGljS2V5KTtcblxuICAgICAgLy8gRGVmYXVsdCB2YWx1ZXNcbiAgICAgIGRhdGEuYWNjb3VudC5zZXR0aW5ncyA9IGRhdGEuYWNjb3VudC5zZXR0aW5ncyB8fCBuZXcgVXNlclNldHRpbmdzKCk7XG4gICAgICBkYXRhLmFjY291bnQuc2V0dGluZ3MubG9jYWxlID0gdGhpcy5zZXR0aW5ncy5sb2NhbGU7XG4gICAgICBkYXRhLmFjY291bnQuc2V0dGluZ3MubGF0TG9uZ0Zvcm1hdCA9IHRoaXMuc2V0dGluZ3MubGF0TG9uZ0Zvcm1hdDtcbiAgICAgIGRhdGEuYWNjb3VudC5zZXR0aW5ncy5jb250ZW50ID0gZGF0YS5hY2NvdW50LnNldHRpbmdzLmNvbnRlbnQgfHwge307XG4gICAgICBkYXRhLmFjY291bnQuZGVwYXJ0bWVudC5pZCA9IGRhdGEuYWNjb3VudC5kZXBhcnRtZW50LmlkIHx8IHRoaXMuZW52aXJvbm1lbnQuZGVmYXVsdERlcGFydG1lbnRJZDtcblxuICAgICAgdGhpcy5fY2FjaGUua2V5cGFpciA9IGtleXBhaXI7XG4gICAgICBjb25zdCBhY2NvdW50ID0gYXdhaXQgdGhpcy5zYXZlUmVtb3RlbHkoZGF0YS5hY2NvdW50LCBrZXlwYWlyKTtcblxuICAgICAgLy8gRGVmYXVsdCB2YWx1ZXNcbiAgICAgIGFjY291bnQuYXZhdGFyID0gYWNjb3VudC5hdmF0YXIgfHwgdGhpcy5lbnZpcm9ubWVudC5iYXNlVXJsICsgREVGQVVMVF9BVkFUQVJfSU1BR0U7XG4gICAgICB0aGlzLl9jYWNoZS5tYWluUHJvZmlsZSA9IFBlcnNvblV0aWxzLmdldE1haW5Qcm9maWxlKGFjY291bnQucHJvZmlsZXMpO1xuXG4gICAgICB0aGlzLl9kYXRhID0gYWNjb3VudDtcbiAgICAgIHRoaXMuX2NhY2hlLnB1YmtleSA9IGFjY291bnQucHVia2V5O1xuXG4gICAgICAvLyBUcnkgdG8gYXV0aCBvbiBwb2RcbiAgICAgIGF3YWl0IHRoaXMuYXV0aGVudGljYXRlKGRhdGEpO1xuXG4gICAgICB0aGlzLl9jYWNoZS5sb2FkZWQgPSB0cnVlO1xuXG4gICAgICBhd2FpdCB0aGlzLnNhdmVMb2NhbGx5KCk7XG5cbiAgICAgIGNvbnNvbGUuZGVidWcoYFthY2NvdW50XSBBY2NvdW50IHN1Y2Nlc3NmdWxseSByZWdpc3RlcmVkIGluICR7RGF0ZS5ub3coKSAtIG5vd31tc2ApO1xuXG4gICAgICAvLyBFbWl0IGV2ZW50c1xuICAgICAgdGhpcy5vbkxvZ2luLm5leHQodGhpcy5fZGF0YSk7XG4gICAgICB0aGlzLm9uQ2hhbmdlLm5leHQodGhpcy5fZGF0YSk7XG5cbiAgICAgIC8vIExpc3RlbiByZW1vdGUgY2hhbmdlc1xuICAgICAgaWYgKHRoaXMuX2VuYWJsZUxpc3RlbkNoYW5nZXMpIHRoaXMuc3RhcnRMaXN0ZW5SZW1vdGVDaGFuZ2VzKCk7XG5cbiAgICAgIHJldHVybiB0aGlzLl9kYXRhO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKChlcnJvciAmJiBlcnJvci5tZXNzYWdlKSB8fCBlcnJvcik7XG4gICAgICB0aGlzLnJlc2V0RGF0YSgpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgYXV0aGVudGljYXRlKGRhdGE/OiBBdXRoRGF0YSkge1xuICAgIC8vIFdhaXQgdGhlIGF1dGggdG9rZW4sIHRoZW4gY29udGludWVcbiAgICBjb25zdCB0b2tlblR5cGUgPSBhd2FpdCBmaXJzdE5vdE5pbFByb21pc2UodGhpcy5fdG9rZW5UeXBlJCk7XG5cbiAgICAvLyBCYXNpYyBhdXRoXG4gICAgaWYgKHRva2VuVHlwZSA9PT0gJ2Jhc2ljJyB8fCB0b2tlblR5cGUgPT09ICdiYXNpYy1hbmQtdG9rZW4nKSB7XG4gICAgICAvLyBHZW5lcmF0ZSB0aGUgYXV0aEJhc2ljLCBpZiB1c2VkXG4gICAgICBpZiAoIXRoaXMuX2NhY2hlLmF1dGhCYXNpYykge1xuICAgICAgICAvLyBTa2lwIGlmIHRva2VuIGFscmVhZHkgcHJvdmlkZWRcbiAgICAgICAgaWYgKCEodGhpcy5fY2FjaGUuYXV0aFRva2VuICYmIHRva2VuVHlwZSA9PT0gJ2Jhc2ljLWFuZC10b2tlbicpKSB7XG4gICAgICAgICAgaWYgKCFkYXRhIHx8ICFkYXRhLnVzZXJuYW1lIHx8ICFkYXRhLnBhc3N3b3JkKSB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdXNlcm5hbWUgYW5kIHBhc3N3b3JkJyk7XG4gICAgICAgICAgdGhpcy5fY2FjaGUuYXV0aEJhc2ljID0gQ3J5cHRvU2VydmljZS5lbmNvZGVCYXNlNjQoYCR7ZGF0YS51c2VybmFtZX06JHtkYXRhLnBhc3N3b3JkfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLm9uQXV0aEJhc2ljQ2hhbmdlLm5leHQodGhpcy5fY2FjaGUuYXV0aEJhc2ljKTtcbiAgICB9XG5cbiAgICAvLyBHZW5lcmF0ZSB0aGUgYXV0aFRva2VuLCBpZiB1c2VkXG4gICAgaWYgKHRva2VuVHlwZSA9PT0gJ3Rva2VuJyB8fCB0b2tlblR5cGUgPT09ICdiYXNpYy1hbmQtdG9rZW4nKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLl9jYWNoZS5hdXRoVG9rZW4gPSBhd2FpdCB0aGlzLmF1dGhlbnRpY2F0ZUFuZEdldFRva2VuKHRoaXMuX2NhY2hlLmF1dGhUb2tlbik7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBOZXZlciBhdXRoZW50aWNhdGUsIG9yIG5vdCByZWFkeSBmb3Igb2ZmbGluZSBtb2RlID0+IGV4aXRcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgIHRoaXMucmVzZXREYXRhKCk7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEZvcmdldCBhdXRoQmFzaWMsIHRvIHN3aXRjaCB0byBhdXRoVG9rZW5cbiAgICBpZiAodG9rZW5UeXBlID09PSAnYmFzaWMtYW5kLXRva2VuJykge1xuICAgICAgdGhpcy5fY2FjaGUuYXV0aEJhc2ljID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5vbkF1dGhCYXNpY0NoYW5nZS5uZXh0KHVuZGVmaW5lZCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgbG9naW4oZGF0YTogQXV0aERhdGEpOiBQcm9taXNlPEFjY291bnQ+IHtcbiAgICBpZiAoIWRhdGEgfHwgIWRhdGEudXNlcm5hbWUgfHwgIWRhdGEucGFzc3dvcmQpIHRocm93IG5ldyBFcnJvcignTWlzc2luZyByZXF1aXJlZCB1c2VybmFtZSBvciBwYXNzd29yZCcpO1xuXG4gICAgY29uc29sZS5kZWJ1ZygnW2FjY291bnRdIExvZ2luLi4uJyk7XG5cbiAgICBsZXQga2V5cGFpcjtcbiAgICB0cnkge1xuICAgICAga2V5cGFpciA9IGF3YWl0IENyeXB0b1NlcnZpY2Uuc2NyeXB0S2V5cGFpcihkYXRhLnVzZXJuYW1lLCBkYXRhLnBhc3N3b3JkKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICB0aGlzLnJlc2V0RGF0YSgpO1xuICAgICAgdGhyb3cgeyBjb2RlOiBFcnJvckNvZGVzLlVOS05PV05fRVJST1IsIG1lc3NhZ2U6ICdFUlJPUi5TQ1JZUFRfRVJST1InIH07XG4gICAgfVxuXG4gICAgLy8gU3RvcmUgcHVia2V5K2tleXBhaXJcbiAgICB0aGlzLl9jYWNoZS5wdWJrZXkgPSBCYXNlNTguZW5jb2RlKGtleXBhaXIucHVibGljS2V5KTtcbiAgICB0aGlzLl9jYWNoZS5rZXlwYWlyID0ga2V5cGFpcjtcblxuICAgIC8vIFRyeSB0byBsb2FkIHByZXZpb3VzIHRva2VuXG4gICAgbGV0IHByZXZpb3VzVG9rZW46IHN0cmluZyA9IGF3YWl0IHRoaXMuc3RvcmFnZS5nZXQoVE9LRU5fU1RPUkFHRV9LRVkpO1xuICAgIHByZXZpb3VzVG9rZW4gPSAocHJldmlvdXNUb2tlbiAmJiBwcmV2aW91c1Rva2VuLnN0YXJ0c1dpdGgodGhpcy5fY2FjaGUucHVia2V5KSAmJiBwcmV2aW91c1Rva2VuKSB8fCBudWxsO1xuXG4gICAgLy8gT2ZmbGluZSBtb2RlXG4gICAgY29uc3Qgb2ZmbGluZSA9IHRoaXMuc2V0dGluZ3MuaGFzT2ZmbGluZUZlYXR1cmUoKSAmJiAodGhpcy5uZXR3b3JrLm9mZmxpbmUgfHwgZGF0YS5vZmZsaW5lID09PSB0cnVlKTtcbiAgICBpZiAob2ZmbGluZSkge1xuICAgICAgdGhpcy5fY2FjaGUuYXV0aFRva2VuID0gcHJldmlvdXNUb2tlbjtcblxuICAgICAgLy8gTWFrZSBzdXJlIG5ldHdvcmsgaWYgc2V0IGFzIG9mZmxpbmVcbiAgICAgIHRoaXMubmV0d29yay5zZXRGb3JjZU9mZmxpbmUodHJ1ZSwgeyBzaG93VG9hc3Q6IGZhbHNlIH0pO1xuICAgICAgY29uc29sZS5pbmZvKGBbYWNjb3VudF0gTG9naW4gW09LXSB7cHVia2V5OiAke3RoaXMuX2NhY2hlLnB1YmtleS5zdWJzdHIoMCwgOCl9fSwge29mZmxpbmU6IHRydWV9YCk7XG4gICAgfVxuXG4gICAgLy8gT25saW5lIG1vZGU6IHRyeSB0byBhdXRoIG9uIHBvZFxuICAgIGVsc2Uge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5hdXRoZW50aWNhdGUoZGF0YSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBOZXZlciBhdXRoZW50aWNhdGUsIG9yIG5vdCByZWFkeSBmb3Igb2ZmbGluZSBtb2RlID0+IGV4aXRcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgIHRoaXMucmVzZXREYXRhKCk7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIExvYWQgYWNjb3VudCBkYXRhXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMubG9hZERhdGEoeyBvZmZsaW5lLCBmZXRjaFBvbGljeTogJ25ldHdvcmstb25seScgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBJZiBhY2NvdW50IG5vdCBmb3VuZCwgY2hlY2sgaWYgZW1haWwgaXMgdmFsaWRcbiAgICAgIGlmIChlcnIgJiYgK2Vyci5jb2RlID09PSBFcnJvckNvZGVzLkxPQURfQUNDT1VOVF9FUlJPUikge1xuICAgICAgICAvLyBDaGVjayBlbWFpbCBleGlzdHNcbiAgICAgICAgaWYgKGRhdGEudXNlcm5hbWUuaW5kZXhPZignQCcpICE9PSAtMSkge1xuICAgICAgICAgIGxldCBpc0VtYWlsRXhpc3RzO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpc0VtYWlsRXhpc3RzID0gYXdhaXQgdGhpcy5pc0VtYWlsRXhpc3RzKGRhdGEudXNlcm5hbWUpO1xuICAgICAgICAgIH0gY2F0Y2ggKG90aGVyRXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IGVycjsgLy8gcmVzZW5kIHRoZSBmaXJzdCBlcnJvclxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIEVtYWlsIG5vdCBleGlzdHMgKG5vIGFjY291bnQpXG4gICAgICAgICAgaWYgKCFpc0VtYWlsRXhpc3RzKSB7XG4gICAgICAgICAgICB0aHJvdyB7IGNvZGU6IEVycm9yQ29kZXMuVU5LTk9XTl9BQ0NPVU5UX0VNQUlMLCBtZXNzYWdlOiAnRVJST1IuVU5LTk9XTl9BQ0NPVU5UX0VNQUlMJyB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEVtYWlsIGV4aXN0cywgc28gZXJyb3IgPSAnYmFkIHBhc3N3b3JkJ1xuICAgICAgICB0aHJvdyB7IGNvZGU6IEVycm9yQ29kZXMuQkFEX1BBU1NXT1JELCBtZXNzYWdlOiAnRVJST1IuQkFEX1BBU1NXT1JEJyB9O1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBlcnI7IC8vIHJlc2VuZCB0aGUgZmlyc3QgZXJyb3JcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgLy8gU3RvcmUgdG8gbG9jYWwgc3RvcmFnZVxuICAgICAgYXdhaXQgdGhpcy5zYXZlTG9jYWxseSgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIHRoaXMucmVzZXREYXRhKCk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICAvLyBFbWl0IGV2ZW50IHRvIG9ic2VydmVyc1xuICAgIHRoaXMub25Mb2dpbi5uZXh0KHRoaXMuX2RhdGEpO1xuICAgIHRoaXMub25DaGFuZ2UubmV4dCh0aGlzLl9kYXRhKTtcblxuICAgIGlmICh0aGlzLl9lbmFibGVMaXN0ZW5DaGFuZ2VzKSB0aGlzLnN0YXJ0TGlzdGVuUmVtb3RlQ2hhbmdlcygpO1xuXG4gICAgcmV0dXJuIHRoaXMuX2RhdGE7XG4gIH1cblxuICBhc3luYyByZWxvYWQob3B0cz86IHsgc2hvd1RvYXN0PzogYm9vbGVhbiB9KTogUHJvbWlzZTxBY2NvdW50PiB7XG4gICAgaWYgKCF0aGlzLl9jYWNoZS5wdWJrZXkpIHRocm93IG5ldyBFcnJvcignVXNlciBub3QgbG9nZ2VkJyk7XG4gICAgaWYgKHRoaXMubmV0d29yay5vZmZsaW5lKSB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBjaGVjayBhY2NvdW50IGluIG9mZmxpbmUgbW9kZScpO1xuXG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBjb25zb2xlLmRlYnVnKGBbYWNjb3VudF0gUmVsb2FkaW5nIGFjY291bnQuLi5gKTtcbiAgICBjb25zdCB3YXNMb2dpbiA9IHRoaXMuaXNMb2dpbigpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMubG9hZERhdGEoKTtcbiAgICAgIGF3YWl0IHRoaXMuc2F2ZUxvY2FsbHkoKTtcblxuICAgICAgY29uc29sZS5kZWJ1ZyhgW2FjY291bnRdIFJlbG9hZGluZyBhY2NvdW50IFtPS10gaW4gJHtEYXRlLm5vdygpIC0gbm93fW1zYCk7XG5cbiAgICAgIC8vIEVtaXQgbG9naW4gZXZlbnQgdG8gc3Vic2NyaWJlcnNcbiAgICAgIHRoaXMub25Mb2dpbi5uZXh0KHRoaXMuX2RhdGEpO1xuICAgICAgdGhpcy5vbkNoYW5nZS5uZXh0KHRoaXMuX2RhdGEpO1xuXG4gICAgICAvLyBEaXNwbGF5IHRvYXN0ICh3aXRob3V0IGF3YWl0LCBiZWNhdXNlIG5vdCBuZWVkIHRvIHdhaXQgdG9hc3QgY2xvc2UgZXZlbnQpXG4gICAgICBpZiAoIW9wdHMgfHwgb3B0cy5zaG93VG9hc3QgIT09IGZhbHNlKSB7XG4gICAgICAgIHRoaXMuc2hvd1RvYXN0KHsgbWVzc2FnZTogJ0FDQ09VTlQuSU5GTy5SRUxPQURFRCcsIHR5cGU6ICdpbmZvJyB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuX2RhdGE7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIENhbm5vdCByZWxvYWQgYnV0IHdhcyBsb2dpbjogZm9yY2UgdG8gbG9nb3V0XG4gICAgICBpZiAod2FzTG9naW4gJiYgIXRoaXMuaXNMb2dpbigpKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFthY2NvdW50XSBSZWxvYWRpbmcgYWNjb3VudCBmYWlsZWQuIFdpbGwgZm9yY2UgbG9nb3V0Li4uYCwgZXJyb3IpO1xuICAgICAgICBhd2FpdCB0aGlzLmxvZ291dCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBvciB1cGRhdGUgYW4gdXNlciBhY2NvdW50LCB0byB0aGUgcmVtb3RlIHN0b3JhZ2VcbiAgICpcbiAgICogQHBhcmFtIGFjY291bnRcbiAgICovXG4gIGFzeW5jIHNhdmUoYWNjb3VudDogQWNjb3VudCk6IFByb21pc2U8QWNjb3VudD4ge1xuICAgIGlmICghdGhpcy5fY2FjaGUucHVia2V5KSByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ1VzZXIgbm90IGxvZ2dlZCcpO1xuICAgIGlmICh0aGlzLl9jYWNoZS5wdWJrZXkgIT09IGFjY291bnQucHVia2V5KSByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ05vdCB1c2VyIGFjY291bnQnKTtcblxuICAgIGFjY291bnQgPSBhd2FpdCB0aGlzLnNhdmVSZW1vdGVseShhY2NvdW50LCB0aGlzLl9jYWNoZS5rZXlwYWlyKTtcblxuICAgIC8vIFNldCBkZWZhdWx0c1xuICAgIGFjY291bnQuYXZhdGFyID0gYWNjb3VudC5hdmF0YXIgfHwgdGhpcy5lbnZpcm9ubWVudC5iYXNlVXJsICsgREVGQVVMVF9BVkFUQVJfSU1BR0U7XG4gICAgdGhpcy5fY2FjaGUubWFpblByb2ZpbGUgPSBQZXJzb25VdGlscy5nZXRNYWluUHJvZmlsZShhY2NvdW50LnByb2ZpbGVzKTtcblxuICAgIHRoaXMuX2RhdGEgPSBhY2NvdW50O1xuXG4gICAgLy8gVXBkYXRlIGNhY2hlXG4gICAgdGhpcy5fY2FjaGUucGVyc29uID0gYWNjb3VudC5hc1BlcnNvbigpO1xuICAgIHRoaXMuX2NhY2hlLmRlcGFydG1lbnQgPSB0aGlzLl9jYWNoZS5wZXJzb24uZGVwYXJ0bWVudDtcblxuICAgIHRoaXMuX2NhY2hlLmxvYWRlZCA9IHRydWU7XG5cbiAgICAvLyBTYXZlIGxvY2FsbHkgKGluIHN0b3JhZ2UpXG4gICAgYXdhaXQgdGhpcy5zYXZlTG9jYWxseSgpO1xuXG4gICAgLy8gU2VuZCBldmVudFxuICAgIHRoaXMub25Mb2dpbi5uZXh0KHRoaXMuX2RhdGEpO1xuICAgIHRoaXMub25DaGFuZ2UubmV4dCh0aGlzLl9kYXRhKTtcblxuICAgIHJldHVybiB0aGlzLl9kYXRhO1xuICB9XG5cbiAgYXN5bmMgbG9nb3V0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGhhZEF1dGhUb2tlbiA9IHRoaXMuX2NhY2hlLmF1dGhUb2tlbiAmJiB0cnVlO1xuICAgIGNvbnN0IGhhZEF1dGhCYXNpYyA9IHRoaXMuX2NhY2hlLmF1dGhCYXNpYyAmJiB0cnVlO1xuICAgIGNvbnN0IHB1YmtleSA9IHRoaXMuX2NhY2hlICYmIHRoaXMuX2NhY2hlLnB1YmtleTtcblxuICAgIC8vIE5vdGlmeSBvYnNlcnZlcnNcbiAgICB0aGlzLm9uV2lsbExvZ291dC5uZXh0KHRoaXMuYWNjb3VudCk7XG5cbiAgICB0aGlzLnJlc2V0RGF0YSgpO1xuXG4gICAgaWYgKCF0aGlzLnNldHRpbmdzLmhhc09mZmxpbmVGZWF0dXJlKCkpIHtcbiAgICAgIC8vIFJlbW92ZSBhbGwgZGF0YSBmcm9tIHRoZSBsb2NhbCBzdG9yYWdlXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIHRoaXMuc3RvcmFnZS5yZW1vdmUoUFVCS0VZX1NUT1JBR0VfS0VZKSxcbiAgICAgICAgdGhpcy5zdG9yYWdlLnJlbW92ZShUT0tFTl9TVE9SQUdFX0tFWSksXG4gICAgICAgIHRoaXMuc3RvcmFnZS5yZW1vdmUoQUNDT1VOVF9TVE9SQUdFX0tFWSksXG4gICAgICAgIChwdWJrZXkgJiYgdGhpcy5zdG9yYWdlLnJlbW92ZShBQ0NPVU5UX1NUT1JBR0VfS0VZICsgJyMnICsgcHVia2V5KSkgfHwgUHJvbWlzZS5yZXNvbHZlKCksXG4gICAgICAgIHRoaXMuc3RvcmFnZS5yZW1vdmUoU0VDS0VZX1NUT1JBR0VfS0VZKSxcbiAgICAgIF0pO1xuICAgIH1cblxuICAgIC8vIE9mZmxpbmUgZmVhdHVyZXMgZW5hYmxlOiBuZWVkIHRvIGtlZXAgc29tZSBkYXRhXG4gICAgZWxzZSB7XG4gICAgICAvLyBBbHdheXMgcmVtb3ZlIG9ubHkgc2VjcmV0IGtleVxuICAgICAgLy8gQnV0IGtlZXA6XG4gICAgICAvLyAtIGFjY291bnQgYnkgcHVia2V5XG4gICAgICAvLyAtIGF1dGggdG9rZW5cbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKFt0aGlzLnN0b3JhZ2UucmVtb3ZlKFBVQktFWV9TVE9SQUdFX0tFWSksIHRoaXMuc3RvcmFnZS5yZW1vdmUoQUNDT1VOVF9TVE9SQUdFX0tFWSksIHRoaXMuc3RvcmFnZS5yZW1vdmUoU0VDS0VZX1NUT1JBR0VfS0VZKV0pO1xuICAgIH1cblxuICAgIC8vIENsZWFuIHBhZ2UgaGlzdG9yeSwgaW4gbG9jYWwgc2V0dGluZ3NcbiAgICBhd2FpdCB0aGlzLnNldHRpbmdzLmNsZWFyUGFnZUhpc3RvcnkoKTtcblxuICAgIC8vIE5vdGlmeSBvYnNlcnZlcnNcbiAgICB0aGlzLm9uTG9nb3V0Lm5leHQoKTtcbiAgICBpZiAoaGFkQXV0aFRva2VuKSB0aGlzLm9uQXV0aFRva2VuQ2hhbmdlLm5leHQodW5kZWZpbmVkKTtcbiAgICBpZiAoaGFkQXV0aEJhc2ljKSB0aGlzLm9uQXV0aEJhc2ljQ2hhbmdlLm5leHQodW5kZWZpbmVkKTtcbiAgICB0aGlzLm9uQ2hhbmdlLm5leHQodW5kZWZpbmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIGEgYWNjb3VudFxuICAgKlxuICAgKiBAcGFyYW0gb3B0c1xuICAgKi9cbiAgYXN5bmMgbG9hZChvcHRzPzogeyBvZmZsaW5lPzogYm9vbGVhbjsgZmV0Y2hQb2xpY3k/OiBGZXRjaFBvbGljeTsgcXVlcnk/OiBhbnkgfSk6IFByb21pc2U8QWNjb3VudCB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IG5vdyA9IHRoaXMuX2RlYnVnICYmIERhdGUubm93KCk7XG4gICAgaWYgKHRoaXMuX2RlYnVnKSBjb25zb2xlLmRlYnVnKGBbYWNjb3VudF0gTG9hZGluZyBhY2NvdW50Li4uYCk7XG4gICAgbGV0IGpzb246IGFueTtcblxuICAgIC8vIExvYWQgbG9jYWxseVxuICAgIGNvbnN0IG9mZmxpbmUgPVxuICAgICAgKHRoaXMubmV0d29yay5vZmZsaW5lICYmICghb3B0cyB8fCAob3B0cy5mZXRjaFBvbGljeSAhPT0gJ25ldHdvcmstb25seScgJiYgb3B0cy5mZXRjaFBvbGljeSAhPT0gJ25vLWNhY2hlJykpKSB8fFxuICAgICAgKG9wdHMgJiYgb3B0cy5vZmZsaW5lID09PSB0cnVlKTtcbiAgICBpZiAob2ZmbGluZSkge1xuICAgICAganNvbiA9IGF3YWl0IHRoaXMuc3RvcmFnZS5nZXQoQUNDT1VOVF9TVE9SQUdFX0tFWSk7XG4gICAgICBqc29uID0gKGpzb24gJiYgdHlwZW9mIGpzb24gPT09ICdzdHJpbmcnICYmIEpTT04ucGFyc2UoanNvbikpIHx8IGpzb247XG4gICAgICBqc29uID0gKGpzb24gJiYgdGhpcy5fY2FjaGUucHVia2V5ICYmIGpzb24ucHVia2V5ID09PSB0aGlzLl9jYWNoZS5wdWJrZXkgJiYganNvbikgfHwgbnVsbDtcbiAgICAgIGlmICghanNvbiAmJiB0aGlzLl9jYWNoZS5wdWJrZXkpIHtcbiAgICAgICAganNvbiA9IGF3YWl0IHRoaXMuc3RvcmFnZS5nZXQoQUNDT1VOVF9TVE9SQUdFX0tFWSArICcjJyArIHRoaXMuX2NhY2hlLnB1YmtleSk7XG4gICAgICAgIGpzb24gPSAoanNvbiAmJiB0eXBlb2YganNvbiA9PT0gJ3N0cmluZycgJiYgSlNPTi5wYXJzZShqc29uKSkgfHwganNvbjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBMb2FkIHJlbW90ZWx5XG4gICAgZWxzZSB7XG4gICAgICBjb25zdCBxdWVyeSA9IG9wdHM/LnF1ZXJ5IHx8ICh0aGlzLmFwaVRva2VuRW5hYmxlZCA/IFF1ZXJpZXMubG9hZFdpdGhUb2tlbnMgOiBRdWVyaWVzLmxvYWQpO1xuICAgICAgY29uc3QgeyBkYXRhIH0gPSBhd2FpdCB0aGlzLmdyYXBocWwucXVlcnk8eyBkYXRhOiBhbnkgfT4oe1xuICAgICAgICBxdWVyeSxcbiAgICAgICAgZXJyb3I6IHsgY29kZTogRXJyb3JDb2Rlcy5MT0FEX0FDQ09VTlRfRVJST1IsIG1lc3NhZ2U6ICdFUlJPUi5MT0FEX0FDQ09VTlRfRVJST1InIH0sXG4gICAgICAgIGZldGNoUG9saWN5OiAob3B0cyAmJiBvcHRzLmZldGNoUG9saWN5KSB8fCAnbm8tY2FjaGUnIHx8IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgICAganNvbiA9IGRhdGE7XG4gICAgfVxuXG4gICAgaWYgKGpzb24pIHtcbiAgICAgIGNvbnN0IGFjY291bnQgPSBBY2NvdW50LmZyb21PYmplY3QoanNvbik7XG4gICAgICBpZiAodGhpcy5fZGVidWcpIGNvbnNvbGUuZGVidWcoYFthY2NvdW50XSBBY2NvdW50IGxvYWRlZCBpbiAke0RhdGUubm93KCkgLSBub3d9bXNgLCBhY2NvdW50KTtcbiAgICAgIHJldHVybiBhY2NvdW50O1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLndhcm4oYFthY2NvdW50XSBBY2NvdW50IG5vdCBmb3VuZCAhYCk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlVG9rZW4oZmxhZ3M6IG51bWJlcik6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3Qgbm93ID0gdGhpcy5fZGVidWcgJiYgRGF0ZS5ub3coKTtcbiAgICBpZiAodGhpcy5fZGVidWcpIGNvbnNvbGUuZGVidWcoYFthY2NvdW50XSBHZW5lcmF0ZSB0b2tlbi4uLmApO1xuXG4gICAgY29uc3QgYXV0aENoYWxsZW5nZSA9IGF3YWl0IHRoaXMuZ2V0QXV0aENoYWxsZW5nZSgpO1xuICAgIC8vIEFkZCBGbGFncyB0byBjaGFsbGVuZ2VcbiAgICBjb25zdCBjaGFsbGVuZ2UgPSBgJHthdXRoQ2hhbGxlbmdlLmNoYWxsZW5nZX06JHtmbGFnc31gO1xuICAgIGNvbnN0IHNpZ25hdHVyZSA9IGF3YWl0IENyeXB0b1NlcnZpY2Uuc2lnbihjaGFsbGVuZ2UsIHRoaXMuX2NhY2hlLmtleXBhaXIpO1xuICAgIGNvbnN0IG5ld1Rva2VuID0gYCR7dGhpcy5fY2FjaGUucHVia2V5fToke2NoYWxsZW5nZX18JHtzaWduYXR1cmV9YDtcblxuICAgIGlmIChuZXdUb2tlbikge1xuICAgICAgaWYgKHRoaXMuX2RlYnVnKSBjb25zb2xlLmRlYnVnKGBbYWNjb3VudF0gVG9rZW4gZ2VuZXJhdGVkIGluICR7RGF0ZS5ub3coKSAtIG5vd31tc2ApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLndhcm4oYFthY2NvdW50XSBUb2tlbiBnZW5lcmF0aW9uIGZhaWxlZCAhYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ld1Rva2VuO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGVtYWlsIGlzIGF2YWlsYWJsZSBmb3IgbmV3IGFjY291bnQgcmVnaXN0cmF0aW9uLlxuICAgKiBUaHJvdyBhbiBlcnJvciBpZiBub3QgYXZhaWxhYmxlXG4gICAqXG4gICAqIEBwYXJhbSBlbWFpbFxuICAgKi9cbiAgYXN5bmMgY2hlY2tFbWFpbEF2YWlsYWJsZShlbWFpbDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgaXNFbWFpbEV4aXN0cyA9IGF3YWl0IHRoaXMuaXNFbWFpbEV4aXN0cyhlbWFpbCk7XG4gICAgaWYgKGlzRW1haWxFeGlzdHMpIHtcbiAgICAgIHRocm93IHsgY29kZTogRXJyb3JDb2Rlcy5FTUFJTF9BTFJFQURZX1JFR0lTVEVSRUQsIG1lc3NhZ2U6ICdFUlJPUi5FTUFJTF9BTFJFQURZX1JFR0lTVEVSRUQnIH07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGVtYWlsIGlzIGV4aXN0cyBpbiBzZXJ2ZXIuXG4gICAqXG4gICAqIEBwYXJhbSBlbWFpbFxuICAgKi9cbiAgYXN5bmMgaXNFbWFpbEV4aXN0cyhlbWFpbDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKHRoaXMuX2RlYnVnKSBjb25zb2xlLmRlYnVnKCdbYWNjb3VudF0gQ2hlY2tpbmcgaWYgeycgKyBlbWFpbCArICd9IGV4aXN0cy4uLicpO1xuXG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuZ3JhcGhxbC5xdWVyeTx7IGlzRW1haWxFeGlzdHM6IGJvb2xlYW4gfSwgSXNFbWFpbEV4aXN0c1ZhcmlhYmxlcz4oe1xuICAgICAgcXVlcnk6IElzRW1haWxFeGlzdHNRdWVyeSxcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICBlbWFpbCxcbiAgICAgICAgaGFzaDogdW5kZWZpbmVkLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZygnW2FjY291bnRdIEVtYWlsIGV4aXN0OiAnICsgKGRhdGEgJiYgZGF0YS5pc0VtYWlsRXhpc3RzKSk7XG5cbiAgICByZXR1cm4gZGF0YSAmJiBkYXRhLmlzRW1haWxFeGlzdHM7XG4gIH1cblxuICBhc3luYyBzZW5kQ29uZmlybWF0aW9uRW1haWwoZW1haWw6IHN0cmluZywgbG9jYWxlPzogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgbG9jYWxlID0gbG9jYWxlIHx8IHRoaXMuc2V0dGluZ3MubG9jYWxlO1xuICAgIGNvbnNvbGUuZGVidWcoJ1thY2NvdW50XSBTZW5kaW5nIGNvbmZpcm1hdGlvbiBlbWFpbCB0byB7JyArIGVtYWlsICsgJ30gd2l0aCBsb2NhbGUgeycgKyBsb2NhbGUgKyAnfS4uLicpO1xuXG4gICAgY29uc3QgeyBkYXRhIH0gPSBhd2FpdCB0aGlzLmdyYXBocWwucXVlcnk8eyBkYXRhOiBib29sZWFuIH0+KHtcbiAgICAgIHF1ZXJ5OiBTZW5kQ29uZmlybUVtYWlsUXVlcnksXG4gICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgZW1haWwsXG4gICAgICAgIGxvY2FsZSxcbiAgICAgIH0sXG4gICAgICBlcnJvcjoge1xuICAgICAgICBjb2RlOiBFcnJvckNvZGVzLlNFTlRfQ09ORklSTUFUSU9OX0VNQUlMX0ZBSUxFRCxcbiAgICAgICAgbWVzc2FnZTogJ0VSUk9SLlNFTlRfQUNDT1VOVF9DT05GSVJNQVRJT05fRU1BSUxfRkFJTEVEJyxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIGFzeW5jIGNvbmZpcm1FbWFpbChlbWFpbDogc3RyaW5nLCBjb2RlOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zb2xlLmRlYnVnKCdbYWNjb3VudF0gU2VuZGluZyBjb25maXJtIHJlcXVlc3QgZm9yIGVtYWlsIHsnICsgZW1haWwgKyAnfSB3aXRoIGNvZGUgeycgKyBjb2RlICsgJ30uLi4nKTtcblxuICAgIGNvbnN0IHsgZGF0YSB9ID0gYXdhaXQgdGhpcy5ncmFwaHFsLnF1ZXJ5PHsgZGF0YTogYm9vbGVhbiB9Pih7XG4gICAgICBxdWVyeTogQ29uZmlybUVtYWlsUXVlcnksXG4gICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgZW1haWwsXG4gICAgICAgIGNvZGUsXG4gICAgICB9LFxuICAgICAgZXJyb3I6IHtcbiAgICAgICAgY29kZTogRXJyb3JDb2Rlcy5DT05GSVJNX0VNQUlMX0ZBSUxFRCxcbiAgICAgICAgbWVzc2FnZTogJ0VSUk9SLkNPTkZJUk1fQUNDT1VOVF9FTUFJTF9GQUlMRUQnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIGFzeW5jIHNlbmRSZXNldFBhc3N3b3JkRW1haWwodXNlcm5hbWU6IHN0cmluZywgbG9jYWxlPzogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgbG9jYWxlID0gbG9jYWxlIHx8IHRoaXMuc2V0dGluZ3MubG9jYWxlO1xuXG4gICAgY29uc29sZS5kZWJ1ZyhgW2FjY291bnRdIFNlbmRpbmcgY2hhbmdlIHBhc3N3b3JkIGVtYWlsIHRvIHske3VzZXJuYW1lfX0gd2l0aCBsb2NhbGUgeyR7bG9jYWxlfX0uLi5gKTtcblxuICAgIGNvbnN0IHsgZGF0YTogaXNPayB9ID0gYXdhaXQgdGhpcy5ncmFwaHFsLnF1ZXJ5PHsgZGF0YTogYm9vbGVhbiB9Pih7XG4gICAgICBxdWVyeTogU2VuZFJlc2V0UGFzc3dvcmRFbWFpbFF1ZXJ5LFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIHVzZXJuYW1lLFxuICAgICAgICBsb2NhbGUsXG4gICAgICB9LFxuICAgICAgZXJyb3I6IHtcbiAgICAgICAgY29kZTogRXJyb3JDb2Rlcy5BVVRIX1VQREFURV9QVUJLRVlfRVJST1IsXG4gICAgICAgIG1lc3NhZ2U6ICdBQ0NPVU5ULkVSUk9SLkNIQU5HRV9QVUJLRVlfRVJST1InLFxuICAgICAgfSxcbiAgICAgIGZldGNoUG9saWN5OiAnbm8tY2FjaGUnLFxuICAgIH0pO1xuICAgIHJldHVybiBpc09rO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlUHVia2V5KGRhdGE6IEF1dGhEYXRhKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKCFkYXRhLnVzZXJuYW1lIHx8ICFkYXRhLnBhc3N3b3JkKSB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgcmVxdWlyZWQgdXNlcm5hbWUgb3IgcGFzc3dvcmQnKTtcbiAgICBpZiAoIXRoaXMuaXNMb2dpbigpKSB0aHJvdyBuZXcgRXJyb3IoJ1Nob3VsZCBiZSBsb2dpbicpO1xuXG4gICAgY29uc3Qga2V5cGFpciA9IGF3YWl0IENyeXB0b1NlcnZpY2Uuc2NyeXB0S2V5cGFpcihkYXRhLnVzZXJuYW1lLCBkYXRhLnBhc3N3b3JkKTtcbiAgICBjb25zdCBwdWJrZXkgPSBCYXNlNTguZW5jb2RlKGtleXBhaXIucHVibGljS2V5KTtcblxuICAgIGNvbnNvbGUuZGVidWcoYFthY2NvdW50XSBVcGRhdGluZyBhY2NvdW50IHB1YmtleSB0byAke3B1YmtleX0gLi4uYCk7XG5cbiAgICBjb25zdCB7IGRhdGE6IHJlcyB9ID0gYXdhaXQgdGhpcy5ncmFwaHFsLnF1ZXJ5PHsgZGF0YTogYm9vbGVhbiB9Pih7XG4gICAgICBxdWVyeTogVXBkYXRlUHViS2V5UXVlcnksXG4gICAgICB2YXJpYWJsZXM6IHsgcHVia2V5IH0sXG4gICAgICBlcnJvcjoge1xuICAgICAgICBjb2RlOiBFcnJvckNvZGVzLkFVVEhfVVBEQVRFX1BVQktFWV9FUlJPUixcbiAgICAgICAgbWVzc2FnZTogJ0VSUk9SLkFDQ09VTlQuVVBEQVRFX1BVQktFWV9FUlJPUicsXG4gICAgICB9LFxuICAgICAgZmV0Y2hQb2xpY3k6ICduby1jYWNoZScsXG4gICAgfSk7XG5cbiAgICBjb25zb2xlLmRlYnVnKGBbYWNjb3VudF0gVXBkYXRpbmcgYWNjb3VudCBwdWJrZXkgcmVzcG9uc2VgLCByZXMpO1xuXG4gICAgaWYgKHJlcykge1xuICAgICAgYXdhaXQgdGhpcy5sb2dvdXQoKTtcbiAgICAgIGF3YWl0IHRoaXMubG9naW4oZGF0YSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIGFzeW5jIHJlc2V0UHVia2V5KGRhdGE6IEF1dGhEYXRhLCB0b2tlbjogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKHRoaXMuaXNMb2dpbigpKSB7XG4gICAgICBhd2FpdCB0aGlzLmxvZ291dCgpO1xuICAgIH1cblxuICAgIC8vIFBhcnNlIGNoYWxsZW5nZVxuICAgIGNvbnN0IGNoYWxsZW5nZSA9IHRva2VuLnNwbGl0KCd8JywgMilbMF0uc3BsaXQoJzonLCAyKVsxXTtcbiAgICBjb25zdCBrZXlwYWlyID0gYXdhaXQgQ3J5cHRvU2VydmljZS5zY3J5cHRLZXlwYWlyKGRhdGEudXNlcm5hbWUsIGRhdGEucGFzc3dvcmQpO1xuICAgIGNvbnN0IHB1YmtleSA9IEJhc2U1OC5lbmNvZGUoa2V5cGFpci5wdWJsaWNLZXkpO1xuICAgIGNvbnN0IHNpZ25hdHVyZSA9IGF3YWl0IENyeXB0b1NlcnZpY2Uuc2lnbihjaGFsbGVuZ2UsIGtleXBhaXIpO1xuICAgIGNvbnN0IG5ld1Rva2VuID0gYCR7cHVia2V5fToke2NoYWxsZW5nZX18JHtzaWduYXR1cmV9YDtcblxuICAgIGNvbnNvbGUuZGVidWcoYFthY2NvdW50XSBSZXNldHRpbmcgYWNjb3VudCBwdWJrZXksIHVzaW5nIHRva2VuOiBgLCBuZXdUb2tlbik7XG5cbiAgICBjb25zdCB7IGRhdGE6IHJlcyB9ID0gYXdhaXQgdGhpcy5ncmFwaHFsLnF1ZXJ5PHsgZGF0YTogYm9vbGVhbiB9Pih7XG4gICAgICBxdWVyeTogUmVzZXRBY2NvdW50UHVia2V5UXVlcnksXG4gICAgICB2YXJpYWJsZXM6IHsgdG9rZW46IG5ld1Rva2VuLCB1c2VybmFtZTogZGF0YS51c2VybmFtZSB9LFxuICAgICAgZXJyb3I6IHtcbiAgICAgICAgY29kZTogRXJyb3JDb2Rlcy5BVVRIX1VQREFURV9QVUJLRVlfRVJST1IsXG4gICAgICAgIG1lc3NhZ2U6ICdFUlJPUi5BQ0NPVU5ULlVQREFURV9QVUJLRVlfRVJST1InLFxuICAgICAgfSxcbiAgICAgIGZldGNoUG9saWN5OiAnbm8tY2FjaGUnLFxuICAgIH0pO1xuXG4gICAgLy8gTG9naW5cbiAgICBpZiAocmVzKSB7XG4gICAgICBhd2FpdCB0aGlzLmxvZ2luKGRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICBsaXN0ZW5DaGFuZ2VzKG9wdHM/OiBBY2NvdW50V2F0Y2hPcHRpb25zKTogU3Vic2NyaXB0aW9uIHtcbiAgICBpZiAodGhpcy5fZW5hYmxlTGlzdGVuQ2hhbmdlcykgcmV0dXJuIG5ldyBTdWJzY3JpcHRpb24oKTsgLy8gQWxyZWFkeSBzdGFydGVkOiBza2lwXG5cbiAgICByZXR1cm4gdGhpcy5zdGFydExpc3RlblJlbW90ZUNoYW5nZXMob3B0cyk7XG4gIH1cblxuICBnZXQgYWRkaXRpb25hbEZpZWxkcygpOiBGb3JtRmllbGREZWZpbml0aW9uW10ge1xuICAgIHJldHVybiB0aGlzLl8kYWRkaXRpb25hbEZpZWxkcy5nZXRWYWx1ZSgpO1xuICB9XG5cbiAgZ2V0ICRhZGRpdGlvbmFsRmllbGRzKCk6IE9ic2VydmFibGU8Rm9ybUZpZWxkRGVmaW5pdGlvbltdPiB7XG4gICAgcmV0dXJuIHRoaXMuXyRhZGRpdGlvbmFsRmllbGRzLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgZ2V0QWRkaXRpb25hbEZpZWxkKGtleTogc3RyaW5nKTogRm9ybUZpZWxkRGVmaW5pdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuXyRhZGRpdGlvbmFsRmllbGRzLmdldFZhbHVlKCkuZmluZCgoZikgPT4gZi5rZXkgPT09IGtleSk7XG4gIH1cblxuICByZWdpc3RlckFkZGl0aW9uYWxGaWVsZChmaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbikge1xuICAgIGNvbnN0IHZhbHVlcyA9IHRoaXMuXyRhZGRpdGlvbmFsRmllbGRzLmdldFZhbHVlKCk7XG4gICAgaWYgKHZhbHVlcy5zb21lKChmKSA9PiBmLmtleSA9PT0gZmllbGQua2V5KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBBZGRpdGlvbmFsIGFjY291bnQgZmllbGQge2tleTogJHtmaWVsZC5rZXl9fSBhbHJlYWR5IGRlZmluZS5gKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2RlYnVnKSBjb25zb2xlLmRlYnVnKGBbYWNjb3VudF0gRm91bmQgYWRkaXRpb25hbCBhY2NvdW50J3MgZmllbGQge2tleTogJHtmaWVsZC5rZXl9fWApO1xuICAgIHRoaXMuXyRhZGRpdGlvbmFsRmllbGRzLm5leHQodmFsdWVzLmNvbmNhdChmaWVsZCkpO1xuICB9XG5cbiAgZ2V0IG9wdGlvbkRlZnMoKTogRm9ybUZpZWxkRGVmaW5pdGlvbltdIHtcbiAgICByZXR1cm4gdGhpcy5fb3B0aW9uRGVmcztcbiAgfVxuXG4gIHJlZ2lzdGVyT3B0aW9uKGRlZjogRm9ybUZpZWxkRGVmaW5pdGlvbikge1xuICAgIGlmICh0aGlzLl9vcHRpb25EZWZzLmZpbmRJbmRleCgoZikgPT4gZi5rZXkgPT09IGRlZi5rZXkpICE9PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBBZGRpdGlvbmFsIG9wdGlvbiB7JHtkZWYua2V5fX0gYWxyZWFkeSBkZWZpbmUuYCk7XG4gICAgfVxuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZyhgW2FjY291bnRdIEFkZGluZyBhZGRpdGlvbmFsIG9wdGlvbiB7JHtkZWYua2V5fX1gLCBkZWYpO1xuICAgIHRoaXMuX29wdGlvbkRlZnMucHVzaChkZWYpO1xuICB9XG5cbiAgcmVnaXN0ZXJPcHRpb25zKGRlZnM6IEZvcm1GaWVsZERlZmluaXRpb25bXSkge1xuICAgIChkZWZzIHx8IFtdKS5mb3JFYWNoKChkZWYpID0+IHRoaXMucmVnaXN0ZXJPcHRpb24oZGVmKSk7XG4gIH1cblxuICAvKiAtLSBwcm90ZWN0ZWQgbWV0aG9kIC0tICovXG5cbiAgcHJvdGVjdGVkIHJlc2V0RGF0YSgpIHtcbiAgICB0aGlzLnN0b3BMaXN0ZW5SZW1vdGVDaGFuZ2VzKCk7XG4gICAgdGhpcy5fY2FjaGUubG9hZGVkID0gZmFsc2U7XG4gICAgdGhpcy5fY2FjaGUua2V5cGFpciA9IG51bGw7XG4gICAgdGhpcy5fY2FjaGUuYXV0aFRva2VuID0gbnVsbDtcbiAgICB0aGlzLl9jYWNoZS5hdXRoQmFzaWMgPSBudWxsO1xuICAgIHRoaXMuX2NhY2hlLnB1YmtleSA9IG51bGw7XG4gICAgdGhpcy5fY2FjaGUubWFpblByb2ZpbGUgPSBudWxsO1xuICAgIHRoaXMuX2NhY2hlLnBlcnNvbiA9IG51bGw7XG4gICAgdGhpcy5fY2FjaGUuZGVwYXJ0bWVudCA9IG51bGw7XG4gICAgdGhpcy5fZGF0YSA9IG5ldyBBY2NvdW50KCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgbG9hZERhdGEob3B0cz86IHsgb2ZmbGluZT86IGJvb2xlYW47IGZldGNoUG9saWN5PzogRmV0Y2hQb2xpY3kgfSk6IFByb21pc2U8QWNjb3VudD4ge1xuICAgIGlmICghdGhpcy5fY2FjaGUucHVia2V5KSB0aHJvdyBuZXcgRXJyb3IoJ1VzZXIgbm90IGxvZ2dlZCcpO1xuXG4gICAgdGhpcy5fY2FjaGUubG9hZGVkID0gZmFsc2U7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgYWNjb3VudCA9IChhd2FpdCB0aGlzLmxvYWQob3B0cykpIHx8IG5ldyBBY2NvdW50KCk7XG5cbiAgICAgIC8vIFNldCBkZWZhdWx0c1xuICAgICAgYWNjb3VudC5hdmF0YXIgPSBhY2NvdW50LmF2YXRhciB8fCB0aGlzLmVudmlyb25tZW50LmJhc2VVcmwgKyBERUZBVUxUX0FWQVRBUl9JTUFHRTtcbiAgICAgIGFjY291bnQuc2V0dGluZ3MgPSBhY2NvdW50LnNldHRpbmdzIHx8IG5ldyBVc2VyU2V0dGluZ3MoKTtcbiAgICAgIGFjY291bnQuc2V0dGluZ3MubG9jYWxlID0gYWNjb3VudC5zZXR0aW5ncy5sb2NhbGUgfHwgdGhpcy5zZXR0aW5ncy5sb2NhbGU7XG4gICAgICBhY2NvdW50LnNldHRpbmdzLmxhdExvbmdGb3JtYXQgPSBhY2NvdW50LnNldHRpbmdzLmxhdExvbmdGb3JtYXQgfHwgdGhpcy5zZXR0aW5ncy5sYXRMb25nRm9ybWF0IHx8ICdERE1NJztcbiAgICAgIGFjY291bnQuc2V0dGluZ3MuY29udGVudCA9IGFjY291bnQuc2V0dGluZ3MuY29udGVudCB8fCB7fTtcblxuICAgICAgLy8gUmVhZCBtYWluIHByb2ZpbGVcbiAgICAgIHRoaXMuX2NhY2hlLm1haW5Qcm9maWxlID0gUGVyc29uVXRpbHMuZ2V0TWFpblByb2ZpbGUoYWNjb3VudC5wcm9maWxlcyk7XG5cbiAgICAgIC8vIFVwZGF0ZSwgaW5zdGVhZCBvZiByZXBsYWNlIGl0XG4gICAgICBpZiAodGhpcy5fZGF0YSkge1xuICAgICAgICB0aGlzLl9kYXRhLmZyb21PYmplY3QoYWNjb3VudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9kYXRhID0gYWNjb3VudDtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2NhY2hlLmxvYWRlZCA9IHRydWU7XG5cbiAgICAgIC8vIEFwcGx5IHNldHRpbmdzLCBmb3VuZCBpbiByZW1vdGUgYWNjb3VudFxuICAgICAgaWYgKGFjY291bnQuc2V0dGluZ3MpIHtcbiAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSB7XG4gICAgICAgICAgLi4udGhpcy5zZXR0aW5ncy5zZXR0aW5ncyxcbiAgICAgICAgICAuLi5hY2NvdW50LnNldHRpbmdzLmFzTG9jYWxTZXR0aW5ncygpLFxuICAgICAgICB9O1xuICAgICAgICBhd2FpdCB0aGlzLnNldHRpbmdzLmFwcGx5KHNldHRpbmdzKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuX2RhdGE7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMucmVzZXREYXRhKCk7XG4gICAgICBpZiAoZXJyb3IuY29kZSAmJiBlcnJvci5tZXNzYWdlKSB0aHJvdyBlcnJvcjtcblxuICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICB0aHJvdyB7XG4gICAgICAgIGNvZGU6IEVycm9yQ29kZXMuTE9BRF9BQ0NPVU5UX0VSUk9SLFxuICAgICAgICBtZXNzYWdlOiAnRVJST1IuTE9BRF9BQ0NPVU5UX0VSUk9SJyxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGxpc3RlblNldHRpbmdzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIFdoZW4gc2V0dGluZ3MgY2hhbmdlZDogc2F2ZSBpdCByZW1vdGVseVxuICAgIHRoaXMucmVnaXN0ZXJTdWJzY3JpcHRpb24oXG4gICAgICB0aGlzLnNldHRpbmdzLm9uQ2hhbmdlXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIGRlYm91bmNlVGltZSgxMDAwKSxcbiAgICAgICAgICBmaWx0ZXIoKCkgPT4gdGhpcy5pc0xvZ2luKCkgJiYgdGhpcy5uZXR3b3JrLm9ubGluZSlcbiAgICAgICAgKVxuICAgICAgICAuc3Vic2NyaWJlKChzZXR0aW5ncykgPT4gdGhpcy5zYXZlTG9jYWxTZXR0aW5nc1JlbW90ZWx5KHNldHRpbmdzKSlcbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHJlc3RvcmVMb2NhbGx5KCk6IFByb21pc2U8QWNjb3VudCB8IHVuZGVmaW5lZD4ge1xuICAgIC8vIFJlc3RvcmUgZnJvbSBzdG9yYWdlXG4gICAgY29uc3QgdmFsdWVzID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgdGhpcy5zdG9yYWdlLmdldChQVUJLRVlfU1RPUkFHRV9LRVkpLFxuICAgICAgdGhpcy5zdG9yYWdlLmdldChUT0tFTl9TVE9SQUdFX0tFWSksXG4gICAgICB0aGlzLnN0b3JhZ2UuZ2V0KFNFQ0tFWV9TVE9SQUdFX0tFWSksXG4gICAgXSk7XG4gICAgbGV0IHB1YmtleSA9IHZhbHVlc1swXTtcbiAgICBsZXQgdG9rZW4gPSB2YWx1ZXNbMV07XG4gICAgY29uc3Qgc2Vja2V5ID0gdmFsdWVzWzJdO1xuXG4gICAgLy8gREVWIG9ubHkgLSBhdXRoIGJ5IHRva2VuXG4gICAgaWYgKCF0aGlzLmVudmlyb25tZW50LnByb2R1Y3Rpb24gJiYgdGhpcy5lbnZpcm9ubWVudC5kZWZhdWx0QXV0aFZhbHVlcz8udG9rZW4pIHtcbiAgICAgIHRva2VuID0gdG9rZW4gfHwgdGhpcy5lbnZpcm9ubWVudC5kZWZhdWx0QXV0aFZhbHVlcy50b2tlbjtcbiAgICAgIHB1YmtleSA9IHB1YmtleSB8fCB0b2tlbj8uc3BsaXQoJzonLCAyKVswXTtcbiAgICB9XG5cbiAgICAvLyBRdWl0IGlmIG5vIHB1YmtleSAobm90IGxvZ2dlZClcbiAgICBpZiAoIXB1YmtleSkgcmV0dXJuO1xuXG4gICAgLy8gUXVpdCBpZiBjb3VsZCBub3QgYXV0aCBvbiBwb2RcbiAgICBjb25zdCBjYW5SZW1vdGVBdXRoID0gdG9rZW4gfHwgc2Vja2V5IHx8IGZhbHNlO1xuICAgIGlmICghY2FuUmVtb3RlQXV0aCkgcmV0dXJuO1xuXG4gICAgaWYgKHRoaXMuX2RlYnVnKSBjb25zb2xlLmRlYnVnKGBbYWNjb3VudF0gQWNjb3VudCByZXN0b3JhdGlvbi4uLmApO1xuXG4gICAgdGhpcy5fY2FjaGUuYXV0aFRva2VuID0gdG9rZW47XG4gICAgdGhpcy5fY2FjaGUucHVia2V5ID0gcHVia2V5O1xuICAgIHRoaXMuX2NhY2hlLmtleXBhaXIgPVxuICAgICAgKHNlY2tleSAmJiB7XG4gICAgICAgIHB1YmxpY0tleTogQmFzZTU4LmRlY29kZShwdWJrZXkpLFxuICAgICAgICBzZWNyZXRLZXk6IEJhc2U1OC5kZWNvZGUoc2Vja2V5KSxcbiAgICAgIH0pIHx8XG4gICAgICBudWxsO1xuXG4gICAgLy8gT25saW5lIG1vZGU6IHRyeSB0byBjb25uZWN0IHRvIHBvZFxuICAgIGlmICh0aGlzLm5ldHdvcmsub25saW5lKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLmF1dGhlbnRpY2F0ZSgpO1xuICAgICAgICBpZiAoIXRoaXMuX2NhY2hlLmF1dGhUb2tlbiAmJiAhdGhpcy5fY2FjaGUuYXV0aEJhc2ljKSB0aHJvdyBuZXcgRXJyb3IoJ0F1dGhlbnRpY2F0aW9uIGZhaWxlZCcpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gT2ZmbGluZSBmZWF0dXJlIGFyZSBlbmFibGU6IGNvbnRpbnVlIGluIG9mZmxpbmUgbW9kZVxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5oYXNPZmZsaW5lRmVhdHVyZSgpKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCdbYWNjb3VudF0gVW5hYmxlIHRvIGF1dGhlbnRpY2F0ZSBvbiBwb2Q6IGZvcmNpbmcgb2ZmbGluZSBtb2RlJyk7XG4gICAgICAgICAgdGhpcy5uZXR3b3JrLnNldEZvcmNlT2ZmbGluZSh0cnVlLCB7IHNob3dUb2FzdDogZmFsc2UgfSk7XG4gICAgICAgICAgLy8gQ29udGludWVcbiAgICAgICAgfVxuICAgICAgICAvLyBObyBvZmZsaW5lIGZlYXR1cmVzIGVuYWJsZSAoPW9mZmxpbmUgbW9kZSBub3QgYWxsb3dlZClcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgdGhpcy5sb2dvdXQoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBHZXQgdGhlIGFjY291bnQsIGZyb20gcHVia2V5XG4gICAgbGV0IGpzb25BY2NvdW50ID0gYXdhaXQgdGhpcy5zdG9yYWdlLmdldChgJHtBQ0NPVU5UX1NUT1JBR0VfS0VZfSMke3B1YmtleX1gKTtcbiAgICBpZiAoIWpzb25BY2NvdW50KSB7XG4gICAgICAvLyBUcnkgdXNpbmcgdGhlIG9sZCBzdG9yYWdlIGtleVxuICAgICAgY29uc3QgYWNjb3VudFN0ciA9IGF3YWl0IHRoaXMuc3RvcmFnZS5nZXQoQUNDT1VOVF9TVE9SQUdFX0tFWSk7XG4gICAgICBqc29uQWNjb3VudCA9IGFjY291bnRTdHIgJiYgKCh0eXBlb2YgYWNjb3VudFN0ciA9PT0gJ3N0cmluZycgJiYgSlNPTi5wYXJzZShqc29uQWNjb3VudCkpIHx8IGFjY291bnRTdHIpO1xuICAgIH1cblxuICAgIC8vIEludmFsaWQgYWNjb3VudDogZG8gbm90IHVzZSBpdFxuICAgIGlmICghanNvbkFjY291bnQgfHwganNvbkFjY291bnQucHVia2V5ICE9PSBwdWJrZXkpIHtcbiAgICAgIC8vIERFViBvbmx5OiBjcmVhdGUgYSBmYWtlIGFjY291bnQgd2l0aCBnaXZlbiB1c2VybmFtZVxuICAgICAgaWYgKCF0aGlzLmVudmlyb25tZW50LnByb2R1Y3Rpb24gJiYgdGhpcy5lbnZpcm9ubWVudC5kZWZhdWx0QXV0aFZhbHVlcy51c2VybmFtZSkge1xuICAgICAgICBjb25zdCB1c2VybmFtZSA9IHRoaXMuZW52aXJvbm1lbnQuZGVmYXVsdEF1dGhWYWx1ZXMudXNlcm5hbWU7XG4gICAgICAgIGpzb25BY2NvdW50ID0geyBwdWJrZXksIHVzZXJuYW1lLCBmaXJzdE5hbWU6IHVzZXJuYW1lLCBsYXN0TmFtZTogdXNlcm5hbWUgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUcmFuc2Zvcm0gdG8gZW50aXR5XG4gICAgY29uc3QgYWNjb3VudCA9IEFjY291bnQuZnJvbU9iamVjdChqc29uQWNjb3VudCk7XG5cbiAgICAvLyBVcGRhdGUgZGF0YVxuICAgIHRoaXMuX2RhdGEgPSBhY2NvdW50O1xuICAgIHRoaXMuX2NhY2hlLm1haW5Qcm9maWxlID0gUGVyc29uVXRpbHMuZ2V0TWFpblByb2ZpbGUoYWNjb3VudC5wcm9maWxlcyk7XG4gICAgdGhpcy5fY2FjaGUubG9hZGVkID0gdHJ1ZTtcblxuICAgIC8vIEVtaXQgZXZlbnRcbiAgICB0aGlzLm9uTG9naW4ubmV4dCh0aGlzLl9kYXRhKTtcbiAgICB0aGlzLm9uQ2hhbmdlLm5leHQodGhpcy5fZGF0YSk7XG5cbiAgICBpZiAodGhpcy5fZW5hYmxlTGlzdGVuQ2hhbmdlcykgdGhpcy5zdGFydExpc3RlblJlbW90ZUNoYW5nZXMoKTtcblxuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZyhgW2FjY291bnRdIEFjY291bnQgcmVzdG9yYXRpb24gW09LXSB7cHVia2V5OiAke3B1YmtleS5zdWJzdHIoMCwgOCl9fSwge3Byb2ZpbGU6ICR7dGhpcy5fY2FjaGUubWFpblByb2ZpbGV9fWApO1xuXG4gICAgcmV0dXJuIGFjY291bnQ7XG4gIH1cblxuICAvKipcbiAgICogU2F2ZSBhY2NvdW50IGludG8gdGhlIGxvY2FsIHN0b3JhZ2VcbiAgICovXG4gIHByb3RlY3RlZCBhc3luYyBzYXZlTG9jYWxseSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuX2NhY2hlLnB1YmtleSkgdGhyb3cgbmV3IEVycm9yKCdVc2VyIG5vdCBsb2dnZWQnKTtcblxuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZyhgW2FjY291bnRdIFNhdmluZyBhY2NvdW50IHske3RoaXMuX2NhY2hlLnB1YmtleS5zdWJzdHJpbmcoMCwgNil9fSBpbiBsb2NhbCBzdG9yYWdlLi4uYCk7XG5cbiAgICAvLyBDb252ZXJ0IGFjY291bnQgdG8ganNvblxuICAgIGNvbnN0IGpzb24gPSB0aGlzLl9kYXRhLmFzT2JqZWN0KHsga2VlcFR5cGVuYW1lOiB0cnVlIH0pO1xuICAgIGNvbnN0IHNlY2tleSA9ICh0aGlzLl9jYWNoZS5rZXlwYWlyICYmIHRoaXMuX2NhY2hlLmtleXBhaXIuc2VjcmV0S2V5ICYmIEJhc2U1OC5lbmNvZGUodGhpcy5fY2FjaGUua2V5cGFpci5zZWNyZXRLZXkpKSB8fCBudWxsO1xuXG4gICAgLy8gQ29udmVydCBhdmF0YXIgVVJMIHRvIGRhdGFVcmwgKGUuZy4gJ2RhdGE6aW1hZ2UvcG5nOjxiYXNlNjQgY29udGVudD4nKVxuICAgIGNvbnN0IGhhc0F2YXRhclVybCA9XG4gICAgICBqc29uLmF2YXRhciAmJiAhanNvbi5hdmF0YXIuZW5kc1dpdGgoREVGQVVMVF9BVkFUQVJfSU1BR0UpICYmIChqc29uLmF2YXRhci5zdGFydHNXaXRoKCdodHRwOi8vJykgfHwganNvbi5hdmF0YXIuc3RhcnRzV2l0aCgnaHR0cHM6Ly8nKSk7XG4gICAgaWYgKGhhc0F2YXRhclVybCAmJiB0aGlzLm5ldHdvcmsub25saW5lKSB7XG4gICAgICBhd2FpdCB0aGlzLmZpbGVcbiAgICAgICAgLmdldEltYWdlKGpzb24uYXZhdGFyLCB7XG4gICAgICAgICAgdGh1bWJuYWlsOiB0cnVlLFxuICAgICAgICAgIG91dHB1dFR5cGU6ICdkYXRhVXJsJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKGRhdGFVcmwpID0+IHtcbiAgICAgICAgICBpZiAoZGF0YVVybCAmJiB0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZygnW2FjY291bnRdIEltYWdlIGZldGNoZWQ6ICcsIGRhdGFVcmwuc3Vic3RyaW5nKDAsIDUwKSk7XG5cbiAgICAgICAgICAvLyBUT0RPOiBtYWtlIHN1cmUgdG8gZGlzcGxheSBCYXNlNjQgaW1hZ2UgaW4gdGhlIG1lbnUgdG9wIGhlYWRlclxuICAgICAgICAgIC8vanNvbkFjY291bnQuYXZhdGFyID0gZGF0YVVybDtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGBbYWNjb3VudF0gRXJyb3Igd2hpbGUgZmV0Y2hpbmcgaW1hZ2U6ICR7anNvbi5hdmF0YXJ9OiAke2Vycn1gKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldChQVUJLRVlfU1RPUkFHRV9LRVksIHRoaXMuX2NhY2hlLnB1YmtleSksXG4gICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoVE9LRU5fU1RPUkFHRV9LRVksIHRoaXMuX2NhY2hlLmF1dGhUb2tlbiksXG4gICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoYCR7QUNDT1VOVF9TVE9SQUdFX0tFWX0jJHt0aGlzLl9jYWNoZS5wdWJrZXl9YCwganNvbiksXG4gICAgICAgIC8vIFNlY3JldCBrZXkgKG9wdGlvbmFsKVxuICAgICAgICAoc2Vja2V5ICYmIHRoaXMuc3RvcmFnZS5zZXQoU0VDS0VZX1NUT1JBR0VfS0VZLCBzZWNrZXkpKSB8fCB0aGlzLnN0b3JhZ2UucmVtb3ZlKFNFQ0tFWV9TVE9SQUdFX0tFWSksXG4gICAgICAgIC8vIFJlbW92ZSBvbGQgc3RvcmFnZSBrZXlcbiAgICAgICAgdGhpcy5zdG9yYWdlLnJlbW92ZShBQ0NPVU5UX1NUT1JBR0VfS0VZKSxcbiAgICAgIF0pO1xuXG4gICAgICBpZiAodGhpcy5fZGVidWcpIGNvbnNvbGUuZGVidWcoJ1thY2NvdW50XSBBY2NvdW50IHNhdmVkIGluIGxvY2FsIHN0b3JhZ2UnKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1thY2NvdW50XSBFcnJvciB3aGlsZSBzYXZpbmcgYWNjb3VudCBsb2NhbGx5OiAnICsgKChlcnIgJiYgZXJyLm1lc3NhZ2UpIHx8IGVyciksIGVycik7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc2F2ZUxvY2FsU2V0dGluZ3NSZW1vdGVseShzb3VyY2U6IExvY2FsU2V0dGluZ3MpIHtcbiAgICBpZiAoIXNvdXJjZSB8fCAhdGhpcy5pc0xvZ2luKCkgfHwgc291cmNlLmFjY291bnRJbmhlcml0YW5jZSA9PT0gZmFsc2UpIHJldHVybjsgLy8gU2tpcFxuICAgIGNvbnN0IGFjY291bnQgPSB0aGlzLmFjY291bnQ7XG5cbiAgICAvLyBNZXJnZSBsb2NhbCBzZXR0aW5ncyBpbnRvIGFjY291bnQncyBzZXR0aW5nc1xuICAgIGNvbnN0IHNldHRpbmdzID0gVXNlclNldHRpbmdzLmZyb21PYmplY3QoYWNjb3VudC5zZXR0aW5ncykgfHwgbmV3IFVzZXJTZXR0aW5ncygpO1xuICAgIGNvbnN0IGNoYW5nZWQgPSBzZXR0aW5ncy5tZXJnZShzb3VyY2UsIFsnbG9jYWxlJywgJ2xhdExvbmdGb3JtYXQnLCAncHJvcGVydGllcyddKTtcblxuICAgIGlmICghY2hhbmdlZCkgcmV0dXJuOyAvLyBTa2lwIGlmIHVuY2hhbmdlZFxuXG4gICAgLy8gU2F2ZSByZW1vdGVseVxuICAgIHRoaXMuYWNjb3VudC5zZXR0aW5ncyA9IHNldHRpbmdzO1xuICAgIGF3YWl0IHRoaXMuc2F2ZVNldHRpbmdzUmVtb3RlbHkoc2V0dGluZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBvciB1cGRhdGUgYW4gdXNlciBhY2NvdW50XG4gICAqXG4gICAqIEBwYXJhbSBhY2NvdW50XG4gICAqIEBwYXJhbSBrZXlQYWlyXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgc2F2ZVJlbW90ZWx5KGFjY291bnQ6IEFjY291bnQsIGtleVBhaXI/OiBLZXlwYWlyKTogUHJvbWlzZTxBY2NvdW50PiB7XG4gICAgYWNjb3VudC5wdWJrZXkgPSBhY2NvdW50LnB1YmtleSB8fCAoa2V5UGFpciAmJiBCYXNlNTguZW5jb2RlKGtleVBhaXIucHVibGljS2V5KSk7XG4gICAgaWYgKCFhY2NvdW50LnB1YmtleSkgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGFjY291bnQgcHVia2V5Jyk7XG5cbiAgICBjb25zdCBub3cgPSB0aGlzLl9kZWJ1ZyAmJiBEYXRlLm5vdygpO1xuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZyhgW2FjY291bnRdIFNhdmluZyBhY2NvdW50IHJlbW90ZWx5Li4uYCk7XG5cbiAgICBjb25zdCBpc05ldyA9IGlzTmlsKGFjY291bnQuaWQpO1xuXG4gICAgLy8gSWYgdGhpcyBpcyBhbiB1cGRhdGU6IGdldCBleGlzdGluZyBhY2NvdW50J3MgdXBkYXRlRGF0ZSwgdG8gYXZvaWQgJ3ZlcnNpb24gZXJyb3InIHdoZW4gc2F2aW5nXG4gICAgaWYgKCFpc05ldykge1xuICAgICAgY29uc3QgZXhpc3RpbmdBY2NvdW50ID0gYXdhaXQgdGhpcy5sb2FkKHsgZmV0Y2hQb2xpY3k6ICduZXR3b3JrLW9ubHknIH0pO1xuICAgICAgaWYgKCFleGlzdGluZ0FjY291bnQgfHwgIWV4aXN0aW5nQWNjb3VudC51cGRhdGVEYXRlKSB7XG4gICAgICAgIHRocm93IHsgY29kZTogRXJyb3JDb2Rlcy5BQ0NPVU5UX05PVF9FWElTVFMsIG1lc3NhZ2U6ICdFUlJPUi5BQ0NPVU5UX05PVF9FWElTVFMnIH07XG4gICAgICB9XG4gICAgICB0aGlzLmNvcHlJZEFuZFVwZGF0ZURhdGUoZXhpc3RpbmdBY2NvdW50LCBhY2NvdW50KTtcbiAgICB9XG5cbiAgICAvLyBNZXJnaW5nIHNldHRpbmdzXG4gICAgYWNjb3VudC5zZXR0aW5ncy5jb250ZW50WydwYWdlcyddID0gdGhpcy5zZXR0aW5ncy5zZXR0aW5ncy5wYWdlcztcbiAgICBhY2NvdW50LnNldHRpbmdzLmNvbnRlbnRbJ3BhZ2VIaXN0b3J5J10gPSB0aGlzLnNldHRpbmdzLnNldHRpbmdzLnBhZ2VIaXN0b3J5O1xuXG4gICAgLy8gQ29udmVydCB0byBqc29uXG4gICAgY29uc3QganNvbiA9IGFjY291bnQuYXNPYmplY3QoTUlOSUZZX0VOVElUWV9GT1JfUE9EKTtcblxuICAgIC8vIFVzZXIgbm90IGFsbG93IHRvIGNoYW5nZSBoaXMgcHJvZmlsZXNcbiAgICBkZWxldGUganNvbi5wcm9maWxlcztcblxuICAgIGNvbnN0IG11dGF0aW9uID0gaXNOZXcgPyBNdXRhdGlvbnMuY3JlYXRlIDogdGhpcy5fYXBpVG9rZW5FbmFibGVkID8gTXV0YXRpb25zLnNhdmVXaXRoVG9rZW5zIDogTXV0YXRpb25zLnNhdmU7XG5cbiAgICAvLyBFeGVjdXRlIG11dGF0aW9uXG4gICAgY29uc3QgeyBkYXRhIH0gPSBhd2FpdCB0aGlzLmdyYXBocWwubXV0YXRlPHsgZGF0YTogQWNjb3VudCB9Pih7XG4gICAgICBtdXRhdGlvbixcbiAgICAgIHZhcmlhYmxlczogeyBkYXRhOiBqc29uIH0sXG4gICAgICBlcnJvcjoge1xuICAgICAgICBjb2RlOiBFcnJvckNvZGVzLlNBVkVfQUNDT1VOVF9FUlJPUixcbiAgICAgICAgbWVzc2FnZTogJ0VSUk9SLlNBVkVfQUNDT1VOVF9FUlJPUicsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gQ29weSB1cGRhdGUgcHJvcGVydGllc1xuICAgIHRoaXMuY29weUlkQW5kVXBkYXRlRGF0ZShkYXRhLCBhY2NvdW50KTtcblxuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZyhgW2FjY291bnRdIEFjY291bnQgcmVtb3RlbHkgc2F2ZWQgaW4gJHtEYXRlLm5vdygpIC0gbm93fW1zYCk7XG5cbiAgICByZXR1cm4gYWNjb3VudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgb3IgdXBkYXRlIHVzZXIgc2V0dGluZ3NcbiAgICpcbiAgICogQHBhcmFtIHNldHRpbmdzXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgc2F2ZVNldHRpbmdzUmVtb3RlbHkoc2V0dGluZ3M6IFVzZXJTZXR0aW5ncykge1xuICAgIGNvbnN0IG5vdyA9IHRoaXMuX2RlYnVnICYmIERhdGUubm93KCk7XG4gICAgaWYgKHRoaXMuX2RlYnVnKSBjb25zb2xlLmRlYnVnKGBbYWNjb3VudF0gU2F2aW5nIHNldHRpbmdzIHJlbW90ZWx5Li4uYCk7XG5cbiAgICBjb25zdCBqc29uID0gc2V0dGluZ3MuYXNPYmplY3QoTUlOSUZZX0VOVElUWV9GT1JfUE9EKTtcblxuICAgIC8vIEV4ZWN1dGUgbXV0YXRpb25cbiAgICBjb25zdCB7IGRhdGEgfSA9IGF3YWl0IHRoaXMuZ3JhcGhxbC5tdXRhdGU8eyBkYXRhOiBVc2VyU2V0dGluZ3MgfT4oe1xuICAgICAgbXV0YXRpb246IE11dGF0aW9ucy5zYXZlU2V0dGluZ3MsXG4gICAgICB2YXJpYWJsZXM6IHsgZGF0YToganNvbiB9LFxuICAgICAgZXJyb3I6IHtcbiAgICAgICAgY29kZTogRXJyb3JDb2Rlcy5TQVZFX1NFVFRJTkdTX0VSUk9SLFxuICAgICAgICBtZXNzYWdlOiAnRVJST1IuU0FWRV9TRVRUSU5HU19FUlJPUicsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gQ29weSB1cGRhdGUgcHJvcGVydGllc1xuICAgIHRoaXMuY29weUlkQW5kVXBkYXRlRGF0ZVNldHRpbmdzKGRhdGEsIHNldHRpbmdzKTtcblxuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZyhgW2FjY291bnRdIFNldHRpbmdzIHJlbW90ZWx5IHNhdmVkIGluICR7RGF0ZS5ub3coKSAtIG5vd31tc2ApO1xuXG4gICAgLy8gU2F2ZSBpbnRvIGFjY291bnRcbiAgICBpZiAodGhpcy5hY2NvdW50KSB0aGlzLmFjY291bnQuc2V0dGluZ3MgPSBzZXR0aW5ncztcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBhdXRoZW50aWNhdGVBbmRHZXRUb2tlbih0b2tlbj86IHN0cmluZywgY291bnRlcj86IG51bWJlcik6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgaWYgKCF0aGlzLl9jYWNoZS5wdWJrZXkpIHRocm93IG5ldyBFcnJvcignVXNlciBub3QgbG9nZ2VkJyk7XG5cbiAgICBpZiAoIWNvdW50ZXIpIGNvbnNvbGUuaW5mbygnW2FjY291bnRdIEF1dGhlbnRpY2F0aW9uIG9uIHBvZC4uLicpO1xuXG4gICAgaWYgKGNvdW50ZXIgPiA0KSB7XG4gICAgICBpZiAodGhpcy5fZGVidWcpIGNvbnNvbGUuZGVidWcoYFthY2NvdW50XSBGYWlsZWQgdG8gYXV0aGVudGljYXRpb24gb24gcG9kIChhZnRlciAke2NvdW50ZXJ9IGF0dGVtcHRzKWApO1xuICAgICAgdGhyb3cgeyBjb2RlOiBFcnJvckNvZGVzLkFVVEhfU0VSVkVSX0VSUk9SLCBtZXNzYWdlOiAnRVJST1IuQVVUSF9TRVJWRVJfRVJST1InIH07XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgdmFsaWRcbiAgICBpZiAodG9rZW4pIHtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLmdyYXBocWwucXVlcnk8eyBhdXRoZW50aWNhdGU6IGJvb2xlYW4gfSwgeyB0b2tlbjogc3RyaW5nIH0+KHtcbiAgICAgICAgcXVlcnk6IEF1dGhRdWVyeSxcbiAgICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgICAgdG9rZW4sXG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgY29kZTogRXJyb3JDb2Rlcy5VTkFVVEhPUklaRUQsXG4gICAgICAgICAgbWVzc2FnZTogJ0VSUk9SLlVOQVVUSE9SSVpFRCcsXG4gICAgICAgIH0sXG4gICAgICAgIGZldGNoUG9saWN5OiAnbm8tY2FjaGUnLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFRva2VuIGlzIGFjY2VwdGVkIGJ5IHRoZSBzZXJ2ZXJcbiAgICAgIGlmIChkYXRhICYmIGRhdGEuYXV0aGVudGljYXRlKSB7XG4gICAgICAgIC8vIFN0b3JlIHRoZSB0b2tlblxuICAgICAgICB0aGlzLm9uQXV0aFRva2VuQ2hhbmdlLm5leHQodG9rZW4pO1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhgW2FjY291bnRdIEF1dGhlbnRpY2F0aW9uIG9uIHBvZCBbT0tdIHtwdWJrZXk6ICcke3RoaXMuX2NhY2hlLnB1YmtleS5zdWJzdHIoMCwgOCl9J31gKTtcbiAgICAgICAgcmV0dXJuIHRva2VuOyAvLyByZXR1cm4gdGhlIHRva2VuXG4gICAgICB9XG5cbiAgICAgIC8vIENvbnRpbnVlICh3aWxsIHJldHJ5IHdpdGggYW5vdGhlciBjaGFsbGVuZ2UpXG4gICAgfVxuXG4gICAgLy8gR2VuZXJhdGUgYSBuZXcgdG9rZW5cbiAgICBjb25zdCBhdXRoQ2hhbGxlbmdlID0gYXdhaXQgdGhpcy5nZXRBdXRoQ2hhbGxlbmdlKCk7XG4gICAgLy8gVE9ETzogY2hlY2sgc2VydmVyIHB1YmtleSBhcyBhIHZhbGlkIGNlcnRpZmljYXRlXG5cbiAgICAvLyBEbyB0aGUgY2hhbGxlbmdlXG4gICAgY29uc3Qgc2lnbmF0dXJlID0gYXdhaXQgQ3J5cHRvU2VydmljZS5zaWduKGF1dGhDaGFsbGVuZ2UuY2hhbGxlbmdlLCB0aGlzLl9jYWNoZS5rZXlwYWlyKTtcbiAgICBjb25zdCBuZXdUb2tlbiA9IGAke3RoaXMuX2NhY2hlLnB1YmtleX06JHthdXRoQ2hhbGxlbmdlLmNoYWxsZW5nZX18JHtzaWduYXR1cmV9YDtcblxuICAgIC8vIGl0ZXJhdGUgd2l0aCB0aGUgbmV3IHRva2VuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuYXV0aGVudGljYXRlQW5kR2V0VG9rZW4obmV3VG9rZW4sIChjb3VudGVyIHx8IDEpICsgMSAvKiBpbmNyZW1lbnQgKi8pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGdldEF1dGhDaGFsbGVuZ2UoKTogUHJvbWlzZTxJQXV0aENoYWxsZW5nZT4ge1xuICAgIGNvbnN0IGNoYWxsZW5nZUVycm9yID0ge1xuICAgICAgY29kZTogRXJyb3JDb2Rlcy5BVVRIX0NIQUxMRU5HRV9FUlJPUixcbiAgICAgIG1lc3NhZ2U6ICdFUlJPUi5BVVRIX0NIQUxMRU5HRV9FUlJPUicsXG4gICAgfTtcbiAgICBjb25zdCB7IGF1dGhDaGFsbGVuZ2UgfSA9IGF3YWl0IHRoaXMuZ3JhcGhxbC5xdWVyeTx7XG4gICAgICBhdXRoQ2hhbGxlbmdlOiBJQXV0aENoYWxsZW5nZTtcbiAgICB9Pih7XG4gICAgICBxdWVyeTogQXV0aENoYWxsZW5nZVF1ZXJ5LFxuICAgICAgdmFyaWFibGVzOiB7fSxcbiAgICAgIGVycm9yOiBjaGFsbGVuZ2VFcnJvcixcbiAgICAgIGZldGNoUG9saWN5OiAnbmV0d29yay1vbmx5JyxcbiAgICB9KTtcblxuICAgIC8vIENoZWNrIGNoYWxsZW5nZVxuICAgIGlmICghYXV0aENoYWxsZW5nZSkgdGhyb3cgY2hhbGxlbmdlRXJyb3I7IC8vIFNob3VsZCBuZXZlciBvY2N1clxuXG4gICAgLy8gQ2hlY2sgc2VydmVyIHNpZ25hdHVyZVxuICAgIGNvbnN0IHNpZ25hdHVyZU9LID0gYXdhaXQgQ3J5cHRvU2VydmljZS52ZXJpZnkoYXV0aENoYWxsZW5nZS5jaGFsbGVuZ2UsIGF1dGhDaGFsbGVuZ2Uuc2lnbmF0dXJlLCBhdXRoQ2hhbGxlbmdlLnB1YmtleSk7XG4gICAgaWYgKCFzaWduYXR1cmVPSykge1xuICAgICAgY29uc29sZS53YXJuKCdGSVhNRTogQmFkIHBlZXIgc2lnbmF0dXJlIG9uIGF1dGggY2hhbGxlbmdlICEnLCBhdXRoQ2hhbGxlbmdlKTtcbiAgICB9XG4gICAgcmV0dXJuIGF1dGhDaGFsbGVuZ2U7XG4gIH1cblxuICBwcm90ZWN0ZWQgc3RhcnRMaXN0ZW5SZW1vdGVDaGFuZ2VzKG9wdHM/OiBBY2NvdW50V2F0Y2hPcHRpb25zKTogU3Vic2NyaXB0aW9uIHtcbiAgICBpZiAodGhpcy5fbGlzdGVuQ2hhbmdlc1N1YnNjcmlwdGlvbikgdGhpcy5zdG9wTGlzdGVuUmVtb3RlQ2hhbmdlcygpOyAvLyBTdG9wIHByZXZpb3VzIHN1YnNjcmlwdGlvblxuICAgIGlmICh0aGlzLm5ldHdvcmsub2ZmbGluZSkgcmV0dXJuIG5ldyBTdWJzY3JpcHRpb24oKTsgLy8gT2ZmbGluZTogc2tpcFxuXG4gICAgdGhpcy5fbGlzdGVuQ2hhbmdlc1N1YnNjcmlwdGlvbiA9IHRoaXMud2F0Y2hDaGFuZ2VzKG9wdHMpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAoZGF0YSkgPT4ge1xuICAgICAgICBjb25zb2xlLmRlYnVnKGBbYWNjb3VudF0gUmVtb3RlIHVwZGF0ZSBkZXRlY3RlZCBhdCAke2RhdGEudXBkYXRlRGF0ZX1gKTtcbiAgICAgICAgdGhpcy5yZWxvYWQoKTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICBpZiAoZXJyICYmICtlcnIuY29kZSA9PT0gU2VydmVyRXJyb3JDb2Rlcy5OT1RfRk9VTkQpIHtcbiAgICAgICAgICBjb25zb2xlLmluZm8oJ1thY2NvdW50XSBbV1NdIEFjY291bnQgbm90IGV4aXN0cyBhbnltb3JlOiBmb3JjZSB1c2VyIHRvIGxvZ291dC4uLicsIGVycik7XG4gICAgICAgICAgdGhpcy5sb2dvdXQoKTtcbiAgICAgICAgfSBlbHNlIGlmIChlcnIgJiYgK2Vyci5jb2RlID09PSBTZXJ2ZXJFcnJvckNvZGVzLlVOQVVUSE9SSVpFRCkge1xuICAgICAgICAgIGNvbnNvbGUuaW5mbygnW2FjY291bnRdIFtXU10gQWNjb3VudCBub3QgYXV0aG9yaXplZDogZm9yY2UgdXNlciB0byBsb2dvdXQuLi4nLCBlcnIpO1xuICAgICAgICAgIHRoaXMubG9nb3V0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCdbYWNjb3VudF0gW1dTXSBSZWNlaXZlZCBlcnJvcjonLCBlcnIpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICAgIHRoaXMuX2xpc3RlbkNoYW5nZXNTdWJzY3JpcHRpb24uYWRkKCgpID0+IHtcbiAgICAgIGNvbnNvbGUuZGVidWcoYFthY2NvdW50XSBTdG9wIHdhdGNoaW5nIHJlbW90ZSBjaGFuZ2VzYCk7XG4gICAgICB0aGlzLl9saXN0ZW5DaGFuZ2VzU3Vic2NyaXB0aW9uID0gbnVsbDtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcy5fbGlzdGVuQ2hhbmdlc1N1YnNjcmlwdGlvbjtcbiAgfVxuXG4gIHByb3RlY3RlZCBzdG9wTGlzdGVuUmVtb3RlQ2hhbmdlcygpIHtcbiAgICB0aGlzLl9saXN0ZW5DaGFuZ2VzU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHdhdGNoQ2hhbmdlcyhvcHRzPzogQWNjb3VudFdhdGNoT3B0aW9ucyk6IE9ic2VydmFibGU8QWNjb3VudD4ge1xuICAgIGlmICghdGhpcy5zdGFydGVkKSB7XG4gICAgICAvLyBXYWl0IHNlcnZpY2UgcmVhZHksIHRoZW4gbG9vcFxuICAgICAgcmV0dXJuIGZyb20odGhpcy5yZWFkeSgpKS5waXBlKHN3aXRjaE1hcCgoKSA9PiB0aGlzLndhdGNoQ2hhbmdlcyhvcHRzKSkpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5fY2FjaGUucHVia2V5KSB0aHJvdyBuZXcgRXJyb3IoJ05vdCBsb2dnZWQgaW4nKTtcbiAgICBpZiAodGhpcy5uZXR3b3JrLm9mZmxpbmUpIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHdhdGNoIGFjY291bnQgY2hhbmdlczogbmV0d29yayBpcyBvZmZsaW5lLicpO1xuXG4gICAgY29uc3QgdmFyaWFibGVzID0ge1xuICAgICAgaW50ZXJ2YWw6IHRvTnVtYmVyKG9wdHMgJiYgb3B0cy5pbnRlcnZhbEluU2Vjb25kcywgdGhpcy5fbGlzdGVuSW50ZXJ2YWxJblNlY29uZHMpLFxuICAgIH07XG5cbiAgICBjb25zb2xlLmRlYnVnKGBbYWNjb3VudF0gV2F0Y2hpbmcgcmVtb3RlIGNoYW5nZXMsIGV2ZXJ5ICR7dmFyaWFibGVzLmludGVydmFsfXNgKTtcblxuICAgIHJldHVybiB0aGlzLmdyYXBocWxcbiAgICAgIC5zdWJzY3JpYmU8eyBkYXRhOiBhbnkgfT4oe1xuICAgICAgICBxdWVyeTogQWNjb3VudFN1YnNjcmlwdGlvbnMubGlzdGVuQ2hhbmdlcyxcbiAgICAgICAgdmFyaWFibGVzLFxuICAgICAgICBlcnJvcjoge1xuICAgICAgICAgIGNvZGU6IEVycm9yQ29kZXMuU1VCU0NSSUJFX0FDQ09VTlRfRVJST1IsXG4gICAgICAgICAgbWVzc2FnZTogJ0VSUk9SLkFDQ09VTlQuU1VCU0NSSUJFX0VSUk9SJyxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgbWFwKCh7IGRhdGEgfSkgPT4gZGF0YSksXG4gICAgICAgIC8vIEtlZXAgb25seSBpZiBuZXdlclxuICAgICAgICBmaWx0ZXIoKGRhdGEpID0+IHtcbiAgICAgICAgICBjb25zdCBjdXJyZW50VXBkYXRlRGF0ZTogTW9tZW50ID0gZnJvbURhdGVJU09TdHJpbmcodGhpcy5fZGF0YT8udXBkYXRlRGF0ZSk7XG4gICAgICAgICAgY29uc3QgcmVtb3RlVXBkYXRlRGF0ZTogTW9tZW50ID0gZnJvbURhdGVJU09TdHJpbmcoZGF0YT8udXBkYXRlRGF0ZSk7XG4gICAgICAgICAgcmV0dXJuIHJlbW90ZVVwZGF0ZURhdGUgJiYgKCFjdXJyZW50VXBkYXRlRGF0ZSB8fCAhcmVtb3RlVXBkYXRlRGF0ZS5pc1NhbWUoY3VycmVudFVwZGF0ZURhdGUsICdtaWxsaXNlY29uZCcpKTtcbiAgICAgICAgfSlcbiAgICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29weUlkQW5kVXBkYXRlRGF0ZShzb3VyY2U6IEFjY291bnQgfCB1bmRlZmluZWQsIHRhcmdldDogQWNjb3VudCkge1xuICAgIGlmICghc291cmNlKSByZXR1cm47XG5cbiAgICB0YXJnZXQuaWQgPSBzb3VyY2UuaWQgfHwgdGFyZ2V0LmlkO1xuICAgIHRhcmdldC51cGRhdGVEYXRlID0gc291cmNlLnVwZGF0ZURhdGUgfHwgdGFyZ2V0LnVwZGF0ZURhdGU7XG5cbiAgICAvLyBVcGRhdGUgc2V0dGluZ3NcbiAgICB0aGlzLmNvcHlJZEFuZFVwZGF0ZURhdGVTZXR0aW5ncyhzb3VyY2Uuc2V0dGluZ3MsIHRhcmdldC5zZXR0aW5ncyk7XG5cbiAgICAvLyBVcGRhdGUgdG9rZW5zXG4gICAgaWYgKHRoaXMuX2FwaVRva2VuRW5hYmxlZCkge1xuICAgICAgdGhpcy5jb3B5SWRBbmRVcGRhdGVEYXRlVG9rZW4oc291cmNlLnRva2VucywgdGFyZ2V0LnRva2Vucyk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGNvcHlJZEFuZFVwZGF0ZURhdGVTZXR0aW5ncyhzb3VyY2U6IFVzZXJTZXR0aW5ncyB8IHVuZGVmaW5lZCwgdGFyZ2V0OiBVc2VyU2V0dGluZ3MpIHtcbiAgICBpZiAoIXNvdXJjZSkgcmV0dXJuO1xuXG4gICAgdGFyZ2V0LmlkID0gc291cmNlLmlkIHx8IHRhcmdldC5pZDtcbiAgICB0YXJnZXQudXBkYXRlRGF0ZSA9IHNvdXJjZS51cGRhdGVEYXRlIHx8IHRhcmdldC51cGRhdGVEYXRlO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvcHlJZEFuZFVwZGF0ZURhdGVUb2tlbihzb3VyY2VzOiBVc2VyVG9rZW5bXSB8IHVuZGVmaW5lZCwgdGFyZ2V0czogVXNlclRva2VuW10pIHtcbiAgICBpZiAoaXNFbXB0eUFycmF5KHNvdXJjZXMpKSByZXR1cm47XG5cbiAgICBzb3VyY2VzLmZvckVhY2goKHNvdXJjZSkgPT4ge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gdGFyZ2V0cy5maW5kKCh2YWx1ZSkgPT4gVXNlclRva2VuLmVxdWFscyh2YWx1ZSwgc291cmNlKSk7XG4gICAgICBpZiAodGFyZ2V0KSB7XG4gICAgICAgIHRhcmdldC5pZCA9IHNvdXJjZS5pZCB8fCB0YXJnZXQuaWQ7XG4gICAgICAgIHRhcmdldC5jcmVhdGlvbkRhdGUgPSBzb3VyY2UuY3JlYXRpb25EYXRlIHx8IHRhcmdldC5jcmVhdGlvbkRhdGU7XG4gICAgICAgIHRhcmdldC51cGRhdGVEYXRlID0gc291cmNlLnVwZGF0ZURhdGUgfHwgdGFyZ2V0LnVwZGF0ZURhdGU7XG4gICAgICAgIHRhcmdldC50b2tlbiA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzaG93VG9hc3Q8VCA9IGFueT4ob3B0czogU2hvd1RvYXN0T3B0aW9ucyk6IFByb21pc2U8T3ZlcmxheUV2ZW50RGV0YWlsPFQ+PiB7XG4gICAgcmV0dXJuIFRvYXN0cy5zaG93KHRoaXMudG9hc3RDb250cm9sbGVyLCB0aGlzLnRyYW5zbGF0ZSwgb3B0cyk7XG4gIH1cbn1cbiJdfQ==