@lenne.tech/ng-base 18.1.2 → 22.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (416) hide show
  1. package/CLAUDE.md +55 -0
  2. package/LICENSE +2 -2
  3. package/README.md +237 -44
  4. package/fesm2022/lenne.tech-ng-base-ai.mjs +767 -0
  5. package/fesm2022/lenne.tech-ng-base-ai.mjs.map +1 -0
  6. package/fesm2022/lenne.tech-ng-base-auth-provide.mjs +939 -0
  7. package/fesm2022/lenne.tech-ng-base-auth-provide.mjs.map +1 -0
  8. package/fesm2022/lenne.tech-ng-base-auth.mjs +454 -0
  9. package/fesm2022/lenne.tech-ng-base-auth.mjs.map +1 -0
  10. package/fesm2022/lenne.tech-ng-base-bug-bug-report-dialog-BRzVmKJr.mjs +825 -0
  11. package/fesm2022/lenne.tech-ng-base-bug-bug-report-dialog-BRzVmKJr.mjs.map +1 -0
  12. package/fesm2022/lenne.tech-ng-base-bug-bug-report-service-DWoTb_iw.mjs +351 -0
  13. package/fesm2022/lenne.tech-ng-base-bug-bug-report-service-DWoTb_iw.mjs.map +1 -0
  14. package/fesm2022/lenne.tech-ng-base-bug-capture-engine-TkjMDdqj.mjs +1046 -0
  15. package/fesm2022/lenne.tech-ng-base-bug-capture-engine-TkjMDdqj.mjs.map +1 -0
  16. package/fesm2022/lenne.tech-ng-base-bug-constants-Brm2KGHi.mjs +4 -0
  17. package/fesm2022/lenne.tech-ng-base-bug-constants-Brm2KGHi.mjs.map +1 -0
  18. package/fesm2022/lenne.tech-ng-base-bug-messages-BsP4fRQU.mjs +179 -0
  19. package/fesm2022/lenne.tech-ng-base-bug-messages-BsP4fRQU.mjs.map +1 -0
  20. package/fesm2022/lenne.tech-ng-base-bug-provide.mjs +26 -0
  21. package/fesm2022/lenne.tech-ng-base-bug-provide.mjs.map +1 -0
  22. package/fesm2022/lenne.tech-ng-base-bug-report-Tzlhe1Cm.mjs +62 -0
  23. package/fesm2022/lenne.tech-ng-base-bug-report-Tzlhe1Cm.mjs.map +1 -0
  24. package/fesm2022/lenne.tech-ng-base-bug-server.mjs +818 -0
  25. package/fesm2022/lenne.tech-ng-base-bug-server.mjs.map +1 -0
  26. package/fesm2022/lenne.tech-ng-base-bug.mjs +196 -0
  27. package/fesm2022/lenne.tech-ng-base-bug.mjs.map +1 -0
  28. package/fesm2022/lenne.tech-ng-base-files-ui.mjs +445 -0
  29. package/fesm2022/lenne.tech-ng-base-files-ui.mjs.map +1 -0
  30. package/fesm2022/lenne.tech-ng-base-files.mjs +474 -0
  31. package/fesm2022/lenne.tech-ng-base-files.mjs.map +1 -0
  32. package/fesm2022/lenne.tech-ng-base-server.mjs +408 -0
  33. package/fesm2022/lenne.tech-ng-base-server.mjs.map +1 -0
  34. package/fesm2022/lenne.tech-ng-base-share.mjs +76 -0
  35. package/fesm2022/lenne.tech-ng-base-share.mjs.map +1 -0
  36. package/fesm2022/lenne.tech-ng-base-sync.mjs +1096 -0
  37. package/fesm2022/lenne.tech-ng-base-sync.mjs.map +1 -0
  38. package/fesm2022/lenne.tech-ng-base-testing.mjs +171 -0
  39. package/fesm2022/lenne.tech-ng-base-testing.mjs.map +1 -0
  40. package/fesm2022/lenne.tech-ng-base-ui-provide.mjs +124 -0
  41. package/fesm2022/lenne.tech-ng-base-ui-provide.mjs.map +1 -0
  42. package/fesm2022/lenne.tech-ng-base-ui.mjs +34611 -0
  43. package/fesm2022/lenne.tech-ng-base-ui.mjs.map +1 -0
  44. package/fesm2022/lenne.tech-ng-base-utils.mjs +287 -0
  45. package/fesm2022/lenne.tech-ng-base-utils.mjs.map +1 -0
  46. package/fesm2022/lenne.tech-ng-base.mjs +615 -902
  47. package/fesm2022/lenne.tech-ng-base.mjs.map +1 -1
  48. package/i18n/auth/de.json +17 -0
  49. package/i18n/auth/en.json +17 -0
  50. package/i18n/bug/de.json +85 -0
  51. package/i18n/bug/en.json +85 -0
  52. package/i18n/de.json +8 -0
  53. package/i18n/en.json +8 -0
  54. package/i18n/files/de.json +27 -0
  55. package/i18n/files/en.json +27 -0
  56. package/i18n/share/de.json +8 -0
  57. package/i18n/share/en.json +8 -0
  58. package/i18n/ui/de.json +38 -0
  59. package/i18n/ui/en.json +38 -0
  60. package/package.json +127 -58
  61. package/types/lenne.tech-ng-base-ai.d.ts +830 -0
  62. package/types/lenne.tech-ng-base-auth-provide.d.ts +603 -0
  63. package/types/lenne.tech-ng-base-auth.d.ts +320 -0
  64. package/types/lenne.tech-ng-base-bug-provide.d.ts +272 -0
  65. package/types/lenne.tech-ng-base-bug-rolldown-runtime-C25Le4-w.d.ts +1 -0
  66. package/types/lenne.tech-ng-base-bug-server.d.ts +316 -0
  67. package/types/lenne.tech-ng-base-bug.d.ts +202 -0
  68. package/types/lenne.tech-ng-base-files-ui.d.ts +116 -0
  69. package/types/lenne.tech-ng-base-files.d.ts +288 -0
  70. package/types/lenne.tech-ng-base-server.d.ts +262 -0
  71. package/types/lenne.tech-ng-base-share.d.ts +21 -0
  72. package/types/lenne.tech-ng-base-sync.d.ts +380 -0
  73. package/types/lenne.tech-ng-base-testing.d.ts +327 -0
  74. package/types/lenne.tech-ng-base-ui-provide.d.ts +65 -0
  75. package/types/lenne.tech-ng-base-ui.d.ts +7732 -0
  76. package/types/lenne.tech-ng-base-utils.d.ts +150 -0
  77. package/types/lenne.tech-ng-base.d.ts +503 -0
  78. package/ui/styles/components/accordion.css +3 -0
  79. package/ui/styles/components/alert-dialog.css +4 -0
  80. package/ui/styles/components/alert.css +3 -0
  81. package/ui/styles/components/aspect-ratio.css +3 -0
  82. package/ui/styles/components/attachment.css +4 -0
  83. package/ui/styles/components/autocomplete.css +4 -0
  84. package/ui/styles/components/avatar.css +3 -0
  85. package/ui/styles/components/badge.css +3 -0
  86. package/ui/styles/components/breadcrumb.css +3 -0
  87. package/ui/styles/components/bubble.css +3 -0
  88. package/ui/styles/components/button-group.css +3 -0
  89. package/ui/styles/components/button.css +3 -0
  90. package/ui/styles/components/calendar.css +5 -0
  91. package/ui/styles/components/card.css +3 -0
  92. package/ui/styles/components/checkbox.css +3 -0
  93. package/ui/styles/components/code-block.css +4 -0
  94. package/ui/styles/components/collapsible.css +3 -0
  95. package/ui/styles/components/combobox.css +5 -0
  96. package/ui/styles/components/command.css +5 -0
  97. package/ui/styles/components/context-menu.css +3 -0
  98. package/ui/styles/components/date-picker.css +7 -0
  99. package/ui/styles/components/dialog.css +4 -0
  100. package/ui/styles/components/drawer.css +3 -0
  101. package/ui/styles/components/dropdown-menu.css +3 -0
  102. package/ui/styles/components/empty.css +3 -0
  103. package/ui/styles/components/field.css +5 -0
  104. package/ui/styles/components/hover-card.css +3 -0
  105. package/ui/styles/components/index.css +91 -0
  106. package/ui/styles/components/input-group.css +6 -0
  107. package/ui/styles/components/input-otp.css +3 -0
  108. package/ui/styles/components/input.css +3 -0
  109. package/ui/styles/components/item.css +4 -0
  110. package/ui/styles/components/kbd.css +3 -0
  111. package/ui/styles/components/label.css +3 -0
  112. package/ui/styles/components/lt-breadcrumb.css +3 -0
  113. package/ui/styles/components/lt-bug-attachments.css +5 -0
  114. package/ui/styles/components/lt-bug-journey-timeline.css +5 -0
  115. package/ui/styles/components/lt-bug-report-dialog.css +15 -0
  116. package/ui/styles/components/lt-bug-report.css +4 -0
  117. package/ui/styles/components/lt-color-mode-button.css +3 -0
  118. package/ui/styles/components/lt-confirm-dialog.css +4 -0
  119. package/ui/styles/components/lt-data-view.css +5 -0
  120. package/ui/styles/components/lt-date-picker.css +3 -0
  121. package/ui/styles/components/lt-date-time-picker.css +5 -0
  122. package/ui/styles/components/lt-enter-action.css +2 -0
  123. package/ui/styles/components/lt-footer.css +3 -0
  124. package/ui/styles/components/lt-form-field.css +4 -0
  125. package/ui/styles/components/lt-header.css +5 -0
  126. package/ui/styles/components/lt-imports.css +21 -0
  127. package/ui/styles/components/lt-navigation-menu.css +3 -0
  128. package/ui/styles/components/lt-notice.css +3 -0
  129. package/ui/styles/components/lt-overlay-defaults.css +3 -0
  130. package/ui/styles/components/lt-page-card.css +3 -0
  131. package/ui/styles/components/lt-page-title.css +2 -0
  132. package/ui/styles/components/lt-password-input.css +4 -0
  133. package/ui/styles/components/lt-readonly-field.css +2 -0
  134. package/ui/styles/components/lt-select.css +4 -0
  135. package/ui/styles/components/lt-text-field.css +5 -0
  136. package/ui/styles/components/lt-toolbar-item.css +2 -0
  137. package/ui/styles/components/lt-toolbar.css +3 -0
  138. package/ui/styles/components/lt-tus-upload-component.css +5 -0
  139. package/ui/styles/components/marker.css +3 -0
  140. package/ui/styles/components/menubar.css +3 -0
  141. package/ui/styles/components/message-scroller.css +4 -0
  142. package/ui/styles/components/message.css +3 -0
  143. package/ui/styles/components/native-select.css +3 -0
  144. package/ui/styles/components/navigation-menu.css +3 -0
  145. package/ui/styles/components/pagination.css +4 -0
  146. package/ui/styles/components/popover.css +3 -0
  147. package/ui/styles/components/progress.css +3 -0
  148. package/ui/styles/components/questionnaire.css +4 -0
  149. package/ui/styles/components/radio-group.css +3 -0
  150. package/ui/styles/components/resizable.css +3 -0
  151. package/ui/styles/components/select.css +3 -0
  152. package/ui/styles/components/separator.css +3 -0
  153. package/ui/styles/components/sheet.css +4 -0
  154. package/ui/styles/components/sidebar.css +9 -0
  155. package/ui/styles/components/skeleton.css +3 -0
  156. package/ui/styles/components/slider.css +3 -0
  157. package/ui/styles/components/sonner.css +4 -0
  158. package/ui/styles/components/spinner.css +3 -0
  159. package/ui/styles/components/switch.css +3 -0
  160. package/ui/styles/components/table.css +3 -0
  161. package/ui/styles/components/tabs.css +4 -0
  162. package/ui/styles/components/textarea.css +3 -0
  163. package/ui/styles/components/toggle-group.css +4 -0
  164. package/ui/styles/components/toggle.css +3 -0
  165. package/ui/styles/components/tooltip.css +3 -0
  166. package/ui/styles/components/trace.css +3 -0
  167. package/ui/styles/components/typography.css +3 -0
  168. package/ui/styles/components/utils.css +2 -0
  169. package/ui/styles/core.css +137 -0
  170. package/ui/styles/palette.css +94 -0
  171. package/ui/styles/theme.css +14 -0
  172. package/ui/styles/transitions.css +131 -0
  173. package/base-cms/index.d.ts +0 -5
  174. package/base-cms/interfaces/base-cms-module-config.interface.d.ts +0 -16
  175. package/base-cms/pages/base-cms/base-cms.component.d.ts +0 -92
  176. package/base-cms/public-api.d.ts +0 -5
  177. package/base-components/components/breadcrumb/breadcrumb.component.d.ts +0 -10
  178. package/base-components/components/change-password/change-password.component.d.ts +0 -24
  179. package/base-components/components/checkbox/checkbox.component.d.ts +0 -12
  180. package/base-components/components/delete-account/delete-account.component.d.ts +0 -15
  181. package/base-components/components/fab-button/fab-button.component.d.ts +0 -16
  182. package/base-components/components/input/input.component.d.ts +0 -27
  183. package/base-components/components/loading-bar/loading-bar.component.d.ts +0 -17
  184. package/base-components/components/model-form/model-form-base.component.d.ts +0 -64
  185. package/base-components/components/model-form/model-form.component.d.ts +0 -139
  186. package/base-components/components/model-form-sub/model-form-sub.component.d.ts +0 -56
  187. package/base-components/components/model-table/model-table.component.d.ts +0 -115
  188. package/base-components/components/refence-input/refence-input.component.d.ts +0 -84
  189. package/base-components/components/select/select.component.d.ts +0 -25
  190. package/base-components/components/skeleton-loader/skeleton-loader.component.d.ts +0 -10
  191. package/base-components/components/tags/tags.component.d.ts +0 -60
  192. package/base-components/components/textarea/textarea.component.d.ts +0 -21
  193. package/base-components/components/toast/toast.component.d.ts +0 -19
  194. package/base-components/components/upload-image/upload-image.component.d.ts +0 -111
  195. package/base-components/directives/back-button.directive.d.ts +0 -9
  196. package/base-components/directives/context-menu.directive.d.ts +0 -22
  197. package/base-components/directives/sort.directive.d.ts +0 -15
  198. package/base-components/directives/stop-propagation.directive.d.ts +0 -10
  199. package/base-components/index.d.ts +0 -5
  200. package/base-components/pipes/ellipses.pipe.d.ts +0 -10
  201. package/base-components/public-api.d.ts +0 -26
  202. package/base-prototype/index.d.ts +0 -5
  203. package/base-prototype/pages/email-verification/email-verification.component.d.ts +0 -18
  204. package/base-prototype/pages/forgot-password/forgot-password.component.d.ts +0 -26
  205. package/base-prototype/pages/login/login.component.d.ts +0 -33
  206. package/base-prototype/pages/profile/profile.component.d.ts +0 -24
  207. package/base-prototype/pages/register/register.component.d.ts +0 -31
  208. package/base-prototype/pages/set-password/set-password.component.d.ts +0 -29
  209. package/base-prototype/public-api.d.ts +0 -9
  210. package/esm2022/base-cms/interfaces/base-cms-module-config.interface.mjs +0 -3
  211. package/esm2022/base-cms/lenne.tech-ng-base-base-cms.mjs +0 -5
  212. package/esm2022/base-cms/pages/base-cms/base-cms.component.mjs +0 -238
  213. package/esm2022/base-cms/public-api.mjs +0 -8
  214. package/esm2022/base-components/components/breadcrumb/breadcrumb.component.mjs +0 -23
  215. package/esm2022/base-components/components/change-password/change-password.component.mjs +0 -97
  216. package/esm2022/base-components/components/checkbox/checkbox.component.mjs +0 -38
  217. package/esm2022/base-components/components/delete-account/delete-account.component.mjs +0 -59
  218. package/esm2022/base-components/components/fab-button/fab-button.component.mjs +0 -24
  219. package/esm2022/base-components/components/input/input.component.mjs +0 -75
  220. package/esm2022/base-components/components/loading-bar/loading-bar.component.mjs +0 -37
  221. package/esm2022/base-components/components/model-form/model-form-base.component.mjs +0 -145
  222. package/esm2022/base-components/components/model-form/model-form.component.mjs +0 -591
  223. package/esm2022/base-components/components/model-form-sub/model-form-sub.component.mjs +0 -117
  224. package/esm2022/base-components/components/model-table/model-table.component.mjs +0 -478
  225. package/esm2022/base-components/components/refence-input/refence-input.component.mjs +0 -278
  226. package/esm2022/base-components/components/select/select.component.mjs +0 -62
  227. package/esm2022/base-components/components/skeleton-loader/skeleton-loader.component.mjs +0 -33
  228. package/esm2022/base-components/components/tags/tags.component.mjs +0 -227
  229. package/esm2022/base-components/components/textarea/textarea.component.mjs +0 -79
  230. package/esm2022/base-components/components/toast/toast.component.mjs +0 -69
  231. package/esm2022/base-components/components/upload-image/upload-image.component.mjs +0 -346
  232. package/esm2022/base-components/directives/back-button.directive.mjs +0 -25
  233. package/esm2022/base-components/directives/context-menu.directive.mjs +0 -112
  234. package/esm2022/base-components/directives/sort.directive.mjs +0 -61
  235. package/esm2022/base-components/directives/stop-propagation.directive.mjs +0 -24
  236. package/esm2022/base-components/lenne.tech-ng-base-base-components.mjs +0 -5
  237. package/esm2022/base-components/pipes/ellipses.pipe.mjs +0 -23
  238. package/esm2022/base-components/public-api.mjs +0 -30
  239. package/esm2022/base-prototype/lenne.tech-ng-base-base-prototype.mjs +0 -5
  240. package/esm2022/base-prototype/pages/email-verification/email-verification.component.mjs +0 -60
  241. package/esm2022/base-prototype/pages/forgot-password/forgot-password.component.mjs +0 -78
  242. package/esm2022/base-prototype/pages/login/login.component.mjs +0 -114
  243. package/esm2022/base-prototype/pages/profile/profile.component.mjs +0 -87
  244. package/esm2022/base-prototype/pages/register/register.component.mjs +0 -100
  245. package/esm2022/base-prototype/pages/set-password/set-password.component.mjs +0 -91
  246. package/esm2022/base-prototype/public-api.mjs +0 -11
  247. package/esm2022/lenne.tech-ng-base.mjs +0 -5
  248. package/esm2022/public-api.mjs +0 -25
  249. package/esm2022/shared/classes/auth.class.mjs +0 -14
  250. package/esm2022/shared/classes/basic-user.class.mjs +0 -49
  251. package/esm2022/shared/classes/graphql-enum.class.mjs +0 -10
  252. package/esm2022/shared/classes/graphql-meta.class.mjs +0 -345
  253. package/esm2022/shared/classes/graphql-type.class.mjs +0 -14
  254. package/esm2022/shared/classes/helper.class.mjs +0 -307
  255. package/esm2022/shared/classes/sort.class.mjs +0 -38
  256. package/esm2022/shared/classes/standard.class.mjs +0 -40
  257. package/esm2022/shared/decorators/debounce.decorator.mjs +0 -12
  258. package/esm2022/shared/enums/comparison-operator.enum.mjs +0 -16
  259. package/esm2022/shared/enums/graphql-request-type.enum.mjs +0 -10
  260. package/esm2022/shared/enums/logical-operator.enum.mjs +0 -10
  261. package/esm2022/shared/enums/skeleton-type.enum.mjs +0 -7
  262. package/esm2022/shared/enums/sort-order.enum.mjs +0 -6
  263. package/esm2022/shared/enums/toast-type.enum.mjs +0 -8
  264. package/esm2022/shared/functions/ws-client.function.mjs +0 -39
  265. package/esm2022/shared/interfaces/base-module-config.interface.mjs +0 -3
  266. package/esm2022/shared/interfaces/breadcrumb.interface.mjs +0 -2
  267. package/esm2022/shared/interfaces/can-component-deactivate.interface.mjs +0 -2
  268. package/esm2022/shared/interfaces/cms-enum-values.interface.mjs +0 -2
  269. package/esm2022/shared/interfaces/cms-field-config.interface.mjs +0 -2
  270. package/esm2022/shared/interfaces/cms-model-config.interface.mjs +0 -2
  271. package/esm2022/shared/interfaces/cms-table-field.interface.mjs +0 -2
  272. package/esm2022/shared/interfaces/combined-filter-input.interface.mjs +0 -2
  273. package/esm2022/shared/interfaces/compress-options.interface.mjs +0 -2
  274. package/esm2022/shared/interfaces/cropping-options.interface.mjs +0 -2
  275. package/esm2022/shared/interfaces/field-object.interface.mjs +0 -2
  276. package/esm2022/shared/interfaces/field.interface.mjs +0 -2
  277. package/esm2022/shared/interfaces/filter-input.interface.mjs +0 -2
  278. package/esm2022/shared/interfaces/find-args.interface.mjs +0 -2
  279. package/esm2022/shared/interfaces/graphql-crud-type.interface.mjs +0 -2
  280. package/esm2022/shared/interfaces/graphql-fields-object.interface.mjs +0 -2
  281. package/esm2022/shared/interfaces/graphql-options.interface.mjs +0 -2
  282. package/esm2022/shared/interfaces/graphql-plus-options.interfacen.mjs +0 -2
  283. package/esm2022/shared/interfaces/graphql-type-collection.interface.mjs +0 -2
  284. package/esm2022/shared/interfaces/login-config.interface.mjs +0 -2
  285. package/esm2022/shared/interfaces/register-config.interface.mjs +0 -2
  286. package/esm2022/shared/interfaces/single-filter-input.interface.mjs +0 -2
  287. package/esm2022/shared/interfaces/sort-input.interface.mjs +0 -2
  288. package/esm2022/shared/interfaces/time-components.interface.mjs +0 -2
  289. package/esm2022/shared/interfaces/toast.interface.mjs +0 -2
  290. package/esm2022/shared/lenne.tech-ng-base-shared.mjs +0 -5
  291. package/esm2022/shared/public-api.mjs +0 -74
  292. package/esm2022/shared/services/auth.service.mjs +0 -152
  293. package/esm2022/shared/services/breadcrumb.service.mjs +0 -69
  294. package/esm2022/shared/services/cms.service.mjs +0 -82
  295. package/esm2022/shared/services/file.service.mjs +0 -86
  296. package/esm2022/shared/services/forms.service.mjs +0 -61
  297. package/esm2022/shared/services/graphql-meta.service.mjs +0 -132
  298. package/esm2022/shared/services/graphql-plus.service.mjs +0 -93
  299. package/esm2022/shared/services/graphql.service.mjs +0 -510
  300. package/esm2022/shared/services/image.service.mjs +0 -102
  301. package/esm2022/shared/services/loader.service.mjs +0 -78
  302. package/esm2022/shared/services/navigation.service.mjs +0 -38
  303. package/esm2022/shared/services/scroll.service.mjs +0 -207
  304. package/esm2022/shared/services/storage.service.mjs +0 -149
  305. package/esm2022/shared/services/toast.service.mjs +0 -39
  306. package/esm2022/shared/services/user.service.mjs +0 -160
  307. package/esm2022/shared/services/ws.service.mjs +0 -17
  308. package/esm2022/shared/types/graphql-fields.type.mjs +0 -2
  309. package/esm2022/shared/types/storage.type.mjs +0 -2
  310. package/esm2022/shared/validators/email.validator.mjs +0 -7
  311. package/esm2022/shared/validators/match.validator.mjs +0 -22
  312. package/esm2022/shared/validators/secure-password.validator.mjs +0 -7
  313. package/esm2022/src/base.module.mjs +0 -64
  314. package/esm2022/src/decorators/auto-unsubscribe.decorator.mjs +0 -23
  315. package/esm2022/src/directives/lazy-load.directive.mjs +0 -48
  316. package/esm2022/src/directives/match-height.directive.mjs +0 -92
  317. package/esm2022/src/directives/resizable.directive.mjs +0 -92
  318. package/esm2022/src/factories/apollo-options.factory.mjs +0 -108
  319. package/esm2022/src/functions/extract-files.function.mjs +0 -87
  320. package/esm2022/src/guards/auth.guard.mjs +0 -91
  321. package/esm2022/src/guards/can-deactivate.guard.mjs +0 -16
  322. package/esm2022/src/guards/logout.guard.mjs +0 -34
  323. package/esm2022/src/pipes/date-ago.pipe.mjs +0 -64
  324. package/esm2022/src/pipes/safe-html.pipe.mjs +0 -22
  325. package/esm2022/src/services/fullscreen.service.mjs +0 -51
  326. package/esm2022/src/services/seo.service.mjs +0 -109
  327. package/esm2022/src/services/theme.service.mjs +0 -44
  328. package/fesm2022/lenne.tech-ng-base-base-cms.mjs +0 -251
  329. package/fesm2022/lenne.tech-ng-base-base-cms.mjs.map +0 -1
  330. package/fesm2022/lenne.tech-ng-base-base-components.mjs +0 -2917
  331. package/fesm2022/lenne.tech-ng-base-base-components.mjs.map +0 -1
  332. package/fesm2022/lenne.tech-ng-base-base-prototype.mjs +0 -505
  333. package/fesm2022/lenne.tech-ng-base-base-prototype.mjs.map +0 -1
  334. package/fesm2022/lenne.tech-ng-base-shared.mjs +0 -2863
  335. package/fesm2022/lenne.tech-ng-base-shared.mjs.map +0 -1
  336. package/index.d.ts +0 -5
  337. package/public-api.d.ts +0 -17
  338. package/shared/classes/auth.class.d.ts +0 -10
  339. package/shared/classes/basic-user.class.d.ts +0 -27
  340. package/shared/classes/graphql-enum.class.d.ts +0 -7
  341. package/shared/classes/graphql-meta.class.d.ts +0 -66
  342. package/shared/classes/graphql-type.class.d.ts +0 -13
  343. package/shared/classes/helper.class.d.ts +0 -99
  344. package/shared/classes/sort.class.d.ts +0 -12
  345. package/shared/classes/standard.class.d.ts +0 -32
  346. package/shared/decorators/debounce.decorator.d.ts +0 -1
  347. package/shared/enums/comparison-operator.enum.d.ts +0 -14
  348. package/shared/enums/graphql-request-type.enum.d.ts +0 -8
  349. package/shared/enums/logical-operator.enum.d.ts +0 -8
  350. package/shared/enums/skeleton-type.enum.d.ts +0 -5
  351. package/shared/enums/sort-order.enum.d.ts +0 -4
  352. package/shared/enums/toast-type.enum.d.ts +0 -6
  353. package/shared/functions/ws-client.function.d.ts +0 -5
  354. package/shared/index.d.ts +0 -5
  355. package/shared/interfaces/base-module-config.interface.d.ts +0 -61
  356. package/shared/interfaces/breadcrumb.interface.d.ts +0 -4
  357. package/shared/interfaces/can-component-deactivate.interface.d.ts +0 -7
  358. package/shared/interfaces/cms-enum-values.interface.d.ts +0 -4
  359. package/shared/interfaces/cms-field-config.interface.d.ts +0 -45
  360. package/shared/interfaces/cms-model-config.interface.d.ts +0 -14
  361. package/shared/interfaces/cms-table-field.interface.d.ts +0 -10
  362. package/shared/interfaces/combined-filter-input.interface.d.ts +0 -9
  363. package/shared/interfaces/compress-options.interface.d.ts +0 -15
  364. package/shared/interfaces/cropping-options.interface.d.ts +0 -12
  365. package/shared/interfaces/field-object.interface.d.ts +0 -6
  366. package/shared/interfaces/field.interface.d.ts +0 -5
  367. package/shared/interfaces/filter-input.interface.d.ts +0 -9
  368. package/shared/interfaces/find-args.interface.d.ts +0 -11
  369. package/shared/interfaces/graphql-crud-type.interface.d.ts +0 -7
  370. package/shared/interfaces/graphql-fields-object.interface.d.ts +0 -6
  371. package/shared/interfaces/graphql-options.interface.d.ts +0 -11
  372. package/shared/interfaces/graphql-plus-options.interfacen.d.ts +0 -9
  373. package/shared/interfaces/graphql-type-collection.interface.d.ts +0 -7
  374. package/shared/interfaces/login-config.interface.d.ts +0 -6
  375. package/shared/interfaces/register-config.interface.d.ts +0 -4
  376. package/shared/interfaces/single-filter-input.interface.d.ts +0 -11
  377. package/shared/interfaces/sort-input.interface.d.ts +0 -5
  378. package/shared/interfaces/time-components.interface.d.ts +0 -6
  379. package/shared/interfaces/toast.interface.d.ts +0 -8
  380. package/shared/public-api.d.ts +0 -65
  381. package/shared/services/auth.service.d.ts +0 -44
  382. package/shared/services/breadcrumb.service.d.ts +0 -32
  383. package/shared/services/cms.service.d.ts +0 -27
  384. package/shared/services/file.service.d.ts +0 -22
  385. package/shared/services/forms.service.d.ts +0 -14
  386. package/shared/services/graphql-meta.service.d.ts +0 -45
  387. package/shared/services/graphql-plus.service.d.ts +0 -27
  388. package/shared/services/graphql.service.d.ts +0 -71
  389. package/shared/services/image.service.d.ts +0 -27
  390. package/shared/services/loader.service.d.ts +0 -32
  391. package/shared/services/navigation.service.d.ts +0 -15
  392. package/shared/services/scroll.service.d.ts +0 -85
  393. package/shared/services/storage.service.d.ts +0 -49
  394. package/shared/services/toast.service.d.ts +0 -15
  395. package/shared/services/user.service.d.ts +0 -77
  396. package/shared/services/ws.service.d.ts +0 -8
  397. package/shared/types/graphql-fields.type.d.ts +0 -5
  398. package/shared/types/storage.type.d.ts +0 -4
  399. package/shared/validators/email.validator.d.ts +0 -1
  400. package/shared/validators/match.validator.d.ts +0 -4
  401. package/shared/validators/secure-password.validator.d.ts +0 -1
  402. package/src/base.module.d.ts +0 -16
  403. package/src/decorators/auto-unsubscribe.decorator.d.ts +0 -5
  404. package/src/directives/lazy-load.directive.d.ts +0 -17
  405. package/src/directives/match-height.directive.d.ts +0 -20
  406. package/src/directives/resizable.directive.d.ts +0 -26
  407. package/src/factories/apollo-options.factory.d.ts +0 -16
  408. package/src/functions/extract-files.function.d.ts +0 -15
  409. package/src/guards/auth.guard.d.ts +0 -27
  410. package/src/guards/can-deactivate.guard.d.ts +0 -10
  411. package/src/guards/logout.guard.d.ts +0 -16
  412. package/src/pipes/date-ago.pipe.d.ts +0 -34
  413. package/src/pipes/safe-html.pipe.d.ts +0 -13
  414. package/src/services/fullscreen.service.d.ts +0 -18
  415. package/src/services/seo.service.d.ts +0 -50
  416. package/src/services/theme.service.d.ts +0 -17
@@ -1,591 +0,0 @@
1
- import { Component, EventEmitter, Input, Output } from '@angular/core';
2
- import { BasicUser, fullEmail, GraphQLRequestType, ToastType } from '@lenne.tech/ng-base/shared';
3
- import { ReactiveFormsModule, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
4
- import { RouterLink } from '@angular/router';
5
- import { FabButtonComponent } from '../fab-button/fab-button.component';
6
- import { ModelFormSubComponent } from '../model-form-sub/model-form-sub.component';
7
- import { NgClass } from '@angular/common';
8
- import * as i0 from "@angular/core";
9
- import * as i1 from "@lenne.tech/ng-base/shared";
10
- import * as i2 from "@angular/router";
11
- import * as i3 from "@angular/forms";
12
- /**
13
- * ModelFormComponent
14
- *
15
- * Hint for handling extensions of this component in project:
16
- * If you want to use complete custom services and methods, extend ModelFormBaseComponent instead of ModelFormComponent
17
- */
18
- export class ModelFormComponent {
19
- graphQLMetaService;
20
- graphQLService;
21
- formsService;
22
- authService;
23
- router;
24
- route;
25
- cmsService;
26
- toastService;
27
- fileService;
28
- modelName;
29
- label;
30
- id;
31
- delete = true;
32
- onlyUpdateMode = false;
33
- duplicate = false;
34
- logging = false;
35
- config;
36
- showFavButton = true;
37
- finished = new EventEmitter();
38
- meta;
39
- form;
40
- _loading = false;
41
- fields;
42
- operation;
43
- keys = [];
44
- user;
45
- object;
46
- fabButtons = [];
47
- fileChanges;
48
- set loading(value) {
49
- if (!value) {
50
- setTimeout(() => {
51
- this._loading = value;
52
- }, 400);
53
- }
54
- else {
55
- this._loading = value;
56
- }
57
- }
58
- constructor(graphQLMetaService, graphQLService, formsService, authService, router, route, cmsService, toastService, fileService) {
59
- this.graphQLMetaService = graphQLMetaService;
60
- this.graphQLService = graphQLService;
61
- this.formsService = formsService;
62
- this.authService = authService;
63
- this.router = router;
64
- this.route = route;
65
- this.cmsService = cmsService;
66
- this.toastService = toastService;
67
- this.fileService = fileService;
68
- }
69
- ngOnInit() {
70
- // Set user for roles check
71
- this.user = BasicUser.map(this.authService.currentUser);
72
- this.graphQLMetaService.getMeta().subscribe((meta) => {
73
- this.meta = meta;
74
- if (this.modelName) {
75
- this.init();
76
- }
77
- });
78
- this.initFabActions();
79
- }
80
- ngOnChanges(changes) {
81
- // Reinit form for new model or load and patch form with new id
82
- if (changes['modelName'] || changes['id']) {
83
- this.init();
84
- }
85
- }
86
- /**
87
- * > If the model name and metadata are present, set the operation to update or create, get the fields from the
88
- * metadata, create the form, and if the value is present, patch the form with the value
89
- */
90
- init(id) {
91
- if (id) {
92
- this.id = id;
93
- }
94
- if (!this.id && this.onlyUpdateMode) {
95
- return;
96
- }
97
- if (this.modelName && this.meta) {
98
- this.operation = this.id ? 'update' : 'create';
99
- if (this.logging) {
100
- console.log('ModelFormComponent::init->operation', this.operation);
101
- console.log('ModelFormComponent::init->meta.getArgs', this.operation + this.capitalizeFirstLetter(this.modelName));
102
- }
103
- this.fields = this.meta.getArgs(this.operation + this.capitalizeFirstLetter(this.modelName), {
104
- type: GraphQLRequestType.MUTATION,
105
- }).fields;
106
- this.fields = this.fields['input'].fields;
107
- this.keys = Object.keys(this.fields);
108
- if (this.logging) {
109
- console.log('ModelFormComponent::init->id', this.id);
110
- console.log('ModelFormComponent::init->fields', this.fields);
111
- console.log('ModelFormComponent::init->keys', this.keys);
112
- }
113
- this.form = this.createForm(this.fields);
114
- if (this.id) {
115
- this.getObjectById(this.id);
116
- }
117
- }
118
- }
119
- /**
120
- * It takes a key as an argument, and returns an array of keys from the sub-object
121
- */
122
- getKeysFromSubObject(key) {
123
- return Object.keys(this.fields[key]);
124
- }
125
- /**
126
- * It takes an id, and then calls the graphQLService to get the object from the database
127
- *
128
- * @param id - The id of the object to be loaded
129
- */
130
- getObjectById(id) {
131
- if (!id) {
132
- return;
133
- }
134
- if (this.logging) {
135
- console.log('ModelFormComponent::getObjectById->id', id);
136
- console.log('ModelFormComponent::getObjectById->requestFields', this.createRequestObject(this.fields));
137
- }
138
- this.graphQLService
139
- .graphQl('get' + this.capitalizeFirstLetter(this.modelName), {
140
- arguments: { id },
141
- fields: this.createRequestObject(this.fields),
142
- type: GraphQLRequestType.QUERY,
143
- })
144
- .subscribe({
145
- next: (response) => {
146
- if (this.logging) {
147
- console.log('ModelFormComponent::get->value', response);
148
- }
149
- this.object = response;
150
- this.form.patchValue({ ...{}, ...response });
151
- // Process patchFields for reference input
152
- for (const [key, value] of Object.entries(this.fields)) {
153
- if (this.nestedObject(key, this.fields)?.type === 'DateTime' ||
154
- this.nestedObject(key, this.config)?.type === 'DateTime') {
155
- this.form.get(key).patchValue(this.formatDate(this.nestedObject(key, response)));
156
- }
157
- // If it not an array
158
- if (this.nestedObject(key, this.config)?.type === 'Reference' &&
159
- !this.nestedObject(key, this.fields)?.isList) {
160
- if (this.form.get(key)) {
161
- this.form
162
- .get(key)
163
- .patchValue(response[this.nestedObject(key, this.config)?.patchField
164
- ? this.nestedObject(key, this.config)?.patchField
165
- : key]?.id);
166
- }
167
- }
168
- // If value is an array
169
- if (this.nestedObject(key, this.config)?.type === 'Reference' &&
170
- this.nestedObject(key, this.fields)?.isList) {
171
- if (this.form.get(key)) {
172
- this.form
173
- .get(key)
174
- .patchValue(response[this.nestedObject(key, this.config)?.patchField
175
- ? this.nestedObject(key, this.config)?.patchField
176
- : key]?.map((e) => e?.id));
177
- }
178
- }
179
- }
180
- if (this.logging) {
181
- console.log('ModelFormComponent::getObjectById->patchedForm', this.form);
182
- }
183
- },
184
- error: (err) => {
185
- console.error('Error on load object', err);
186
- this.finished.emit(null);
187
- },
188
- });
189
- }
190
- /**
191
- * It takes a GraphQL type collection and returns an array of strings and objects
192
- *
193
- * @param fields - IGraphQLTypeCollection - This is the object that is returned from the
194
- * introspection query.
195
- * @returns An array of strings and objects.
196
- */
197
- createRequestObject(fields) {
198
- const requestFields = [];
199
- for (const [key, value] of Object.entries(fields)) {
200
- if (this.config[key]?.exclude !== undefined && this.config[key]?.exclude) {
201
- continue;
202
- }
203
- if (Object.keys(fields[key]?.fields)?.length === 0) {
204
- if (this.config[key]?.type !== 'Reference') {
205
- requestFields.push(key);
206
- }
207
- else {
208
- requestFields.push({ [this.config[key]?.patchField ? this.config[key]?.patchField : key]: ['id'] });
209
- }
210
- }
211
- else {
212
- const subkeys = this.createRequestObject(fields[key].fields);
213
- const resultObject = {};
214
- resultObject[key] = subkeys;
215
- requestFields.push(resultObject);
216
- }
217
- }
218
- if (this.logging) {
219
- console.log('ModelFormComponent::createRequestObject->requestFields', requestFields);
220
- }
221
- return requestFields;
222
- }
223
- /**
224
- * It takes a collection of GraphQL types and creates a form group with a form control for each type
225
- *
226
- * @param fields - IGraphQLTypeCollection
227
- * @param parents
228
- */
229
- createForm(fields, parents = []) {
230
- const group = {};
231
- let internParents = [...[], ...parents];
232
- for (const [key, value] of Object.entries(fields)) {
233
- if (Object.keys(value?.fields)?.length === 0) {
234
- group[key] = new UntypedFormControl(null, this.processValidators(this.nestedObject(internParents.length ? internParents.join('.') + '.' + key : key, this.config), value));
235
- }
236
- else {
237
- internParents.push(key);
238
- group[key] = this.createForm(fields[key].fields, internParents);
239
- internParents = [];
240
- }
241
- }
242
- if (this.logging) {
243
- console.log('ModelFormComponent::createForm->group', group);
244
- }
245
- return new UntypedFormGroup(group);
246
- }
247
- /**
248
- * Process form validators for control
249
- */
250
- processValidators(config, value) {
251
- const validators = [];
252
- if (config) {
253
- if (config?.required !== undefined ? config?.required : value.isRequired) {
254
- validators.push(Validators.required);
255
- }
256
- if (config?.type === 'Email') {
257
- validators.push(fullEmail());
258
- }
259
- if (config?.type === 'Password') {
260
- validators.push(Validators.minLength(6));
261
- }
262
- if (typeof config?.min === 'number') {
263
- validators.push(Validators.min(config.min));
264
- }
265
- if (typeof config?.max === 'number') {
266
- validators.push(Validators.max(config.max));
267
- }
268
- if (Array.isArray(config?.validators)) {
269
- validators.push(...config?.validators);
270
- }
271
- }
272
- return validators;
273
- }
274
- /**
275
- * It calls the graphQLService to delete the object with the id of the object that is currently being edited
276
- */
277
- deleteObject() {
278
- this.cmsService.deleteObject(this.id, this.modelName).then(() => {
279
- this.toastService.show({
280
- id: this.modelName + '-success',
281
- type: ToastType.SUCCESS,
282
- title: 'Erfolgreich',
283
- description: this.label + ' wurde erfolgreich gelöscht.',
284
- });
285
- this.finished.emit(null);
286
- });
287
- }
288
- /**
289
- * It sends a GraphQL mutation to the server to duplicate the object
290
- */
291
- async duplicateObject() {
292
- this.cmsService.duplicateObject(this.id, this.modelName).then(async (value) => {
293
- if (value?.id) {
294
- await this.router.navigate(['../'], { relativeTo: this.route });
295
- this.toastService.show({
296
- id: this.modelName + '-success',
297
- type: ToastType.SUCCESS,
298
- title: 'Erfolgreich',
299
- description: this.label + ' wurde erfolgreich dupliziert.',
300
- });
301
- }
302
- else {
303
- this.finished.emit(null);
304
- }
305
- });
306
- }
307
- /**
308
- * It takes a string, capitalizes the first letter, and returns the modified string
309
- *
310
- * @param value - The string to capitalize.
311
- * @returns The first letter of the string is being capitalized and the rest of the string is being returned.
312
- */
313
- capitalizeFirstLetter(value) {
314
- return this.cmsService.capitalizeFirstLetter(value);
315
- }
316
- /**
317
- * It takes an AbstractControl and returns a FormControl
318
- *
319
- * @param control - AbstractControl | null | undefined
320
- * @returns A FormControl
321
- */
322
- transformToControl(control) {
323
- return control;
324
- }
325
- /**
326
- * It takes the key of the form control that has changed, gets the value of that form control, creates an object with the
327
- * key and value, and then sends that object to the GraphQL server to update the database
328
- */
329
- imageChanged(key) {
330
- const data = {};
331
- data[key] = this.form.get(key).value;
332
- if (this.logging) {
333
- console.log('ModelFormComponent::imageChanged->body', data);
334
- }
335
- if (this.id) {
336
- try {
337
- this.graphQLService
338
- .graphQl('update' + this.capitalizeFirstLetter(this.modelName), {
339
- arguments: { id: this.id, input: data },
340
- fields: ['id'],
341
- type: GraphQLRequestType.MUTATION,
342
- })
343
- .subscribe({
344
- next: (value) => {
345
- if (this.logging) {
346
- console.log('ModelFormComponent::imageChanged->success', value);
347
- }
348
- },
349
- });
350
- }
351
- catch (e) {
352
- if (this.logging) {
353
- console.log('ModelFormComponent::imageChanged->error', e);
354
- }
355
- }
356
- }
357
- }
358
- /**
359
- * It takes the form, validates it, and then sends it to the GraphQL server
360
- *
361
- * @returns The id of the newly created or updated object.
362
- */
363
- submit(secret = false) {
364
- return new Promise(async (resolve, reject) => {
365
- if (!secret) {
366
- this.loading = true;
367
- }
368
- if (this.form.invalid && !secret) {
369
- this.formsService.validateAllFormFields(this.form);
370
- this.formsService.scrollToInvalidControl(this.form);
371
- this.loading = false;
372
- resolve(null);
373
- return;
374
- }
375
- if (this.operation === 'update' && !this.id) {
376
- console.error('ID is missing for update!');
377
- this.loading = false;
378
- resolve(null);
379
- return;
380
- }
381
- if (this.logging) {
382
- console.log('ModelFormComponent::submit->formValue', this.form.value);
383
- }
384
- // Prepare data for server request
385
- let data = Object.assign({}, this.form.value);
386
- data = this.prepareDataForRequest(this.config, this.fields, data);
387
- if (this.logging) {
388
- console.log('ModelFormComponent::submit->valueToGraphql', data);
389
- console.log('ModelFormComponent::submit->fileChanges', this.fileChanges);
390
- }
391
- if (this.fileChanges?.length) {
392
- for (const fileChange of this.fileChanges) {
393
- const key = fileChange.field;
394
- const config = this.nestedObject(key, this.config);
395
- if (fileChange.file) {
396
- // Upload
397
- const value = this.form.get(key).value;
398
- // Check if file is an ID or a base64 string
399
- if (typeof value === 'string') {
400
- // Delete if ID
401
- if (!this.form.get(key).value?.startsWith('data:')) {
402
- const deleteResult = await this.fileService.delete(this.nestedObject(key, this.config)?.url, this.nestedObject(key, this.config)?.deletePath || '/files/', this.nestedObject(key, this.object));
403
- if (deleteResult) {
404
- this.nestedObject(key, data, '');
405
- }
406
- }
407
- const uploadResult = await this.fileService.upload(this.nestedObject(key, this.config)?.url, this.nestedObject(key, this.config)?.uploadPath || '/files/upload', fileChange.file);
408
- if (uploadResult?.id) {
409
- this.nestedObject(key, data, uploadResult.id);
410
- }
411
- }
412
- else if (config?.imageMode && config?.imageMode !== 'file') {
413
- // Delete
414
- const result = await this.fileService.delete(config?.url, this.nestedObject(key, this.config)?.deletePath || '/files/', this.nestedObject(key, this.object));
415
- if (result) {
416
- this.nestedObject(key, data, '');
417
- }
418
- }
419
- }
420
- }
421
- }
422
- this.graphQLService
423
- .graphQl(this.operation + this.capitalizeFirstLetter(this.modelName), {
424
- arguments: this.operation === 'update' ? { id: this.id, input: data } : { input: data },
425
- fields: ['id'],
426
- type: GraphQLRequestType.MUTATION,
427
- })
428
- .subscribe({
429
- next: (value) => {
430
- if (!secret) {
431
- this.loading = false;
432
- this.finished.emit(null);
433
- this.toastService.show({
434
- id: this.modelName + '-success',
435
- type: ToastType.SUCCESS,
436
- title: 'Erfolgreich',
437
- description: this.label + ' wurde erfolgreich ' + (this.operation === 'create' ? 'erstellt.' : 'aktualisiert.'),
438
- });
439
- }
440
- resolve(value);
441
- },
442
- error: (err) => {
443
- if (!secret) {
444
- console.error('Failed on ' + this.operation, err);
445
- this.loading = false;
446
- this.toastService.show({
447
- id: this.modelName + '-success',
448
- type: ToastType.ERROR,
449
- description: 'Beim ' +
450
- (this.operation === 'create' ? 'erstellen' : 'aktualisieren') +
451
- ' von ' +
452
- this.label +
453
- ' ist etwas schiefgelaufen.',
454
- });
455
- }
456
- reject();
457
- },
458
- });
459
- });
460
- }
461
- /**
462
- * Prepare data for server
463
- */
464
- prepareDataForRequest(config, fieldsConfig, data) {
465
- if (!data) {
466
- return data;
467
- }
468
- for (const [key, value] of Object.entries(data)) {
469
- if ((this.fields[key]?.type === 'DateTime' || this.config[key]?.type === 'DateTime') && value === '') {
470
- data[key] = null;
471
- continue;
472
- }
473
- if ((config[key]?.roles ? !this.user.hasAllRoles(config[key]?.roles) : false) || config[key]?.exclude) {
474
- delete data[key];
475
- continue;
476
- }
477
- if (value && typeof value === 'object' && !Array.isArray(value) && this.fields[key]?.type !== 'Upload') {
478
- data[key] = Object.keys(data[key])
479
- .filter((k) => data[key][k] != null)
480
- .reduce((a, k) => ({ ...a, [k]: data[key][k] }), {});
481
- if (Object.keys(data[key])?.length === 0) {
482
- if (this.logging) {
483
- console.log('Object is empty from result');
484
- }
485
- data[key] = null;
486
- }
487
- }
488
- // Set type for graphql method
489
- if (fieldsConfig[key]?.type === 'Float') {
490
- if (value) {
491
- data[key] = Number(value);
492
- }
493
- else {
494
- data[key] = null;
495
- }
496
- }
497
- if (fieldsConfig[key]?.fields && Object.keys(fieldsConfig[key]?.fields).length > 0) {
498
- data[key] = this.prepareDataForRequest(config[key]?.fields, fieldsConfig[key]?.fields, data[key]);
499
- }
500
- }
501
- return data;
502
- }
503
- /**
504
- * Init fab buttons for mobile devices
505
- */
506
- initFabActions() {
507
- const saveEvent = new EventEmitter();
508
- this.fabButtons.push({ icon: 'bi-check-lg', color: 'var(--bs-success)', event: saveEvent });
509
- saveEvent.subscribe(() => this.submit(false));
510
- if (this.duplicate && this.operation === 'update') {
511
- const event = new EventEmitter();
512
- this.fabButtons.push({ icon: 'bi-back', color: 'var(--bs-info)', event });
513
- event.subscribe(() => this.duplicateObject());
514
- }
515
- if (this.operation === 'update' && this.delete) {
516
- const event = new EventEmitter();
517
- this.fabButtons.push({ icon: 'bi-trash3', color: 'var(--bs-danger)', event });
518
- event.subscribe(() => this.deleteObject());
519
- }
520
- }
521
- /**
522
- * Set file changes for process
523
- */
524
- processFileChanges(event) {
525
- const index = this.fileChanges?.findIndex((e) => e.field === event.field);
526
- if (index !== undefined && index !== -1) {
527
- this.fileChanges[index] = event;
528
- }
529
- else if (this.fileChanges) {
530
- this.fileChanges.push(event);
531
- }
532
- else {
533
- this.fileChanges = [event];
534
- }
535
- }
536
- formatDate(date) {
537
- if (!date) {
538
- return null;
539
- }
540
- const newDate = new Date(date);
541
- return newDate.toISOString().substring(0, 16);
542
- }
543
- nestedObject(key, nestedObject, value) {
544
- const props = key.split('.');
545
- let result = nestedObject;
546
- for (let i = 0; i < props.length; i++) {
547
- if (value && i === props.length - 1) {
548
- result[props[i]] = value;
549
- return result[props[i]];
550
- }
551
- result =
552
- result[props[i]]?.fields && Object.keys(result[props[i]]?.fields)?.length > 0
553
- ? result[props[i]]?.fields
554
- : result[props[i]];
555
- }
556
- return result;
557
- }
558
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: ModelFormComponent, deps: [{ token: i1.GraphQLMetaService }, { token: i1.GraphQLService }, { token: i1.FormsService }, { token: i1.AuthService }, { token: i2.Router }, { token: i2.ActivatedRoute }, { token: i1.CmsService }, { token: i1.ToastService }, { token: i1.FileService }], target: i0.ɵɵFactoryTarget.Component });
559
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.2", type: ModelFormComponent, isStandalone: true, selector: "base-model-form", inputs: { modelName: "modelName", label: "label", id: "id", delete: "delete", onlyUpdateMode: "onlyUpdateMode", duplicate: "duplicate", logging: "logging", config: "config", showFavButton: "showFavButton" }, outputs: { finished: "finished" }, usesOnChanges: true, ngImport: i0, template: "@if (form) {\n <div class=\"w-100\">\n <div class=\"d-flex flex-row justify-content-between mt-3\">\n <div class=\"responsive-back d-flex d-lg-none\">\n <i class=\"bi bi-arrow-left\" routerLink=\"../\"></i>\n </div>\n <h2 class=\"mb-0\">\n {{ label ? label : capitalizeFirstLetter(modelName) }} {{ operation === 'update' ? 'bearbeiten' : 'erstellen' }}\n </h2>\n <div class=\"d-none d-lg-flex flex-row align-items-center justify-content-end\">\n @if (id && duplicate && !_loading) {\n <button class=\"btn btn-outline-primary me-2\" (click)=\"duplicateObject()\">\n Duplizieren\n </button>\n }\n @if (!_loading) {\n <button\n class=\"btn btn-primary\"\n type=\"button\"\n [disabled]=\"!form.touched && !form.dirty\"\n (click)=\"submit(false)\"\n >\n {{ operation === 'create' ? 'Erstellen' : 'Speichern' }}\n </button>\n }\n @if (_loading) {\n <button class=\"btn btn-primary\" type=\"button\" disabled>\n <span class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\"></span>\n {{ operation === 'create' ? 'Erstellen' : 'Speichern' }}...\n </button>\n }\n </div>\n </div>\n <form [formGroup]=\"form\">\n <base-model-form-sub\n [id]=\"id\"\n [fields]=\"fields\"\n [config]=\"config\"\n [form]=\"form\"\n (imageChanged)=\"imageChanged($event)\"\n (fileChanged)=\"processFileChanges($event)\"\n ></base-model-form-sub>\n <div class=\"d-none d-lg-flex mt-4\" [ngClass]=\"id && delete ? 'justify-content-between' : 'justify-content-end'\">\n @if (id && delete) {\n <div>\n <button class=\"btn btn-danger\" type=\"button\" (click)=\"deleteObject()\">L\u00F6schen</button>\n </div>\n }\n <div>\n @if (!_loading) {\n <button\n class=\"btn btn-primary\"\n type=\"button\"\n [disabled]=\"!form.touched && !form.dirty\"\n (click)=\"submit(false)\"\n >\n {{ operation === 'create' ? 'Erstellen' : 'Speichern' }}\n </button>\n }\n @if (_loading) {\n <button class=\"btn btn-primary\" type=\"button\" disabled>\n <span class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\"></span>\n {{ operation === 'create' ? 'Erstellen' : 'Speichern' }}...\n </button>\n }\n </div>\n </div>\n </form>\n</div>\n}\n\n@if (showFavButton) {\n <div class=\"d-block d-lg-none responsive-action-button\">\n <base-fab-button [buttons]=\"fabButtons\"></base-fab-button>\n </div>\n}\n", styles: [".responsive-back{display:flex;align-items:center;margin-right:6px}.responsive-back .bi-arrow-left{font-size:28px}h2{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.responsive-action-button{position:fixed;bottom:15px;right:15px;z-index:100}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ModelFormSubComponent, selector: "base-model-form-sub", inputs: ["id", "parentKey", "fields", "form", "config"], outputs: ["imageChanged", "fileChanged"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: FabButtonComponent, selector: "base-fab-button", inputs: ["fabIcon", "buttons"] }] });
560
- }
561
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: ModelFormComponent, decorators: [{
562
- type: Component,
563
- args: [{ selector: 'base-model-form', standalone: true, imports: [
564
- RouterLink,
565
- ReactiveFormsModule,
566
- ModelFormSubComponent,
567
- NgClass,
568
- FabButtonComponent
569
- ], template: "@if (form) {\n <div class=\"w-100\">\n <div class=\"d-flex flex-row justify-content-between mt-3\">\n <div class=\"responsive-back d-flex d-lg-none\">\n <i class=\"bi bi-arrow-left\" routerLink=\"../\"></i>\n </div>\n <h2 class=\"mb-0\">\n {{ label ? label : capitalizeFirstLetter(modelName) }} {{ operation === 'update' ? 'bearbeiten' : 'erstellen' }}\n </h2>\n <div class=\"d-none d-lg-flex flex-row align-items-center justify-content-end\">\n @if (id && duplicate && !_loading) {\n <button class=\"btn btn-outline-primary me-2\" (click)=\"duplicateObject()\">\n Duplizieren\n </button>\n }\n @if (!_loading) {\n <button\n class=\"btn btn-primary\"\n type=\"button\"\n [disabled]=\"!form.touched && !form.dirty\"\n (click)=\"submit(false)\"\n >\n {{ operation === 'create' ? 'Erstellen' : 'Speichern' }}\n </button>\n }\n @if (_loading) {\n <button class=\"btn btn-primary\" type=\"button\" disabled>\n <span class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\"></span>\n {{ operation === 'create' ? 'Erstellen' : 'Speichern' }}...\n </button>\n }\n </div>\n </div>\n <form [formGroup]=\"form\">\n <base-model-form-sub\n [id]=\"id\"\n [fields]=\"fields\"\n [config]=\"config\"\n [form]=\"form\"\n (imageChanged)=\"imageChanged($event)\"\n (fileChanged)=\"processFileChanges($event)\"\n ></base-model-form-sub>\n <div class=\"d-none d-lg-flex mt-4\" [ngClass]=\"id && delete ? 'justify-content-between' : 'justify-content-end'\">\n @if (id && delete) {\n <div>\n <button class=\"btn btn-danger\" type=\"button\" (click)=\"deleteObject()\">L\u00F6schen</button>\n </div>\n }\n <div>\n @if (!_loading) {\n <button\n class=\"btn btn-primary\"\n type=\"button\"\n [disabled]=\"!form.touched && !form.dirty\"\n (click)=\"submit(false)\"\n >\n {{ operation === 'create' ? 'Erstellen' : 'Speichern' }}\n </button>\n }\n @if (_loading) {\n <button class=\"btn btn-primary\" type=\"button\" disabled>\n <span class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\"></span>\n {{ operation === 'create' ? 'Erstellen' : 'Speichern' }}...\n </button>\n }\n </div>\n </div>\n </form>\n</div>\n}\n\n@if (showFavButton) {\n <div class=\"d-block d-lg-none responsive-action-button\">\n <base-fab-button [buttons]=\"fabButtons\"></base-fab-button>\n </div>\n}\n", styles: [".responsive-back{display:flex;align-items:center;margin-right:6px}.responsive-back .bi-arrow-left{font-size:28px}h2{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.responsive-action-button{position:fixed;bottom:15px;right:15px;z-index:100}\n"] }]
570
- }], ctorParameters: () => [{ type: i1.GraphQLMetaService }, { type: i1.GraphQLService }, { type: i1.FormsService }, { type: i1.AuthService }, { type: i2.Router }, { type: i2.ActivatedRoute }, { type: i1.CmsService }, { type: i1.ToastService }, { type: i1.FileService }], propDecorators: { modelName: [{
571
- type: Input
572
- }], label: [{
573
- type: Input
574
- }], id: [{
575
- type: Input
576
- }], delete: [{
577
- type: Input
578
- }], onlyUpdateMode: [{
579
- type: Input
580
- }], duplicate: [{
581
- type: Input
582
- }], logging: [{
583
- type: Input
584
- }], config: [{
585
- type: Input
586
- }], showFavButton: [{
587
- type: Input
588
- }], finished: [{
589
- type: Output
590
- }] } });
591
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwtZm9ybS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1iYXNlL2Jhc2UtY29tcG9uZW50cy9jb21wb25lbnRzL21vZGVsLWZvcm0vbW9kZWwtZm9ybS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1iYXNlL2Jhc2UtY29tcG9uZW50cy9jb21wb25lbnRzL21vZGVsLWZvcm0vbW9kZWwtZm9ybS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQXFCLE1BQU0sRUFBaUIsTUFBTSxlQUFlLENBQUM7QUFDekcsT0FBTyxFQUVMLFNBQVMsRUFLVCxTQUFTLEVBR1Qsa0JBQWtCLEVBS2xCLFNBQVMsRUFDVixNQUFNLDRCQUE0QixDQUFDO0FBQ3BDLE9BQU8sRUFBbUIsbUJBQW1CLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEgsT0FBTyxFQUEwQixVQUFVLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRSxPQUFPLEVBQVUsa0JBQWtCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUNoRixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUNuRixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0saUJBQWlCLENBQUM7Ozs7O0FBRTFDOzs7OztHQUtHO0FBY0gsTUFBTSxPQUFPLGtCQUFrQjtJQW1DbkI7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBMUNELFNBQVMsQ0FBUztJQUNsQixLQUFLLENBQVM7SUFDZCxFQUFFLENBQWdCO0lBQ2xCLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDZCxjQUFjLEdBQUcsS0FBSyxDQUFDO0lBQ3ZCLFNBQVMs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QkFBcUIsbUtBQ3JCLE9BQU8sb0ZBQ1Asa0JBQWtCOzsyRkFHVCxrQkFBa0I7a0JBYjlCLFNBQVM7K0JBQ0UsaUJBQWlCLGNBR2YsSUFBSSxXQUNQO3dCQUNQLFVBQVU7d0JBQ1YsbUJBQW1CO3dCQUNuQixxQkFBcUI7d0JBQ3JCLE9BQU87d0JBQ1Asa0JBQWtCO3FCQUNuQjt5U0FHUSxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxFQUFFO3NCQUFWLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBRUksUUFBUTtzQkFBakIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25DaGFuZ2VzLCBPbkluaXQsIE91dHB1dCwgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgQXV0aFNlcnZpY2UsXG4gIEJhc2ljVXNlcixcbiAgQ01TRmllbGRDb25maWcsXG4gIENtc1NlcnZpY2UsXG4gIEZpbGVTZXJ2aWNlLFxuICBGb3Jtc1NlcnZpY2UsXG4gIGZ1bGxFbWFpbCxcbiAgR3JhcGhRTE1ldGEsXG4gIEdyYXBoUUxNZXRhU2VydmljZSxcbiAgR3JhcGhRTFJlcXVlc3RUeXBlLFxuICBHcmFwaFFMU2VydmljZSxcbiAgR3JhcGhRTFR5cGUsXG4gIElHcmFwaFFMVHlwZUNvbGxlY3Rpb24sXG4gIFRvYXN0U2VydmljZSxcbiAgVG9hc3RUeXBlXG59IGZyb20gJ0BsZW5uZS50ZWNoL25nLWJhc2Uvc2hhcmVkJztcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgUmVhY3RpdmVGb3Jtc01vZHVsZSwgVW50eXBlZEZvcm1Db250cm9sLCBVbnR5cGVkRm9ybUdyb3VwLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciwgUm91dGVyTGluayB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBCdXR0b24sIEZhYkJ1dHRvbkNvbXBvbmVudCB9IGZyb20gJy4uL2ZhYi1idXR0b24vZmFiLWJ1dHRvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgTW9kZWxGb3JtU3ViQ29tcG9uZW50IH0gZnJvbSAnLi4vbW9kZWwtZm9ybS1zdWIvbW9kZWwtZm9ybS1zdWIuY29tcG9uZW50JztcbmltcG9ydCB7IE5nQ2xhc3MgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuXG4vKipcbiAqIE1vZGVsRm9ybUNvbXBvbmVudFxuICpcbiAqIEhpbnQgZm9yIGhhbmRsaW5nIGV4dGVuc2lvbnMgb2YgdGhpcyBjb21wb25lbnQgaW4gcHJvamVjdDpcbiAqIElmIHlvdSB3YW50IHRvIHVzZSBjb21wbGV0ZSBjdXN0b20gc2VydmljZXMgYW5kIG1ldGhvZHMsIGV4dGVuZCBNb2RlbEZvcm1CYXNlQ29tcG9uZW50IGluc3RlYWQgb2YgTW9kZWxGb3JtQ29tcG9uZW50XG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2Jhc2UtbW9kZWwtZm9ybScsXG4gIHRlbXBsYXRlVXJsOiAnLi9tb2RlbC1mb3JtLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vbW9kZWwtZm9ybS5jb21wb25lbnQuc2NzcyddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgUm91dGVyTGluayxcbiAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICAgIE1vZGVsRm9ybVN1YkNvbXBvbmVudCxcbiAgICBOZ0NsYXNzLFxuICAgIEZhYkJ1dHRvbkNvbXBvbmVudFxuICBdXG59KVxuZXhwb3J0IGNsYXNzIE1vZGVsRm9ybUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgbW9kZWxOYW1lOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGxhYmVsOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGlkOiBzdHJpbmcgfCBudWxsO1xuICBASW5wdXQoKSBkZWxldGUgPSB0cnVlO1xuICBASW5wdXQoKSBvbmx5VXBkYXRlTW9kZSA9IGZhbHNlO1xuICBASW5wdXQoKSBkdXBsaWNhdGUgPSBmYWxzZTtcbiAgQElucHV0KCkgbG9nZ2luZyA9IGZhbHNlO1xuICBASW5wdXQoKSBjb25maWc6IHsgW2tleTogc3RyaW5nXTogQ01TRmllbGRDb25maWcgfTtcbiAgQElucHV0KCkgc2hvd0ZhdkJ1dHRvbiA9IHRydWU7XG5cbiAgQE91dHB1dCgpIGZpbmlzaGVkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIG1ldGE6IEdyYXBoUUxNZXRhO1xuICBmb3JtOiBVbnR5cGVkRm9ybUdyb3VwO1xuICBfbG9hZGluZyA9IGZhbHNlO1xuICBmaWVsZHM6IFJlY29yZDxzdHJpbmcsIEdyYXBoUUxUeXBlPjtcbiAgb3BlcmF0aW9uOiBzdHJpbmc7XG4gIGtleXM6IHN0cmluZ1tdID0gW107XG4gIHVzZXI6IEJhc2ljVXNlcjtcbiAgb2JqZWN0OiBhbnk7XG4gIGZhYkJ1dHRvbnM6IEJ1dHRvbltdID0gW107XG4gIGZpbGVDaGFuZ2VzOiBbeyBmaWVsZDogc3RyaW5nOyBmaWxlOiBGaWxlIHwgbnVsbCB9XTtcblxuICBzZXQgbG9hZGluZyh2YWx1ZTogYm9vbGVhbikge1xuICAgIGlmICghdmFsdWUpIHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLl9sb2FkaW5nID0gdmFsdWU7XG4gICAgICB9LCA0MDApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9sb2FkaW5nID0gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBncmFwaFFMTWV0YVNlcnZpY2U6IEdyYXBoUUxNZXRhU2VydmljZSxcbiAgICBwcml2YXRlIGdyYXBoUUxTZXJ2aWNlOiBHcmFwaFFMU2VydmljZSxcbiAgICBwcml2YXRlIGZvcm1zU2VydmljZTogRm9ybXNTZXJ2aWNlLFxuICAgIHByaXZhdGUgYXV0aFNlcnZpY2U6IEF1dGhTZXJ2aWNlLFxuICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgcHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgcHJpdmF0ZSBjbXNTZXJ2aWNlOiBDbXNTZXJ2aWNlLFxuICAgIHByaXZhdGUgdG9hc3RTZXJ2aWNlOiBUb2FzdFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBmaWxlU2VydmljZTogRmlsZVNlcnZpY2VcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIFNldCB1c2VyIGZvciByb2xlcyBjaGVja1xuICAgIHRoaXMudXNlciA9IEJhc2ljVXNlci5tYXAodGhpcy5hdXRoU2VydmljZS5jdXJyZW50VXNlcik7XG5cbiAgICB0aGlzLmdyYXBoUUxNZXRhU2VydmljZS5nZXRNZXRhKCkuc3Vic2NyaWJlKChtZXRhKSA9PiB7XG4gICAgICB0aGlzLm1ldGEgPSBtZXRhO1xuXG4gICAgICBpZiAodGhpcy5tb2RlbE5hbWUpIHtcbiAgICAgICAgdGhpcy5pbml0KCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmluaXRGYWJBY3Rpb25zKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgLy8gUmVpbml0IGZvcm0gZm9yIG5ldyBtb2RlbCBvciBsb2FkIGFuZCBwYXRjaCBmb3JtIHdpdGggbmV3IGlkXG4gICAgaWYgKGNoYW5nZXNbJ21vZGVsTmFtZSddIHx8IGNoYW5nZXNbJ2lkJ10pIHtcbiAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiA+IElmIHRoZSBtb2RlbCBuYW1lIGFuZCBtZXRhZGF0YSBhcmUgcHJlc2VudCwgc2V0IHRoZSBvcGVyYXRpb24gdG8gdXBkYXRlIG9yIGNyZWF0ZSwgZ2V0IHRoZSBmaWVsZHMgZnJvbSB0aGVcbiAgICogbWV0YWRhdGEsIGNyZWF0ZSB0aGUgZm9ybSwgYW5kIGlmIHRoZSB2YWx1ZSBpcyBwcmVzZW50LCBwYXRjaCB0aGUgZm9ybSB3aXRoIHRoZSB2YWx1ZVxuICAgKi9cbiAgaW5pdChpZD86IHN0cmluZykge1xuICAgIGlmIChpZCkge1xuICAgICAgdGhpcy5pZCA9IGlkO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5pZCAmJiB0aGlzLm9ubHlVcGRhdGVNb2RlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubW9kZWxOYW1lICYmIHRoaXMubWV0YSkge1xuICAgICAgdGhpcy5vcGVyYXRpb24gPSB0aGlzLmlkID8gJ3VwZGF0ZScgOiAnY3JlYXRlJztcblxuICAgICAgaWYgKHRoaXMubG9nZ2luZykge1xuICAgICAgICBjb25zb2xlLmxvZygnTW9kZWxGb3JtQ29tcG9uZW50Ojppbml0LT5vcGVyYXRpb24nLCB0aGlzLm9wZXJhdGlvbik7XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICdNb2RlbEZvcm1Db21wb25lbnQ6OmluaXQtPm1ldGEuZ2V0QXJncycsXG4gICAgICAgICAgdGhpcy5vcGVyYXRpb24gKyB0aGlzLmNhcGl0YWxpemVGaXJzdExldHRlcih0aGlzLm1vZGVsTmFtZSlcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5maWVsZHMgPSB0aGlzLm1ldGEuZ2V0QXJncyh0aGlzLm9wZXJhdGlvbiArIHRoaXMuY2FwaXRhbGl6ZUZpcnN0TGV0dGVyKHRoaXMubW9kZWxOYW1lKSwge1xuICAgICAgICB0eXBlOiBHcmFwaFFMUmVxdWVzdFR5cGUuTVVUQVRJT04sXG4gICAgICB9KS5maWVsZHM7XG4gICAgICB0aGlzLmZpZWxkcyA9IHRoaXMuZmllbGRzWydpbnB1dCddLmZpZWxkcyBhcyBhbnk7XG4gICAgICB0aGlzLmtleXMgPSBPYmplY3Qua2V5cyh0aGlzLmZpZWxkcyk7XG5cbiAgICAgIGlmICh0aGlzLmxvZ2dpbmcpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01vZGVsRm9ybUNvbXBvbmVudDo6aW5pdC0+aWQnLCB0aGlzLmlkKTtcbiAgICAgICAgY29uc29sZS5sb2coJ01vZGVsRm9ybUNvbXBvbmVudDo6aW5pdC0+ZmllbGRzJywgdGhpcy5maWVsZHMpO1xuICAgICAgICBjb25zb2xlLmxvZygnTW9kZWxGb3JtQ29tcG9uZW50Ojppbml0LT5rZXlzJywgdGhpcy5rZXlzKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5mb3JtID0gdGhpcy5jcmVhdGVGb3JtKHRoaXMuZmllbGRzKTtcblxuICAgICAgaWYgKHRoaXMuaWQpIHtcbiAgICAgICAgdGhpcy5nZXRPYmplY3RCeUlkKHRoaXMuaWQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJdCB0YWtlcyBhIGtleSBhcyBhbiBhcmd1bWVudCwgYW5kIHJldHVybnMgYW4gYXJyYXkgb2Yga2V5cyBmcm9tIHRoZSBzdWItb2JqZWN0XG4gICAqL1xuICBnZXRLZXlzRnJvbVN1Yk9iamVjdChrZXk6IHN0cmluZykge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmZpZWxkc1trZXldKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJdCB0YWtlcyBhbiBpZCwgYW5kIHRoZW4gY2FsbHMgdGhlIGdyYXBoUUxTZXJ2aWNlIHRvIGdldCB0aGUgb2JqZWN0IGZyb20gdGhlIGRhdGFiYXNlXG4gICAqXG4gICAqIEBwYXJhbSBpZCAtIFRoZSBpZCBvZiB0aGUgb2JqZWN0IHRvIGJlIGxvYWRlZFxuICAgKi9cbiAgZ2V0T2JqZWN0QnlJZChpZDogc3RyaW5nKSB7XG4gICAgaWYgKCFpZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmxvZ2dpbmcpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdNb2RlbEZvcm1Db21wb25lbnQ6OmdldE9iamVjdEJ5SWQtPmlkJywgaWQpO1xuICAgICAgY29uc29sZS5sb2coJ01vZGVsRm9ybUNvbXBvbmVudDo6Z2V0T2JqZWN0QnlJZC0+cmVxdWVzdEZpZWxkcycsIHRoaXMuY3JlYXRlUmVxdWVzdE9iamVjdCh0aGlzLmZpZWxkcykpO1xuICAgIH1cblxuICAgIHRoaXMuZ3JhcGhRTFNlcnZpY2VcbiAgICAgIC5ncmFwaFFsKCdnZXQnICsgdGhpcy5jYXBpdGFsaXplRmlyc3RMZXR0ZXIodGhpcy5tb2RlbE5hbWUpLCB7XG4gICAgICAgIGFyZ3VtZW50czogeyBpZCB9LFxuICAgICAgICBmaWVsZHM6IHRoaXMuY3JlYXRlUmVxdWVzdE9iamVjdCh0aGlzLmZpZWxkcyksXG4gICAgICAgIHR5cGU6IEdyYXBoUUxSZXF1ZXN0VHlwZS5RVUVSWSxcbiAgICAgIH0pXG4gICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMubG9nZ2luZykge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ01vZGVsRm9ybUNvbXBvbmVudDo6Z2V0LT52YWx1ZScsIHJlc3BvbnNlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLm9iamVjdCA9IHJlc3BvbnNlO1xuICAgICAgICAgIHRoaXMuZm9ybS5wYXRjaFZhbHVlKHsgLi4ue30sIC4uLnJlc3BvbnNlIH0pO1xuXG4gICAgICAgICAgLy8gUHJvY2VzcyBwYXRjaEZpZWxkcyBmb3IgcmVmZXJlbmNlIGlucHV0XG4gICAgICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5maWVsZHMpKSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIHRoaXMubmVzdGVkT2JqZWN0KGtleSwgdGhpcy5maWVsZHMpPy50eXBlID09PSAnRGF0ZVRpbWUnIHx8XG4gICAgICAgICAgICAgIHRoaXMubmVzdGVkT2JqZWN0KGtleSwgdGhpcy5jb25maWcpPy50eXBlID09PSAnRGF0ZVRpbWUnXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhpcy5mb3JtLmdldChrZXkpLnBhdGNoVmFsdWUodGhpcy5mb3JtYXREYXRlKHRoaXMubmVzdGVkT2JqZWN0KGtleSwgcmVzcG9uc2UpKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIGl0IG5vdCBhbiBhcnJheVxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICB0aGlzLm5lc3RlZE9iamVjdChrZXksIHRoaXMuY29uZmlnKT8udHlwZSA9PT0gJ1JlZmVyZW5jZScgJiZcbiAgICAgICAgICAgICAgIXRoaXMubmVzdGVkT2JqZWN0KGtleSwgdGhpcy5maWVsZHMpPy5pc0xpc3RcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBpZiAodGhpcy5mb3JtLmdldChrZXkpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtXG4gICAgICAgICAgICAgICAgICAuZ2V0KGtleSlcbiAgICAgICAgICAgICAgICAgIC5wYXRjaFZhbHVlKFxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZVtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5lc3RlZE9iamVjdChrZXksIHRoaXMuY29uZmlnKT8ucGF0Y2hGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgPyB0aGlzLm5lc3RlZE9iamVjdChrZXksIHRoaXMuY29uZmlnKT8ucGF0Y2hGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgOiBrZXlcbiAgICAgICAgICAgICAgICAgICAgXT8uaWRcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgdmFsdWUgaXMgYW4gYXJyYXlcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgdGhpcy5uZXN0ZWRPYmplY3Qoa2V5LCB0aGlzLmNvbmZpZyk/LnR5cGUgPT09ICdSZWZlcmVuY2UnICYmXG4gICAgICAgICAgICAgIHRoaXMubmVzdGVkT2JqZWN0KGtleSwgdGhpcy5maWVsZHMpPy5pc0xpc3RcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBpZiAodGhpcy5mb3JtLmdldChrZXkpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtXG4gICAgICAgICAgICAgICAgICAuZ2V0KGtleSlcbiAgICAgICAgICAgICAgICAgIC5wYXRjaFZhbHVlKFxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZVtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5lc3RlZE9iamVjdChrZXksIHRoaXMuY29uZmlnKT8ucGF0Y2hGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgPyB0aGlzLm5lc3RlZE9iamVjdChrZXksIHRoaXMuY29uZmlnKT8ucGF0Y2hGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgOiBrZXlcbiAgICAgICAgICAgICAgICAgICAgXT8ubWFwKChlKSA9PiBlPy5pZClcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodGhpcy5sb2dnaW5nKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnTW9kZWxGb3JtQ29tcG9uZW50OjpnZXRPYmplY3RCeUlkLT5wYXRjaGVkRm9ybScsIHRoaXMuZm9ybSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIG9uIGxvYWQgb2JqZWN0JywgZXJyKTtcbiAgICAgICAgICB0aGlzLmZpbmlzaGVkLmVtaXQobnVsbCk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJdCB0YWtlcyBhIEdyYXBoUUwgdHlwZSBjb2xsZWN0aW9uIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIHN0cmluZ3MgYW5kIG9iamVjdHNcbiAgICpcbiAgICogQHBhcmFtIGZpZWxkcyAtIElHcmFwaFFMVHlwZUNvbGxlY3Rpb24gLSBUaGlzIGlzIHRoZSBvYmplY3QgdGhhdCBpcyByZXR1cm5lZCBmcm9tIHRoZVxuICAgKiBpbnRyb3NwZWN0aW9uIHF1ZXJ5LlxuICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiBzdHJpbmdzIGFuZCBvYmplY3RzLlxuICAgKi9cbiAgY3JlYXRlUmVxdWVzdE9iamVjdChmaWVsZHM6IElHcmFwaFFMVHlwZUNvbGxlY3Rpb24pIHtcbiAgICBjb25zdCByZXF1ZXN0RmllbGRzOiBhbnkgPSBbXTtcblxuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGZpZWxkcykpIHtcbiAgICAgIGlmICh0aGlzLmNvbmZpZ1trZXldPy5leGNsdWRlICE9PSB1bmRlZmluZWQgJiYgdGhpcy5jb25maWdba2V5XT8uZXhjbHVkZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKE9iamVjdC5rZXlzKGZpZWxkc1trZXldPy5maWVsZHMpPy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnW2tleV0/LnR5cGUgIT09ICdSZWZlcmVuY2UnKSB7XG4gICAgICAgICAgcmVxdWVzdEZpZWxkcy5wdXNoKGtleSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVxdWVzdEZpZWxkcy5wdXNoKHsgW3RoaXMuY29uZmlnW2tleV0/LnBhdGNoRmllbGQgPyB0aGlzLmNvbmZpZ1trZXldPy5wYXRjaEZpZWxkIDoga2V5XTogWydpZCddIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBzdWJrZXlzID0gdGhpcy5jcmVhdGVSZXF1ZXN0T2JqZWN0KGZpZWxkc1trZXldLmZpZWxkcyBhcyBJR3JhcGhRTFR5cGVDb2xsZWN0aW9uKTtcbiAgICAgICAgY29uc3QgcmVzdWx0T2JqZWN0ID0ge307XG4gICAgICAgIHJlc3VsdE9iamVjdFtrZXldID0gc3Via2V5cztcbiAgICAgICAgcmVxdWVzdEZpZWxkcy5wdXNoKHJlc3VsdE9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubG9nZ2luZykge1xuICAgICAgY29uc29sZS5sb2coJ01vZGVsRm9ybUNvbXBvbmVudDo6Y3JlYXRlUmVxdWVzdE9iamVjdC0+cmVxdWVzdEZpZWxkcycsIHJlcXVlc3RGaWVsZHMpO1xuICAgIH1cblxuICAgIHJldHVybiByZXF1ZXN0RmllbGRzO1xuICB9XG5cbiAgLyoqXG4gICAqIEl0IHRha2VzIGEgY29sbGVjdGlvbiBvZiBHcmFwaFFMIHR5cGVzIGFuZCBjcmVhdGVzIGEgZm9ybSBncm91cCB3aXRoIGEgZm9ybSBjb250cm9sIGZvciBlYWNoIHR5cGVcbiAgICpcbiAgICogQHBhcmFtIGZpZWxkcyAtIElHcmFwaFFMVHlwZUNvbGxlY3Rpb25cbiAgICogQHBhcmFtIHBhcmVudHNcbiAgICovXG4gIGNyZWF0ZUZvcm0oZmllbGRzOiBJR3JhcGhRTFR5cGVDb2xsZWN0aW9uLCBwYXJlbnRzOiBhbnlbXSA9IFtdKSB7XG4gICAgY29uc3QgZ3JvdXA6IGFueSA9IHt9O1xuICAgIGxldCBpbnRlcm5QYXJlbnRzID0gWy4uLltdLCAuLi5wYXJlbnRzXTtcblxuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGZpZWxkcykpIHtcbiAgICAgIGlmIChPYmplY3Qua2V5cyh2YWx1ZT8uZmllbGRzKT8ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGdyb3VwW2tleV0gPSBuZXcgVW50eXBlZEZvcm1Db250cm9sKFxuICAgICAgICAgIG51bGwsXG4gICAgICAgICAgdGhpcy5wcm9jZXNzVmFsaWRhdG9ycyhcbiAgICAgICAgICAgIHRoaXMubmVzdGVkT2JqZWN0KGludGVyblBhcmVudHMubGVuZ3RoID8gaW50ZXJuUGFyZW50cy5qb2luKCcuJykgKyAnLicgKyBrZXkgOiBrZXksIHRoaXMuY29uZmlnKSxcbiAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW50ZXJuUGFyZW50cy5wdXNoKGtleSk7XG4gICAgICAgIGdyb3VwW2tleV0gPSB0aGlzLmNyZWF0ZUZvcm0oZmllbGRzW2tleV0uZmllbGRzIGFzIElHcmFwaFFMVHlwZUNvbGxlY3Rpb24sIGludGVyblBhcmVudHMpO1xuICAgICAgICBpbnRlcm5QYXJlbnRzID0gW107XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubG9nZ2luZykge1xuICAgICAgY29uc29sZS5sb2coJ01vZGVsRm9ybUNvbXBvbmVudDo6Y3JlYXRlRm9ybS0+Z3JvdXAnLCBncm91cCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBVbnR5cGVkRm9ybUdyb3VwKGdyb3VwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9jZXNzIGZvcm0gdmFsaWRhdG9ycyBmb3IgY29udHJvbFxuICAgKi9cbiAgcHJvY2Vzc1ZhbGlkYXRvcnMoY29uZmlnOiBhbnksIHZhbHVlOiBJR3JhcGhRTFR5cGVDb2xsZWN0aW9uIHwgR3JhcGhRTFR5cGUpIHtcbiAgICBjb25zdCB2YWxpZGF0b3JzID0gW107XG5cbiAgICBpZiAoY29uZmlnKSB7XG4gICAgICBpZiAoY29uZmlnPy5yZXF1aXJlZCAhPT0gdW5kZWZpbmVkID8gY29uZmlnPy5yZXF1aXJlZCA6IHZhbHVlLmlzUmVxdWlyZWQpIHtcbiAgICAgICAgdmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMucmVxdWlyZWQpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnPy50eXBlID09PSAnRW1haWwnKSB7XG4gICAgICAgIHZhbGlkYXRvcnMucHVzaChmdWxsRW1haWwoKSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWc/LnR5cGUgPT09ICdQYXNzd29yZCcpIHtcbiAgICAgICAgdmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMubWluTGVuZ3RoKDYpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBjb25maWc/Lm1pbiA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgdmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMubWluKGNvbmZpZy5taW4pKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBjb25maWc/Lm1heCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgdmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMubWF4KGNvbmZpZy5tYXgpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY29uZmlnPy52YWxpZGF0b3JzKSkge1xuICAgICAgICB2YWxpZGF0b3JzLnB1c2goLi4uY29uZmlnPy52YWxpZGF0b3JzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsaWRhdG9ycztcbiAgfVxuXG4gIC8qKlxuICAgKiBJdCBjYWxscyB0aGUgZ3JhcGhRTFNlcnZpY2UgdG8gZGVsZXRlIHRoZSBvYmplY3Qgd2l0aCB0aGUgaWQgb2YgdGhlIG9iamVjdCB0aGF0IGlzIGN1cnJlbnRseSBiZWluZyBlZGl0ZWRcbiAgICovXG4gIGRlbGV0ZU9iamVjdCgpIHtcbiAgICB0aGlzLmNtc1NlcnZpY2UuZGVsZXRlT2JqZWN0KHRoaXMuaWQsIHRoaXMubW9kZWxOYW1lKS50aGVuKCgpID0+IHtcbiAgICAgIHRoaXMudG9hc3RTZXJ2aWNlLnNob3coe1xuICAgICAgICBpZDogdGhpcy5tb2RlbE5hbWUgKyAnLXN1Y2Nlc3MnLFxuICAgICAgICB0eXBlOiBUb2FzdFR5cGUuU1VDQ0VTUyxcbiAgICAgICAgdGl0bGU6ICdFcmZvbGdyZWljaCcsXG4gICAgICAgIGRlc2NyaXB0aW9uOiB0aGlzLmxhYmVsICsgJyB3dXJkZSBlcmZvbGdyZWljaCBnZWzDtnNjaHQuJyxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5maW5pc2hlZC5lbWl0KG51bGwpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEl0IHNlbmRzIGEgR3JhcGhRTCBtdXRhdGlvbiB0byB0aGUgc2VydmVyIHRvIGR1cGxpY2F0ZSB0aGUgb2JqZWN0XG4gICAqL1xuICBhc3luYyBkdXBsaWNhdGVPYmplY3QoKSB7XG4gICAgdGhpcy5jbXNTZXJ2aWNlLmR1cGxpY2F0ZU9iamVjdCh0aGlzLmlkLCB0aGlzLm1vZGVsTmFtZSkudGhlbihhc3luYyAodmFsdWUpID0+IHtcbiAgICAgIGlmICh2YWx1ZT8uaWQpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycuLi8nXSwgeyByZWxhdGl2ZVRvOiB0aGlzLnJvdXRlIH0pO1xuICAgICAgICB0aGlzLnRvYXN0U2VydmljZS5zaG93KHtcbiAgICAgICAgICBpZDogdGhpcy5tb2RlbE5hbWUgKyAnLXN1Y2Nlc3MnLFxuICAgICAgICAgIHR5cGU6IFRvYXN0VHlwZS5TVUNDRVNTLFxuICAgICAgICAgIHRpdGxlOiAnRXJmb2xncmVpY2gnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiB0aGlzLmxhYmVsICsgJyB3dXJkZSBlcmZvbGdyZWljaCBkdXBsaXppZXJ0LicsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5maW5pc2hlZC5lbWl0KG51bGwpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEl0IHRha2VzIGEgc3RyaW5nLCBjYXBpdGFsaXplcyB0aGUgZmlyc3QgbGV0dGVyLCBhbmQgcmV0dXJucyB0aGUgbW9kaWZpZWQgc3RyaW5nXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBzdHJpbmcgdG8gY2FwaXRhbGl6ZS5cbiAgICogQHJldHVybnMgVGhlIGZpcnN0IGxldHRlciBvZiB0aGUgc3RyaW5nIGlzIGJlaW5nIGNhcGl0YWxpemVkIGFuZCB0aGUgcmVzdCBvZiB0aGUgc3RyaW5nIGlzIGJlaW5nIHJldHVybmVkLlxuICAgKi9cbiAgY2FwaXRhbGl6ZUZpcnN0TGV0dGVyKHZhbHVlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5jbXNTZXJ2aWNlLmNhcGl0YWxpemVGaXJzdExldHRlcih2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogSXQgdGFrZXMgYW4gQWJzdHJhY3RDb250cm9sIGFuZCByZXR1cm5zIGEgRm9ybUNvbnRyb2xcbiAgICpcbiAgICogQHBhcmFtIGNvbnRyb2wgLSBBYnN0cmFjdENvbnRyb2wgfCBudWxsIHwgdW5kZWZpbmVkXG4gICAqIEByZXR1cm5zIEEgRm9ybUNvbnRyb2xcbiAgICovXG4gIHRyYW5zZm9ybVRvQ29udHJvbChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wgfCBudWxsIHwgdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGNvbnRyb2wgYXMgVW50eXBlZEZvcm1Db250cm9sO1xuICB9XG5cbiAgLyoqXG4gICAqIEl0IHRha2VzIHRoZSBrZXkgb2YgdGhlIGZvcm0gY29udHJvbCB0aGF0IGhhcyBjaGFuZ2VkLCBnZXRzIHRoZSB2YWx1ZSBvZiB0aGF0IGZvcm0gY29udHJvbCwgY3JlYXRlcyBhbiBvYmplY3Qgd2l0aCB0aGVcbiAgICoga2V5IGFuZCB2YWx1ZSwgYW5kIHRoZW4gc2VuZHMgdGhhdCBvYmplY3QgdG8gdGhlIEdyYXBoUUwgc2VydmVyIHRvIHVwZGF0ZSB0aGUgZGF0YWJhc2VcbiAgICovXG4gIGltYWdlQ2hhbmdlZChrZXk6IHN0cmluZykge1xuICAgIGNvbnN0IGRhdGEgPSB7fTtcbiAgICBkYXRhW2tleV0gPSB0aGlzLmZvcm0uZ2V0KGtleSkudmFsdWU7XG5cbiAgICBpZiAodGhpcy5sb2dnaW5nKSB7XG4gICAgICBjb25zb2xlLmxvZygnTW9kZWxGb3JtQ29tcG9uZW50OjppbWFnZUNoYW5nZWQtPmJvZHknLCBkYXRhKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdGhpcy5ncmFwaFFMU2VydmljZVxuICAgICAgICAgIC5ncmFwaFFsKCd1cGRhdGUnICsgdGhpcy5jYXBpdGFsaXplRmlyc3RMZXR0ZXIodGhpcy5tb2RlbE5hbWUpLCB7XG4gICAgICAgICAgICBhcmd1bWVudHM6IHsgaWQ6IHRoaXMuaWQsIGlucHV0OiBkYXRhIH0sXG4gICAgICAgICAgICBmaWVsZHM6IFsnaWQnXSxcbiAgICAgICAgICAgIHR5cGU6IEdyYXBoUUxSZXF1ZXN0VHlwZS5NVVRBVElPTixcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgbmV4dDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLmxvZ2dpbmcpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnTW9kZWxGb3JtQ29tcG9uZW50OjppbWFnZUNoYW5nZWQtPnN1Y2Nlc3MnLCB2YWx1ZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmICh0aGlzLmxvZ2dpbmcpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnTW9kZWxGb3JtQ29tcG9uZW50OjppbWFnZUNoYW5nZWQtPmVycm9yJywgZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSXQgdGFrZXMgdGhlIGZvcm0sIHZhbGlkYXRlcyBpdCwgYW5kIHRoZW4gc2VuZHMgaXQgdG8gdGhlIEdyYXBoUUwgc2VydmVyXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBpZCBvZiB0aGUgbmV3bHkgY3JlYXRlZCBvciB1cGRhdGVkIG9iamVjdC5cbiAgICovXG4gIHN1Ym1pdChzZWNyZXQgPSBmYWxzZSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBpZiAoIXNlY3JldCkge1xuICAgICAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5mb3JtLmludmFsaWQgJiYgIXNlY3JldCkge1xuICAgICAgICB0aGlzLmZvcm1zU2VydmljZS52YWxpZGF0ZUFsbEZvcm1GaWVsZHModGhpcy5mb3JtIGFzIGFueSk7XG4gICAgICAgIHRoaXMuZm9ybXNTZXJ2aWNlLnNjcm9sbFRvSW52YWxpZENvbnRyb2wodGhpcy5mb3JtKTtcbiAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIHJlc29sdmUobnVsbCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMub3BlcmF0aW9uID09PSAndXBkYXRlJyAmJiAhdGhpcy5pZCkge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdJRCBpcyBtaXNzaW5nIGZvciB1cGRhdGUhJyk7XG4gICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICByZXNvbHZlKG51bGwpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmxvZ2dpbmcpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ01vZGVsRm9ybUNvbXBvbmVudDo6c3VibWl0LT5mb3JtVmFsdWUnLCB0aGlzLmZvcm0udmFsdWUpO1xuICAgICAgfVxuXG4gICAgICAvLyBQcmVwYXJlIGRhdGEgZm9yIHNlcnZlciByZXF1ZXN0XG4gICAgICBsZXQgZGF0YSA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMuZm9ybS52YWx1ZSk7XG4gICAgICBkYXRhID0gdGhpcy5wcmVwYXJlRGF0YUZvclJlcXVlc3QodGhpcy5jb25maWcsIHRoaXMuZmllbGRzLCBkYXRhKTtcblxuICAgICAgaWYgKHRoaXMubG9nZ2luZykge1xuICAgICAgICBjb25zb2xlLmxvZygnTW9kZWxGb3JtQ29tcG9uZW50OjpzdWJtaXQtPnZhbHVlVG9HcmFwaHFsJywgZGF0YSk7XG4gICAgICAgIGNvbnNvbGUubG9nKCdNb2RlbEZvcm1Db21wb25lbnQ6OnN1Ym1pdC0+ZmlsZUNoYW5nZXMnLCB0aGlzLmZpbGVDaGFuZ2VzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuZmlsZUNoYW5nZXM/Lmxlbmd0aCkge1xuICAgICAgICBmb3IgKGNvbnN0IGZpbGVDaGFuZ2Ugb2YgdGhpcy5maWxlQ2hhbmdlcykge1xuICAgICAgICAgIGNvbnN0IGtleSA9IGZpbGVDaGFuZ2UuZmllbGQ7XG4gICAgICAgICAgY29uc3QgY29uZmlnID0gdGhpcy5uZXN0ZWRPYmplY3Qoa2V5LCB0aGlzLmNvbmZpZyk7XG5cbiAgICAgICAgICBpZiAoZmlsZUNoYW5nZS5maWxlKSB7XG4gICAgICAgICAgICAvLyBVcGxvYWRcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5mb3JtLmdldChrZXkpLnZhbHVlO1xuXG4gICAgICAgICAgICAvLyBDaGVjayBpZiBmaWxlIGlzIGFuIElEIG9yIGEgYmFzZTY0IHN0cmluZ1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgLy8gRGVsZXRlIGlmIElEXG4gICAgICAgICAgICAgIGlmICghdGhpcy5mb3JtLmdldChrZXkpLnZhbHVlPy5zdGFydHNXaXRoKCdkYXRhOicpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGVsZXRlUmVzdWx0ID0gYXdhaXQgdGhpcy5maWxlU2VydmljZS5kZWxldGUoXG4gICAgICAgICAgICAgICAgICB0aGlzLm5lc3RlZE9iamVjdChrZXksIHRoaXMuY29uZmlnKT8udXJsLFxuICAgICAgICAgICAgICAgICAgdGhpcy5uZXN0ZWRPYmplY3Qoa2V5LCB0aGlzLmNvbmZpZyk/LmRlbGV0ZVBhdGggfHwgJy9maWxlcy8nLFxuICAgICAgICAgICAgICAgICAgdGhpcy5uZXN0ZWRPYmplY3Qoa2V5LCB0aGlzLm9iamVjdClcbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgaWYgKGRlbGV0ZVJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgdGhpcy5uZXN0ZWRPYmplY3Qoa2V5LCBkYXRhLCAnJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3QgdXBsb2FkUmVzdWx0ID0gYXdhaXQgdGhpcy5maWxlU2VydmljZS51cGxvYWQoXG4gICAgICAgICAgICAgICAgdGhpcy5uZXN0ZWRPYmplY3Qoa2V5LCB0aGlzLmNvbmZpZyk/LnVybCxcbiAgICAgICAgICAgICAgICB0aGlzLm5lc3RlZE9iamVjdChrZXksIHRoaXMuY29uZmlnKT8udXBsb2FkUGF0aCB8fCAnL2ZpbGVzL3VwbG9hZCcsXG4gICAgICAgICAgICAgICAgZmlsZUNoYW5nZS5maWxlXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgaWYgKHVwbG9hZFJlc3VsdD8uaWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5lc3RlZE9iamVjdChrZXksIGRhdGEsIHVwbG9hZFJlc3VsdC5pZCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY29uZmlnPy5pbWFnZU1vZGUgJiYgY29uZmlnPy5pbWFnZU1vZGUgIT09ICdmaWxlJykge1xuICAgICAgICAgICAgICAvLyBEZWxldGVcbiAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5maWxlU2VydmljZS5kZWxldGUoXG4gICAgICAgICAgICAgICAgY29uZmlnPy51cmwsXG4gICAgICAgICAgICAgICAgdGhpcy5uZXN0ZWRPYmplY3Qoa2V5LCB0aGlzLmNvbmZpZyk/LmRlbGV0ZVBhdGggfHwgJy9maWxlcy8nLFxuICAgICAgICAgICAgICAgIHRoaXMubmVzdGVkT2JqZWN0KGtleSwgdGhpcy5vYmplY3QpXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHRoaXMubmVzdGVkT2JqZWN0KGtleSwgZGF0YSwgJycpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZ3JhcGhRTFNlcnZpY2VcbiAgICAgICAgLmdyYXBoUWwodGhpcy5vcGVyYXRpb24gKyB0aGlzLmNhcGl0YWxpemVGaXJzdExldHRlcih0aGlzLm1vZGVsTmFtZSksIHtcbiAgICAgICAgICBhcmd1bWVudHM6IHRoaXMub3BlcmF0aW9uID09PSAndXBkYXRlJyA/IHsgaWQ6IHRoaXMuaWQsIGlucHV0OiBkYXRhIH0gOiB7IGlucHV0OiBkYXRhIH0sXG4gICAgICAgICAgZmllbGRzOiBbJ2lkJ10sXG4gICAgICAgICAgdHlwZTogR3JhcGhRTFJlcXVlc3RUeXBlLk1VVEFUSU9OLFxuICAgICAgICB9KVxuICAgICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgICBuZXh0OiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIGlmICghc2VjcmV0KSB7XG4gICAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICB0aGlzLmZpbmlzaGVkLmVtaXQobnVsbCk7XG4gICAgICAgICAgICAgIHRoaXMudG9hc3RTZXJ2aWNlLnNob3coe1xuICAgICAgICAgICAgICAgIGlkOiB0aGlzLm1vZGVsTmFtZSArICctc3VjY2VzcycsXG4gICAgICAgICAgICAgICAgdHlwZTogVG9hc3RUeXBlLlNVQ0NFU1MsXG4gICAgICAgICAgICAgICAgdGl0bGU6ICdFcmZvbGdyZWljaCcsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICAgICAgICB0aGlzLmxhYmVsICsgJyB3dXJkZSBlcmZvbGdyZWljaCAnICsgKHRoaXMub3BlcmF0aW9uID09PSAnY3JlYXRlJyA/ICdlcnN0ZWxsdC4nIDogJ2FrdHVhbGlzaWVydC4nKSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJlc29sdmUodmFsdWUpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgICAgIGlmICghc2VjcmV0KSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCBvbiAnICsgdGhpcy5vcGVyYXRpb24sIGVycik7XG4gICAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgIHRoaXMudG9hc3RTZXJ2aWNlLnNob3coe1xuICAgICAgICAgICAgICAgIGlkOiB0aGlzLm1vZGVsTmFtZSArICctc3VjY2VzcycsXG4gICAgICAgICAgICAgICAgdHlwZTogVG9hc3RUeXBlLkVSUk9SLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgJ0JlaW0gJyArXG4gICAgICAgICAgICAgICAgICAodGhpcy5vcGVyYXRpb24gPT09ICdjcmVhdGUnID8gJ2Vyc3RlbGxlbicgOiAnYWt0dWFsaXNpZXJlbicpICtcbiAgICAgICAgICAgICAgICAgICcgdm9uICcgK1xuICAgICAgICAgICAgICAgICAgdGhpcy5sYWJlbCArXG4gICAgICAgICAgICAgICAgICAnIGlzdCBldHdhcyBzY2hpZWZnZWxhdWZlbi4nLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmVqZWN0KCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUHJlcGFyZSBkYXRhIGZvciBzZXJ2ZXJcbiAgICovXG4gIHByZXBhcmVEYXRhRm9yUmVxdWVzdChjb25maWcsIGZpZWxkc0NvbmZpZywgZGF0YSkge1xuICAgIGlmICghZGF0YSkge1xuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoZGF0YSkpIHtcbiAgICAgIGlmICgodGhpcy5maWVsZHNba2V5XT8udHlwZSA9PT0gJ0RhdGVUaW1lJyB8fCB0aGlzLmNvbmZpZ1trZXldPy50eXBlID09PSAnRGF0ZVRpbWUnKSAmJiB2YWx1ZSA9PT0gJycpIHtcbiAgICAgICAgZGF0YVtrZXldID0gbnVsbDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmICgoY29uZmlnW2tleV0/LnJvbGVzID8gIXRoaXMudXNlci5oYXNBbGxSb2xlcyhjb25maWdba2V5XT8ucm9sZXMpIDogZmFsc2UpIHx8IGNvbmZpZ1trZXldPy5leGNsdWRlKSB7XG4gICAgICAgIGRlbGV0ZSBkYXRhW2tleV07XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdGhpcy5maWVsZHNba2V5XT8udHlwZSAhPT0gJ1VwbG9hZCcpIHtcbiAgICAgICAgZGF0YVtrZXldID0gT2JqZWN0LmtleXMoZGF0YVtrZXldKVxuICAgICAgICAgIC5maWx0ZXIoKGspID0+IGRhdGFba2V5XVtrXSAhPSBudWxsKVxuICAgICAgICAgIC5yZWR1Y2UoKGEsIGspID0+ICh7IC4uLmEsIFtrXTogZGF0YVtrZXldW2tdIH0pLCB7fSk7XG5cbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKGRhdGFba2V5XSk/Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIGlmICh0aGlzLmxvZ2dpbmcpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdPYmplY3QgaXMgZW1wdHkgZnJvbSByZXN1bHQnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGF0YVtrZXldID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTZXQgdHlwZSBmb3IgZ3JhcGhxbCBtZXRob2RcbiAgICAgIGlmIChmaWVsZHNDb25maWdba2V5XT8udHlwZSA9PT0gJ0Zsb2F0Jykge1xuICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICBkYXRhW2tleV0gPSBOdW1iZXIodmFsdWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRhdGFba2V5XSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGZpZWxkc0NvbmZpZ1trZXldPy5maWVsZHMgJiYgT2JqZWN0LmtleXMoZmllbGRzQ29uZmlnW2tleV0/LmZpZWxkcykubGVuZ3RoID4gMCkge1xuICAgICAgICBkYXRhW2tleV0gPSB0aGlzLnByZXBhcmVEYXRhRm9yUmVxdWVzdChjb25maWdba2V5XT8uZmllbGRzLCBmaWVsZHNDb25maWdba2V5XT8uZmllbGRzLCBkYXRhW2tleV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXQgZmFiIGJ1dHRvbnMgZm9yIG1vYmlsZSBkZXZpY2VzXG4gICAqL1xuICBpbml0RmFiQWN0aW9ucygpIHtcbiAgICBjb25zdCBzYXZlRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG4gICAgdGhpcy5mYWJCdXR0b25zLnB1c2goeyBpY29uOiAnYmktY2hlY2stbGcnLCBjb2xvcjogJ3ZhcigtLWJzLXN1Y2Nlc3MpJywgZXZlbnQ6IHNhdmVFdmVudCB9KTtcbiAgICBzYXZlRXZlbnQuc3Vic2NyaWJlKCgpID0+IHRoaXMuc3VibWl0KGZhbHNlKSk7XG5cbiAgICBpZiAodGhpcy5kdXBsaWNhdGUgJiYgdGhpcy5vcGVyYXRpb24gPT09ICd1cGRhdGUnKSB7XG4gICAgICBjb25zdCBldmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcbiAgICAgIHRoaXMuZmFiQnV0dG9ucy5wdXNoKHsgaWNvbjogJ2JpLWJhY2snLCBjb2xvcjogJ3ZhcigtLWJzLWluZm8pJywgZXZlbnQgfSk7XG4gICAgICBldmVudC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5kdXBsaWNhdGVPYmplY3QoKSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3BlcmF0aW9uID09PSAndXBkYXRlJyAmJiB0aGlzLmRlbGV0ZSkge1xuICAgICAgY29uc3QgZXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG4gICAgICB0aGlzLmZhYkJ1dHRvbnMucHVzaCh7IGljb246ICdiaS10cmFzaDMnLCBjb2xvcjogJ3ZhcigtLWJzLWRhbmdlciknLCBldmVudCB9KTtcbiAgICAgIGV2ZW50LnN1YnNjcmliZSgoKSA9PiB0aGlzLmRlbGV0ZU9iamVjdCgpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0IGZpbGUgY2hhbmdlcyBmb3IgcHJvY2Vzc1xuICAgKi9cbiAgcHJvY2Vzc0ZpbGVDaGFuZ2VzKGV2ZW50OiB7IGZpZWxkOiBzdHJpbmc7IGZpbGU6IEZpbGUgfCBudWxsOyBiYXNlNjQ6IHN0cmluZyB8IG51bGwgfSkge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5maWxlQ2hhbmdlcz8uZmluZEluZGV4KChlKSA9PiBlLmZpZWxkID09PSBldmVudC5maWVsZCk7XG5cbiAgICBpZiAoaW5kZXggIT09IHVuZGVmaW5lZCAmJiBpbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuZmlsZUNoYW5nZXNbaW5kZXhdID0gZXZlbnQ7XG4gICAgfSBlbHNlIGlmICh0aGlzLmZpbGVDaGFuZ2VzKSB7XG4gICAgICB0aGlzLmZpbGVDaGFuZ2VzLnB1c2goZXZlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZpbGVDaGFuZ2VzID0gW2V2ZW50XTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZvcm1hdERhdGUoZGF0ZSkge1xuICAgIGlmICghZGF0ZSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IG5ld0RhdGUgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICByZXR1cm4gbmV3RGF0ZS50b0lTT1N0cmluZygpLnN1YnN0cmluZygwLCAxNik7XG4gIH1cblxuICBwcml2YXRlIG5lc3RlZE9iamVjdChrZXk6IHN0cmluZywgbmVzdGVkT2JqZWN0OiBhbnksIHZhbHVlPzogYW55KSB7XG4gICAgY29uc3QgcHJvcHMgPSBrZXkuc3BsaXQoJy4nKTtcbiAgICBsZXQgcmVzdWx0OiBhbnkgPSBuZXN0ZWRPYmplY3Q7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodmFsdWUgJiYgaSA9PT0gcHJvcHMubGVuZ3RoIC0gMSkge1xuICAgICAgICByZXN1bHRbcHJvcHNbaV1dID0gdmFsdWU7XG4gICAgICAgIHJldHVybiByZXN1bHRbcHJvcHNbaV1dO1xuICAgICAgfVxuXG4gICAgICByZXN1bHQgPVxuICAgICAgICByZXN1bHRbcHJvcHNbaV1dPy5maWVsZHMgJiYgT2JqZWN0LmtleXMocmVzdWx0W3Byb3BzW2ldXT8uZmllbGRzKT8ubGVuZ3RoID4gMFxuICAgICAgICAgID8gcmVzdWx0W3Byb3BzW2ldXT8uZmllbGRzXG4gICAgICAgICAgOiByZXN1bHRbcHJvcHNbaV1dO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cbiIsIkBpZiAoZm9ybSkge1xuICA8ZGl2IGNsYXNzPVwidy0xMDBcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGZsZXgtcm93IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIG10LTNcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJyZXNwb25zaXZlLWJhY2sgZC1mbGV4IGQtbGctbm9uZVwiPlxuICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWFycm93LWxlZnRcIiByb3V0ZXJMaW5rPVwiLi4vXCI+PC9pPlxuICAgICAgPC9kaXY+XG4gICAgICA8aDIgY2xhc3M9XCJtYi0wXCI+XG4gICAgICAgIHt7IGxhYmVsID8gbGFiZWwgOiBjYXBpdGFsaXplRmlyc3RMZXR0ZXIobW9kZWxOYW1lKSB9fSB7eyBvcGVyYXRpb24gPT09ICd1cGRhdGUnID8gJ2JlYXJiZWl0ZW4nIDogJ2Vyc3RlbGxlbicgfX1cbiAgICAgIDwvaDI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZC1ub25lIGQtbGctZmxleCBmbGV4LXJvdyBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWVuZFwiPlxuICAgICAgICBAaWYgKGlkICYmIGR1cGxpY2F0ZSAmJiAhX2xvYWRpbmcpIHtcbiAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgbWUtMlwiIChjbGljayk9XCJkdXBsaWNhdGVPYmplY3QoKVwiPlxuICAgICAgICAgICAgRHVwbGl6aWVyZW5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgfVxuICAgICAgICBAaWYgKCFfbG9hZGluZykge1xuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCJcbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFmb3JtLnRvdWNoZWQgJiYgIWZvcm0uZGlydHlcIlxuICAgICAgICAgICAgKGNsaWNrKT1cInN1Ym1pdChmYWxzZSlcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAge3sgb3BlcmF0aW9uID09PSAnY3JlYXRlJyA/ICdFcnN0ZWxsZW4nIDogJ1NwZWljaGVybicgfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgfVxuICAgICAgICBAaWYgKF9sb2FkaW5nKSB7XG4gICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIHR5cGU9XCJidXR0b25cIiBkaXNhYmxlZD5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3Bpbm5lci1ib3JkZXIgc3Bpbm5lci1ib3JkZXItc21cIiByb2xlPVwic3RhdHVzXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9zcGFuPlxuICAgICAgICAgICAge3sgb3BlcmF0aW9uID09PSAnY3JlYXRlJyA/ICdFcnN0ZWxsZW4nIDogJ1NwZWljaGVybicgfX0uLi5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGZvcm0gW2Zvcm1Hcm91cF09XCJmb3JtXCI+XG4gICAgICA8YmFzZS1tb2RlbC1mb3JtLXN1YlxuICAgICAgICBbaWRdPVwiaWRcIlxuICAgICAgICBbZmllbGRzXT1cImZpZWxkc1wiXG4gICAgICAgIFtjb25maWddPVwiY29uZmlnXCJcbiAgICAgICAgW2Zvcm1dPVwiZm9ybVwiXG4gICAgICAgIChpbWFnZUNoYW5nZWQpPVwiaW1hZ2VDaGFuZ2VkKCRldmVudClcIlxuICAgICAgICAoZmlsZUNoYW5nZWQpPVwicHJvY2Vzc0ZpbGVDaGFuZ2VzKCRldmVudClcIlxuICAgICAgPjwvYmFzZS1tb2RlbC1mb3JtLXN1Yj5cbiAgICAgIDxkaXYgY2xhc3M9XCJkLW5vbmUgZC1sZy1mbGV4IG10LTRcIiBbbmdDbGFzc109XCJpZCAmJiBkZWxldGUgPyAnanVzdGlmeS1jb250ZW50LWJldHdlZW4nIDogJ2p1c3RpZnktY29udGVudC1lbmQnXCI+XG4gICAgICAgIEBpZiAoaWQgJiYgZGVsZXRlKSB7XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWRhbmdlclwiIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiZGVsZXRlT2JqZWN0KClcIj5Mw7ZzY2hlbjwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgQGlmICghX2xvYWRpbmcpIHtcbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIlxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFmb3JtLnRvdWNoZWQgJiYgIWZvcm0uZGlydHlcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwic3VibWl0KGZhbHNlKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgIHt7IG9wZXJhdGlvbiA9PT0gJ2NyZWF0ZScgPyAnRXJzdGVsbGVuJyA6ICdTcGVpY2hlcm4nIH19XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIH1cbiAgICAgICAgQGlmIChfbG9hZGluZykge1xuICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiB0eXBlPVwiYnV0dG9uXCIgZGlzYWJsZWQ+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNwaW5uZXItYm9yZGVyIHNwaW5uZXItYm9yZGVyLXNtXCIgcm9sZT1cInN0YXR1c1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvc3Bhbj5cbiAgICAgICAgICAgIHt7IG9wZXJhdGlvbiA9PT0gJ2NyZWF0ZScgPyAnRXJzdGVsbGVuJyA6ICdTcGVpY2hlcm4nIH19Li4uXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Zvcm0+XG48L2Rpdj5cbn1cblxuQGlmIChzaG93RmF2QnV0dG9uKSB7XG4gIDxkaXYgY2xhc3M9XCJkLWJsb2NrIGQtbGctbm9uZSByZXNwb25zaXZlLWFjdGlvbi1idXR0b25cIj5cbiAgICA8YmFzZS1mYWItYnV0dG9uIFtidXR0b25zXT1cImZhYkJ1dHRvbnNcIj48L2Jhc2UtZmFiLWJ1dHRvbj5cbiAgPC9kaXY+XG59XG4iXX0=