@lenne.tech/ng-base 15.0.0-beta-2 → 16.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 (241) hide show
  1. package/base-components/base-components.module.d.ts +1 -2
  2. package/base-components/components/checkbox/checkbox.component.d.ts +1 -1
  3. package/base-components/components/delete-account/delete-account.component.d.ts +1 -1
  4. package/base-components/components/fab-button/fab-button.component.d.ts +1 -1
  5. package/base-components/components/input/input.component.d.ts +1 -1
  6. package/base-components/components/loading-bar/loading-bar.component.d.ts +1 -1
  7. package/base-components/components/model-form/model-form-base.component.d.ts +1 -1
  8. package/base-components/components/model-form/model-form.component.d.ts +1 -1
  9. package/base-components/components/model-form-sub/model-form-sub.component.d.ts +1 -1
  10. package/base-components/components/model-table/model-table.component.d.ts +17 -5
  11. package/base-components/components/refence-input/refence-input.component.d.ts +1 -1
  12. package/base-components/components/select/select.component.d.ts +1 -1
  13. package/base-components/components/skeleton-loader/skeleton-loader.component.d.ts +1 -1
  14. package/base-components/components/tags/tags.component.d.ts +1 -1
  15. package/base-components/components/textarea/textarea.component.d.ts +1 -1
  16. package/base-components/components/toast/toast.component.d.ts +1 -1
  17. package/base-components/components/upload-image/upload-image.component.d.ts +1 -1
  18. package/base-components/directives/context-menu.directive.d.ts +1 -1
  19. package/base-components/directives/sort.directive.d.ts +3 -2
  20. package/base-prototype/pages/login/login.component.d.ts +1 -1
  21. package/base-prototype/pages/profile/profile.component.d.ts +1 -1
  22. package/base-prototype/pages/set-password/set-password.component.d.ts +1 -1
  23. package/esm2022/base-cms/base-cms-routing.module.mjs +33 -0
  24. package/esm2022/base-cms/base-cms.module.mjs +61 -0
  25. package/esm2022/base-cms/pages/base-cms/base-cms.component.mjs +233 -0
  26. package/esm2022/base-components/base-components.module.mjs +123 -0
  27. package/esm2022/base-components/components/breadcrumb/breadcrumb.component.mjs +21 -0
  28. package/esm2022/base-components/components/change-password/change-password.component.mjs +96 -0
  29. package/esm2022/base-components/components/checkbox/checkbox.component.mjs +35 -0
  30. package/esm2022/base-components/components/delete-account/delete-account.component.mjs +61 -0
  31. package/esm2022/base-components/components/fab-button/fab-button.component.mjs +21 -0
  32. package/esm2022/base-components/components/input/input.component.mjs +72 -0
  33. package/esm2022/base-components/components/loading-bar/loading-bar.component.mjs +39 -0
  34. package/esm2022/base-components/components/model-form/model-form-base.component.mjs +145 -0
  35. package/esm2022/base-components/components/model-form/model-form.component.mjs +585 -0
  36. package/esm2022/base-components/components/model-form-sub/model-form-sub.component.mjs +111 -0
  37. package/esm2022/base-components/components/model-table/model-table.component.mjs +470 -0
  38. package/esm2022/base-components/components/refence-input/refence-input.component.mjs +273 -0
  39. package/esm2022/base-components/components/select/select.component.mjs +59 -0
  40. package/esm2022/base-components/components/skeleton-loader/skeleton-loader.component.mjs +32 -0
  41. package/esm2022/base-components/components/tags/tags.component.mjs +224 -0
  42. package/esm2022/base-components/components/textarea/textarea.component.mjs +76 -0
  43. package/esm2022/base-components/components/toast/toast.component.mjs +70 -0
  44. package/esm2022/base-components/components/upload-image/upload-image.component.mjs +343 -0
  45. package/esm2022/base-components/directives/back-button.directive.mjs +25 -0
  46. package/esm2022/base-components/directives/context-menu.directive.mjs +112 -0
  47. package/esm2022/base-components/directives/sort.directive.mjs +61 -0
  48. package/esm2022/base-components/directives/stop-propagation.directive.mjs +24 -0
  49. package/esm2022/base-components/pipes/ellipses.pipe.mjs +23 -0
  50. package/esm2022/base-prototype/base-prototype.module.mjs +54 -0
  51. package/esm2022/base-prototype/pages/email-verification/email-verification.component.mjs +62 -0
  52. package/esm2022/base-prototype/pages/forgot-password/forgot-password.component.mjs +75 -0
  53. package/esm2022/base-prototype/pages/login/login.component.mjs +111 -0
  54. package/esm2022/base-prototype/pages/profile/profile.component.mjs +86 -0
  55. package/esm2022/base-prototype/pages/register/register.component.mjs +94 -0
  56. package/esm2022/base-prototype/pages/set-password/set-password.component.mjs +90 -0
  57. package/esm2022/shared/classes/auth.class.mjs +14 -0
  58. package/esm2022/shared/classes/basic-user.class.mjs +49 -0
  59. package/esm2022/shared/classes/graphql-enum.class.mjs +10 -0
  60. package/esm2022/shared/classes/graphql-meta.class.mjs +345 -0
  61. package/esm2022/shared/classes/graphql-type.class.mjs +14 -0
  62. package/esm2022/shared/classes/sort.class.mjs +38 -0
  63. package/esm2022/shared/services/auth.service.mjs +153 -0
  64. package/esm2022/shared/services/breadcrumb.service.mjs +70 -0
  65. package/{esm2020 → esm2022}/shared/services/cms.service.mjs +7 -5
  66. package/esm2022/shared/services/file.service.mjs +87 -0
  67. package/esm2022/shared/services/forms.service.mjs +62 -0
  68. package/esm2022/shared/services/graphql-meta.service.mjs +133 -0
  69. package/esm2022/shared/services/graphql-plus.service.mjs +94 -0
  70. package/esm2022/shared/services/graphql.service.mjs +511 -0
  71. package/esm2022/shared/services/image.service.mjs +103 -0
  72. package/esm2022/shared/services/loader.service.mjs +79 -0
  73. package/esm2022/shared/services/navigation.service.mjs +39 -0
  74. package/esm2022/shared/services/scroll.service.mjs +208 -0
  75. package/esm2022/shared/services/storage.service.mjs +142 -0
  76. package/esm2022/shared/services/toast.service.mjs +40 -0
  77. package/esm2022/shared/services/user.service.mjs +161 -0
  78. package/esm2022/shared/services/ws.service.mjs +18 -0
  79. package/esm2022/src/base.module.mjs +98 -0
  80. package/esm2022/src/directives/lazy-load.directive.mjs +48 -0
  81. package/esm2022/src/directives/match-height.directive.mjs +92 -0
  82. package/esm2022/src/directives/resizable.directive.mjs +92 -0
  83. package/esm2022/src/factories/apollo-options.factory.mjs +108 -0
  84. package/esm2022/src/functions/extract-files.function.mjs +87 -0
  85. package/esm2022/src/guards/auth.guard.mjs +84 -0
  86. package/esm2022/src/guards/can-deactivate.guard.mjs +17 -0
  87. package/esm2022/src/guards/logout.guard.mjs +35 -0
  88. package/esm2022/src/pipes/date-ago.pipe.mjs +64 -0
  89. package/esm2022/src/pipes/safe-html.pipe.mjs +23 -0
  90. package/esm2022/src/services/fullscreen.service.mjs +52 -0
  91. package/esm2022/src/services/seo.service.mjs +100 -0
  92. package/esm2022/src/services/theme.service.mjs +45 -0
  93. package/{fesm2020 → fesm2022}/lenne.tech-ng-base-base-cms.mjs +42 -30
  94. package/{fesm2020 → fesm2022}/lenne.tech-ng-base-base-cms.mjs.map +1 -1
  95. package/{fesm2020 → fesm2022}/lenne.tech-ng-base-base-components.mjs +467 -286
  96. package/fesm2022/lenne.tech-ng-base-base-components.mjs.map +1 -0
  97. package/{fesm2020 → fesm2022}/lenne.tech-ng-base-base-prototype.mjs +127 -87
  98. package/{fesm2015 → fesm2022}/lenne.tech-ng-base-base-prototype.mjs.map +1 -1
  99. package/{fesm2020 → fesm2022}/lenne.tech-ng-base-shared.mjs +165 -113
  100. package/{fesm2020 → fesm2022}/lenne.tech-ng-base-shared.mjs.map +1 -1
  101. package/{fesm2020 → fesm2022}/lenne.tech-ng-base.mjs +113 -90
  102. package/fesm2022/lenne.tech-ng-base.mjs.map +1 -0
  103. package/package.json +27 -42
  104. package/src/directives/lazy-load.directive.d.ts +1 -1
  105. package/src/directives/match-height.directive.d.ts +1 -1
  106. package/src/directives/resizable.directive.d.ts +1 -1
  107. package/src/guards/auth.guard.d.ts +2 -2
  108. package/src/guards/can-deactivate.guard.d.ts +1 -2
  109. package/src/guards/logout.guard.d.ts +2 -2
  110. package/esm2020/base-cms/base-cms-routing.module.mjs +0 -32
  111. package/esm2020/base-cms/base-cms.module.mjs +0 -59
  112. package/esm2020/base-cms/pages/base-cms/base-cms.component.mjs +0 -222
  113. package/esm2020/base-components/base-components.module.mjs +0 -123
  114. package/esm2020/base-components/components/breadcrumb/breadcrumb.component.mjs +0 -18
  115. package/esm2020/base-components/components/change-password/change-password.component.mjs +0 -90
  116. package/esm2020/base-components/components/checkbox/checkbox.component.mjs +0 -31
  117. package/esm2020/base-components/components/delete-account/delete-account.component.mjs +0 -56
  118. package/esm2020/base-components/components/fab-button/fab-button.component.mjs +0 -21
  119. package/esm2020/base-components/components/input/input.component.mjs +0 -67
  120. package/esm2020/base-components/components/loading-bar/loading-bar.component.mjs +0 -35
  121. package/esm2020/base-components/components/model-form/model-form-base.component.mjs +0 -136
  122. package/esm2020/base-components/components/model-form/model-form.component.mjs +0 -564
  123. package/esm2020/base-components/components/model-form-sub/model-form-sub.component.mjs +0 -102
  124. package/esm2020/base-components/components/model-table/model-table.component.mjs +0 -397
  125. package/esm2020/base-components/components/refence-input/refence-input.component.mjs +0 -261
  126. package/esm2020/base-components/components/select/select.component.mjs +0 -54
  127. package/esm2020/base-components/components/skeleton-loader/skeleton-loader.component.mjs +0 -32
  128. package/esm2020/base-components/components/tags/tags.component.mjs +0 -218
  129. package/esm2020/base-components/components/textarea/textarea.component.mjs +0 -72
  130. package/esm2020/base-components/components/toast/toast.component.mjs +0 -68
  131. package/esm2020/base-components/components/upload-image/upload-image.component.mjs +0 -324
  132. package/esm2020/base-components/directives/back-button.directive.mjs +0 -23
  133. package/esm2020/base-components/directives/context-menu.directive.mjs +0 -108
  134. package/esm2020/base-components/directives/sort.directive.mjs +0 -54
  135. package/esm2020/base-components/directives/stop-propagation.directive.mjs +0 -23
  136. package/esm2020/base-components/pipes/ellipses.pipe.mjs +0 -22
  137. package/esm2020/base-prototype/base-prototype.module.mjs +0 -53
  138. package/esm2020/base-prototype/pages/email-verification/email-verification.component.mjs +0 -55
  139. package/esm2020/base-prototype/pages/forgot-password/forgot-password.component.mjs +0 -67
  140. package/esm2020/base-prototype/pages/login/login.component.mjs +0 -102
  141. package/esm2020/base-prototype/pages/profile/profile.component.mjs +0 -81
  142. package/esm2020/base-prototype/pages/register/register.component.mjs +0 -86
  143. package/esm2020/base-prototype/pages/set-password/set-password.component.mjs +0 -82
  144. package/esm2020/shared/classes/auth.class.mjs +0 -17
  145. package/esm2020/shared/classes/basic-user.class.mjs +0 -52
  146. package/esm2020/shared/classes/graphql-enum.class.mjs +0 -9
  147. package/esm2020/shared/classes/graphql-meta.class.mjs +0 -344
  148. package/esm2020/shared/classes/graphql-type.class.mjs +0 -17
  149. package/esm2020/shared/classes/sort.class.mjs +0 -40
  150. package/esm2020/shared/services/auth.service.mjs +0 -148
  151. package/esm2020/shared/services/breadcrumb.service.mjs +0 -68
  152. package/esm2020/shared/services/file.service.mjs +0 -84
  153. package/esm2020/shared/services/forms.service.mjs +0 -59
  154. package/esm2020/shared/services/graphql-meta.service.mjs +0 -123
  155. package/esm2020/shared/services/graphql-plus.service.mjs +0 -89
  156. package/esm2020/shared/services/graphql.service.mjs +0 -507
  157. package/esm2020/shared/services/image.service.mjs +0 -102
  158. package/esm2020/shared/services/loader.service.mjs +0 -79
  159. package/esm2020/shared/services/navigation.service.mjs +0 -36
  160. package/esm2020/shared/services/scroll.service.mjs +0 -179
  161. package/esm2020/shared/services/storage.service.mjs +0 -140
  162. package/esm2020/shared/services/toast.service.mjs +0 -41
  163. package/esm2020/shared/services/user.service.mjs +0 -155
  164. package/esm2020/shared/services/ws.service.mjs +0 -16
  165. package/esm2020/src/base.module.mjs +0 -97
  166. package/esm2020/src/directives/lazy-load.directive.mjs +0 -45
  167. package/esm2020/src/directives/match-height.directive.mjs +0 -84
  168. package/esm2020/src/directives/resizable.directive.mjs +0 -90
  169. package/esm2020/src/factories/apollo-options.factory.mjs +0 -106
  170. package/esm2020/src/functions/extract-files.function.mjs +0 -84
  171. package/esm2020/src/guards/auth.guard.mjs +0 -80
  172. package/esm2020/src/guards/can-deactivate.guard.mjs +0 -16
  173. package/esm2020/src/guards/logout.guard.mjs +0 -32
  174. package/esm2020/src/pipes/date-ago.pipe.mjs +0 -65
  175. package/esm2020/src/pipes/safe-html.pipe.mjs +0 -21
  176. package/esm2020/src/services/fullscreen.service.mjs +0 -51
  177. package/esm2020/src/services/seo.service.mjs +0 -97
  178. package/esm2020/src/services/theme.service.mjs +0 -43
  179. package/fesm2015/lenne.tech-ng-base-base-cms.mjs +0 -322
  180. package/fesm2015/lenne.tech-ng-base-base-cms.mjs.map +0 -1
  181. package/fesm2015/lenne.tech-ng-base-base-components.mjs +0 -2806
  182. package/fesm2015/lenne.tech-ng-base-base-components.mjs.map +0 -1
  183. package/fesm2015/lenne.tech-ng-base-base-prototype.mjs +0 -495
  184. package/fesm2015/lenne.tech-ng-base-shared.mjs +0 -2749
  185. package/fesm2015/lenne.tech-ng-base-shared.mjs.map +0 -1
  186. package/fesm2015/lenne.tech-ng-base.mjs +0 -902
  187. package/fesm2015/lenne.tech-ng-base.mjs.map +0 -1
  188. package/fesm2020/lenne.tech-ng-base-base-components.mjs.map +0 -1
  189. package/fesm2020/lenne.tech-ng-base-base-prototype.mjs.map +0 -1
  190. package/fesm2020/lenne.tech-ng-base.mjs.map +0 -1
  191. /package/{esm2020 → esm2022}/base-cms/interfaces/base-cms-module-config.interface.mjs +0 -0
  192. /package/{esm2020 → esm2022}/base-cms/lenne.tech-ng-base-base-cms.mjs +0 -0
  193. /package/{esm2020 → esm2022}/base-cms/public-api.mjs +0 -0
  194. /package/{esm2020 → esm2022}/base-components/lenne.tech-ng-base-base-components.mjs +0 -0
  195. /package/{esm2020 → esm2022}/base-components/public-api.mjs +0 -0
  196. /package/{esm2020 → esm2022}/base-prototype/lenne.tech-ng-base-base-prototype.mjs +0 -0
  197. /package/{esm2020 → esm2022}/base-prototype/public-api.mjs +0 -0
  198. /package/{esm2020 → esm2022}/lenne.tech-ng-base.mjs +0 -0
  199. /package/{esm2020 → esm2022}/public-api.mjs +0 -0
  200. /package/{esm2020 → esm2022}/shared/classes/helper.class.mjs +0 -0
  201. /package/{esm2020 → esm2022}/shared/classes/standard.class.mjs +0 -0
  202. /package/{esm2020 → esm2022}/shared/decorators/debounce.decorator.mjs +0 -0
  203. /package/{esm2020 → esm2022}/shared/enums/comparison-operator.enum.mjs +0 -0
  204. /package/{esm2020 → esm2022}/shared/enums/graphql-request-type.enum.mjs +0 -0
  205. /package/{esm2020 → esm2022}/shared/enums/logical-operator.enum.mjs +0 -0
  206. /package/{esm2020 → esm2022}/shared/enums/skeleton-type.enum.mjs +0 -0
  207. /package/{esm2020 → esm2022}/shared/enums/sort-order.enum.mjs +0 -0
  208. /package/{esm2020 → esm2022}/shared/enums/toast-type.enum.mjs +0 -0
  209. /package/{esm2020 → esm2022}/shared/functions/ws-client.function.mjs +0 -0
  210. /package/{esm2020 → esm2022}/shared/interfaces/base-module-config.interface.mjs +0 -0
  211. /package/{esm2020 → esm2022}/shared/interfaces/breadcrumb.interface.mjs +0 -0
  212. /package/{esm2020 → esm2022}/shared/interfaces/can-component-deactivate.interface.mjs +0 -0
  213. /package/{esm2020 → esm2022}/shared/interfaces/cms-enum-values.interface.mjs +0 -0
  214. /package/{esm2020 → esm2022}/shared/interfaces/cms-field-config.interface.mjs +0 -0
  215. /package/{esm2020 → esm2022}/shared/interfaces/cms-model-config.interface.mjs +0 -0
  216. /package/{esm2020 → esm2022}/shared/interfaces/cms-table-field.interface.mjs +0 -0
  217. /package/{esm2020 → esm2022}/shared/interfaces/combined-filter-input.interface.mjs +0 -0
  218. /package/{esm2020 → esm2022}/shared/interfaces/compress-options.interface.mjs +0 -0
  219. /package/{esm2020 → esm2022}/shared/interfaces/cropping-options.interface.mjs +0 -0
  220. /package/{esm2020 → esm2022}/shared/interfaces/field-object.interface.mjs +0 -0
  221. /package/{esm2020 → esm2022}/shared/interfaces/field.interface.mjs +0 -0
  222. /package/{esm2020 → esm2022}/shared/interfaces/filter-input.interface.mjs +0 -0
  223. /package/{esm2020 → esm2022}/shared/interfaces/find-args.interface.mjs +0 -0
  224. /package/{esm2020 → esm2022}/shared/interfaces/graphql-crud-type.interface.mjs +0 -0
  225. /package/{esm2020 → esm2022}/shared/interfaces/graphql-fields-object.interface.mjs +0 -0
  226. /package/{esm2020 → esm2022}/shared/interfaces/graphql-options.interface.mjs +0 -0
  227. /package/{esm2020 → esm2022}/shared/interfaces/graphql-plus-options.interfacen.mjs +0 -0
  228. /package/{esm2020 → esm2022}/shared/interfaces/graphql-type-collection.interface.mjs +0 -0
  229. /package/{esm2020 → esm2022}/shared/interfaces/login-config.interface.mjs +0 -0
  230. /package/{esm2020 → esm2022}/shared/interfaces/single-filter-input.interface.mjs +0 -0
  231. /package/{esm2020 → esm2022}/shared/interfaces/sort-input.interface.mjs +0 -0
  232. /package/{esm2020 → esm2022}/shared/interfaces/time-components.interface.mjs +0 -0
  233. /package/{esm2020 → esm2022}/shared/interfaces/toast.interface.mjs +0 -0
  234. /package/{esm2020 → esm2022}/shared/lenne.tech-ng-base-shared.mjs +0 -0
  235. /package/{esm2020 → esm2022}/shared/public-api.mjs +0 -0
  236. /package/{esm2020 → esm2022}/shared/types/graphql-fields.type.mjs +0 -0
  237. /package/{esm2020 → esm2022}/shared/types/storage.type.mjs +0 -0
  238. /package/{esm2020 → esm2022}/shared/validators/email.validator.mjs +0 -0
  239. /package/{esm2020 → esm2022}/shared/validators/match.validator.mjs +0 -0
  240. /package/{esm2020 → esm2022}/shared/validators/secure-password.validator.mjs +0 -0
  241. /package/{esm2020 → esm2022}/src/decorators/auto-unsubscribe.decorator.mjs +0 -0
@@ -1,397 +0,0 @@
1
- import { Component, EventEmitter, Input, Output, ViewChild, ViewContainerRef, } from '@angular/core';
2
- import { GraphQLRequestType, SortOrderEnum, ToastType, } from '@lenne.tech/ng-base/shared';
3
- import * as i0 from "@angular/core";
4
- import * as i1 from "@lenne.tech/ng-base/shared";
5
- import * as i2 from "@angular/common";
6
- import * as i3 from "../../directives/sort.directive";
7
- import * as i4 from "../../directives/context-menu.directive";
8
- import * as i5 from "../model-form/model-form.component";
9
- import * as i6 from "../fab-button/fab-button.component";
10
- import * as i7 from "../../pipes/ellipses.pipe";
11
- export class ModelTableComponent {
12
- constructor(graphQLMetaService, graphQLService, cmsService, toastService, scrollService) {
13
- this.graphQLMetaService = graphQLMetaService;
14
- this.graphQLService = graphQLService;
15
- this.cmsService = cmsService;
16
- this.toastService = toastService;
17
- this.scrollService = scrollService;
18
- this.createMode = false;
19
- this.logging = false;
20
- this.create = true;
21
- this.update = true;
22
- this.delete = true;
23
- this.import = true;
24
- this.export = true;
25
- this.duplicate = true;
26
- this.modelConfig = null;
27
- this.showFavButton = false;
28
- this.idSelected = new EventEmitter();
29
- this.createModeChanged = new EventEmitter();
30
- this.uniqueField = 'id';
31
- this.tableFields = {
32
- id: { label: 'ID' },
33
- name: { label: 'Name' },
34
- title: { label: 'Titel' },
35
- description: { label: 'Beschreibung' },
36
- email: { label: 'E-Mail' },
37
- createdAt: { label: 'Erstellt am', dateFormat: 'dd.MM.YYYY HH:mm' },
38
- updatedAt: { label: 'Bearbeitet am', dateFormat: 'dd.MM.YYYY HH:mm' },
39
- };
40
- this.objects = [];
41
- this.availableFields = [];
42
- this.id = '';
43
- this.queryName = null;
44
- this.possibleFields = {};
45
- this.componentRef = undefined;
46
- this.selectedPageIndex = 0;
47
- this.pages = [];
48
- }
49
- ngAfterViewInit() {
50
- // Needed time out to prevent ExpressionChangedAfterItHasBeenCheckedError
51
- setTimeout(() => {
52
- this.integrateCustomFormComponent();
53
- }, 10);
54
- }
55
- ngOnInit() {
56
- this.graphQLMetaService.getMeta().subscribe((meta) => {
57
- this.meta = meta;
58
- if (this.modelName) {
59
- this.init();
60
- }
61
- if (this.objectId) {
62
- this.id = this.objectId;
63
- // Needed time out for rerender
64
- setTimeout(() => {
65
- this.integrateCustomFormComponent();
66
- }, 10);
67
- }
68
- });
69
- }
70
- ngOnChanges(changes) {
71
- if (changes['modelName'] && this.meta) {
72
- this.init();
73
- }
74
- if (changes['objectId'] && this.meta) {
75
- if (this.id !== this.objectId) {
76
- if (this.logging) {
77
- console.log('ModelTableComponent::ngOnChanges->selectedId', this.id);
78
- }
79
- this.id = this.objectId;
80
- }
81
- }
82
- this.setChangesInComponentRef();
83
- }
84
- /**
85
- * We're using the `meta` service to get the fields that are available for the `find` query for the model we're working
86
- * with. We're then using that information to populate the `availableFields` array
87
- */
88
- async init() {
89
- this.availableFields = [];
90
- this.pages = [];
91
- this.totalCount = null;
92
- this.camelModelName = this.kebabToCamelCase(this.modelName);
93
- // Set query name
94
- if (!this.modelConfig?.queryName) {
95
- this.queryName = 'findAndCount' + this.capitalizeFirstLetter(this.camelModelName) + 's';
96
- }
97
- else {
98
- this.queryName = this.modelConfig?.queryName;
99
- }
100
- if (this.modelConfig?.tableFields) {
101
- this.tableFields = this.modelConfig.tableFields;
102
- }
103
- if (this.logging) {
104
- console.log('ModelTableComponent::init->modelName', this.modelName);
105
- console.log('ModelTableComponent::init->camelModelName', this.camelModelName);
106
- console.log('ModelTableComponent::init->queryName', this.queryName);
107
- console.log('ModelTableComponent::init->tableFields', this.tableFields);
108
- }
109
- this.possibleFields = this.meta.getFields(this.queryName).fields;
110
- let keys;
111
- if (this.possibleFields?.items && Object.keys(this.possibleFields?.items?.fields).length > 0) {
112
- keys = Object.keys(this.possibleFields.items.fields);
113
- }
114
- else {
115
- keys = Object.keys(this.possibleFields);
116
- }
117
- const tableFieldKeys = Object.keys(this.tableFields);
118
- tableFieldKeys?.forEach((field) => {
119
- if (keys.includes(field)) {
120
- this.availableFields.push(field);
121
- }
122
- });
123
- if (this.logging) {
124
- console.log('ModelTableComponent::init->possibleFields', this.possibleFields);
125
- console.log('ModelTableComponent::init->keys', keys);
126
- console.log('ModelTableComponent::init->availableFields', this.availableFields);
127
- }
128
- this.selectedPageIndex = 0;
129
- this.objects = await this.loadObjects(this.availableFields, 0, 25);
130
- }
131
- integrateCustomFormComponent() {
132
- if (!this.customFormTemplate || this.componentRef) {
133
- return;
134
- }
135
- const customComponent = this.modelConfig?.customTemplateComponent;
136
- if (customComponent) {
137
- this.componentRef = this.customFormTemplate?.createComponent(customComponent);
138
- this.setChangesInComponentRef();
139
- this.componentRef.instance.finished.subscribe(() => {
140
- this.selectId('');
141
- });
142
- }
143
- }
144
- setChangesInComponentRef() {
145
- if (this.componentRef) {
146
- const data = {
147
- config: this.config,
148
- delete: this.delete,
149
- duplicate: this.duplicate,
150
- id: this.id,
151
- label: this.modelConfig?.label,
152
- logging: this.logging,
153
- modelName: this.camelModelName,
154
- showFavButton: this.showFavButton,
155
- };
156
- for (const [key, value] of Object.entries(data)) {
157
- this.componentRef.setInput(key, value);
158
- }
159
- }
160
- }
161
- /**
162
- * When the user clicks the "Create New" button, the createModeChanged event is emitted, which is then handled by the
163
- * parent component
164
- */
165
- createNewObject() {
166
- this.createMode = true;
167
- this.createModeChanged.emit(true);
168
- }
169
- /**
170
- * It loads the objects from the database and stores them in the objects variable
171
- *
172
- * @param fields - string[] - The fields you want to load from the database.
173
- * @param skip
174
- * @param limit
175
- */
176
- loadObjects(fields, skip = 0, limit = 25) {
177
- return new Promise((resolve, reject) => {
178
- const requestFields = [...fields];
179
- const idInFields = requestFields.find((e) => e === 'id');
180
- if (!idInFields) {
181
- requestFields.push('id');
182
- }
183
- const isFindAndCount = this.queryName.includes('findAndCount');
184
- this.graphQLService
185
- .graphQl(this.queryName, {
186
- arguments: {
187
- sort: [{ field: 'createdAt', order: SortOrderEnum.ASC }],
188
- limit: isFindAndCount ? limit : null,
189
- skip: isFindAndCount ? skip : null,
190
- },
191
- fields: isFindAndCount ? ['totalCount', { items: requestFields }] : requestFields,
192
- type: GraphQLRequestType.QUERY,
193
- })
194
- .subscribe({
195
- next: (value) => {
196
- let items;
197
- if (this.logging) {
198
- console.log('ModelTableComponent::loadObjects->value', value);
199
- }
200
- if (value?.totalCount >= 0) {
201
- items = value.items;
202
- this.totalCount = value.totalCount;
203
- this.pages = [];
204
- let numbers = 0;
205
- while (numbers < this.totalCount) {
206
- this.pages.push({
207
- skip: numbers,
208
- limit: 25,
209
- });
210
- numbers = numbers + 25;
211
- }
212
- }
213
- else {
214
- items = value;
215
- }
216
- resolve(items);
217
- },
218
- error: (err) => {
219
- console.log('Error on loading objects', err);
220
- reject(err);
221
- },
222
- });
223
- });
224
- }
225
- /**
226
- * If the update property is true, then set the selectedId property to the id of the object passed in, and emit the
227
- * selectedId property
228
- */
229
- selectId(object) {
230
- if (!object) {
231
- this.createMode = false;
232
- this.createModeChanged.emit(false);
233
- }
234
- if (this.update) {
235
- this.id = object['id'];
236
- this.idSelected.emit(this.id);
237
- }
238
- }
239
- /**
240
- * It calls the duplicateObject function in the cmsService, passing in the id of the object to be duplicated and the
241
- * modelName of the object
242
- */
243
- async duplicateObject(id) {
244
- await this.cmsService.duplicateObject(id, this.camelModelName);
245
- this.selectedPageIndex = 0;
246
- this.objects = await this.loadObjects(this.availableFields, this.pages[this.selectedPageIndex].skip, this.pages[this.selectedPageIndex].limit);
247
- }
248
- /**
249
- * It calls the deleteObject function in the cmsService, passing in the id of the object to delete and the name of the
250
- * model
251
- */
252
- async deleteObject(id) {
253
- await this.cmsService.deleteObject(id, this.camelModelName);
254
- this.selectedPageIndex = 0;
255
- this.objects = await this.loadObjects(this.availableFields, this.pages[this.selectedPageIndex].skip, this.pages[this.selectedPageIndex].limit);
256
- }
257
- /**
258
- * It takes a string, capitalizes the first letter, and returns the modified string
259
- */
260
- capitalizeFirstLetter(value) {
261
- return this.cmsService.capitalizeFirstLetter(value);
262
- }
263
- /**
264
- * Kebab to camel case string
265
- */
266
- kebabToCamelCase(str) {
267
- return str.replace(/-./g, (match) => match[1].toUpperCase());
268
- }
269
- /**
270
- * Import objects from json file
271
- */
272
- processImport(event) {
273
- // Create a new FileReader() object
274
- const reader = new FileReader();
275
- // Setup the callback event to run when the file is read
276
- reader.onload = async (readerEvent) => {
277
- let jsonResult = JSON.parse(readerEvent.target.result);
278
- if (!Array.isArray(jsonResult)) {
279
- jsonResult = [jsonResult];
280
- }
281
- for (let i = 0; i < jsonResult.length; i++) {
282
- try {
283
- this.graphQLService
284
- .graphQl('create' + this.capitalizeFirstLetter(this.modelName), {
285
- arguments: { input: jsonResult[i] },
286
- fields: ['id'],
287
- type: GraphQLRequestType.MUTATION,
288
- })
289
- .subscribe({
290
- next: async () => {
291
- this.toastService.show({
292
- id: this.modelName + '-' + i + '-success',
293
- type: ToastType.SUCCESS,
294
- title: 'Erfolgreich',
295
- description: 'Element ' + (i + 1) + ' von ' + jsonResult.length + ' erfolgreich importiert.',
296
- });
297
- if (i === jsonResult.length - 1) {
298
- this.selectedPageIndex = 0;
299
- this.objects = await this.loadObjects(this.availableFields, this.pages[this.selectedPageIndex].skip, this.pages[this.selectedPageIndex].limit);
300
- }
301
- },
302
- error: () => {
303
- this.toastService.show({
304
- id: this.modelName + '-' + i + '-error',
305
- type: ToastType.ERROR,
306
- title: 'Error',
307
- description: 'Element ' + (i + 1) + ' von ' + jsonResult.length + ' konnte nicht importiert werden.',
308
- });
309
- },
310
- });
311
- }
312
- catch (e) {
313
- this.toastService.show({
314
- id: this.modelName + '-' + i + '-error',
315
- type: ToastType.ERROR,
316
- title: 'Error',
317
- description: 'Element ' + (i + 1) + ' von ' + jsonResult.length + ' konnte nicht importiert werden.',
318
- });
319
- }
320
- }
321
- };
322
- // Read the file
323
- reader.readAsText(event.target.files[0]);
324
- }
325
- /**
326
- * Export objects as json
327
- */
328
- async processExport() {
329
- const keys = this.getAllKeys();
330
- const items = await this.loadObjects(keys, this.pages[this.selectedPageIndex].skip, this.pages[this.selectedPageIndex].limit);
331
- const data = JSON.stringify(items);
332
- const blob = new Blob([data], { type: 'text/json;charset=utf-8;' });
333
- const url = URL.createObjectURL(blob);
334
- const link = document.createElement('a');
335
- link.setAttribute('href', url);
336
- link.setAttribute('download', this.modelName + 's.json');
337
- document.body.appendChild(link);
338
- link.click();
339
- }
340
- /**
341
- * Get all keys for request to export objects as json
342
- */
343
- getAllKeys() {
344
- const items = [];
345
- for (const [key, value] of Object.entries(this.possibleFields)) {
346
- if (!this.possibleFields[key].fields || Object.keys(this.possibleFields[key].fields).length === 0) {
347
- items.push(key);
348
- }
349
- }
350
- return items;
351
- }
352
- async selectPage(i) {
353
- this.selectedPageIndex = i;
354
- await this.scrollService.scrollTo('model-table-top');
355
- this.objects = await this.loadObjects(this.availableFields, this.pages[this.selectedPageIndex].skip, this.pages[this.selectedPageIndex].limit);
356
- }
357
- }
358
- ModelTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.5", ngImport: i0, type: ModelTableComponent, deps: [{ token: i1.GraphQLMetaService }, { token: i1.GraphQLService }, { token: i1.CmsService }, { token: i1.ToastService }, { token: i1.ScrollService }], target: i0.ɵɵFactoryTarget.Component });
359
- ModelTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.5", type: ModelTableComponent, selector: "base-model-table", inputs: { modelName: "modelName", objectId: "objectId", createMode: "createMode", logging: "logging", create: "create", update: "update", delete: "delete", import: "import", export: "export", duplicate: "duplicate", modelConfig: "modelConfig", config: "config", showFavButton: "showFavButton" }, outputs: { idSelected: "idSelected", createModeChanged: "createModeChanged" }, viewQueries: [{ propertyName: "customFormTemplate", first: true, predicate: ["customFormTemplate"], descendants: true, read: ViewContainerRef }], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"!id && !createMode\">\n <div class=\"w-100 d-flex flex-row justify-content-between align-items-center mb-2 mb-lg-4\">\n <h2 id=\"model-table-top\" class=\"mb-0\" *ngIf=\"modelName\">\n {{\n modelConfig?.plural\n ? modelConfig?.plural\n : modelConfig?.label\n ? modelConfig?.label\n : capitalizeFirstLetter(camelModelName) + 's'\n }}\n </h2>\n <div class=\"d-flex align-items-center d-none d-lg-block\">\n <input #importFile type=\"file\" accept=\".json\" class=\"d-none\" (change)=\"processImport($event)\" />\n <div class=\"btn-group me-4\" *ngIf=\"import || export\">\n <i\n class=\"bi bi-three-dots-vertical\"\n id=\"settingsDropdown\"\n type=\"button\"\n data-bs-toggle=\"dropdown\"\n data-bs-auto-close=\"true\"\n aria-expanded=\"false\"\n ></i>\n <ul class=\"dropdown-menu dropdown-menu-end\" aria-labelledby=\"settingsDropdown\">\n <li><a class=\"dropdown-item cursor-pointer\" *ngIf=\"export\" (click)=\"processExport()\">Export</a></li>\n <li><a class=\"dropdown-item cursor-pointer\" *ngIf=\"import\" (click)=\"importFile.click()\"> Import </a></li>\n </ul>\n </div>\n <button class=\"btn btn-primary\" (click)=\"createNewObject()\" *ngIf=\"create\">Erstellen</button>\n </div>\n </div>\n\n <div\n class=\"table-responsive\"\n [ltContextMenu]=\"contextMenu\"\n [selectors]=\"'.object-col'\"\n #contextMenuData=\"contextMenuData\"\n >\n <table class=\"table table-hover bg-white d-none d-lg-table\">\n <thead>\n <tr>\n <th\n scope=\"col\"\n *ngFor=\"let field of availableFields\"\n [baseSort]=\"objects\"\n data-order=\"desc\"\n [attr.data-name]=\"field\"\n >\n {{ tableFields[field]?.label ? tableFields[field]?.label : capitalizeFirstLetter(field) }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr class=\"object-col\" *ngFor=\"let object of objects\" [id]=\"object[uniqueField]\">\n <td class=\"cursor-pointer\" *ngFor=\"let field of availableFields\" (click)=\"selectId(object)\">\n <ng-container *ngIf=\"tableFields[field]?.dateFormat\">\n {{ object[field] | date: tableFields[field]?.dateFormat }} Uhr\n </ng-container>\n\n <ng-container *ngIf=\"tableFields[field]?.enumValues\">\n {{ tableFields[field]?.enumValues[object[field]]?.text }}\n </ng-container>\n\n <ng-container *ngIf=\"!tableFields[field]?.dateFormat && !tableFields[field]?.enumValues\">\n {{ object[field] | baseEllipses: 60 }}\n </ng-container>\n </td>\n </tr>\n </tbody>\n </table>\n\n <div class=\"d-flex d-lg-none flex-column flex-grow-1\">\n <div class=\"table-card\" *ngFor=\"let object of objects\" [id]=\"object[uniqueField]\">\n <div class=\"table-card-entry\" *ngFor=\"let field of availableFields; let i = index\" (click)=\"selectId(object)\">\n <b *ngIf=\"i > 0\"\n >{{ tableFields[field]?.label ? tableFields[field]?.label : capitalizeFirstLetter(field) }}:</b\n >\n <p [ngClass]=\"{ 'table-card-entry-first': i === 0 }\">\n <ng-container *ngIf=\"tableFields[field]?.dateFormat\">\n {{ object[field] | date: tableFields[field]?.dateFormat }} Uhr\n </ng-container>\n\n <ng-container *ngIf=\"tableFields[field]?.enumValues\">\n {{ tableFields[field]?.enumValues[object[field]]?.text }}\n </ng-container>\n\n <ng-container *ngIf=\"!tableFields[field]?.dateFormat && !tableFields[field]?.enumValues\">\n {{ object[field] | baseEllipses: 60 }}\n </ng-container>\n </p>\n </div>\n </div>\n </div>\n\n <nav *ngIf=\"totalCount >= 0\">\n <ul class=\"pagination justify-content-center\">\n <li class=\"page-item\">\n <a\n class=\"page-link\"\n (click)=\"selectPage(selectedPageIndex - 1)\"\n aria-label=\"Previous\"\n [ngClass]=\"{ disabled: selectedPageIndex - 1 > 0 }\"\n >\n <span aria-hidden=\"true\">&laquo;</span>\n </a>\n </li>\n <li class=\"page-item\" *ngFor=\"let page of pages; let i = index\">\n <a class=\"page-link\" [ngClass]=\"{ active: selectedPageIndex === i }\" (click)=\"selectPage(i)\">{{ i + 1 }}</a>\n </li>\n <li class=\"page-item\">\n <a\n class=\"page-link\"\n (click)=\"selectPage(selectedPageIndex + 1)\"\n aria-label=\"Next\"\n [ngClass]=\"{ disabled: pages[selectedPageIndex + 1] }\"\n >\n <span aria-hidden=\"true\">&raquo;</span>\n </a>\n </li>\n </ul>\n </nav>\n\n <div class=\"context-menu\" #contextMenu>\n <div class=\"context-menu-item\" (click)=\"selectId({ id: contextMenuData.clickedElement?.id })\">Bearbeiten</div>\n <div class=\"context-menu-item\" *ngIf=\"duplicate\" (click)=\"duplicateObject(contextMenuData.clickedElement?.id)\">\n Duplizieren\n </div>\n <div class=\"context-menu-item\" *ngIf=\"delete\" (click)=\"deleteObject(contextMenuData.clickedElement?.id)\">\n L\u00F6schen\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"w-100\" *ngIf=\"id || createMode\">\n <button class=\"d-none d-lg-block btn btn-outline-primary mb-3\" (click)=\"selectId('')\">Zur\u00FCck</button>\n <base-model-form\n *ngIf=\"!modelConfig?.customTemplateComponent\"\n [modelName]=\"camelModelName\"\n [label]=\"modelConfig?.label\"\n [config]=\"config\"\n [logging]=\"logging\"\n [id]=\"id\"\n (finished)=\"selectId('')\"\n [delete]=\"delete\"\n [duplicate]=\"duplicate\"\n [showFavButton]=\"showFavButton\"\n ></base-model-form>\n <ng-template *ngIf=\"modelConfig?.customTemplateComponent\" #customFormTemplate></ng-template>\n</div>\n\n<div class=\"responsive-action-button d-block d-lg-none\">\n <base-fab-button\n [fabIcon]=\"'bi-plus'\"\n (click)=\"createNewObject()\"\n *ngIf=\"!(id || createMode) && showFavButton\"\n ></base-fab-button>\n</div>\n", styles: [".cursor-pointer{cursor:pointer}.asc:after,.desc:after{border-style:solid;border-width:.2em .2em 0 0;content:\"\";display:inline-block;height:.45em;left:5px;position:relative;transform:rotate(-45deg);vertical-align:middle;width:.45em}.asc:after{transform:rotate(135deg)}td{vertical-align:middle}.bi,th{cursor:pointer;-webkit-user-select:none;user-select:none}.table>:not(:first-child){border-top:0}table{border-radius:.25rem;border-color:#e2e8f0!important}table thead{text-transform:uppercase;font-size:12px}table thead th{padding:12px 24px}table tbody tr td{font-weight:400!important;font-size:16px;padding:16px 24px}.context-menu{opacity:.01%;pointer-events:none;background-color:#fff;border:1px solid #ccc;box-shadow:1px 1px 10px #0000001a;padding:10px 0;position:fixed;top:0;left:0;width:200px}.context-menu-item{cursor:pointer;padding:8px 15px}.context-menu-item:hover{color:var(--bs-primary)}.table-card{background:var(--bs-white);padding:10px;margin-bottom:10px}.table-card-entry{margin-top:4px}.table-card-entry-first{font-size:18px;font-weight:800;color:var(--bs-primary)}.responsive-action-button{position:fixed;bottom:15px;right:15px}.bi-three-dots-vertical{font-size:18px;line-height:18px}.page-item{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.SortDirective, selector: "[baseSort]", inputs: ["baseSort"] }, { kind: "directive", type: i4.ContextMenuDirective, selector: "[ltContextMenu]", inputs: ["contextMenuData", "ltContextMenu", "xGap", "yGap", "overflowSpace", "selectors"], outputs: ["clickedElement"], exportAs: ["contextMenuData"] }, { kind: "component", type: i5.ModelFormComponent, selector: "base-model-form", inputs: ["modelName", "label", "id", "delete", "onlyUpdateMode", "duplicate", "logging", "config", "showFavButton"], outputs: ["finished"] }, { kind: "component", type: i6.FabButtonComponent, selector: "base-fab-button", inputs: ["fabIcon", "buttons"] }, { kind: "pipe", type: i2.DatePipe, name: "date" }, { kind: "pipe", type: i7.EllipsesPipe, name: "baseEllipses" }] });
360
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.5", ngImport: i0, type: ModelTableComponent, decorators: [{
361
- type: Component,
362
- args: [{ selector: 'base-model-table', template: "<div *ngIf=\"!id && !createMode\">\n <div class=\"w-100 d-flex flex-row justify-content-between align-items-center mb-2 mb-lg-4\">\n <h2 id=\"model-table-top\" class=\"mb-0\" *ngIf=\"modelName\">\n {{\n modelConfig?.plural\n ? modelConfig?.plural\n : modelConfig?.label\n ? modelConfig?.label\n : capitalizeFirstLetter(camelModelName) + 's'\n }}\n </h2>\n <div class=\"d-flex align-items-center d-none d-lg-block\">\n <input #importFile type=\"file\" accept=\".json\" class=\"d-none\" (change)=\"processImport($event)\" />\n <div class=\"btn-group me-4\" *ngIf=\"import || export\">\n <i\n class=\"bi bi-three-dots-vertical\"\n id=\"settingsDropdown\"\n type=\"button\"\n data-bs-toggle=\"dropdown\"\n data-bs-auto-close=\"true\"\n aria-expanded=\"false\"\n ></i>\n <ul class=\"dropdown-menu dropdown-menu-end\" aria-labelledby=\"settingsDropdown\">\n <li><a class=\"dropdown-item cursor-pointer\" *ngIf=\"export\" (click)=\"processExport()\">Export</a></li>\n <li><a class=\"dropdown-item cursor-pointer\" *ngIf=\"import\" (click)=\"importFile.click()\"> Import </a></li>\n </ul>\n </div>\n <button class=\"btn btn-primary\" (click)=\"createNewObject()\" *ngIf=\"create\">Erstellen</button>\n </div>\n </div>\n\n <div\n class=\"table-responsive\"\n [ltContextMenu]=\"contextMenu\"\n [selectors]=\"'.object-col'\"\n #contextMenuData=\"contextMenuData\"\n >\n <table class=\"table table-hover bg-white d-none d-lg-table\">\n <thead>\n <tr>\n <th\n scope=\"col\"\n *ngFor=\"let field of availableFields\"\n [baseSort]=\"objects\"\n data-order=\"desc\"\n [attr.data-name]=\"field\"\n >\n {{ tableFields[field]?.label ? tableFields[field]?.label : capitalizeFirstLetter(field) }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr class=\"object-col\" *ngFor=\"let object of objects\" [id]=\"object[uniqueField]\">\n <td class=\"cursor-pointer\" *ngFor=\"let field of availableFields\" (click)=\"selectId(object)\">\n <ng-container *ngIf=\"tableFields[field]?.dateFormat\">\n {{ object[field] | date: tableFields[field]?.dateFormat }} Uhr\n </ng-container>\n\n <ng-container *ngIf=\"tableFields[field]?.enumValues\">\n {{ tableFields[field]?.enumValues[object[field]]?.text }}\n </ng-container>\n\n <ng-container *ngIf=\"!tableFields[field]?.dateFormat && !tableFields[field]?.enumValues\">\n {{ object[field] | baseEllipses: 60 }}\n </ng-container>\n </td>\n </tr>\n </tbody>\n </table>\n\n <div class=\"d-flex d-lg-none flex-column flex-grow-1\">\n <div class=\"table-card\" *ngFor=\"let object of objects\" [id]=\"object[uniqueField]\">\n <div class=\"table-card-entry\" *ngFor=\"let field of availableFields; let i = index\" (click)=\"selectId(object)\">\n <b *ngIf=\"i > 0\"\n >{{ tableFields[field]?.label ? tableFields[field]?.label : capitalizeFirstLetter(field) }}:</b\n >\n <p [ngClass]=\"{ 'table-card-entry-first': i === 0 }\">\n <ng-container *ngIf=\"tableFields[field]?.dateFormat\">\n {{ object[field] | date: tableFields[field]?.dateFormat }} Uhr\n </ng-container>\n\n <ng-container *ngIf=\"tableFields[field]?.enumValues\">\n {{ tableFields[field]?.enumValues[object[field]]?.text }}\n </ng-container>\n\n <ng-container *ngIf=\"!tableFields[field]?.dateFormat && !tableFields[field]?.enumValues\">\n {{ object[field] | baseEllipses: 60 }}\n </ng-container>\n </p>\n </div>\n </div>\n </div>\n\n <nav *ngIf=\"totalCount >= 0\">\n <ul class=\"pagination justify-content-center\">\n <li class=\"page-item\">\n <a\n class=\"page-link\"\n (click)=\"selectPage(selectedPageIndex - 1)\"\n aria-label=\"Previous\"\n [ngClass]=\"{ disabled: selectedPageIndex - 1 > 0 }\"\n >\n <span aria-hidden=\"true\">&laquo;</span>\n </a>\n </li>\n <li class=\"page-item\" *ngFor=\"let page of pages; let i = index\">\n <a class=\"page-link\" [ngClass]=\"{ active: selectedPageIndex === i }\" (click)=\"selectPage(i)\">{{ i + 1 }}</a>\n </li>\n <li class=\"page-item\">\n <a\n class=\"page-link\"\n (click)=\"selectPage(selectedPageIndex + 1)\"\n aria-label=\"Next\"\n [ngClass]=\"{ disabled: pages[selectedPageIndex + 1] }\"\n >\n <span aria-hidden=\"true\">&raquo;</span>\n </a>\n </li>\n </ul>\n </nav>\n\n <div class=\"context-menu\" #contextMenu>\n <div class=\"context-menu-item\" (click)=\"selectId({ id: contextMenuData.clickedElement?.id })\">Bearbeiten</div>\n <div class=\"context-menu-item\" *ngIf=\"duplicate\" (click)=\"duplicateObject(contextMenuData.clickedElement?.id)\">\n Duplizieren\n </div>\n <div class=\"context-menu-item\" *ngIf=\"delete\" (click)=\"deleteObject(contextMenuData.clickedElement?.id)\">\n L\u00F6schen\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"w-100\" *ngIf=\"id || createMode\">\n <button class=\"d-none d-lg-block btn btn-outline-primary mb-3\" (click)=\"selectId('')\">Zur\u00FCck</button>\n <base-model-form\n *ngIf=\"!modelConfig?.customTemplateComponent\"\n [modelName]=\"camelModelName\"\n [label]=\"modelConfig?.label\"\n [config]=\"config\"\n [logging]=\"logging\"\n [id]=\"id\"\n (finished)=\"selectId('')\"\n [delete]=\"delete\"\n [duplicate]=\"duplicate\"\n [showFavButton]=\"showFavButton\"\n ></base-model-form>\n <ng-template *ngIf=\"modelConfig?.customTemplateComponent\" #customFormTemplate></ng-template>\n</div>\n\n<div class=\"responsive-action-button d-block d-lg-none\">\n <base-fab-button\n [fabIcon]=\"'bi-plus'\"\n (click)=\"createNewObject()\"\n *ngIf=\"!(id || createMode) && showFavButton\"\n ></base-fab-button>\n</div>\n", styles: [".cursor-pointer{cursor:pointer}.asc:after,.desc:after{border-style:solid;border-width:.2em .2em 0 0;content:\"\";display:inline-block;height:.45em;left:5px;position:relative;transform:rotate(-45deg);vertical-align:middle;width:.45em}.asc:after{transform:rotate(135deg)}td{vertical-align:middle}.bi,th{cursor:pointer;-webkit-user-select:none;user-select:none}.table>:not(:first-child){border-top:0}table{border-radius:.25rem;border-color:#e2e8f0!important}table thead{text-transform:uppercase;font-size:12px}table thead th{padding:12px 24px}table tbody tr td{font-weight:400!important;font-size:16px;padding:16px 24px}.context-menu{opacity:.01%;pointer-events:none;background-color:#fff;border:1px solid #ccc;box-shadow:1px 1px 10px #0000001a;padding:10px 0;position:fixed;top:0;left:0;width:200px}.context-menu-item{cursor:pointer;padding:8px 15px}.context-menu-item:hover{color:var(--bs-primary)}.table-card{background:var(--bs-white);padding:10px;margin-bottom:10px}.table-card-entry{margin-top:4px}.table-card-entry-first{font-size:18px;font-weight:800;color:var(--bs-primary)}.responsive-action-button{position:fixed;bottom:15px;right:15px}.bi-three-dots-vertical{font-size:18px;line-height:18px}.page-item{cursor:pointer}\n"] }]
363
- }], ctorParameters: function () { return [{ type: i1.GraphQLMetaService }, { type: i1.GraphQLService }, { type: i1.CmsService }, { type: i1.ToastService }, { type: i1.ScrollService }]; }, propDecorators: { modelName: [{
364
- type: Input
365
- }], objectId: [{
366
- type: Input
367
- }], createMode: [{
368
- type: Input
369
- }], logging: [{
370
- type: Input
371
- }], create: [{
372
- type: Input
373
- }], update: [{
374
- type: Input
375
- }], delete: [{
376
- type: Input
377
- }], import: [{
378
- type: Input
379
- }], export: [{
380
- type: Input
381
- }], duplicate: [{
382
- type: Input
383
- }], modelConfig: [{
384
- type: Input
385
- }], config: [{
386
- type: Input
387
- }], showFavButton: [{
388
- type: Input
389
- }], idSelected: [{
390
- type: Output
391
- }], createModeChanged: [{
392
- type: Output
393
- }], customFormTemplate: [{
394
- type: ViewChild,
395
- args: ['customFormTemplate', { read: ViewContainerRef }]
396
- }] } });
397
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwtdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctYmFzZS9iYXNlLWNvbXBvbmVudHMvY29tcG9uZW50cy9tb2RlbC10YWJsZS9tb2RlbC10YWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1iYXNlL2Jhc2UtY29tcG9uZW50cy9jb21wb25lbnRzL21vZGVsLXRhYmxlL21vZGVsLXRhYmxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCxTQUFTLEVBRVQsWUFBWSxFQUNaLEtBQUssRUFHTCxNQUFNLEVBRU4sU0FBUyxFQUNULGdCQUFnQixHQUNqQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBT0wsa0JBQWtCLEVBSWxCLGFBQWEsRUFFYixTQUFTLEdBQ1YsTUFBTSw0QkFBNEIsQ0FBQzs7Ozs7Ozs7O0FBT3BDLE1BQU0sT0FBTyxtQkFBbUI7SUEyQzlCLFlBQ1Usa0JBQXNDLEVBQ3RDLGNBQThCLEVBQzlCLFVBQXNCLEVBQ3RCLFlBQTBCLEVBQzFCLGFBQTRCO1FBSjVCLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDdEMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUE3QzdCLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFDbkIsWUFBTyxHQUFHLEtBQUssQ0FBQztRQUNoQixXQUFNLEdBQUcsSUFBSSxDQUFDO1FBQ2QsV0FBTSxHQUFHLElBQUksQ0FBQztRQUNkLFdBQU0sR0FBRyxJQUFJLENBQUM7UUFDZCxXQUFNLEdBQUcsSUFBSSxDQUFDO1FBQ2QsV0FBTSxHQUFHLElBQUksQ0FBQztRQUNkLGNBQVMsR0FBRyxJQUFJLENB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LEVBQ3ZDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsS0FBSyxDQUN6QyxDQUFDO0lBQ0osQ0FBQzs7Z0hBcGFVLG1CQUFtQjtvR0FBbkIsbUJBQW1CLG9oQkFrQlcsZ0JBQWdCLGtEQ3BEM0Qsc3RNQTZKQTsyRkQzSGEsbUJBQW1CO2tCQUwvQixTQUFTOytCQUNFLGtCQUFrQjtzTkFLbkIsU0FBUztzQkFBakIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUVJLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csaUJBQWlCO3NCQUExQixNQUFNO2dCQUVzRCxrQkFBa0I7c0JBQTlFLFNBQVM7dUJBQUMsb0JBQW9CLEVBQUUsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDb21wb25lbnQsXG4gIENvbXBvbmVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBWaWV3Q29udGFpbmVyUmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIENNU0ZpZWxkQ29uZmlnLFxuICBDTVNNb2RlbENvbmZpZyxcbiAgQ21zU2VydmljZSxcbiAgQ01TVGFibGVGaWVsZCxcbiAgR3JhcGhRTE1ldGEsXG4gIEdyYXBoUUxNZXRhU2VydmljZSxcbiAgR3JhcGhRTFJlcXVlc3RUeXBlLFxuICBHcmFwaFFMU2VydmljZSxcbiAgR3JhcGhRTFR5cGUsXG4gIFNjcm9sbFNlcnZpY2UsXG4gIFNvcnRPcmRlckVudW0sXG4gIFRvYXN0U2VydmljZSxcbiAgVG9hc3RUeXBlLFxufSBmcm9tICdAbGVubmUudGVjaC9uZy1iYXNlL3NoYXJlZCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2Jhc2UtbW9kZWwtdGFibGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vbW9kZWwtdGFibGUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9tb2RlbC10YWJsZS5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBNb2RlbFRhYmxlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIEFmdGVyVmlld0luaXQge1xuICBASW5wdXQoKSBtb2RlbE5hbWU6IHN0cmluZztcbiAgQElucHV0KCkgb2JqZWN0SWQ6IHN0cmluZztcbiAgQElucHV0KCkgY3JlYXRlTW9kZSA9IGZhbHNlO1xuICBASW5wdXQoKSBsb2dnaW5nID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNyZWF0ZSA9IHRydWU7XG4gIEBJbnB1dCgpIHVwZGF0ZSA9IHRydWU7XG4gIEBJbnB1dCgpIGRlbGV0ZSA9IHRydWU7XG4gIEBJbnB1dCgpIGltcG9ydCA9IHRydWU7XG4gIEBJbnB1dCgpIGV4cG9ydCA9IHRydWU7XG4gIEBJbnB1dCgpIGR1cGxpY2F0ZSA9IHRydWU7XG4gIEBJbnB1dCgpIG1vZGVsQ29uZmlnOiBDTVNNb2RlbENvbmZpZyA9IG51bGw7XG4gIEBJbnB1dCgpIGNvbmZpZzogeyBba2V5OiBzdHJpbmddOiBDTVNGaWVsZENvbmZpZyB9O1xuICBASW5wdXQoKSBzaG93RmF2QnV0dG9uID0gZmFsc2U7XG5cbiAgQE91dHB1dCgpIGlkU2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgQE91dHB1dCgpIGNyZWF0ZU1vZGVDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuXG4gIEBWaWV3Q2hpbGQoJ2N1c3RvbUZvcm1UZW1wbGF0ZScsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiB9KSBjdXN0b21Gb3JtVGVtcGxhdGU6IFZpZXdDb250YWluZXJSZWY7XG5cbiAgdW5pcXVlRmllbGQgPSAnaWQnO1xuICB0YWJsZUZpZWxkczogQ01TVGFibGVGaWVsZCA9IHtcbiAgICBpZDogeyBsYWJlbDogJ0lEJyB9LFxuICAgIG5hbWU6IHsgbGFiZWw6ICdOYW1lJyB9LFxuICAgIHRpdGxlOiB7IGxhYmVsOiAnVGl0ZWwnIH0sXG4gICAgZGVzY3JpcHRpb246IHsgbGFiZWw6ICdCZXNjaHJlaWJ1bmcnIH0sXG4gICAgZW1haWw6IHsgbGFiZWw6ICdFLU1haWwnIH0sXG4gICAgY3JlYXRlZEF0OiB7IGxhYmVsOiAnRXJzdGVsbHQgYW0nLCBkYXRlRm9ybWF0OiAnZGQuTU0uWVlZWSBISDptbScgfSxcbiAgICB1cGRhdGVkQXQ6IHsgbGFiZWw6ICdCZWFyYmVpdGV0IGFtJywgZGF0ZUZvcm1hdDogJ2RkLk1NLllZWVkgSEg6bW0nIH0sXG4gIH07XG4gIG1ldGEhOiBHcmFwaFFMTWV0YTtcbiAgb2JqZWN0czogYW55W10gPSBbXTtcbiAgYXZhaWxhYmxlRmllbGRzOiBzdHJpbmdbXSA9IFtdO1xuICBpZCA9ICcnO1xuICBxdWVyeU5hbWU6IHN0cmluZyA9IG51bGw7XG4gIGNhbWVsTW9kZWxOYW1lOiBzdHJpbmc7XG4gIHBvc3NpYmxlRmllbGRzOiBSZWNvcmQ8c3RyaW5nLCBHcmFwaFFMVHlwZT4gPSB7fTtcbiAgY29tcG9uZW50UmVmOiBDb21wb25lbnRSZWY8YW55PiA9IHVuZGVmaW5lZDtcblxuICB0b3RhbENvdW50OiBudW1iZXI7XG4gIHNlbGVjdGVkUGFnZUluZGV4ID0gMDtcbiAgcGFnZXMgPSBbXTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGdyYXBoUUxNZXRhU2VydmljZTogR3JhcGhRTE1ldGFTZXJ2aWNlLFxuICAgIHByaXZhdGUgZ3JhcGhRTFNlcnZpY2U6IEdyYXBoUUxTZXJ2aWNlLFxuICAgIHByaXZhdGUgY21zU2VydmljZTogQ21zU2VydmljZSxcbiAgICBwcml2YXRlIHRvYXN0U2VydmljZTogVG9hc3RTZXJ2aWNlLFxuICAgIHByaXZhdGUgc2Nyb2xsU2VydmljZTogU2Nyb2xsU2VydmljZVxuICApIHt9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIC8vIE5lZWRlZCB0aW1lIG91dCB0byBwcmV2ZW50IEV4cHJlc3Npb25DaGFuZ2VkQWZ0ZXJJdEhhc0JlZW5DaGVja2VkRXJyb3JcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuaW50ZWdyYXRlQ3VzdG9tRm9ybUNvbXBvbmVudCgpO1xuICAgIH0sIDEwKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuZ3JhcGhRTE1ldGFTZXJ2aWNlLmdldE1ldGEoKS5zdWJzY3JpYmUoKG1ldGEpID0+IHtcbiAgICAgIHRoaXMubWV0YSA9IG1ldGE7XG5cbiAgICAgIGlmICh0aGlzLm1vZGVsTmFtZSkge1xuICAgICAgICB0aGlzLmluaXQoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMub2JqZWN0SWQpIHtcbiAgICAgICAgdGhpcy5pZCA9IHRoaXMub2JqZWN0SWQ7XG5cbiAgICAgICAgLy8gTmVlZGVkIHRpbWUgb3V0IGZvciByZXJlbmRlclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0aGlzLmludGVncmF0ZUN1c3RvbUZvcm1Db21wb25lbnQoKTtcbiAgICAgICAgfSwgMTApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGlmIChjaGFuZ2VzWydtb2RlbE5hbWUnXSAmJiB0aGlzLm1ldGEpIHtcbiAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjaGFuZ2VzWydvYmplY3RJZCddICYmIHRoaXMubWV0YSkge1xuICAgICAgaWYgKHRoaXMuaWQgIT09IHRoaXMub2JqZWN0SWQpIHtcbiAgICAgICAgaWYgKHRoaXMubG9nZ2luZykge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdNb2RlbFRhYmxlQ29tcG9uZW50OjpuZ09uQ2hhbmdlcy0+c2VsZWN0ZWRJZCcsIHRoaXMuaWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pZCA9IHRoaXMub2JqZWN0SWQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zZXRDaGFuZ2VzSW5Db21wb25lbnRSZWYoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXZSdyZSB1c2luZyB0aGUgYG1ldGFgIHNlcnZpY2UgdG8gZ2V0IHRoZSBmaWVsZHMgdGhhdCBhcmUgYXZhaWxhYmxlIGZvciB0aGUgYGZpbmRgIHF1ZXJ5IGZvciB0aGUgbW9kZWwgd2UncmUgd29ya2luZ1xuICAgKiB3aXRoLiBXZSdyZSB0aGVuIHVzaW5nIHRoYXQgaW5mb3JtYXRpb24gdG8gcG9wdWxhdGUgdGhlIGBhdmFpbGFibGVGaWVsZHNgIGFycmF5XG4gICAqL1xuICBhc3luYyBpbml0KCkge1xuICAgIHRoaXMuYXZhaWxhYmxlRmllbGRzID0gW107XG4gICAgdGhpcy5wYWdlcyA9IFtdO1xuICAgIHRoaXMudG90YWxDb3VudCA9IG51bGw7XG4gICAgdGhpcy5jYW1lbE1vZGVsTmFtZSA9IHRoaXMua2ViYWJUb0NhbWVsQ2FzZSh0aGlzLm1vZGVsTmFtZSk7XG5cbiAgICAvLyBTZXQgcXVlcnkgbmFtZVxuICAgIGlmICghdGhpcy5tb2RlbENvbmZpZz8ucXVlcnlOYW1lKSB7XG4gICAgICB0aGlzLnF1ZXJ5TmFtZSA9ICdmaW5kQW5kQ291bnQnICsgdGhpcy5jYXBpdGFsaXplRmlyc3RMZXR0ZXIodGhpcy5jYW1lbE1vZGVsTmFtZSkgKyAncyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucXVlcnlOYW1lID0gdGhpcy5tb2RlbENvbmZpZz8ucXVlcnlOYW1lO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm1vZGVsQ29uZmlnPy50YWJsZUZpZWxkcykge1xuICAgICAgdGhpcy50YWJsZUZpZWxkcyA9IHRoaXMubW9kZWxDb25maWcudGFibGVGaWVsZHM7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubG9nZ2luZykge1xuICAgICAgY29uc29sZS5sb2coJ01vZGVsVGFibGVDb21wb25lbnQ6OmluaXQtPm1vZGVsTmFtZScsIHRoaXMubW9kZWxOYW1lKTtcbiAgICAgIGNvbnNvbGUubG9nKCdNb2RlbFRhYmxlQ29tcG9uZW50Ojppbml0LT5jYW1lbE1vZGVsTmFtZScsIHRoaXMuY2FtZWxNb2RlbE5hbWUpO1xuICAgICAgY29uc29sZS5sb2coJ01vZGVsVGFibGVDb21wb25lbnQ6OmluaXQtPnF1ZXJ5TmFtZScsIHRoaXMucXVlcnlOYW1lKTtcbiAgICAgIGNvbnNvbGUubG9nKCdNb2RlbFRhYmxlQ29tcG9uZW50Ojppbml0LT50YWJsZUZpZWxkcycsIHRoaXMudGFibGVGaWVsZHMpO1xuICAgIH1cblxuICAgIHRoaXMucG9zc2libGVGaWVsZHMgPSB0aGlzLm1ldGEuZ2V0RmllbGRzKHRoaXMucXVlcnlOYW1lKS5maWVsZHM7XG4gICAgbGV0IGtleXM7XG4gICAgaWYgKHRoaXMucG9zc2libGVGaWVsZHM/Lml0ZW1zICYmIE9iamVjdC5rZXlzKHRoaXMucG9zc2libGVGaWVsZHM/Lml0ZW1zPy5maWVsZHMpLmxlbmd0aCA+IDApIHtcbiAgICAgIGtleXMgPSBPYmplY3Qua2V5cyh0aGlzLnBvc3NpYmxlRmllbGRzLml0ZW1zLmZpZWxkcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGtleXMgPSBPYmplY3Qua2V5cyh0aGlzLnBvc3NpYmxlRmllbGRzKTtcbiAgICB9XG5cbiAgICBjb25zdCB0YWJsZUZpZWxkS2V5cyA9IE9iamVjdC5rZXlzKHRoaXMudGFibGVGaWVsZHMpO1xuICAgIHRhYmxlRmllbGRLZXlzPy5mb3JFYWNoKChmaWVsZCkgPT4ge1xuICAgICAgaWYgKGtleXMuaW5jbHVkZXMoZmllbGQpKSB7XG4gICAgICAgIHRoaXMuYXZhaWxhYmxlRmllbGRzLnB1c2goZmllbGQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMubG9nZ2luZykge1xuICAgICAgY29uc29sZS5sb2coJ01vZGVsVGFibGVDb21wb25lbnQ6OmluaXQtPnBvc3NpYmxlRmllbGRzJywgdGhpcy5wb3NzaWJsZUZpZWxkcyk7XG4gICAgICBjb25zb2xlLmxvZygnTW9kZWxUYWJsZUNvbXBvbmVudDo6aW5pdC0+a2V5cycsIGtleXMpO1xuICAgICAgY29uc29sZS5sb2coJ01vZGVsVGFibGVDb21wb25lbnQ6OmluaXQtPmF2YWlsYWJsZUZpZWxkcycsIHRoaXMuYXZhaWxhYmxlRmllbGRzKTtcbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdGVkUGFnZUluZGV4ID0gMDtcbiAgICB0aGlzLm9iamVjdHMgPSBhd2FpdCB0aGlzLmxvYWRPYmplY3RzKHRoaXMuYXZhaWxhYmxlRmllbGRzLCAwLCAyNSk7XG4gIH1cblxuICBpbnRlZ3JhdGVDdXN0b21Gb3JtQ29tcG9uZW50KCkge1xuICAgIGlmICghdGhpcy5jdXN0b21Gb3JtVGVtcGxhdGUgfHwgdGhpcy5jb21wb25lbnRSZWYpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjdXN0b21Db21wb25lbnQgPSB0aGlzLm1vZGVsQ29uZmlnPy5jdXN0b21UZW1wbGF0ZUNvbXBvbmVudDtcbiAgICBpZiAoY3VzdG9tQ29tcG9uZW50KSB7XG4gICAgICB0aGlzLmNvbXBvbmVudFJlZiA9IHRoaXMuY3VzdG9tRm9ybVRlbXBsYXRlPy5jcmVhdGVDb21wb25lbnQ8YW55PihjdXN0b21Db21wb25lbnQpO1xuICAgICAgdGhpcy5zZXRDaGFuZ2VzSW5Db21wb25lbnRSZWYoKTtcbiAgICAgIHRoaXMuY29tcG9uZW50UmVmLmluc3RhbmNlLmZpbmlzaGVkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuc2VsZWN0SWQoJycpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgc2V0Q2hhbmdlc0luQ29tcG9uZW50UmVmKCkge1xuICAgIGlmICh0aGlzLmNvbXBvbmVudFJlZikge1xuICAgICAgY29uc3QgZGF0YSA9IHtcbiAgICAgICAgY29uZmlnOiB0aGlzLmNvbmZpZyxcbiAgICAgICAgZGVsZXRlOiB0aGlzLmRlbGV0ZSxcbiAgICAgICAgZHVwbGljYXRlOiB0aGlzLmR1cGxpY2F0ZSxcbiAgICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgICAgIGxhYmVsOiB0aGlzLm1vZGVsQ29uZmlnPy5sYWJlbCxcbiAgICAgICAgbG9nZ2luZzogdGhpcy5sb2dnaW5nLFxuICAgICAgICBtb2RlbE5hbWU6IHRoaXMuY2FtZWxNb2RlbE5hbWUsXG4gICAgICAgIHNob3dGYXZCdXR0b246IHRoaXMuc2hvd0ZhdkJ1dHRvbixcbiAgICAgIH07XG5cbiAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGRhdGEpKSB7XG4gICAgICAgIHRoaXMuY29tcG9uZW50UmVmLnNldElucHV0KGtleSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBXaGVuIHRoZSB1c2VyIGNsaWNrcyB0aGUgXCJDcmVhdGUgTmV3XCIgYnV0dG9uLCB0aGUgY3JlYXRlTW9kZUNoYW5nZWQgZXZlbnQgaXMgZW1pdHRlZCwgd2hpY2ggaXMgdGhlbiBoYW5kbGVkIGJ5IHRoZVxuICAgKiBwYXJlbnQgY29tcG9uZW50XG4gICAqL1xuICBjcmVhdGVOZXdPYmplY3QoKSB7XG4gICAgdGhpcy5jcmVhdGVNb2RlID0gdHJ1ZTtcbiAgICB0aGlzLmNyZWF0ZU1vZGVDaGFuZ2VkLmVtaXQodHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogSXQgbG9hZHMgdGhlIG9iamVjdHMgZnJvbSB0aGUgZGF0YWJhc2UgYW5kIHN0b3JlcyB0aGVtIGluIHRoZSBvYmplY3RzIHZhcmlhYmxlXG4gICAqXG4gICAqIEBwYXJhbSBmaWVsZHMgLSBzdHJpbmdbXSAtIFRoZSBmaWVsZHMgeW91IHdhbnQgdG8gbG9hZCBmcm9tIHRoZSBkYXRhYmFzZS5cbiAgICogQHBhcmFtIHNraXBcbiAgICogQHBhcmFtIGxpbWl0XG4gICAqL1xuICBsb2FkT2JqZWN0cyhmaWVsZHM6IHN0cmluZ1tdLCBza2lwID0gMCwgbGltaXQgPSAyNSk6IFByb21pc2U8YW55W10+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8YW55W10+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHJlcXVlc3RGaWVsZHMgPSBbLi4uZmllbGRzXTtcbiAgICAgIGNvbnN0IGlkSW5GaWVsZHMgPSByZXF1ZXN0RmllbGRzLmZpbmQoKGUpID0+IGUgPT09ICdpZCcpO1xuXG4gICAgICBpZiAoIWlkSW5GaWVsZHMpIHtcbiAgICAgICAgcmVxdWVzdEZpZWxkcy5wdXNoKCdpZCcpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBpc0ZpbmRBbmRDb3VudCA9IHRoaXMucXVlcnlOYW1lLmluY2x1ZGVzKCdmaW5kQW5kQ291bnQnKTtcblxuICAgICAgdGhpcy5ncmFwaFFMU2VydmljZVxuICAgICAgICAuZ3JhcGhRbCh0aGlzLnF1ZXJ5TmFtZSwge1xuICAgICAgICAgIGFyZ3VtZW50czoge1xuICAgICAgICAgICAgc29ydDogW3sgZmllbGQ6ICdjcmVhdGVkQXQnLCBvcmRlcjogU29ydE9yZGVyRW51bS5BU0MgfV0sXG4gICAgICAgICAgICBsaW1pdDogaXNGaW5kQW5kQ291bnQgPyBsaW1pdCA6IG51bGwsXG4gICAgICAgICAgICBza2lwOiBpc0ZpbmRBbmRDb3VudCA/IHNraXAgOiBudWxsLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZmllbGRzOiBpc0ZpbmRBbmRDb3VudCA/IFsndG90YWxDb3VudCcsIHsgaXRlbXM6IHJlcXVlc3RGaWVsZHMgfV0gOiByZXF1ZXN0RmllbGRzLFxuICAgICAgICAgIHR5cGU6IEdyYXBoUUxSZXF1ZXN0VHlwZS5RVUVSWSxcbiAgICAgICAgfSlcbiAgICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgICAgbmV4dDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBsZXQgaXRlbXM7XG4gICAgICAgICAgICBpZiAodGhpcy5sb2dnaW5nKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdNb2RlbFRhYmxlQ29tcG9uZW50Ojpsb2FkT2JqZWN0cy0+dmFsdWUnLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh2YWx1ZT8udG90YWxDb3VudCA+PSAwKSB7XG4gICAgICAgICAgICAgIGl0ZW1zID0gdmFsdWUuaXRlbXM7XG4gICAgICAgICAgICAgIHRoaXMudG90YWxDb3VudCA9IHZhbHVlLnRvdGFsQ291bnQ7XG4gICAgICAgICAgICAgIHRoaXMucGFnZXMgPSBbXTtcbiAgICAgICAgICAgICAgbGV0IG51bWJlcnMgPSAwO1xuXG4gICAgICAgICAgICAgIHdoaWxlIChudW1iZXJzIDwgdGhpcy50b3RhbENvdW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wYWdlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIHNraXA6IG51bWJlcnMsXG4gICAgICAgICAgICAgICAgICBsaW1pdDogMjUsXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBudW1iZXJzID0gbnVtYmVycyArIDI1O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpdGVtcyA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXNvbHZlKGl0ZW1zKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVycm9yOiAoZXJyKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnRXJyb3Igb24gbG9hZGluZyBvYmplY3RzJywgZXJyKTtcbiAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIElmIHRoZSB1cGRhdGUgcHJvcGVydHkgaXMgdHJ1ZSwgdGhlbiBzZXQgdGhlIHNlbGVjdGVkSWQgcHJvcGVydHkgdG8gdGhlIGlkIG9mIHRoZSBvYmplY3QgcGFzc2VkIGluLCBhbmQgZW1pdCB0aGVcbiAgICogc2VsZWN0ZWRJZCBwcm9wZXJ0eVxuICAgKi9cbiAgc2VsZWN0SWQob2JqZWN0OiBhbnkpIHtcbiAgICBpZiAoIW9iamVjdCkge1xuICAgICAgdGhpcy5jcmVhdGVNb2RlID0gZmFsc2U7XG4gICAgICB0aGlzLmNyZWF0ZU1vZGVDaGFuZ2VkLmVtaXQoZmFsc2UpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnVwZGF0ZSkge1xuICAgICAgdGhpcy5pZCA9IG9iamVjdFsnaWQnXTtcbiAgICAgIHRoaXMuaWRTZWxlY3RlZC5lbWl0KHRoaXMuaWQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJdCBjYWxscyB0aGUgZHVwbGljYXRlT2JqZWN0IGZ1bmN0aW9uIGluIHRoZSBjbXNTZXJ2aWNlLCBwYXNzaW5nIGluIHRoZSBpZCBvZiB0aGUgb2JqZWN0IHRvIGJlIGR1cGxpY2F0ZWQgYW5kIHRoZVxuICAgKiBtb2RlbE5hbWUgb2YgdGhlIG9iamVjdFxuICAgKi9cbiAgYXN5bmMgZHVwbGljYXRlT2JqZWN0KGlkOiBzdHJpbmcpIHtcbiAgICBhd2FpdCB0aGlzLmNtc1NlcnZpY2UuZHVwbGljYXRlT2JqZWN0KGlkLCB0aGlzLmNhbWVsTW9kZWxOYW1lKTtcbiAgICB0aGlzLnNlbGVjdGVkUGFnZUluZGV4ID0gMDtcbiAgICB0aGlzLm9iamVjdHMgPSBhd2FpdCB0aGlzLmxvYWRPYmplY3RzKFxuICAgICAgdGhpcy5hdmFpbGFibGVGaWVsZHMsXG4gICAgICB0aGlzLnBhZ2VzW3RoaXMuc2VsZWN0ZWRQYWdlSW5kZXhdLnNraXAsXG4gICAgICB0aGlzLnBhZ2VzW3RoaXMuc2VsZWN0ZWRQYWdlSW5kZXhdLmxpbWl0XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJdCBjYWxscyB0aGUgZGVsZXRlT2JqZWN0IGZ1bmN0aW9uIGluIHRoZSBjbXNTZXJ2aWNlLCBwYXNzaW5nIGluIHRoZSBpZCBvZiB0aGUgb2JqZWN0IHRvIGRlbGV0ZSBhbmQgdGhlIG5hbWUgb2YgdGhlXG4gICAqIG1vZGVsXG4gICAqL1xuICBhc3luYyBkZWxldGVPYmplY3QoaWQ6IHN0cmluZykge1xuICAgIGF3YWl0IHRoaXMuY21zU2VydmljZS5kZWxldGVPYmplY3QoaWQsIHRoaXMuY2FtZWxNb2RlbE5hbWUpO1xuICAgIHRoaXMuc2VsZWN0ZWRQYWdlSW5kZXggPSAwO1xuICAgIHRoaXMub2JqZWN0cyA9IGF3YWl0IHRoaXMubG9hZE9iamVjdHMoXG4gICAgICB0aGlzLmF2YWlsYWJsZUZpZWxkcyxcbiAgICAgIHRoaXMucGFnZXNbdGhpcy5zZWxlY3RlZFBhZ2VJbmRleF0uc2tpcCxcbiAgICAgIHRoaXMucGFnZXNbdGhpcy5zZWxlY3RlZFBhZ2VJbmRleF0ubGltaXRcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEl0IHRha2VzIGEgc3RyaW5nLCBjYXBpdGFsaXplcyB0aGUgZmlyc3QgbGV0dGVyLCBhbmQgcmV0dXJucyB0aGUgbW9kaWZpZWQgc3RyaW5nXG4gICAqL1xuICBjYXBpdGFsaXplRmlyc3RMZXR0ZXIodmFsdWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmNtc1NlcnZpY2UuY2FwaXRhbGl6ZUZpcnN0TGV0dGVyKHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBLZWJhYiB0byBjYW1lbCBjYXNlIHN0cmluZ1xuICAgKi9cbiAga2ViYWJUb0NhbWVsQ2FzZShzdHI6IHN0cmluZykge1xuICAgIHJldHVybiBzdHIucmVwbGFjZSgvLS4vZywgKG1hdGNoKSA9PiBtYXRjaFsxXS50b1VwcGVyQ2FzZSgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnQgb2JqZWN0cyBmcm9tIGpzb24gZmlsZVxuICAgKi9cbiAgcHJvY2Vzc0ltcG9ydChldmVudCkge1xuICAgIC8vIENyZWF0ZSBhIG5ldyBGaWxlUmVhZGVyKCkgb2JqZWN0XG4gICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcblxuICAgIC8vIFNldHVwIHRoZSBjYWxsYmFjayBldmVudCB0byBydW4gd2hlbiB0aGUgZmlsZSBpcyByZWFkXG4gICAgcmVhZGVyLm9ubG9hZCA9IGFzeW5jIChyZWFkZXJFdmVudCkgPT4ge1xuICAgICAgbGV0IGpzb25SZXN1bHQgPSBKU09OLnBhcnNlKHJlYWRlckV2ZW50LnRhcmdldC5yZXN1bHQgYXMgYW55KTtcblxuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGpzb25SZXN1bHQpKSB7XG4gICAgICAgIGpzb25SZXN1bHQgPSBbanNvblJlc3VsdF07XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwganNvblJlc3VsdC5sZW5ndGg7IGkrKykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuZ3JhcGhRTFNlcnZpY2VcbiAgICAgICAgICAgIC5ncmFwaFFsKCdjcmVhdGUnICsgdGhpcy5jYXBpdGFsaXplRmlyc3RMZXR0ZXIodGhpcy5tb2RlbE5hbWUpLCB7XG4gICAgICAgICAgICAgIGFyZ3VtZW50czogeyBpbnB1dDoganNvblJlc3VsdFtpXSB9LFxuICAgICAgICAgICAgICBmaWVsZHM6IFsnaWQnXSxcbiAgICAgICAgICAgICAgdHlwZTogR3JhcGhRTFJlcXVlc3RUeXBlLk1VVEFUSU9OLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgICBuZXh0OiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy50b2FzdFNlcnZpY2Uuc2hvdyh7XG4gICAgICAgICAgICAgICAgICBpZDogdGhpcy5tb2RlbE5hbWUgKyAnLScgKyBpICsgJy1zdWNjZXNzJyxcbiAgICAgICAgICAgICAgICAgIHR5cGU6IFRvYXN0VHlwZS5TVUNDRVNTLFxuICAgICAgICAgICAgICAgICAgdGl0bGU6ICdFcmZvbGdyZWljaCcsXG4gICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ0VsZW1lbnQgJyArIChpICsgMSkgKyAnIHZvbiAnICsganNvblJlc3VsdC5sZW5ndGggKyAnIGVyZm9sZ3JlaWNoIGltcG9ydGllcnQuJyxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGlmIChpID09PSBqc29uUmVzdWx0Lmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRQYWdlSW5kZXggPSAwO1xuICAgICAgICAgICAgICAgICAgdGhpcy5vYmplY3RzID0gYXdhaXQgdGhpcy5sb2FkT2JqZWN0cyhcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hdmFpbGFibGVGaWVsZHMsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGFnZXNbdGhpcy5zZWxlY3RlZFBhZ2VJbmRleF0uc2tpcCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYWdlc1t0aGlzLnNlbGVjdGVkUGFnZUluZGV4XS5saW1pdFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy50b2FzdFNlcnZpY2Uuc2hvdyh7XG4gICAgICAgICAgICAgICAgICBpZDogdGhpcy5tb2RlbE5hbWUgKyAnLScgKyBpICsgJy1lcnJvcicsXG4gICAgICAgICAgICAgICAgICB0eXBlOiBUb2FzdFR5cGUuRVJST1IsXG4gICAgICAgICAgICAgICAgICB0aXRsZTogJ0Vycm9yJyxcbiAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnRWxlbWVudCAnICsgKGkgKyAxKSArICcgdm9uICcgKyBqc29uUmVzdWx0Lmxlbmd0aCArICcga29ubnRlIG5pY2h0IGltcG9ydGllcnQgd2VyZGVuLicsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHRoaXMudG9hc3RTZXJ2aWNlLnNob3coe1xuICAgICAgICAgICAgaWQ6IHRoaXMubW9kZWxOYW1lICsgJy0nICsgaSArICctZXJyb3InLFxuICAgICAgICAgICAgdHlwZTogVG9hc3RUeXBlLkVSUk9SLFxuICAgICAgICAgICAgdGl0bGU6ICdFcnJvcicsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogJ0VsZW1lbnQgJyArIChpICsgMSkgKyAnIHZvbiAnICsganNvblJlc3VsdC5sZW5ndGggKyAnIGtvbm50ZSBuaWNodCBpbXBvcnRpZXJ0IHdlcmRlbi4nLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIFJlYWQgdGhlIGZpbGVcbiAgICByZWFkZXIucmVhZEFzVGV4dChldmVudC50YXJnZXQuZmlsZXNbMF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cG9ydCBvYmplY3RzIGFzIGpzb25cbiAgICovXG4gIGFzeW5jIHByb2Nlc3NFeHBvcnQoKSB7XG4gICAgY29uc3Qga2V5cyA9IHRoaXMuZ2V0QWxsS2V5cygpO1xuICAgIGNvbnN0IGl0ZW1zID0gYXdhaXQgdGhpcy5sb2FkT2JqZWN0cyhcbiAgICAgIGtleXMsXG4gICAgICB0aGlzLnBhZ2VzW3RoaXMuc2VsZWN0ZWRQYWdlSW5kZXhdLnNraXAsXG4gICAgICB0aGlzLnBhZ2VzW3RoaXMuc2VsZWN0ZWRQYWdlSW5kZXhdLmxpbWl0XG4gICAgKTtcbiAgICBjb25zdCBkYXRhID0gSlNPTi5zdHJpbmdpZnkoaXRlbXMpO1xuICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbZGF0YV0sIHsgdHlwZTogJ3RleHQvanNvbjtjaGFyc2V0PXV0Zi04OycgfSk7XG4gICAgY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICBjb25zdCBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuXG4gICAgbGluay5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCB1cmwpO1xuICAgIGxpbmsuc2V0QXR0cmlidXRlKCdkb3dubG9hZCcsIHRoaXMubW9kZWxOYW1lICsgJ3MuanNvbicpO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgbGluay5jbGljaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwga2V5cyBmb3IgcmVxdWVzdCB0byBleHBvcnQgb2JqZWN0cyBhcyBqc29uXG4gICAqL1xuICBnZXRBbGxLZXlzKCkge1xuICAgIGNvbnN0IGl0ZW1zID0gW107XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5wb3NzaWJsZUZpZWxkcykpIHtcbiAgICAgIGlmICghdGhpcy5wb3NzaWJsZUZpZWxkc1trZXldLmZpZWxkcyB8fCBPYmplY3Qua2V5cyh0aGlzLnBvc3NpYmxlRmllbGRzW2tleV0uZmllbGRzKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgaXRlbXMucHVzaChrZXkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBpdGVtcztcbiAgfVxuXG4gIGFzeW5jIHNlbGVjdFBhZ2UoaTogbnVtYmVyKSB7XG4gICAgdGhpcy5zZWxlY3RlZFBhZ2VJbmRleCA9IGk7XG4gICAgYXdhaXQgdGhpcy5zY3JvbGxTZXJ2aWNlLnNjcm9sbFRvKCdtb2RlbC10YWJsZS10b3AnKTtcbiAgICB0aGlzLm9iamVjdHMgPSBhd2FpdCB0aGlzLmxvYWRPYmplY3RzKFxuICAgICAgdGhpcy5hdmFpbGFibGVGaWVsZHMsXG4gICAgICB0aGlzLnBhZ2VzW3RoaXMuc2VsZWN0ZWRQYWdlSW5kZXhdLnNraXAsXG4gICAgICB0aGlzLnBhZ2VzW3RoaXMuc2VsZWN0ZWRQYWdlSW5kZXhdLmxpbWl0XG4gICAgKTtcbiAgfVxufVxuIiwiPGRpdiAqbmdJZj1cIiFpZCAmJiAhY3JlYXRlTW9kZVwiPlxuICA8ZGl2IGNsYXNzPVwidy0xMDAgZC1mbGV4IGZsZXgtcm93IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlciBtYi0yIG1iLWxnLTRcIj5cbiAgICA8aDIgaWQ9XCJtb2RlbC10YWJsZS10b3BcIiBjbGFzcz1cIm1iLTBcIiAqbmdJZj1cIm1vZGVsTmFtZVwiPlxuICAgICAge3tcbiAgICAgICAgbW9kZWxDb25maWc/LnBsdXJhbFxuICAgICAgICAgID8gbW9kZWxDb25maWc/LnBsdXJhbFxuICAgICAgICAgIDogbW9kZWxDb25maWc/LmxhYmVsXG4gICAgICAgICAgPyBtb2RlbENvbmZpZz8ubGFiZWxcbiAgICAgICAgICA6IGNhcGl0YWxpemVGaXJzdExldHRlcihjYW1lbE1vZGVsTmFtZSkgKyAncydcbiAgICAgIH19XG4gICAgPC9oMj5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBkLW5vbmUgZC1sZy1ibG9ja1wiPlxuICAgICAgPGlucHV0ICNpbXBvcnRGaWxlIHR5cGU9XCJmaWxlXCIgYWNjZXB0PVwiLmpzb25cIiBjbGFzcz1cImQtbm9uZVwiIChjaGFuZ2UpPVwicHJvY2Vzc0ltcG9ydCgkZXZlbnQpXCIgLz5cbiAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgbWUtNFwiICpuZ0lmPVwiaW1wb3J0IHx8IGV4cG9ydFwiPlxuICAgICAgICA8aVxuICAgICAgICAgIGNsYXNzPVwiYmkgYmktdGhyZWUtZG90cy12ZXJ0aWNhbFwiXG4gICAgICAgICAgaWQ9XCJzZXR0aW5nc0Ryb3Bkb3duXCJcbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBkYXRhLWJzLXRvZ2dsZT1cImRyb3Bkb3duXCJcbiAgICAgICAgICBkYXRhLWJzLWF1dG8tY2xvc2U9XCJ0cnVlXCJcbiAgICAgICAgICBhcmlhLWV4cGFuZGVkPVwiZmFsc2VcIlxuICAgICAgICA+PC9pPlxuICAgICAgICA8dWwgY2xhc3M9XCJkcm9wZG93bi1tZW51IGRyb3Bkb3duLW1lbnUtZW5kXCIgYXJpYS1sYWJlbGxlZGJ5PVwic2V0dGluZ3NEcm9wZG93blwiPlxuICAgICAgICAgIDxsaT48YSBjbGFzcz1cImRyb3Bkb3duLWl0ZW0gY3Vyc29yLXBvaW50ZXJcIiAqbmdJZj1cImV4cG9ydFwiIChjbGljayk9XCJwcm9jZXNzRXhwb3J0KClcIj5FeHBvcnQ8L2E+PC9saT5cbiAgICAgICAgICA8bGk+PGEgY2xhc3M9XCJkcm9wZG93bi1pdGVtIGN1cnNvci1wb2ludGVyXCIgKm5nSWY9XCJpbXBvcnRcIiAoY2xpY2spPVwiaW1wb3J0RmlsZS5jbGljaygpXCI+IEltcG9ydCA8L2E+PC9saT5cbiAgICAgICAgPC91bD5cbiAgICAgIDwvZGl2PlxuICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIChjbGljayk9XCJjcmVhdGVOZXdPYmplY3QoKVwiICpuZ0lmPVwiY3JlYXRlXCI+RXJzdGVsbGVuPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDxkaXZcbiAgICBjbGFzcz1cInRhYmxlLXJlc3BvbnNpdmVcIlxuICAgIFtsdENvbnRleHRNZW51XT1cImNvbnRleHRNZW51XCJcbiAgICBbc2VsZWN0b3JzXT1cIicub2JqZWN0LWNvbCdcIlxuICAgICNjb250ZXh0TWVudURhdGE9XCJjb250ZXh0TWVudURhdGFcIlxuICA+XG4gICAgPHRhYmxlIGNsYXNzPVwidGFibGUgdGFibGUtaG92ZXIgYmctd2hpdGUgZC1ub25lIGQtbGctdGFibGVcIj5cbiAgICAgIDx0aGVhZD5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0aFxuICAgICAgICAgICAgc2NvcGU9XCJjb2xcIlxuICAgICAgICAgICAgKm5nRm9yPVwibGV0IGZpZWxkIG9mIGF2YWlsYWJsZUZpZWxkc1wiXG4gICAgICAgICAgICBbYmFzZVNvcnRdPVwib2JqZWN0c1wiXG4gICAgICAgICAgICBkYXRhLW9yZGVyPVwiZGVzY1wiXG4gICAgICAgICAgICBbYXR0ci5kYXRhLW5hbWVdPVwiZmllbGRcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIHt7IHRhYmxlRmllbGRzW2ZpZWxkXT8ubGFiZWwgPyB0YWJsZUZpZWxkc1tmaWVsZF0/LmxhYmVsIDogY2FwaXRhbGl6ZUZpcnN0TGV0dGVyKGZpZWxkKSB9fVxuICAgICAgICAgIDwvdGg+XG4gICAgICAgIDwvdHI+XG4gICAgICA8L3RoZWFkPlxuICAgICAgPHRib2R5PlxuICAgICAgICA8dHIgY2xhc3M9XCJvYmplY3QtY29sXCIgKm5nRm9yPVwibGV0IG9iamVjdCBvZiBvYmplY3RzXCIgW2lkXT1cIm9iamVjdFt1bmlxdWVGaWVsZF1cIj5cbiAgICAgICAgICA8dGQgY2xhc3M9XCJjdXJzb3ItcG9pbnRlclwiICpuZ0Zvcj1cImxldCBmaWVsZCBvZiBhdmFpbGFibGVGaWVsZHNcIiAoY2xpY2spPVwic2VsZWN0SWQob2JqZWN0KVwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInRhYmxlRmllbGRzW2ZpZWxkXT8uZGF0ZUZvcm1hdFwiPlxuICAgICAgICAgICAgICB7eyBvYmplY3RbZmllbGRdIHwgZGF0ZTogdGFibGVGaWVsZHNbZmllbGRdPy5kYXRlRm9ybWF0IH19IFVoclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ0YWJsZUZpZWxkc1tmaWVsZF0/LmVudW1WYWx1ZXNcIj5cbiAgICAgICAgICAgICAge3sgdGFibGVGaWVsZHNbZmllbGRdPy5lbnVtVmFsdWVzW29iamVjdFtmaWVsZF1dPy50ZXh0IH19XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiF0YWJsZUZpZWxkc1tmaWVsZF0/LmRhdGVGb3JtYXQgJiYgIXRhYmxlRmllbGRzW2ZpZWxkXT8uZW51bVZhbHVlc1wiPlxuICAgICAgICAgICAgICB7eyBvYmplY3RbZmllbGRdIHwgYmFzZUVsbGlwc2VzOiA2MCB9fVxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgIDwvdGJvZHk+XG4gICAgPC90YWJsZT5cblxuICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZC1sZy1ub25lIGZsZXgtY29sdW1uIGZsZXgtZ3Jvdy0xXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwidGFibGUtY2FyZFwiICpuZ0Zvcj1cImxldCBvYmplY3Qgb2Ygb2JqZWN0c1wiIFtpZF09XCJvYmplY3RbdW5pcXVlRmllbGRdXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1jYXJkLWVudHJ5XCIgKm5nRm9yPVwibGV0IGZpZWxkIG9mIGF2YWlsYWJsZUZpZWxkczsgbGV0IGkgPSBpbmRleFwiIChjbGljayk9XCJzZWxlY3RJZChvYmplY3QpXCI+XG4gICAgICAgICAgPGIgKm5nSWY9XCJpID4gMFwiXG4gICAgICAgICAgICA+e3sgdGFibGVGaWVsZHNbZmllbGRdPy5sYWJlbCA/IHRhYmxlRmllbGRzW2ZpZWxkXT8ubGFiZWwgOiBjYXBpdGFsaXplRmlyc3RMZXR0ZXIoZmllbGQpIH19OjwvYlxuICAgICAgICAgID5cbiAgICAgICAgICA8cCBbbmdDbGFzc109XCJ7ICd0YWJsZS1jYXJkLWVudHJ5LWZpcnN0JzogaSA9PT0gMCB9XCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidGFibGVGaWVsZHNbZmllbGRdPy5kYXRlRm9ybWF0XCI+XG4gICAgICAgICAgICAgIHt7IG9iamVjdFtmaWVsZF0gfCBkYXRlOiB0YWJsZUZpZWxkc1tmaWVsZF0/LmRhdGVGb3JtYXQgfX0gVWhyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInRhYmxlRmllbGRzW2ZpZWxkXT8uZW51bVZhbHVlc1wiPlxuICAgICAgICAgICAgICB7eyB0YWJsZUZpZWxkc1tmaWVsZF0/LmVudW1WYWx1ZXNbb2JqZWN0W2ZpZWxkXV0/LnRleHQgfX1cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXRhYmxlRmllbGRzW2ZpZWxkXT8uZGF0ZUZvcm1hdCAmJiAhdGFibGVGaWVsZHNbZmllbGRdPy5lbnVtVmFsdWVzXCI+XG4gICAgICAgICAgICAgIHt7IG9iamVjdFtmaWVsZF0gfCBiYXNlRWxsaXBzZXM6IDYwIH19XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8bmF2ICpuZ0lmPVwidG90YWxDb3VudCA+PSAwXCI+XG4gICAgICA8dWwgY2xhc3M9XCJwYWdpbmF0aW9uIGp1c3RpZnktY29udGVudC1jZW50ZXJcIj5cbiAgICAgICAgPGxpIGNsYXNzPVwicGFnZS1pdGVtXCI+XG4gICAgICAgICAgPGFcbiAgICAgICAgICAgIGNsYXNzPVwicGFnZS1saW5rXCJcbiAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RQYWdlKHNlbGVjdGVkUGFnZUluZGV4IC0gMSlcIlxuICAgICAgICAgICAgYXJpYS1sYWJlbD1cIlByZXZpb3VzXCJcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgZGlzYWJsZWQ6IHNlbGVjdGVkUGFnZUluZGV4IC0gMSA+IDAgfVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHNwYW4gYXJpYS1oaWRkZW49XCJ0cnVlXCI+JmxhcXVvOzwvc3Bhbj5cbiAgICAgICAgICA8L2E+XG4gICAgICAgIDwvbGk+XG4gICAgICAgIDxsaSBjbGFzcz1cInBhZ2UtaXRlbVwiICpuZ0Zvcj1cImxldCBwYWdlIG9mIHBhZ2VzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgPGEgY2xhc3M9XCJwYWdlLWxpbmtcIiBbbmdDbGFzc109XCJ7IGFjdGl2ZTogc2VsZWN0ZWRQYWdlSW5kZXggPT09IGkgfVwiIChjbGljayk9XCJzZWxlY3RQYWdlKGkpXCI+e3sgaSArIDEgfX08L2E+XG4gICAgICAgIDwvbGk+XG4gICAgICAgIDxsaSBjbGFzcz1cInBhZ2UtaXRlbVwiPlxuICAgICAgICAgIDxhXG4gICAgICAgICAgICBjbGFzcz1cInBhZ2UtbGlua1wiXG4gICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0UGFnZShzZWxlY3RlZFBhZ2VJbmRleCArIDEpXCJcbiAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJOZXh0XCJcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgZGlzYWJsZWQ6IHBhZ2VzW3NlbGVjdGVkUGFnZUluZGV4ICsgMV0gfVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHNwYW4gYXJpYS1oaWRkZW49XCJ0cnVlXCI+JnJhcXVvOzwvc3Bhbj5cbiAgICAgICAgICA8L2E+XG4gICAgICAgIDwvbGk+XG4gICAgICA8L3VsPlxuICAgIDwvbmF2PlxuXG4gICAgPGRpdiBjbGFzcz1cImNvbnRleHQtbWVudVwiICNjb250ZXh0TWVudT5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb250ZXh0LW1lbnUtaXRlbVwiIChjbGljayk9XCJzZWxlY3RJZCh7IGlkOiBjb250ZXh0TWVudURhdGEuY2xpY2tlZEVsZW1lbnQ/LmlkIH0pXCI+QmVhcmJlaXRlbjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImNvbnRleHQtbWVudS1pdGVtXCIgKm5nSWY9XCJkdXBsaWNhdGVcIiAoY2xpY2spPVwiZHVwbGljYXRlT2JqZWN0KGNvbnRleHRNZW51RGF0YS5jbGlja2VkRWxlbWVudD8uaWQpXCI+XG4gICAgICAgIER1cGxpemllcmVuXG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb250ZXh0LW1lbnUtaXRlbVwiICpuZ0lmPVwiZGVsZXRlXCIgKGNsaWNrKT1cImRlbGV0ZU9iamVjdChjb250ZXh0TWVudURhdGEuY2xpY2tlZEVsZW1lbnQ/LmlkKVwiPlxuICAgICAgICBMw7ZzY2hlblxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG5cbjxkaXYgY2xhc3M9XCJ3LTEwMFwiICpuZ0lmPVwiaWQgfHwgY3JlYXRlTW9kZVwiPlxuICA8YnV0dG9uIGNsYXNzPVwiZC1ub25lIGQtbGctYmxvY2sgYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgbWItM1wiIChjbGljayk9XCJzZWxlY3RJZCgnJylcIj5adXLDvGNrPC9idXR0b24+XG4gIDxiYXNlLW1vZGVsLWZvcm1cbiAgICAqbmdJZj1cIiFtb2RlbENvbmZpZz8uY3VzdG9tVGVtcGxhdGVDb21wb25lbnRcIlxuICAgIFttb2RlbE5hbWVdPVwiY2FtZWxNb2RlbE5hbWVcIlxuICAgIFtsYWJlbF09XCJtb2RlbENvbmZpZz8ubGFiZWxcIlxuICAgIFtjb25maWddPVwiY29uZmlnXCJcbiAgICBbbG9nZ2luZ109XCJsb2dnaW5nXCJcbiAgICBbaWRdPVwiaWRcIlxuICAgIChmaW5pc2hlZCk9XCJzZWxlY3RJZCgnJylcIlxuICAgIFtkZWxldGVdPVwiZGVsZXRlXCJcbiAgICBbZHVwbGljYXRlXT1cImR1cGxpY2F0ZVwiXG4gICAgW3Nob3dGYXZCdXR0b25dPVwic2hvd0ZhdkJ1dHRvblwiXG4gID48L2Jhc2UtbW9kZWwtZm9ybT5cbiAgPG5nLXRlbXBsYXRlICpuZ0lmPVwibW9kZWxDb25maWc/LmN1c3RvbVRlbXBsYXRlQ29tcG9uZW50XCIgI2N1c3RvbUZvcm1UZW1wbGF0ZT48L25nLXRlbXBsYXRlPlxuPC9kaXY+XG5cbjxkaXYgY2xhc3M9XCJyZXNwb25zaXZlLWFjdGlvbi1idXR0b24gZC1ibG9jayBkLWxnLW5vbmVcIj5cbiAgPGJhc2UtZmFiLWJ1dHRvblxuICAgIFtmYWJJY29uXT1cIidiaS1wbHVzJ1wiXG4gICAgKGNsaWNrKT1cImNyZWF0ZU5ld09iamVjdCgpXCJcbiAgICAqbmdJZj1cIiEoaWQgfHwgY3JlYXRlTW9kZSkgJiYgc2hvd0ZhdkJ1dHRvblwiXG4gID48L2Jhc2UtZmFiLWJ1dHRvbj5cbjwvZGl2PlxuIl19