@unifylib/ui-lib 1.0.3 → 1.0.65

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 (265) hide show
  1. package/esm2022/iq-ui-lib.mjs +5 -0
  2. package/esm2022/lib/base-model/SearchStrConfig.mjs +11 -0
  3. package/esm2022/lib/base-model/api-response.mjs +2 -0
  4. package/esm2022/lib/base-model/audit-log-entry.mjs +3 -0
  5. package/esm2022/lib/base-model/button-action-settings.mjs +17 -0
  6. package/esm2022/lib/base-model/column-def.model.mjs +28 -0
  7. package/esm2022/lib/base-model/do-action-request.mjs +8 -0
  8. package/esm2022/lib/base-model/field-action.mjs +6 -0
  9. package/esm2022/lib/base-model/field-filter.model.mjs +3 -0
  10. package/esm2022/lib/base-model/field-info.mjs +64 -0
  11. package/esm2022/lib/base-model/field-predicate.model.mjs +10 -0
  12. package/esm2022/lib/base-model/filter-request.mjs +13 -0
  13. package/esm2022/lib/base-model/filter.model.mjs +25 -0
  14. package/esm2022/lib/base-model/get-items-list.mjs +10 -0
  15. package/esm2022/lib/base-model/index.mjs +13 -0
  16. package/esm2022/lib/base-model/items-total.model.mjs +8 -0
  17. package/esm2022/lib/base-model/line-item.model.mjs +12 -0
  18. package/esm2022/lib/base-model/lookupItem.mjs +16 -0
  19. package/esm2022/lib/base-model/page-info.mjs +17 -0
  20. package/esm2022/lib/base-model/permission-matrix.model.mjs +2 -0
  21. package/esm2022/lib/base-model/report-request.model.mjs +17 -0
  22. package/esm2022/lib/base-model/response-envelop.model.mjs +10 -0
  23. package/esm2022/lib/base-model/snack-message.model.mjs +11 -0
  24. package/esm2022/lib/base-model/table-column.interface.mjs +2 -0
  25. package/esm2022/lib/base-model/table-page-user-action.interface.mjs +21 -0
  26. package/esm2022/lib/base-model/workflow/workflow-steps.model.mjs +9 -0
  27. package/esm2022/lib/base-model/workflow/workflow.model.mjs +42 -0
  28. package/esm2022/lib/components/action-comment/action-comment.component.mjs +111 -0
  29. package/esm2022/lib/components/action-confirmation/action-confirmation.component.mjs +68 -0
  30. package/esm2022/lib/components/activity-report-form/activity-report-form.component.mjs +486 -0
  31. package/esm2022/lib/components/advanced-filter/field-filter/field-filter.component.mjs +44 -0
  32. package/esm2022/lib/components/advanced-filter/filter-builder/filter-builder.component.mjs +323 -0
  33. package/esm2022/lib/components/audit-log-details-dialog/audit-log-details-dialog.component.mjs +70 -0
  34. package/esm2022/lib/components/audit-log-list/audit-log.component.mjs +97 -0
  35. package/esm2022/lib/components/auto-complete/auto-complete.component.mjs +300 -0
  36. package/esm2022/lib/components/base-form/base-form.component.mjs +284 -0
  37. package/esm2022/lib/components/base-form-canvas/MaxDigitsDirective.mjs +29 -0
  38. package/esm2022/lib/components/base-form-canvas/NumbersOnlyDirective.mjs +132 -0
  39. package/esm2022/lib/components/base-form-canvas/base-form-canvas.component.mjs +789 -0
  40. package/esm2022/lib/components/base-input-dialog/base-input-dialog.component.mjs +72 -0
  41. package/esm2022/lib/components/base-table/base-table.component.mjs +708 -0
  42. package/esm2022/lib/components/button-actions/button-actions.component.mjs +101 -0
  43. package/esm2022/lib/components/editable-base-table/editable-base-table.component.mjs +507 -0
  44. package/esm2022/lib/components/equation-builder/equation-builder.component.mjs +117 -0
  45. package/esm2022/lib/components/item-line-editor/item-line-editor.component.mjs +322 -0
  46. package/esm2022/lib/components/multi-auto-complete/multi-auto-complete.component.mjs +294 -0
  47. package/esm2022/lib/components/paginator/paginator.component.mjs +181 -0
  48. package/esm2022/lib/components/permission-matrix/permission-matrix.component.mjs +129 -0
  49. package/esm2022/lib/components/report-details-dialog/report-details-dialog.component.mjs +102 -0
  50. package/esm2022/lib/components/report-form/report-form.component.mjs +485 -0
  51. package/esm2022/lib/components/search-bar/search-bar.component.mjs +63 -0
  52. package/esm2022/lib/components/section-form-canvas/section-form-canvas.component.mjs +99 -0
  53. package/esm2022/lib/components/shared/action-button/action-button.component.mjs +59 -0
  54. package/esm2022/lib/components/shared/action-card/action-card.component.mjs +93 -0
  55. package/esm2022/lib/components/shared/attachment-uploader/attachment-uploader.component.mjs +74 -0
  56. package/esm2022/lib/components/shared-list/shared-list.component.mjs +47 -0
  57. package/esm2022/lib/components/snackbar-static/snackbar-static.component.mjs +43 -0
  58. package/esm2022/lib/components/title-bar/title-bar.component.mjs +185 -0
  59. package/esm2022/lib/services/backend-service.mjs +241 -0
  60. package/esm2022/lib/services/index.mjs +4 -0
  61. package/esm2022/lib/services/top-panel.mjs +22 -0
  62. package/esm2022/lib/services/trigger-form.service.mjs +17 -0
  63. package/esm2022/lib/utils/base-utils.mjs +101 -0
  64. package/esm2022/lib/validators/date-range-validator.mjs +27 -0
  65. package/esm2022/lib/validators/index.mjs +4 -0
  66. package/esm2022/lib/validators/match-list.validator.mjs +9 -0
  67. package/esm2022/lib/validators/multi-email-validator.mjs +13 -0
  68. package/esm2022/public-api.mjs +30 -0
  69. package/esm2022/unifylib-ui-lib.mjs +5 -0
  70. package/fesm2022/iq-ui-lib.mjs +6713 -0
  71. package/fesm2022/iq-ui-lib.mjs.map +1 -0
  72. package/fesm2022/unifylib-ui-lib.mjs +6713 -0
  73. package/fesm2022/unifylib-ui-lib.mjs.map +1 -0
  74. package/index.d.ts +5 -0
  75. package/lib/base-model/SearchStrConfig.d.ts +8 -0
  76. package/{src/lib/base-model/api-response.ts → lib/base-model/api-response.d.ts} +5 -7
  77. package/lib/base-model/audit-log-entry.d.ts +7 -0
  78. package/lib/base-model/button-action-settings.d.ts +16 -0
  79. package/lib/base-model/column-def.model.d.ts +11 -0
  80. package/lib/base-model/do-action-request.d.ts +10 -0
  81. package/lib/base-model/field-action.d.ts +6 -0
  82. package/lib/base-model/field-filter.model.d.ts +7 -0
  83. package/lib/base-model/field-info.d.ts +59 -0
  84. package/lib/base-model/field-predicate.model.d.ts +7 -0
  85. package/lib/base-model/filter-request.d.ts +15 -0
  86. package/lib/base-model/filter.model.d.ts +22 -0
  87. package/lib/base-model/get-items-list.d.ts +21 -0
  88. package/lib/base-model/index.d.ts +12 -0
  89. package/lib/base-model/items-total.model.d.ts +6 -0
  90. package/lib/base-model/line-item.model.d.ts +10 -0
  91. package/lib/base-model/lookupItem.d.ts +13 -0
  92. package/{src/lib/base-model/page-info.ts → lib/base-model/page-info.d.ts} +26 -24
  93. package/lib/base-model/permission-matrix.model.d.ts +18 -0
  94. package/lib/base-model/report-request.model.d.ts +18 -0
  95. package/lib/base-model/response-envelop.model.d.ts +8 -0
  96. package/lib/base-model/snack-message.model.d.ts +7 -0
  97. package/lib/base-model/table-column.interface.d.ts +31 -0
  98. package/lib/base-model/table-page-user-action.interface.d.ts +14 -0
  99. package/lib/base-model/workflow/workflow-steps.model.d.ts +7 -0
  100. package/lib/base-model/workflow/workflow.model.d.ts +13 -0
  101. package/lib/components/action-comment/action-comment.component.d.ts +35 -0
  102. package/lib/components/action-confirmation/action-confirmation.component.d.ts +27 -0
  103. package/lib/components/activity-report-form/activity-report-form.component.d.ts +93 -0
  104. package/lib/components/advanced-filter/field-filter/field-filter.component.d.ts +21 -0
  105. package/lib/components/advanced-filter/filter-builder/filter-builder.component.d.ts +51 -0
  106. package/lib/components/audit-log-details-dialog/audit-log-details-dialog.component.d.ts +25 -0
  107. package/lib/components/audit-log-list/audit-log.component.d.ts +29 -0
  108. package/lib/components/auto-complete/auto-complete.component.d.ts +52 -0
  109. package/lib/components/base-form/base-form.component.d.ts +59 -0
  110. package/lib/components/base-form-canvas/MaxDigitsDirective.d.ts +7 -0
  111. package/lib/components/base-form-canvas/NumbersOnlyDirective.d.ts +23 -0
  112. package/lib/components/base-form-canvas/base-form-canvas.component.d.ts +142 -0
  113. package/lib/components/base-input-dialog/base-input-dialog.component.d.ts +23 -0
  114. package/lib/components/base-table/base-table.component.d.ts +172 -0
  115. package/lib/components/button-actions/button-actions.component.d.ts +19 -0
  116. package/lib/components/editable-base-table/editable-base-table.component.d.ts +109 -0
  117. package/lib/components/equation-builder/equation-builder.component.d.ts +23 -0
  118. package/lib/components/item-line-editor/item-line-editor.component.d.ts +66 -0
  119. package/lib/components/multi-auto-complete/multi-auto-complete.component.d.ts +53 -0
  120. package/lib/components/paginator/paginator.component.d.ts +41 -0
  121. package/lib/components/permission-matrix/permission-matrix.component.d.ts +26 -0
  122. package/lib/components/report-details-dialog/report-details-dialog.component.d.ts +34 -0
  123. package/lib/components/report-form/report-form.component.d.ts +92 -0
  124. package/lib/components/search-bar/search-bar.component.d.ts +29 -0
  125. package/lib/components/section-form-canvas/section-form-canvas.component.d.ts +32 -0
  126. package/lib/components/shared/action-button/action-button.component.d.ts +17 -0
  127. package/lib/components/shared/action-card/action-card.component.d.ts +37 -0
  128. package/lib/components/shared/attachment-uploader/attachment-uploader.component.d.ts +18 -0
  129. package/lib/components/shared-list/shared-list.component.d.ts +21 -0
  130. package/lib/components/snackbar-static/snackbar-static.component.d.ts +15 -0
  131. package/lib/components/title-bar/title-bar.component.d.ts +54 -0
  132. package/lib/services/backend-service.d.ts +59 -0
  133. package/{src/lib/services/index.ts → lib/services/index.d.ts} +1 -1
  134. package/lib/services/top-panel.d.ts +8 -0
  135. package/lib/services/trigger-form.service.d.ts +7 -0
  136. package/lib/utils/base-utils.d.ts +13 -0
  137. package/lib/validators/date-range-validator.d.ts +2 -0
  138. package/lib/validators/match-list.validator.d.ts +4 -0
  139. package/lib/validators/multi-email-validator.d.ts +6 -0
  140. package/package.json +16 -3
  141. package/public-api.d.ts +26 -0
  142. package/ng-package.json +0 -7
  143. package/src/lib/base-model/SearchStrConfig.ts +0 -12
  144. package/src/lib/base-model/audit-log-entry.ts +0 -7
  145. package/src/lib/base-model/button-action-settings.ts +0 -25
  146. package/src/lib/base-model/column-def.model.ts +0 -34
  147. package/src/lib/base-model/do-action-request.ts +0 -11
  148. package/src/lib/base-model/field-action.ts +0 -7
  149. package/src/lib/base-model/field-filter.model.ts +0 -14
  150. package/src/lib/base-model/field-info.ts +0 -98
  151. package/src/lib/base-model/field-predicate.model.ts +0 -7
  152. package/src/lib/base-model/filter-request.ts +0 -27
  153. package/src/lib/base-model/filter.model.ts +0 -49
  154. package/src/lib/base-model/get-items-list.ts +0 -24
  155. package/src/lib/base-model/index.ts +0 -11
  156. package/src/lib/base-model/lookupItem.ts +0 -21
  157. package/src/lib/base-model/null-snackmessage.ts +0 -9
  158. package/src/lib/base-model/report-request.model.ts +0 -33
  159. package/src/lib/base-model/response-envelop.model.ts +0 -15
  160. package/src/lib/base-model/snack-message.model.ts +0 -14
  161. package/src/lib/base-model/snackmessage-interface.ts +0 -7
  162. package/src/lib/base-model/table-column.interface.ts +0 -29
  163. package/src/lib/base-model/table-page-user-action.interface.ts +0 -33
  164. package/src/lib/base-model/workflow/workflow-steps.model.ts +0 -9
  165. package/src/lib/base-model/workflow/workflow.model.ts +0 -52
  166. package/src/lib/components/action-confirmation/action-confirmation.component.css +0 -34
  167. package/src/lib/components/action-confirmation/action-confirmation.component.html +0 -18
  168. package/src/lib/components/action-confirmation/action-confirmation.component.spec.ts +0 -23
  169. package/src/lib/components/action-confirmation/action-confirmation.component.ts +0 -58
  170. package/src/lib/components/activity-report-form/activity-report-form.component.html +0 -109
  171. package/src/lib/components/activity-report-form/activity-report-form.component.scss +0 -0
  172. package/src/lib/components/activity-report-form/activity-report-form.component.spec.ts +0 -25
  173. package/src/lib/components/activity-report-form/activity-report-form.component.ts +0 -605
  174. package/src/lib/components/audit-log-details-dialog/audit-log-details-dialog.component.css +0 -51
  175. package/src/lib/components/audit-log-details-dialog/audit-log-details-dialog.component.html +0 -23
  176. package/src/lib/components/audit-log-details-dialog/audit-log-details-dialog.component.spec.ts +0 -23
  177. package/src/lib/components/audit-log-details-dialog/audit-log-details-dialog.component.ts +0 -69
  178. package/src/lib/components/audit-log-list/audit-log.component.html +0 -23
  179. package/src/lib/components/audit-log-list/audit-log.component.scss +0 -0
  180. package/src/lib/components/audit-log-list/audit-log.component.spec.ts +0 -25
  181. package/src/lib/components/audit-log-list/audit-log.component.ts +0 -116
  182. package/src/lib/components/auto-complete/auto-complete.component.css +0 -14
  183. package/src/lib/components/auto-complete/auto-complete.component.html +0 -29
  184. package/src/lib/components/auto-complete/auto-complete.component.spec.ts +0 -23
  185. package/src/lib/components/auto-complete/auto-complete.component.ts +0 -330
  186. package/src/lib/components/base-form/base-form.component.html +0 -58
  187. package/src/lib/components/base-form/base-form.component.scss +0 -0
  188. package/src/lib/components/base-form/base-form.component.spec.ts +0 -25
  189. package/src/lib/components/base-form/base-form.component.ts +0 -305
  190. package/src/lib/components/base-form-canvas/base-form-canvas.component.css +0 -22
  191. package/src/lib/components/base-form-canvas/base-form-canvas.component.html +0 -1006
  192. package/src/lib/components/base-form-canvas/base-form-canvas.component.spec.ts +0 -23
  193. package/src/lib/components/base-form-canvas/base-form-canvas.component.ts +0 -573
  194. package/src/lib/components/base-input-dialog/base-input-dialog.component.css +0 -0
  195. package/src/lib/components/base-input-dialog/base-input-dialog.component.html +0 -42
  196. package/src/lib/components/base-input-dialog/base-input-dialog.component.spec.ts +0 -23
  197. package/src/lib/components/base-input-dialog/base-input-dialog.component.ts +0 -78
  198. package/src/lib/components/base-table/base-table.component.html +0 -242
  199. package/src/lib/components/base-table/base-table.component.scss +0 -31
  200. package/src/lib/components/base-table/base-table.component.spec.ts +0 -25
  201. package/src/lib/components/base-table/base-table.component.ts +0 -568
  202. package/src/lib/components/button-actions/button-actions.component.html +0 -28
  203. package/src/lib/components/button-actions/button-actions.component.scss +0 -6
  204. package/src/lib/components/button-actions/button-actions.component.spec.ts +0 -23
  205. package/src/lib/components/button-actions/button-actions.component.ts +0 -72
  206. package/src/lib/components/editable-base-table/editable-base-table.component.html +0 -372
  207. package/src/lib/components/editable-base-table/editable-base-table.component.scss +0 -44
  208. package/src/lib/components/editable-base-table/editable-base-table.component.spec.ts +0 -25
  209. package/src/lib/components/editable-base-table/editable-base-table.component.ts +0 -570
  210. package/src/lib/components/equation-builder/equation-builder.component.css +0 -0
  211. package/src/lib/components/equation-builder/equation-builder.component.html +0 -31
  212. package/src/lib/components/equation-builder/equation-builder.component.spec.ts +0 -23
  213. package/src/lib/components/equation-builder/equation-builder.component.ts +0 -121
  214. package/src/lib/components/multi-auto-complete/multi-auto-complete.component.css +0 -11
  215. package/src/lib/components/multi-auto-complete/multi-auto-complete.component.html +0 -38
  216. package/src/lib/components/multi-auto-complete/multi-auto-complete.component.spec.ts +0 -23
  217. package/src/lib/components/multi-auto-complete/multi-auto-complete.component.ts +0 -317
  218. package/src/lib/components/paginator/paginator.component.css +0 -25
  219. package/src/lib/components/paginator/paginator.component.html +0 -34
  220. package/src/lib/components/paginator/paginator.component.ts +0 -94
  221. package/src/lib/components/rejection-comment/action-comment.component.css +0 -33
  222. package/src/lib/components/rejection-comment/action-comment.component.html +0 -46
  223. package/src/lib/components/rejection-comment/action-comment.component.spec.ts +0 -23
  224. package/src/lib/components/rejection-comment/action-comment.component.ts +0 -86
  225. package/src/lib/components/report-details-dialog/report-details-dialog.component.css +0 -17
  226. package/src/lib/components/report-details-dialog/report-details-dialog.component.html +0 -16
  227. package/src/lib/components/report-details-dialog/report-details-dialog.component.spec.ts +0 -23
  228. package/src/lib/components/report-details-dialog/report-details-dialog.component.ts +0 -113
  229. package/src/lib/components/report-form/report-form.component.html +0 -94
  230. package/src/lib/components/report-form/report-form.component.scss +0 -0
  231. package/src/lib/components/report-form/report-form.component.spec.ts +0 -25
  232. package/src/lib/components/report-form/report-form.component.ts +0 -588
  233. package/src/lib/components/search-bar/search-bar.component.html +0 -62
  234. package/src/lib/components/search-bar/search-bar.component.scss +0 -8
  235. package/src/lib/components/search-bar/search-bar.component.spec.ts +0 -25
  236. package/src/lib/components/search-bar/search-bar.component.ts +0 -70
  237. package/src/lib/components/shared/attachment-uploader/attachment-uploader.component.css +0 -54
  238. package/src/lib/components/shared/attachment-uploader/attachment-uploader.component.html +0 -22
  239. package/src/lib/components/shared/attachment-uploader/attachment-uploader.component.spec.ts +0 -23
  240. package/src/lib/components/shared/attachment-uploader/attachment-uploader.component.ts +0 -45
  241. package/src/lib/components/shared-list/shared-list.component.css +0 -0
  242. package/src/lib/components/shared-list/shared-list.component.html +0 -17
  243. package/src/lib/components/shared-list/shared-list.component.spec.ts +0 -23
  244. package/src/lib/components/shared-list/shared-list.component.ts +0 -53
  245. package/src/lib/components/title-bar/title-bar.component.css +0 -0
  246. package/src/lib/components/title-bar/title-bar.component.css.map +0 -1
  247. package/src/lib/components/title-bar/title-bar.component.html +0 -31
  248. package/src/lib/components/title-bar/title-bar.component.scss +0 -23
  249. package/src/lib/components/title-bar/title-bar.component.spec.ts +0 -23
  250. package/src/lib/components/title-bar/title-bar.component.ts +0 -119
  251. package/src/lib/services/backend-service.ts +0 -286
  252. package/src/lib/services/top-panel.ts +0 -17
  253. package/src/lib/services/trigger-form.service.ts +0 -11
  254. package/src/lib/share-module/shared-module.ts +0 -10
  255. package/src/lib/styles/invoiceq-theme.scss +0 -252
  256. package/src/lib/styles/styles.scss +0 -1723
  257. package/src/lib/utils/base-utils.ts +0 -102
  258. package/src/lib/validators/date-range-validator.ts +0 -31
  259. package/src/lib/validators/match-list.validator.ts +0 -10
  260. package/src/lib/validators/multi-email-validator.ts +0 -15
  261. package/src/public-api.ts +0 -21
  262. package/tsconfig.lib.json +0 -15
  263. package/tsconfig.lib.prod.json +0 -11
  264. package/tsconfig.spec.json +0 -15
  265. /package/{src/lib/validators/index.ts → lib/validators/index.d.ts} +0 -0
@@ -0,0 +1,294 @@
1
+ import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
2
+ import { ALL_ITEM, LookupItem } from "../../base-model";
3
+ import { MatAutocomplete, MatAutocompleteTrigger, MatOption } from "@angular/material/autocomplete";
4
+ import { of } from "rxjs";
5
+ import { FormControl, ReactiveFormsModule, Validators } from "@angular/forms";
6
+ import { MatFormField } from "@angular/material/form-field";
7
+ import { MatChip, MatChipGrid, MatChipInput, MatChipListbox } from "@angular/material/chips";
8
+ import { AsyncPipe, NgForOf, NgIf } from "@angular/common";
9
+ import { MatIcon } from "@angular/material/icon";
10
+ import { MatInput } from "@angular/material/input";
11
+ import { MatLabel } from '@angular/material/form-field';
12
+ import { buildItemsList } from "../../utils/base-utils";
13
+ import { FilterRequest } from "../../base-model";
14
+ import { Filter } from "../../base-model";
15
+ import { RequireMatch } from "../../validators";
16
+ import { MatChipsModule } from '@angular/material/chips';
17
+ import { MatIconModule } from '@angular/material/icon';
18
+ import { MatIconButton } from '@angular/material/button';
19
+ import { TranslateModule } from '@ngx-translate/core';
20
+ import * as i0 from "@angular/core";
21
+ import * as i1 from "../../services";
22
+ import * as i2 from "@ngx-translate/core";
23
+ import * as i3 from "@angular/material/icon";
24
+ import * as i4 from "@angular/material/chips";
25
+ import * as i5 from "@angular/forms";
26
+ export class MultiAutoCompleteComponent {
27
+ constructor(backendService, translateService) {
28
+ this.backendService = backendService;
29
+ this.translateService = translateService;
30
+ this.lookupItems = [];
31
+ this.selectedItems = [];
32
+ this.cascadedIdz = [];
33
+ this.isRequired = false;
34
+ this.readonly = false;
35
+ this.selectedValue = new EventEmitter();
36
+ this.question = 'Would you like to add ?"';
37
+ this.multiControl = new FormControl();
38
+ this._columns = ['id', 'code', 'englishName', 'arabicName'];
39
+ }
40
+ ngOnInit() {
41
+ // this.form = this.rootFormGroup.control;
42
+ this.selectedItems = [];
43
+ this.multiControl = new FormControl(this.form?.controls[this.field?.property]);
44
+ this.multiControl.enable();
45
+ this.updateFieldAttributes();
46
+ if (!this.field.acceptNewItem) {
47
+ // @ts-ignore
48
+ this.multiControl.setValidators([RequireMatch]);
49
+ }
50
+ this.multiControl.setValue(this.form?.controls[this.field?.property]?.value);
51
+ this.multiControl.valueChanges.subscribe(v => {
52
+ if (typeof v === 'string') {
53
+ clearTimeout(this.timer);
54
+ this.timer = setTimeout(() => {
55
+ this.filterLookupItems(v, null);
56
+ }, 700);
57
+ }
58
+ });
59
+ // this.multiControl.valueChanges.subscribe(v => {
60
+ // if (typeof v === 'string') this.filterLookupItems(v, null);
61
+ // })
62
+ // this.filterAutoCompleteData(this.field.property);
63
+ this.getLookupData();
64
+ if (this.field.cascadedBy) {
65
+ this.form?.get(this.field.cascadedBy)?.valueChanges.subscribe(v => {
66
+ this.removeChildItemsIfCascadedByRemoved(v);
67
+ });
68
+ }
69
+ }
70
+ updateFieldAttributes() {
71
+ if (this.field.readonly) {
72
+ this.multiControl.disable();
73
+ this.isRequired = false;
74
+ }
75
+ else if (this.field.required) {
76
+ this.form?.controls[this.field?.property].setValidators([Validators.required]);
77
+ this.form?.controls[this.field?.property].updateValueAndValidity();
78
+ this.multiControl.setValidators([Validators.required]);
79
+ this.isRequired = true;
80
+ }
81
+ this.multiControl.updateValueAndValidity();
82
+ }
83
+ removeChildItemsIfCascadedByRemoved(v) {
84
+ this.cascadedIdz = [];
85
+ v.forEach(a => {
86
+ this.cascadedIdz.push(a.id);
87
+ });
88
+ let toDeleteIdz = [];
89
+ this.selectedItems?.forEach(x => {
90
+ const del = this.cascadedIdz.findIndex(y => y === x[this.field.cascadedBy]?.id);
91
+ if (del < 0) {
92
+ toDeleteIdz.push(x['id']);
93
+ }
94
+ });
95
+ if (toDeleteIdz) {
96
+ this.selectedItems = this.selectedItems.filter(s => !toDeleteIdz.includes(s.id));
97
+ this.form.get(this.field.property).patchValue(this.selectedItems, { emitEvent: true });
98
+ }
99
+ }
100
+ ngOnChanges({ defaultValue, field }) {
101
+ this.patchLookupValue(defaultValue?.currentValue);
102
+ if (field?.currentValue) {
103
+ this.field = field.currentValue;
104
+ this.updateFieldAttributes();
105
+ }
106
+ }
107
+ getLookupData() {
108
+ const listItems = buildItemsList('', this.field.lookupApiPath);
109
+ const filterRequest = new FilterRequest();
110
+ filterRequest.filters = [];
111
+ this.cascadedIdz = [];
112
+ if (this.field.cascadedBy) {
113
+ this.form.get(this.field.cascadedBy)?.value?.forEach(a => {
114
+ this.cascadedIdz.push(a.id);
115
+ });
116
+ }
117
+ if (this.field.cascadedBy && this.cascadedIdz?.length > 0) {
118
+ filterRequest.filters.push(new Filter({
119
+ key: 'id', fieldName: this.field.cascadedBy, label: '',
120
+ filterType: 'FILED_FILTER', operator: 'IN',
121
+ valueObject: this.cascadedIdz
122
+ }));
123
+ }
124
+ filterRequest.columns = ['id', 'code', 'englishName', 'arabicName'];
125
+ this.backendService.getLookupItemsByMultiFilter(listItems, filterRequest).subscribe((resp => {
126
+ if (resp.valid) {
127
+ this.lookupItems = this.field.includeAllOption ? [ALL_ITEM].concat(resp.body) : resp.body;
128
+ if (!this.form.get('id')?.value) {
129
+ this.patchLookupValue(this.lookupItems?.find(l => l.defaultValue));
130
+ }
131
+ this.patchLookupValue(this.multiControl.value);
132
+ }
133
+ }));
134
+ }
135
+ selected(value) {
136
+ if (value.id !== -1 && this.selectedItems.findIndex(i => i.id === value.id) === -1) {
137
+ this.selectedItems?.push(value);
138
+ this.itemInput.nativeElement.value = '';
139
+ this.form.get(this.field.property)?.setValue(this.selectedItems);
140
+ // @ts-ignore
141
+ this.selectedValue.emit(this.selectedItems);
142
+ this.multiControl.setValue(null);
143
+ }
144
+ }
145
+ displayFn(selected) {
146
+ return selected ? selected.englishName : undefined;
147
+ }
148
+ isSelected(item) {
149
+ return this.selectedItems?.some(selected => selected.id === item.id); // Use your unique identifier
150
+ }
151
+ _allowSelection(option) {
152
+ return {
153
+ 'prevent-selection': option.id === -1,
154
+ };
155
+ }
156
+ itemNameByLag(item) {
157
+ // return item.arabicName;
158
+ return this.translateService.getDefaultLang() === 'en' ? item.englishName : item.arabicName;
159
+ }
160
+ filterLookupItems(name, trigger) {
161
+ if (trigger) {
162
+ trigger.openPanel();
163
+ }
164
+ if (name === undefined) {
165
+ name = '';
166
+ }
167
+ const listItems = buildItemsList(name, this.field.lookupApiPath);
168
+ const filterRequest = new FilterRequest();
169
+ filterRequest.filters = this.field.lookupFilterList || [];
170
+ filterRequest.searchStr = name;
171
+ this.cascadedIdz = [];
172
+ if (this.field.cascadedBy) {
173
+ this.form.get(this.field.cascadedBy)?.value?.forEach(a => {
174
+ this.cascadedIdz.push(a.id);
175
+ });
176
+ }
177
+ if (this.field.cascadedBy && this.cascadedIdz?.length > 0) {
178
+ filterRequest.filters.push(new Filter({
179
+ key: 'id', joinObjectName: this.field.cascadedBy, fieldName: this.field.cascadedBy, label: '',
180
+ filterType: 'FILED_FILTER', operator: 'IN',
181
+ valueObject: this.cascadedIdz
182
+ }));
183
+ }
184
+ filterRequest.columns = [...this._columns, ...(this.field.extraLookupsColumns ?? [])];
185
+ this.backendService.getLookupItemsByMultiFilter(listItems, filterRequest).subscribe(resp => {
186
+ // console.log('result -->', resp);
187
+ let items = [];
188
+ if (resp.valid) {
189
+ // resp.body.forEach(r => items.push(r));
190
+ items = resp.body.filter(item =>
191
+ // (item.englishName.toLowerCase().includes(name.toLowerCase()) ||
192
+ // item.arabicName.toLowerCase().includes(name.toLowerCase())) &&
193
+ this.selectedItems?.findIndex(i => i.id === item.id) === -1);
194
+ if (!items?.length) {
195
+ this.field.acceptNewItem ?
196
+ items?.push(new LookupItem({ id: -2, englishName: this.question + name, arabicName: this.question + name })) :
197
+ items?.push(new LookupItem({ id: -1, englishName: 'No match ...', arabicName: 'غير موجود ... ' }));
198
+ }
199
+ }
200
+ else {
201
+ this.field.acceptNewItem ?
202
+ items?.push(new LookupItem({ id: -2, englishName: this.question + name, arabicName: this.question + name })) :
203
+ items?.push(new LookupItem({ id: -1, englishName: 'No match ...', arabicName: 'غير موجود ... ' }));
204
+ }
205
+ this.lookupItems$ = of(items);
206
+ });
207
+ return;
208
+ }
209
+ patchLookupValue(defaultValue) {
210
+ if (defaultValue) {
211
+ // this.form?.get(this.field.property)?.patchValue(defaultValue);
212
+ this.selectedItems = defaultValue;
213
+ this.multiControl.setValue(defaultValue);
214
+ this.multiControl.patchValue(defaultValue, { emitEvent: true });
215
+ }
216
+ }
217
+ remove(item) {
218
+ const index = this.selectedItems.indexOf(item);
219
+ if (index >= 0) {
220
+ this.selectedItems.splice(index, 1);
221
+ this.form.get(this.field.property).patchValue(this.selectedItems, { emitEvent: true });
222
+ }
223
+ }
224
+ get matErrorDescribedBy() {
225
+ const control = this.form?.get(this.field?.property);
226
+ if (!control || !this.field?.property) {
227
+ return null;
228
+ }
229
+ const visible = (control.value || control.value === 0) && control.status === 'INVALID';
230
+ return visible ? `error-${this.field.property}` : null;
231
+ }
232
+ getLabel() {
233
+ return this.translateService.instant(this.field.label);
234
+ }
235
+ onKeydown(event, autocompleteTrigger) {
236
+ if (event.key === 'Enter') {
237
+ this.filterLookupItems('', autocompleteTrigger);
238
+ autocompleteTrigger.openPanel();
239
+ event.preventDefault();
240
+ }
241
+ }
242
+ openLookupPanel(autocompleteTrigger) {
243
+ this.filterLookupItems('', autocompleteTrigger);
244
+ autocompleteTrigger.openPanel();
245
+ }
246
+ getId() {
247
+ return this.field.property;
248
+ }
249
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MultiAutoCompleteComponent, deps: [{ token: i1.BackendService }, { token: i2.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
250
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: MultiAutoCompleteComponent, isStandalone: true, selector: "app-multi-auto-complete", inputs: { field: "field", form: "form", defaultValue: "defaultValue", pathParam: "pathParam", readonly: "readonly" }, outputs: { selectedValue: "selectedValue" }, viewQueries: [{ propertyName: "itemInput", first: true, predicate: ["itemInput"], descendants: true }, { propertyName: "matACTrigger", first: true, predicate: ["autocompleteTrigger"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"this.field\" class=\"main-multi-auto\">\r\n <div class=\"matField\">\r\n <mat-form-field class=\"full-width\" appearance=\"outline\" floatLabel=\"always\">\r\n <mat-label>{{ getLabel() }}</mat-label>\r\n <mat-chip-listbox #chipList [selectable]=\"true\">\r\n <mat-chip\r\n *ngFor=\"let item of selectedItems\"\r\n [removable]=\"true\"\r\n (removed)=\"remove(item)\">\r\n {{ itemNameByLag(item) }}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n <input class=\"chip-input\" type=\"text\"\r\n [id]=\"getId()\" #itemInput\r\n [formControl]=\"multiControl\"\r\n [matAutocomplete]=\"auto\" matInput\r\n [readonly]=\"readonly\"\r\n [required]=\"isRequired\"\r\n (keydown)=\"onKeydown($event, autocompleteTrigger)\"\r\n [disabled]=\"field.readonly\"\r\n #autocompleteTrigger=\"matAutocompleteTrigger\"\r\n [attr.aria-describedby]=\"matErrorDescribedBy\"\r\n >\r\n </mat-chip-listbox>\r\n\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"arrow_drop_down_autocomplete\"\r\n [attr.aria-label]=\"'BASE_TABLE.openLookupOptions' | translate\"\r\n (click)=\"openLookupPanel(autocompleteTrigger)\">\r\n <mat-icon aria-hidden=\"true\">arrow_drop_down</mat-icon>\r\n </button>\r\n <mat-autocomplete #auto=\"matAutocomplete\" autoActiveFirstOption [displayWith]=\"displayFn\"\r\n (optionSelected)=\"selected($event.option.value)\">\r\n <ng-container *ngIf=\"!field.readonly\">\r\n <mat-option *ngFor=\"let item of lookupItems$ | async\" [value]=\"item\"\r\n [disabled]=\"field.readonly || isSelected(item)\">\r\n {{ itemNameByLag(item) }}\r\n </mat-option>\r\n </ng-container>\r\n </mat-autocomplete>\r\n <ng-content select=\"mat-error\"></ng-content>\r\n </mat-form-field>\r\n </div>\r\n</ng-container>\r\n", styles: [":is() .matField{margin-bottom:24px!important}:is() .matField .mat-form-field-wrapper{padding:0!important;margin-bottom:0!important}.full-width{width:100%}.chip-input{flex:1 1 auto}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled", "tabIndex"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i4.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "directive", type: i4.MatChipRemove, selector: "[matChipRemove]" }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
251
+ }
252
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MultiAutoCompleteComponent, decorators: [{
253
+ type: Component,
254
+ args: [{ selector: 'app-multi-auto-complete', standalone: true, imports: [
255
+ MatFormField,
256
+ MatChip,
257
+ MatIconModule,
258
+ MatChipsModule,
259
+ NgForOf,
260
+ MatIcon,
261
+ ReactiveFormsModule,
262
+ MatAutocompleteTrigger,
263
+ MatChipInput,
264
+ MatInput,
265
+ MatAutocomplete,
266
+ MatOption,
267
+ AsyncPipe,
268
+ NgIf,
269
+ MatChipGrid,
270
+ MatChipListbox,
271
+ MatLabel,
272
+ MatIconButton,
273
+ TranslateModule,
274
+ ], template: "<ng-container *ngIf=\"this.field\" class=\"main-multi-auto\">\r\n <div class=\"matField\">\r\n <mat-form-field class=\"full-width\" appearance=\"outline\" floatLabel=\"always\">\r\n <mat-label>{{ getLabel() }}</mat-label>\r\n <mat-chip-listbox #chipList [selectable]=\"true\">\r\n <mat-chip\r\n *ngFor=\"let item of selectedItems\"\r\n [removable]=\"true\"\r\n (removed)=\"remove(item)\">\r\n {{ itemNameByLag(item) }}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n <input class=\"chip-input\" type=\"text\"\r\n [id]=\"getId()\" #itemInput\r\n [formControl]=\"multiControl\"\r\n [matAutocomplete]=\"auto\" matInput\r\n [readonly]=\"readonly\"\r\n [required]=\"isRequired\"\r\n (keydown)=\"onKeydown($event, autocompleteTrigger)\"\r\n [disabled]=\"field.readonly\"\r\n #autocompleteTrigger=\"matAutocompleteTrigger\"\r\n [attr.aria-describedby]=\"matErrorDescribedBy\"\r\n >\r\n </mat-chip-listbox>\r\n\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"arrow_drop_down_autocomplete\"\r\n [attr.aria-label]=\"'BASE_TABLE.openLookupOptions' | translate\"\r\n (click)=\"openLookupPanel(autocompleteTrigger)\">\r\n <mat-icon aria-hidden=\"true\">arrow_drop_down</mat-icon>\r\n </button>\r\n <mat-autocomplete #auto=\"matAutocomplete\" autoActiveFirstOption [displayWith]=\"displayFn\"\r\n (optionSelected)=\"selected($event.option.value)\">\r\n <ng-container *ngIf=\"!field.readonly\">\r\n <mat-option *ngFor=\"let item of lookupItems$ | async\" [value]=\"item\"\r\n [disabled]=\"field.readonly || isSelected(item)\">\r\n {{ itemNameByLag(item) }}\r\n </mat-option>\r\n </ng-container>\r\n </mat-autocomplete>\r\n <ng-content select=\"mat-error\"></ng-content>\r\n </mat-form-field>\r\n </div>\r\n</ng-container>\r\n", styles: [":is() .matField{margin-bottom:24px!important}:is() .matField .mat-form-field-wrapper{padding:0!important;margin-bottom:0!important}.full-width{width:100%}.chip-input{flex:1 1 auto}\n"] }]
275
+ }], ctorParameters: () => [{ type: i1.BackendService }, { type: i2.TranslateService }], propDecorators: { itemInput: [{
276
+ type: ViewChild,
277
+ args: ['itemInput']
278
+ }], matACTrigger: [{
279
+ type: ViewChild,
280
+ args: ['autocompleteTrigger']
281
+ }], field: [{
282
+ type: Input
283
+ }], form: [{
284
+ type: Input
285
+ }], defaultValue: [{
286
+ type: Input
287
+ }], pathParam: [{
288
+ type: Input
289
+ }], readonly: [{
290
+ type: Input
291
+ }], selectedValue: [{
292
+ type: Output
293
+ }] } });
294
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktYXV0by1jb21wbGV0ZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9pbnZvaWNlcS91aS1saWIvc3JjL2xpYi9jb21wb25lbnRzL211bHRpLWF1dG8tY29tcGxldGUvbXVsdGktYXV0by1jb21wbGV0ZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9pbnZvaWNlcS91aS1saWIvc3JjL2xpYi9jb21wb25lbnRzL211bHRpLWF1dG8tY29tcGxldGUvbXVsdGktYXV0by1jb21wbGV0ZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsU0FBUyxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFpQixTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDM0csT0FBTyxFQUFDLFFBQVEsRUFBRSxVQUFVLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQztBQUN0RCxPQUFPLEVBQUMsZUFBZSxFQUFFLHNCQUFzQixFQUFFLFNBQVMsRUFBQyxNQUFNLGdDQUFnQyxDQUFDO0FBQ2xHLE9BQU8sRUFBYSxFQUFFLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFFcEMsT0FBTyxFQUFDLFdBQVcsRUFBYSxtQkFBbUIsRUFBRSxVQUFVLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUl2RixPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sOEJBQThCLENBQUM7QUFDMUQsT0FBTyxFQUFDLE9BQU8sRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBQyxNQUFNLHlCQUF5QixDQUFDO0FBQzNGLE9BQU8sRUFBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pELE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQztBQUMvQyxPQUFPLEVBQUMsUUFBUSxFQUFD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U0FBUyxFQUFFLENBQUM7SUFDbEMsQ0FBQztJQUNELEtBQUs7UUFDSCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDO0lBQzdCLENBQUM7K0dBeFJVLDBCQUEwQjttR0FBMUIsMEJBQTBCLHlkQ3BEdkMsMmtFQThDQSxnUERqQkksWUFBWSw0TEFDWixPQUFPLDZTQUNQLGFBQWEsbUxBQ2IsY0FBYywwVUFDZCxPQUFPLGtIQUVQLG1CQUFtQix1eUJBQ25CLHNCQUFzQixxUUFFdEIsUUFBUSxpVUFDUixlQUFlLHlXQUNmLFNBQVMsZ0pBQ1QsU0FBUyw4Q0FDVCxJQUFJLDZGQUdKLFFBQVEsc0RBQ1IsYUFBYSw0RkFDYixlQUFlOzs0RkFLTiwwQkFBMEI7a0JBM0J0QyxTQUFTOytCQUNFLHlCQUF5QixjQUN2QixJQUFJLFdBQ1A7d0JBQ1AsWUFBWTt3QkFDWixPQUFPO3dCQUNQLGFBQWE7d0JBQ2IsY0FBYzt3QkFDZCxPQUFPO3dCQUNQLE9BQU87d0JBQ1AsbUJBQW1CO3dCQUNuQixzQkFBc0I7d0JBQ3RCLFlBQVk7d0JBQ1osUUFBUTt3QkFDUixlQUFlO3dCQUNmLFNBQVM7d0JBQ1QsU0FBUzt3QkFDVCxJQUFJO3dCQUNKLFdBQVc7d0JBQ1gsY0FBYzt3QkFDZCxRQUFRO3dCQUNSLGFBQWE7d0JBQ2IsZUFBZTtxQkFDaEI7a0hBTXVCLFNBQVM7c0JBQWhDLFNBQVM7dUJBQUMsV0FBVztnQkFDWSxZQUFZO3NCQUE3QyxTQUFTO3VCQUFDLHFCQUFxQjtnQkFXaEMsS0FBSztzQkFESixLQUFLO2dCQUlOLElBQUk7c0JBREgsS0FBSztnQkFJTixZQUFZO3NCQURYLEtBQUs7Z0JBSU4sU0FBUztzQkFEUixLQUFLO2dCQUlOLFFBQVE7c0JBRFAsS0FBSztnQkFJTixhQUFhO3NCQURaLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0LCBTaW1wbGVDaGFuZ2VzLCBWaWV3Q2hpbGR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge0FMTF9JVEVNLCBMb29rdXBJdGVtfSBmcm9tIFwiLi4vLi4vYmFzZS1tb2RlbFwiO1xyXG5pbXBvcnQge01hdEF1dG9jb21wbGV0ZSwgTWF0QXV0b2NvbXBsZXRlVHJpZ2dlciwgTWF0T3B0aW9ufSBmcm9tIFwiQGFuZ3VsYXIvbWF0ZXJpYWwvYXV0b2NvbXBsZXRlXCI7XHJcbmltcG9ydCB7T2JzZXJ2YWJsZSwgb2Z9IGZyb20gXCJyeGpzXCI7XHJcbmltcG9ydCB7RmllbGRJbmZvfSBmcm9tIFwiLi4vLi4vYmFzZS1tb2RlbFwiO1xyXG5pbXBvcnQge0Zvcm1Db250cm9sLCBGb3JtR3JvdXAsIFJlYWN0aXZlRm9ybXNNb2R1bGUsIFZhbGlkYXRvcnN9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xyXG5pbXBvcnQge0JhY2tlbmRTZXJ2aWNlfSBmcm9tIFwiLi4vLi4vc2VydmljZXNcIjtcclxuaW1wb3J0IHtUcmFuc2xhdGVTZXJ2aWNlfSBmcm9tIFwiQG5neC10cmFuc2xhdGUvY29yZVwiO1xyXG5pbXBvcnQge0dldEl0ZW1zTGlzdH0gZnJvbSBcIi4uLy4uL2Jhc2UtbW9kZWwvZ2V0LWl0ZW1zLWxpc3RcIjtcclxuaW1wb3J0IHtNYXRGb3JtRmllbGR9IGZyb20gXCJAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkXCI7XHJcbmltcG9ydCB7TWF0Q2hpcCwgTWF0Q2hpcEdyaWQsIE1hdENoaXBJbnB1dCwgTWF0Q2hpcExpc3Rib3h9IGZyb20gXCJAYW5ndWxhci9tYXRlcmlhbC9jaGlwc1wiO1xyXG5pbXBvcnQge0FzeW5jUGlwZSwgTmdGb3JPZiwgTmdJZn0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xyXG5pbXBvcnQge01hdEljb259IGZyb20gXCJAYW5ndWxhci9tYXRlcmlhbC9pY29uXCI7XHJcbmltcG9ydCB7TWF0SW5wdXR9IGZyb20gXCJAYW5ndWxhci9tYXRlcmlhbC9pbnB1dFwiO1xyXG5pbXBvcnQgeyBNYXRMYWJlbCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xyXG5pbXBvcnQge2J1aWxkSXRlbXNMaXN0fSBmcm9tIFwiLi4vLi4vdXRpbHMvYmFzZS11dGlsc1wiO1xyXG5pbXBvcnQge0ZpbHRlclJlcXVlc3R9IGZyb20gXCIuLi8uLi9iYXNlLW1vZGVsXCI7XHJcbmltcG9ydCB7RmlsdGVyfSBmcm9tIFwiLi4vLi4vYmFzZS1tb2RlbFwiO1xyXG5pbXBvcnQge1JlcXVpcmVNYXRjaH0gZnJvbSBcIi4uLy4uL3ZhbGlkYXRvcnNcIjtcclxuaW1wb3J0IHsgTWF0Q2hpcHNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jaGlwcyc7XHJcbmltcG9ydCB7IE1hdEljb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcclxuaW1wb3J0IHsgTWF0SWNvbkJ1dHRvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XHJcbmltcG9ydCB7IFRyYW5zbGF0ZU1vZHVsZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xyXG5cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnYXBwLW11bHRpLWF1dG8tY29tcGxldGUnLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgaW1wb3J0czogW1xyXG4gICAgTWF0Rm9ybUZpZWxkLFxyXG4gICAgTWF0Q2hpcCxcclxuICAgIE1hdEljb25Nb2R1bGUsXHJcbiAgICBNYXRDaGlwc01vZHVsZSxcclxuICAgIE5nRm9yT2YsXHJcbiAgICBNYXRJY29uLFxyXG4gICAgUmVhY3RpdmVGb3Jtc01vZHVsZSxcclxuICAgIE1hdEF1dG9jb21wbGV0ZVRyaWdnZXIsXHJcbiAgICBNYXRDaGlwSW5wdXQsXHJcbiAgICBNYXRJbnB1dCxcclxuICAgIE1hdEF1dG9jb21wbGV0ZSxcclxuICAgIE1hdE9wdGlvbixcclxuICAgIEFzeW5jUGlwZSxcclxuICAgIE5nSWYsXHJcbiAgICBNYXRDaGlwR3JpZCxcclxuICAgIE1hdENoaXBMaXN0Ym94LFxyXG4gICAgTWF0TGFiZWwsXHJcbiAgICBNYXRJY29uQnV0dG9uLFxyXG4gICAgVHJhbnNsYXRlTW9kdWxlLFxyXG4gIF0sXHJcbiAgdGVtcGxhdGVVcmw6ICcuL211bHRpLWF1dG8tY29tcGxldGUuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsOiAnLi9tdWx0aS1hdXRvLWNvbXBsZXRlLmNvbXBvbmVudC5jc3MnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNdWx0aUF1dG9Db21wbGV0ZUNvbXBvbmVudCB7XHJcbi8vIEB0cy1pZ25vcmVcclxuICBAVmlld0NoaWxkKCdpdGVtSW5wdXQnKSBpdGVtSW5wdXQ6IEVsZW1lbnRSZWY8SFRNTElucHV0RWxlbWVudD47XHJcbiAgQFZpZXdDaGlsZCgnYXV0b2NvbXBsZXRlVHJpZ2dlcicpIG1hdEFDVHJpZ2dlcjogTWF0QXV0b2NvbXBsZXRlVHJpZ2dlcjtcclxuXHJcbiAgbG9va3VwSXRlbXMkOiBPYnNlcnZhYmxlPExvb2t1cEl0ZW1bXT4gfCB1bmRlZmluZWQ7XHJcbiAgcHJpdmF0ZSBsb29rdXBJdGVtczogTG9va3VwSXRlbVtdID0gW107XHJcblxyXG4gIHNlbGVjdGVkSXRlbXM6IExvb2t1cEl0ZW1bXSA9IFtdO1xyXG4gIGNhc2NhZGVkSWR6OiBudW1iZXJbXSA9IFtdO1xyXG4gIGlzUmVxdWlyZWQ6IGJvb2xlYW49IGZhbHNlO1xyXG4gIHByaXZhdGUgdGltZXI6IGFueTtcclxuXHJcbiAgQElucHV0KCkvLyBAdHMtaWdub3JlXHJcbiAgZmllbGQ6IEZpZWxkSW5mbztcclxuICAvL1xyXG4gIEBJbnB1dCgpLy8gQHRzLWlnbm9yZVxyXG4gIGZvcm06IEZvcm1Hcm91cDtcclxuXHJcbiAgQElucHV0KCkvLyBAdHMtaWdub3JlXHJcbiAgZGVmYXVsdFZhbHVlOiBhbnk7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgcGF0aFBhcmFtOiBhbnk7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgcmVhZG9ubHkgOiBib29sZWFuPWZhbHNlO1xyXG5cclxuICBAT3V0cHV0KClcclxuICBzZWxlY3RlZFZhbHVlOiBFdmVudEVtaXR0ZXI8TG9va3VwSXRlbVtdPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuXHJcbiAgcXVlc3Rpb24gPSAnV291bGQgeW91IGxpa2UgdG8gYWRkID9cIic7XHJcblxyXG4gIG11bHRpQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbCgpO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGJhY2tlbmRTZXJ2aWNlOiBCYWNrZW5kU2VydmljZSwgcHJpdmF0ZSAgdHJhbnNsYXRlU2VydmljZTogVHJhbnNsYXRlU2VydmljZSkge1xyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICAvLyB0aGlzLmZvcm0gPSB0aGlzLnJvb3RGb3JtR3JvdXAuY29udHJvbDtcclxuICAgIHRoaXMuc2VsZWN0ZWRJdGVtcyA9IFtdO1xyXG4gICAgdGhpcy5tdWx0aUNvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2wodGhpcy5mb3JtPy5jb250cm9sc1t0aGlzLmZpZWxkPy5wcm9wZXJ0eV0pO1xyXG5cclxuICAgIHRoaXMubXVsdGlDb250cm9sLmVuYWJsZSgpO1xyXG4gICAgdGhpcy51cGRhdGVGaWVsZEF0dHJpYnV0ZXMoKTtcclxuXHJcbiAgICBpZiAoIXRoaXMuZmllbGQuYWNjZXB0TmV3SXRlbSl7XHJcbiAgICAgIC8vIEB0cy1pZ25vcmVcclxuICAgICAgdGhpcy5tdWx0aUNvbnRyb2wuc2V0VmFsaWRhdG9ycyhbUmVxdWlyZU1hdGNoXSk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5tdWx0aUNvbnRyb2wuc2V0VmFsdWUodGhpcy5mb3JtPy5jb250cm9sc1t0aGlzLmZpZWxkPy5wcm9wZXJ0eV0/LnZhbHVlKTtcclxuXHJcbiAgICB0aGlzLm11bHRpQ29udHJvbC52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKCB2ID0+IHtcclxuICAgICAgICBpZiAodHlwZW9mIHYgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lcik7XHJcbiAgICAgICAgICB0aGlzLnRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuZmlsdGVyTG9va3VwSXRlbXModiwgbnVsbCk7fSwgNzAwKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICk7XHJcblxyXG4gICAgLy8gdGhpcy5tdWx0aUNvbnRyb2wudmFsdWVDaGFuZ2VzLnN1YnNjcmliZSh2ID0+IHtcclxuICAgIC8vICAgICBpZiAodHlwZW9mIHYgPT09ICdzdHJpbmcnKSB0aGlzLmZpbHRlckxvb2t1cEl0ZW1zKHYsIG51bGwpO1xyXG4gICAgLy8gfSlcclxuICAgIC8vIHRoaXMuZmlsdGVyQXV0b0NvbXBsZXRlRGF0YSh0aGlzLmZpZWxkLnByb3BlcnR5KTtcclxuXHJcbiAgICB0aGlzLmdldExvb2t1cERhdGEoKTtcclxuICAgIGlmICh0aGlzLmZpZWxkLmNhc2NhZGVkQnkpIHtcclxuICAgICAgdGhpcy5mb3JtPy5nZXQodGhpcy5maWVsZC5jYXNjYWRlZEJ5KT8udmFsdWVDaGFuZ2VzLnN1YnNjcmliZSh2ID0+IHtcclxuICAgICAgICB0aGlzLnJlbW92ZUNoaWxkSXRlbXNJZkNhc2NhZGVkQnlSZW1vdmVkKHYpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVwZGF0ZUZpZWxkQXR0cmlidXRlcygpIHtcclxuICAgIGlmICh0aGlzLmZpZWxkLnJlYWRvbmx5KSB7XHJcbiAgICAgIHRoaXMubXVsdGlDb250cm9sLmRpc2FibGUoKTtcclxuICAgICAgdGhpcy5pc1JlcXVpcmVkID0gZmFsc2U7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMuZmllbGQucmVxdWlyZWQpIHtcclxuICAgICAgdGhpcy5mb3JtPy5jb250cm9sc1t0aGlzLmZpZWxkPy5wcm9wZXJ0eV0uc2V0VmFsaWRhdG9ycyhbVmFsaWRhdG9ycy5yZXF1aXJlZF0pO1xyXG4gICAgICB0aGlzLmZvcm0/LmNvbnRyb2xzW3RoaXMuZmllbGQ/LnByb3BlcnR5XS51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgIHRoaXMubXVsdGlDb250cm9sLnNldFZhbGlkYXRvcnMoW1ZhbGlkYXRvcnMucmVxdWlyZWRdKTtcclxuICAgICAgdGhpcy5pc1JlcXVpcmVkID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIHRoaXMubXVsdGlDb250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgcmVtb3ZlQ2hpbGRJdGVtc0lmQ2FzY2FkZWRCeVJlbW92ZWQodikge1xyXG4gICAgdGhpcy5jYXNjYWRlZElkeiA9IFtdO1xyXG4gICAgdi5mb3JFYWNoKGEgPT4ge1xyXG4gICAgICB0aGlzLmNhc2NhZGVkSWR6LnB1c2goYS5pZCk7XHJcbiAgICB9KTtcclxuICAgIGxldCB0b0RlbGV0ZUlkeiA9IFtdO1xyXG4gICAgdGhpcy5zZWxlY3RlZEl0ZW1zPy5mb3JFYWNoKHggPT4ge1xyXG4gICAgICBjb25zdCBkZWwgPSB0aGlzLmNhc2NhZGVkSWR6LmZpbmRJbmRleCh5ID0+IHkgPT09IHhbdGhpcy5maWVsZC5jYXNjYWRlZEJ5XT8uaWQpO1xyXG4gICAgICBpZiAoZGVsIDwgMCkge1xyXG4gICAgICAgIHRvRGVsZXRlSWR6LnB1c2goeFsnaWQnXSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIGlmICh0b0RlbGV0ZUlkeikge1xyXG4gICAgICB0aGlzLnNlbGVjdGVkSXRlbXMgPSB0aGlzLnNlbGVjdGVkSXRlbXMuZmlsdGVyKHMgPT4gIXRvRGVsZXRlSWR6LmluY2x1ZGVzKHMuaWQpKTtcclxuICAgICAgdGhpcy5mb3JtLmdldCh0aGlzLmZpZWxkLnByb3BlcnR5KS5wYXRjaFZhbHVlKHRoaXMuc2VsZWN0ZWRJdGVtcywge2VtaXRFdmVudDogdHJ1ZX0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoe2RlZmF1bHRWYWx1ZSwgZmllbGR9OiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XHJcbiAgICB0aGlzLnBhdGNoTG9va3VwVmFsdWUoZGVmYXVsdFZhbHVlPy5jdXJyZW50VmFsdWUpO1xyXG4gICAgaWYgKGZpZWxkPy5jdXJyZW50VmFsdWUpIHtcclxuICAgICAgdGhpcy5maWVsZCA9IGZpZWxkLmN1cnJlbnRWYWx1ZTtcclxuICAgICAgdGhpcy51cGRhdGVGaWVsZEF0dHJpYnV0ZXMoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0TG9va3VwRGF0YSgpIHtcclxuICAgIGNvbnN0IGxpc3RJdGVtczogR2V0SXRlbXNMaXN0ID0gYnVpbGRJdGVtc0xpc3QoJycsIHRoaXMuZmllbGQubG9va3VwQXBpUGF0aCk7XHJcblxyXG4gICAgY29uc3QgZmlsdGVyUmVxdWVzdDogRmlsdGVyUmVxdWVzdCA9IG5ldyBGaWx0ZXJSZXF1ZXN0KCk7XHJcbiAgICBmaWx0ZXJSZXF1ZXN0LmZpbHRlcnMgPSBbXTtcclxuICAgIHRoaXMuY2FzY2FkZWRJZHogPSBbXTtcclxuICAgIGlmICh0aGlzLmZpZWxkLmNhc2NhZGVkQnkpIHtcclxuICAgICAgdGhpcy5mb3JtLmdldCh0aGlzLmZpZWxkLmNhc2NhZGVkQnkpPy52YWx1ZT8uZm9yRWFjaChhID0+IHtcclxuICAgICAgICB0aGlzLmNhc2NhZGVkSWR6LnB1c2goYS5pZCk7XHJcbiAgICAgIH0pXHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5maWVsZC5jYXNjYWRlZEJ5ICYmIHRoaXMuY2FzY2FkZWRJZHo/Lmxlbmd0aCA+IDApIHtcclxuICAgICAgZmlsdGVyUmVxdWVzdC5maWx0ZXJzLnB1c2gobmV3IEZpbHRlcih7XHJcbiAgICAgICAga2V5OiAnaWQnLCBmaWVsZE5hbWU6IHRoaXMuZmllbGQuY2FzY2FkZWRCeSwgbGFiZWw6ICcnLFxyXG4gICAgICAgIGZpbHRlclR5cGU6ICdGSUxFRF9GSUxURVInLCBvcGVyYXRvcjogJ0lOJyxcclxuICAgICAgICB2YWx1ZU9iamVjdDogdGhpcy5jYXNjYWRlZElkelxyXG4gICAgICB9KSk7XHJcbiAgICB9XHJcblxyXG4gICAgZmlsdGVyUmVxdWVzdC5jb2x1bW5zID0gWydpZCcsJ2NvZGUnLCdlbmdsaXNoTmFtZScsJ2FyYWJpY05hbWUnXTtcclxuICAgIHRoaXMuYmFja2VuZFNlcnZpY2UuZ2V0TG9va3VwSXRlbXNCeU11bHRpRmlsdGVyKGxpc3RJdGVtcywgZmlsdGVyUmVxdWVzdCkuc3Vic2NyaWJlKChyZXNwID0+IHtcclxuICAgICAgaWYgKHJlc3AudmFsaWQpIHtcclxuICAgICAgICB0aGlzLmxvb2t1cEl0ZW1zID0gdGhpcy5maWVsZC5pbmNsdWRlQWxsT3B0aW9uID8gW0FMTF9JVEVNXS5jb25jYXQocmVzcC5ib2R5KSA6IHJlc3AuYm9keTtcclxuICAgICAgICBpZiAoIXRoaXMuZm9ybS5nZXQoJ2lkJyk/LnZhbHVlKSB7XHJcbiAgICAgICAgICB0aGlzLnBhdGNoTG9va3VwVmFsdWUodGhpcy5sb29rdXBJdGVtcz8uZmluZChsID0+IGwuZGVmYXVsdFZhbHVlKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMucGF0Y2hMb29rdXBWYWx1ZSh0aGlzLm11bHRpQ29udHJvbC52YWx1ZSk7XHJcblxyXG4gICAgICB9XHJcblxyXG4gICAgfSkpO1xyXG4gIH1cclxuXHJcblxyXG4gIHNlbGVjdGVkKHZhbHVlOiBhbnkpOiB2b2lkIHtcclxuICAgIGlmICh2YWx1ZS5pZCAhPT0gLTEgJiYgdGhpcy5zZWxlY3RlZEl0ZW1zLmZpbmRJbmRleChpID0+IGkuaWQgPT09IHZhbHVlLmlkKSA9PT0gLTEpIHtcclxuICAgICAgdGhpcy5zZWxlY3RlZEl0ZW1zPy5wdXNoKHZhbHVlKTtcclxuICAgICAgdGhpcy5pdGVtSW5wdXQubmF0aXZlRWxlbWVudC52YWx1ZSA9ICcnO1xyXG4gICAgICB0aGlzLmZvcm0uZ2V0KHRoaXMuZmllbGQucHJvcGVydHkpPy5zZXRWYWx1ZSh0aGlzLnNlbGVjdGVkSXRlbXMpO1xyXG4gICAgICAvLyBAdHMtaWdub3JlXHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRWYWx1ZS5lbWl0KHRoaXMuc2VsZWN0ZWRJdGVtcyk7XHJcbiAgICAgIHRoaXMubXVsdGlDb250cm9sLnNldFZhbHVlKG51bGwpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZGlzcGxheUZuKHNlbGVjdGVkOiBhbnkpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHNlbGVjdGVkID8gc2VsZWN0ZWQuZW5nbGlzaE5hbWUgOiB1bmRlZmluZWQ7XHJcblxyXG4gIH1cclxuICBpc1NlbGVjdGVkKGl0ZW06IGFueSk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRJdGVtcz8uc29tZShzZWxlY3RlZCA9PiBzZWxlY3RlZC5pZCA9PT0gaXRlbS5pZCk7IC8vIFVzZSB5b3VyIHVuaXF1ZSBpZGVudGlmaWVyXHJcbiAgfVxyXG5cclxuICBfYWxsb3dTZWxlY3Rpb24ob3B0aW9uOiBMb29rdXBJdGVtKTogeyBbY2xhc3NOYW1lOiBzdHJpbmddOiBib29sZWFuIH0ge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgJ3ByZXZlbnQtc2VsZWN0aW9uJzogb3B0aW9uLmlkID09PSAtMSxcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGl0ZW1OYW1lQnlMYWcoaXRlbTogYW55KTogc3RyaW5nIHtcclxuICAgIC8vIHJldHVybiBpdGVtLmFyYWJpY05hbWU7XHJcbiAgICByZXR1cm4gdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmdldERlZmF1bHRMYW5nKCkgPT09ICdlbicgPyBpdGVtLmVuZ2xpc2hOYW1lIDogaXRlbS5hcmFiaWNOYW1lXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IF9jb2x1bW5zID0gWydpZCcsJ2NvZGUnLCdlbmdsaXNoTmFtZScsJ2FyYWJpY05hbWUnXTtcclxuXHJcbiAgZmlsdGVyTG9va3VwSXRlbXMobmFtZTogYW55LCB0cmlnZ2VyOiBNYXRBdXRvY29tcGxldGVUcmlnZ2VyKSB7XHJcbiAgICBpZiAodHJpZ2dlcikge1xyXG4gICAgICB0cmlnZ2VyLm9wZW5QYW5lbCgpO1xyXG4gICAgfVxyXG4gICAgaWYgKG5hbWUgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICBuYW1lID0gJyc7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgbGlzdEl0ZW1zOiBHZXRJdGVtc0xpc3QgPSBidWlsZEl0ZW1zTGlzdChuYW1lLCB0aGlzLmZpZWxkLmxvb2t1cEFwaVBhdGgpO1xyXG5cclxuICAgIGNvbnN0IGZpbHRlclJlcXVlc3Q6IEZpbHRlclJlcXVlc3QgPSBuZXcgRmlsdGVyUmVxdWVzdCgpO1xyXG4gICAgZmlsdGVyUmVxdWVzdC5maWx0ZXJzID0gdGhpcy5maWVsZC5sb29rdXBGaWx0ZXJMaXN0IHx8IFtdO1xyXG4gICAgZmlsdGVyUmVxdWVzdC5zZWFyY2hTdHIgPSBuYW1lO1xyXG4gICAgdGhpcy5jYXNjYWRlZElkeiA9IFtdO1xyXG4gICAgaWYgKHRoaXMuZmllbGQuY2FzY2FkZWRCeSkge1xyXG4gICAgICB0aGlzLmZvcm0uZ2V0KHRoaXMuZmllbGQuY2FzY2FkZWRCeSk/LnZhbHVlPy5mb3JFYWNoKGEgPT4ge1xyXG4gICAgICAgIHRoaXMuY2FzY2FkZWRJZHoucHVzaChhLmlkKTtcclxuICAgICAgfSlcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmZpZWxkLmNhc2NhZGVkQnkgJiYgdGhpcy5jYXNjYWRlZElkej8ubGVuZ3RoID4gMCkge1xyXG4gICAgICBmaWx0ZXJSZXF1ZXN0LmZpbHRlcnMucHVzaChuZXcgRmlsdGVyKHtcclxuICAgICAgICBrZXk6ICdpZCcsam9pbk9iamVjdE5hbWU6IHRoaXMuZmllbGQuY2FzY2FkZWRCeSwgZmllbGROYW1lOiB0aGlzLmZpZWxkLmNhc2NhZGVkQnksIGxhYmVsOiAnJyxcclxuICAgICAgICBmaWx0ZXJUeXBlOiAnRklMRURfRklMVEVSJywgb3BlcmF0b3I6ICdJTicsXHJcbiAgICAgICAgdmFsdWVPYmplY3Q6IHRoaXMuY2FzY2FkZWRJZHpcclxuICAgICAgfSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGZpbHRlclJlcXVlc3QuY29sdW1ucyA9IFsuLi50aGlzLl9jb2x1bW5zLCAuLi4odGhpcy5maWVsZC5leHRyYUxvb2t1cHNDb2x1bW5zID8/IFtdKV07XHJcblxyXG4gICAgdGhpcy5iYWNrZW5kU2VydmljZS5nZXRMb29rdXBJdGVtc0J5TXVsdGlGaWx0ZXIobGlzdEl0ZW1zLCBmaWx0ZXJSZXF1ZXN0KS5zdWJzY3JpYmUocmVzcCA9PiB7XHJcbiAgICAgIC8vIGNvbnNvbGUubG9nKCdyZXN1bHQgLS0+JywgcmVzcCk7XHJcbiAgICAgIGxldCBpdGVtczogTG9va3VwSXRlbVtdID0gW107XHJcbiAgICAgIGlmIChyZXNwLnZhbGlkKSB7XHJcbiAgICAgICAgLy8gcmVzcC5ib2R5LmZvckVhY2gociA9PiBpdGVtcy5wdXNoKHIpKTtcclxuICAgICAgICBpdGVtcyA9IHJlc3AuYm9keS5maWx0ZXIoaXRlbSA9PlxyXG4gICAgICAgICAgLy8gKGl0ZW0uZW5nbGlzaE5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhuYW1lLnRvTG93ZXJDYXNlKCkpIHx8XHJcbiAgICAgICAgICAvLyBpdGVtLmFyYWJpY05hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhuYW1lLnRvTG93ZXJDYXNlKCkpKSAmJlxyXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZEl0ZW1zPy5maW5kSW5kZXgoIGk9PiBpLmlkID09PWl0ZW0uaWQgKSA9PT0tMSApO1xyXG4gICAgICAgIGlmICghaXRlbXM/Lmxlbmd0aCkge1xyXG4gICAgICAgICAgdGhpcy5maWVsZC5hY2NlcHROZXdJdGVtID9cclxuICAgICAgICAgICAgaXRlbXM/LnB1c2gobmV3IExvb2t1cEl0ZW0oe2lkOiAtMiwgZW5nbGlzaE5hbWU6IHRoaXMucXVlc3Rpb24gKyBuYW1lLCBhcmFiaWNOYW1lOiB0aGlzLnF1ZXN0aW9uICsgbmFtZX0pKTpcclxuICAgICAgICAgICAgaXRlbXM/LnB1c2gobmV3IExvb2t1cEl0ZW0oe2lkOiAtMSwgZW5nbGlzaE5hbWU6ICdObyBtYXRjaCAuLi4nLCBhcmFiaWNOYW1lOiAn2LrZitixINmF2YjYrNmI2K8gIC4uLiAnfSkpIDtcclxuXHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuZmllbGQuYWNjZXB0TmV3SXRlbSA/XHJcbiAgICAgICAgICBpdGVtcz8ucHVzaChuZXcgTG9va3VwSXRlbSh7aWQ6IC0yLCBlbmdsaXNoTmFtZTogdGhpcy5xdWVzdGlvbiArIG5hbWUsIGFyYWJpY05hbWU6IHRoaXMucXVlc3Rpb24gKyBuYW1lfSkpOlxyXG4gICAgICAgICAgaXRlbXM/LnB1c2gobmV3IExvb2t1cEl0ZW0oe2lkOiAtMSwgZW5nbGlzaE5hbWU6ICdObyBtYXRjaCAuLi4nLCBhcmFiaWNOYW1lOiAn2LrZitixINmF2YjYrNmI2K8gIC4uLiAnfSkpIDtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmxvb2t1cEl0ZW1zJCA9IG9mKGl0ZW1zKTtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBwYXRjaExvb2t1cFZhbHVlKGRlZmF1bHRWYWx1ZTogYW55KSB7XHJcbiAgICBpZiAoZGVmYXVsdFZhbHVlKSB7XHJcbiAgICAgIC8vIHRoaXMuZm9ybT8uZ2V0KHRoaXMuZmllbGQucHJvcGVydHkpPy5wYXRjaFZhbHVlKGRlZmF1bHRWYWx1ZSk7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRJdGVtcyA9IGRlZmF1bHRWYWx1ZTtcclxuICAgICAgdGhpcy5tdWx0aUNvbnRyb2wuc2V0VmFsdWUoZGVmYXVsdFZhbHVlKTtcclxuICAgICAgdGhpcy5tdWx0aUNvbnRyb2wucGF0Y2hWYWx1ZShkZWZhdWx0VmFsdWUsIHtlbWl0RXZlbnQ6IHRydWV9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJlbW92ZShpdGVtOiBMb29rdXBJdGVtKSB7XHJcbiAgICBjb25zdCBpbmRleCA9IHRoaXMuc2VsZWN0ZWRJdGVtcy5pbmRleE9mKGl0ZW0pO1xyXG4gICAgaWYgKGluZGV4ID49IDApIHtcclxuICAgICAgdGhpcy5zZWxlY3RlZEl0ZW1zLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgIHRoaXMuZm9ybS5nZXQodGhpcy5maWVsZC5wcm9wZXJ0eSkucGF0Y2hWYWx1ZSh0aGlzLnNlbGVjdGVkSXRlbXMsIHtlbWl0RXZlbnQ6IHRydWV9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBtYXRFcnJvckRlc2NyaWJlZEJ5KCk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgY29udHJvbCA9IHRoaXMuZm9ybT8uZ2V0KHRoaXMuZmllbGQ/LnByb3BlcnR5KTtcclxuICAgIGlmICghY29udHJvbCB8fCAhdGhpcy5maWVsZD8ucHJvcGVydHkpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICBjb25zdCB2aXNpYmxlID1cclxuICAgICAgKGNvbnRyb2wudmFsdWUgfHwgY29udHJvbC52YWx1ZSA9PT0gMCkgJiYgY29udHJvbC5zdGF0dXMgPT09ICdJTlZBTElEJztcclxuICAgIHJldHVybiB2aXNpYmxlID8gYGVycm9yLSR7dGhpcy5maWVsZC5wcm9wZXJ0eX1gIDogbnVsbDtcclxuICB9XHJcblxyXG4gIGdldExhYmVsKCkge1xyXG4gICAgcmV0dXJuIHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KHRoaXMuZmllbGQubGFiZWwpO1xyXG4gIH1cclxuICBvbktleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQsIGF1dG9jb21wbGV0ZVRyaWdnZXI6IE1hdEF1dG9jb21wbGV0ZVRyaWdnZXIpIHtcclxuICAgIGlmIChldmVudC5rZXkgPT09ICdFbnRlcicpIHtcclxuICAgICAgdGhpcy5maWx0ZXJMb29rdXBJdGVtcygnJywgYXV0b2NvbXBsZXRlVHJpZ2dlcik7XHJcbiAgICAgIGF1dG9jb21wbGV0ZVRyaWdnZXIub3BlblBhbmVsKCk7XHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvcGVuTG9va3VwUGFuZWwoYXV0b2NvbXBsZXRlVHJpZ2dlcjogTWF0QXV0b2NvbXBsZXRlVHJpZ2dlcik6IHZvaWQge1xyXG4gICAgdGhpcy5maWx0ZXJMb29rdXBJdGVtcygnJywgYXV0b2NvbXBsZXRlVHJpZ2dlcik7XHJcbiAgICBhdXRvY29tcGxldGVUcmlnZ2VyLm9wZW5QYW5lbCgpO1xyXG4gIH1cclxuICBnZXRJZCgpIHtcclxuICAgIHJldHVybiB0aGlzLmZpZWxkLnByb3BlcnR5O1xyXG4gIH1cclxufVxyXG4iLCI8bmctY29udGFpbmVyICpuZ0lmPVwidGhpcy5maWVsZFwiIGNsYXNzPVwibWFpbi1tdWx0aS1hdXRvXCI+XHJcbiAgPGRpdiBjbGFzcz1cIm1hdEZpZWxkXCI+XHJcbiAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCIgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBmbG9hdExhYmVsPVwiYWx3YXlzXCI+XHJcbiAgICAgIDxtYXQtbGFiZWw+e3sgZ2V0TGFiZWwoKSB9fTwvbWF0LWxhYmVsPlxyXG4gICAgICA8bWF0LWNoaXAtbGlzdGJveCAjY2hpcExpc3QgW3NlbGVjdGFibGVdPVwidHJ1ZVwiPlxyXG4gICAgICAgIDxtYXQtY2hpcFxyXG4gICAgICAgICAgKm5nRm9yPVwibGV0IGl0ZW0gb2Ygc2VsZWN0ZWRJdGVtc1wiXHJcbiAgICAgICAgICBbcmVtb3ZhYmxlXT1cInRydWVcIlxyXG4gICAgICAgICAgKHJlbW92ZWQpPVwicmVtb3ZlKGl0ZW0pXCI+XHJcbiAgICAgICAgICB7eyBpdGVtTmFtZUJ5TGFnKGl0ZW0pIH19XHJcbiAgICAgICAgICA8bWF0LWljb24gbWF0Q2hpcFJlbW92ZT5jYW5jZWw8L21hdC1pY29uPlxyXG4gICAgICAgIDwvbWF0LWNoaXA+XHJcbiAgICAgICAgPGlucHV0IGNsYXNzPVwiY2hpcC1pbnB1dFwiIHR5cGU9XCJ0ZXh0XCJcclxuICAgICAgICAgICAgICAgW2lkXT1cImdldElkKClcIiAjaXRlbUlucHV0XHJcbiAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJtdWx0aUNvbnRyb2xcIlxyXG4gICAgICAgICAgICAgICBbbWF0QXV0b2NvbXBsZXRlXT1cImF1dG9cIiBtYXRJbnB1dFxyXG4gICAgICAgICAgICAgICBbcmVhZG9ubHldPVwicmVhZG9ubHlcIlxyXG4gICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwiaXNSZXF1aXJlZFwiXHJcbiAgICAgICAgICAgICAgIChrZXlkb3duKT1cIm9uS2V5ZG93bigkZXZlbnQsIGF1dG9jb21wbGV0ZVRyaWdnZXIpXCJcclxuICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImZpZWxkLnJlYWRvbmx5XCJcclxuICAgICAgICAgICAgICAgI2F1dG9jb21wbGV0ZVRyaWdnZXI9XCJtYXRBdXRvY29tcGxldGVUcmlnZ2VyXCJcclxuICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1kZXNjcmliZWRieV09XCJtYXRFcnJvckRlc2NyaWJlZEJ5XCJcclxuICAgICAgICA+XHJcbiAgICAgIDwvbWF0LWNoaXAtbGlzdGJveD5cclxuXHJcbiAgICAgIDxidXR0b25cclxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcclxuICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICBjbGFzcz1cImFycm93X2Ryb3BfZG93bl9hdXRvY29tcGxldGVcIlxyXG4gICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ0JBU0VfVEFCTEUub3Blbkxvb2t1cE9wdGlvbnMnIHwgdHJhbnNsYXRlXCJcclxuICAgICAgICAoY2xpY2spPVwib3Blbkxvb2t1cFBhbmVsKGF1dG9jb21wbGV0ZVRyaWdnZXIpXCI+XHJcbiAgICAgICAgPG1hdC1pY29uIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPmFycm93X2Ryb3BfZG93bjwvbWF0LWljb24+XHJcbiAgICAgIDwvYnV0dG9uPlxyXG4gICAgICA8bWF0LWF1dG9jb21wbGV0ZSAjYXV0bz1cIm1hdEF1dG9jb21wbGV0ZVwiIGF1dG9BY3RpdmVGaXJzdE9wdGlvbiBbZGlzcGxheVdpdGhdPVwiZGlzcGxheUZuXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKG9wdGlvblNlbGVjdGVkKT1cInNlbGVjdGVkKCRldmVudC5vcHRpb24udmFsdWUpXCI+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFmaWVsZC5yZWFkb25seVwiPlxyXG4gICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGl0ZW0gb2YgIGxvb2t1cEl0ZW1zJCB8IGFzeW5jXCIgW3ZhbHVlXT1cIml0ZW1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImZpZWxkLnJlYWRvbmx5IHx8IGlzU2VsZWN0ZWQoaXRlbSlcIj5cclxuICAgICAgICAgICAge3sgaXRlbU5hbWVCeUxhZyhpdGVtKSB9fVxyXG4gICAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICA8L21hdC1hdXRvY29tcGxldGU+XHJcbiAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIm1hdC1lcnJvclwiPjwvbmctY29udGVudD5cclxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgPC9kaXY+XHJcbjwvbmctY29udGFpbmVyPlxyXG4iXX0=
@@ -0,0 +1,181 @@
1
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
2
+ import { MatIconModule } from '@angular/material/icon';
3
+ import { MatButtonModule } from '@angular/material/button';
4
+ import { NgIf, NgForOf } from '@angular/common';
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "@angular/cdk/bidi";
7
+ import * as i2 from "@angular/cdk/a11y";
8
+ import * as i3 from "@ngx-translate/core";
9
+ import * as i4 from "@angular/material/icon";
10
+ export class PaginatorComponent {
11
+ constructor(directionality, liveAnnouncer, translate) {
12
+ this.directionality = directionality;
13
+ this.liveAnnouncer = liveAnnouncer;
14
+ this.translate = translate;
15
+ this.currentPage = 1;
16
+ this.totalItems = 0;
17
+ this.pageSize = 10;
18
+ this.pageSizeOptions = [5, 10, 25, 50];
19
+ this.mobileLoadMoreIncrement = 2;
20
+ this.displayedItems = 0;
21
+ this.pageChange = new EventEmitter();
22
+ this.pageSizeChange = new EventEmitter();
23
+ this.loadMore = new EventEmitter();
24
+ this.currentDirection = 'ltr';
25
+ this.Math = Math;
26
+ }
27
+ ngOnInit() {
28
+ this.currentDirection = this.directionality.value;
29
+ this.directionality.change?.subscribe((value) => {
30
+ this.currentDirection = value;
31
+ });
32
+ if (!this.pageSizeOptions.includes(this.pageSize)) {
33
+ Promise.resolve().then(() => {
34
+ this.pageSize = this.pageSizeOptions[1];
35
+ this.pageSizeChange.emit(this.pageSize);
36
+ });
37
+ }
38
+ if (this.displayedItems === 0) {
39
+ this.displayedItems = this.pageSize;
40
+ }
41
+ }
42
+ ngOnChanges() {
43
+ if (this.currentPage > this.totalPages) {
44
+ this.currentPage = this.totalPages || 1;
45
+ }
46
+ if (this.displayedItems === 0 || (this.displayedItems === this.pageSize && this.currentPage > 1)) {
47
+ this.displayedItems = Math.min(this.currentPage * this.pageSize, this.totalItems);
48
+ }
49
+ }
50
+ get totalPages() {
51
+ return Math.ceil(this.totalItems / this.pageSize);
52
+ }
53
+ get startIndex() {
54
+ return this.totalItems === 0 ? 0 : (this.currentPage - 1) * this.pageSize + 1;
55
+ }
56
+ get endIndex() {
57
+ return Math.min(this.currentPage * this.pageSize, this.totalItems);
58
+ }
59
+ goToPage(page) {
60
+ if (page >= 1 && page <= this.totalPages) {
61
+ const previous = this.currentPage;
62
+ this.currentPage = page;
63
+ this.pageChange.emit(this.currentPage);
64
+ if (previous !== this.currentPage) {
65
+ queueMicrotask(() => this.announcePagination());
66
+ }
67
+ }
68
+ }
69
+ nextPage() {
70
+ if (this.currentPage < this.totalPages) {
71
+ this.goToPage(this.currentPage + 1);
72
+ }
73
+ }
74
+ previousPage() {
75
+ if (this.currentPage > 1) {
76
+ this.goToPage(this.currentPage - 1);
77
+ }
78
+ }
79
+ onPageSizeChange(size) {
80
+ this.pageSize = size;
81
+ this.currentPage = 1;
82
+ this.pageSizeChange.emit(this.pageSize);
83
+ this.pageChange.emit(this.currentPage);
84
+ queueMicrotask(() => this.announcePagination());
85
+ }
86
+ announcePagination() {
87
+ const message = this.translate.instant('BASE_TABLE.paginationStatus', {
88
+ current: this.currentPage,
89
+ total: this.totalPages,
90
+ start: this.startIndex,
91
+ end: this.endIndex,
92
+ items: this.totalItems,
93
+ });
94
+ void this.liveAnnouncer.announce(message, 'polite');
95
+ }
96
+ getPageNumbers() {
97
+ const TOTAL = this.totalPages;
98
+ const CURRENT = this.currentPage;
99
+ const PAGES = [];
100
+ if (TOTAL <= 7) {
101
+ for (let i = 1; i <= TOTAL; i++) {
102
+ PAGES.push(i);
103
+ }
104
+ }
105
+ else {
106
+ PAGES.push(1);
107
+ if (CURRENT <= 3) {
108
+ for (let i = 2; i <= 4; i++) {
109
+ PAGES.push(i);
110
+ }
111
+ PAGES.push('...');
112
+ PAGES.push(TOTAL - 1);
113
+ PAGES.push(TOTAL);
114
+ }
115
+ else if (CURRENT >= TOTAL - 2) {
116
+ PAGES.push(2);
117
+ PAGES.push('...');
118
+ for (let i = TOTAL - 3; i <= TOTAL; i++) {
119
+ PAGES.push(i);
120
+ }
121
+ }
122
+ else {
123
+ PAGES.push(2);
124
+ PAGES.push('...');
125
+ PAGES.push(CURRENT - 1);
126
+ PAGES.push(CURRENT);
127
+ PAGES.push(CURRENT + 1);
128
+ PAGES.push('...');
129
+ PAGES.push(TOTAL - 1);
130
+ PAGES.push(TOTAL);
131
+ }
132
+ }
133
+ return PAGES;
134
+ }
135
+ isEllipsis(page) {
136
+ return page === '...';
137
+ }
138
+ isActive(page) {
139
+ return typeof page === 'number' && page === this.currentPage;
140
+ }
141
+ onLoadMore() {
142
+ if (this.canLoadMore) {
143
+ this.loadMore.emit(this.mobileLoadMoreIncrement);
144
+ queueMicrotask(() => this.announcePagination());
145
+ }
146
+ }
147
+ get canLoadMore() {
148
+ return this.displayedItems < this.totalItems;
149
+ }
150
+ get currentPageNumber() {
151
+ return Math.ceil(this.displayedItems / this.mobileLoadMoreIncrement) || 1;
152
+ }
153
+ get totalPageNumbers() {
154
+ return Math.ceil(this.totalItems / this.mobileLoadMoreIncrement);
155
+ }
156
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PaginatorComponent, deps: [{ token: i1.Directionality }, { token: i2.LiveAnnouncer }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
157
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: PaginatorComponent, isStandalone: true, selector: "app-paginator", inputs: { currentPage: "currentPage", totalItems: "totalItems", pageSize: "pageSize", pageSizeOptions: "pageSizeOptions", mobileLoadMoreIncrement: "mobileLoadMoreIncrement", displayedItems: "displayedItems" }, outputs: { pageChange: "pageChange", pageSizeChange: "pageSizeChange", loadMore: "loadMore" }, usesOnChanges: true, ngImport: i0, template: "<!-- Desktop Pagination -->\r\n<div class=\"paginator-container paginator-desktop\" [dir]=\"currentDirection\" [class.rtl]=\"currentDirection === 'rtl'\">\r\n <button\r\n class=\"paginator-button paginator-nav-button\"\r\n [class.disabled]=\"currentPage === 1\"\r\n [disabled]=\"currentPage === 1\"\r\n (click)=\"previousPage()\"\r\n type=\"button\">\r\n <mat-icon class=\"paginator-icon paginator-icon-left\">chevron_left</mat-icon>\r\n </button>\r\n\r\n <ng-container *ngFor=\"let page of getPageNumbers()\">\r\n <button\r\n *ngIf=\"!isEllipsis(page)\"\r\n class=\"paginator-button paginator-page-button\"\r\n [class.active]=\"isActive(page)\"\r\n [disabled]=\"isActive(page)\"\r\n (click)=\"goToPage(+page)\"\r\n type=\"button\">\r\n <span class=\"paginator-page-number\">{{ page }}</span>\r\n </button>\r\n <div *ngIf=\"isEllipsis(page)\" class=\"paginator-button paginator-ellipsis\">\r\n <span class=\"paginator-ellipsis-text\">...</span>\r\n </div>\r\n </ng-container>\r\n\r\n <button\r\n class=\"paginator-button paginator-nav-button\"\r\n [class.disabled]=\"currentPage === totalPages\"\r\n [disabled]=\"currentPage === totalPages\"\r\n (click)=\"nextPage()\"\r\n type=\"button\">\r\n <mat-icon class=\"paginator-icon paginator-icon-right\">chevron_right</mat-icon>\r\n </button>\r\n</div>\r\n\r\n<!-- Mobile \"Load More\" Pagination -->\r\n<div class=\"paginator-mobile\">\r\n <button\r\n class=\"paginator-load-more-button\"\r\n [disabled]=\"!canLoadMore\"\r\n (click)=\"onLoadMore()\"\r\n type=\"button\">\r\n <span class=\"paginator-load-more-text\">Load More</span>\r\n </button>\r\n <p class=\"paginator-page-indicator\">{{ currentPageNumber }} of {{ totalPageNumbers }}</p>\r\n</div>", styles: [".paginator-container{display:flex;align-items:center;justify-content:flex-end;gap:8px;width:100%;margin-top:16px}.paginator-container.rtl .paginator-icon,.paginator-container[dir=rtl] .paginator-icon{transform:rotate(180deg)}.paginator-button{width:32px;height:32px;border-radius:8px;border:1px solid #f0eeee;background:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;box-sizing:border-box;transition:all .2s;font-family:Lusail,sans-serif;font-size:14px;line-height:1.2;color:#888;font-weight:300}.paginator-button:hover:not(.disabled):not(.active){background:#fafafa}.paginator-button.disabled{cursor:not-allowed;opacity:.5}.paginator-page-button{font-weight:300}.paginator-page-button.active{border-color:#0d4261;background:#fff;color:#0d4261;font-weight:500;cursor:default}.paginator-page-number{font-family:Lusail,sans-serif;font-size:14px;line-height:1.2;font-weight:inherit;color:inherit;height:14px}.paginator-ellipsis{border:1px solid #f0eeee;background:#fff;cursor:default;color:#888}.paginator-ellipsis-text{font-family:Lusail,sans-serif;font-size:14px;line-height:1.2;font-weight:300;color:#888}.paginator-nav-button{border:1px solid #f0eeee;background:#fff}.paginator-icon{font-size:16px;width:16px;height:16px;color:#000;display:flex;align-items:center;justify-content:center}.paginator-button.disabled .paginator-icon{opacity:.5}.paginator-mobile{display:none;flex-direction:column;align-items:center;justify-content:center;gap:8px;width:100%}.paginator-load-more-button{background:#fff;border:1px solid #f0eeee;border-radius:8px;height:39px;padding:8px 16px 4px;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;width:100%;max-width:100%;box-sizing:border-box;font-family:Lusail,sans-serif;font-weight:400;font-size:14px;line-height:1.2;color:#000;margin-top:12px}.paginator-load-more-button:hover:not(:disabled){background:#fafafa}.paginator-load-more-button:disabled{cursor:not-allowed;opacity:.5}.paginator-load-more-text{font-family:Lusail,sans-serif;font-weight:400;font-size:14px;line-height:1.2;color:#000;text-align:center}.paginator-page-indicator{font-family:Lusail,sans-serif;font-weight:300;font-size:14px;line-height:1.2;color:#888;text-align:center;margin:0;width:auto}@media (max-width: 768px){.paginator-desktop{display:none}.paginator-mobile{display:flex}}@media (min-width: 769px){.paginator-desktop{display:flex}.paginator-mobile{display:none}}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1.Dir, selector: "[dir]", inputs: ["dir"], outputs: ["dirChange"], exportAs: ["dir"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] }); }
158
+ }
159
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PaginatorComponent, decorators: [{
160
+ type: Component,
161
+ args: [{ selector: 'app-paginator', standalone: true, imports: [MatIconModule, MatButtonModule, NgIf, NgForOf], template: "<!-- Desktop Pagination -->\r\n<div class=\"paginator-container paginator-desktop\" [dir]=\"currentDirection\" [class.rtl]=\"currentDirection === 'rtl'\">\r\n <button\r\n class=\"paginator-button paginator-nav-button\"\r\n [class.disabled]=\"currentPage === 1\"\r\n [disabled]=\"currentPage === 1\"\r\n (click)=\"previousPage()\"\r\n type=\"button\">\r\n <mat-icon class=\"paginator-icon paginator-icon-left\">chevron_left</mat-icon>\r\n </button>\r\n\r\n <ng-container *ngFor=\"let page of getPageNumbers()\">\r\n <button\r\n *ngIf=\"!isEllipsis(page)\"\r\n class=\"paginator-button paginator-page-button\"\r\n [class.active]=\"isActive(page)\"\r\n [disabled]=\"isActive(page)\"\r\n (click)=\"goToPage(+page)\"\r\n type=\"button\">\r\n <span class=\"paginator-page-number\">{{ page }}</span>\r\n </button>\r\n <div *ngIf=\"isEllipsis(page)\" class=\"paginator-button paginator-ellipsis\">\r\n <span class=\"paginator-ellipsis-text\">...</span>\r\n </div>\r\n </ng-container>\r\n\r\n <button\r\n class=\"paginator-button paginator-nav-button\"\r\n [class.disabled]=\"currentPage === totalPages\"\r\n [disabled]=\"currentPage === totalPages\"\r\n (click)=\"nextPage()\"\r\n type=\"button\">\r\n <mat-icon class=\"paginator-icon paginator-icon-right\">chevron_right</mat-icon>\r\n </button>\r\n</div>\r\n\r\n<!-- Mobile \"Load More\" Pagination -->\r\n<div class=\"paginator-mobile\">\r\n <button\r\n class=\"paginator-load-more-button\"\r\n [disabled]=\"!canLoadMore\"\r\n (click)=\"onLoadMore()\"\r\n type=\"button\">\r\n <span class=\"paginator-load-more-text\">Load More</span>\r\n </button>\r\n <p class=\"paginator-page-indicator\">{{ currentPageNumber }} of {{ totalPageNumbers }}</p>\r\n</div>", styles: [".paginator-container{display:flex;align-items:center;justify-content:flex-end;gap:8px;width:100%;margin-top:16px}.paginator-container.rtl .paginator-icon,.paginator-container[dir=rtl] .paginator-icon{transform:rotate(180deg)}.paginator-button{width:32px;height:32px;border-radius:8px;border:1px solid #f0eeee;background:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;box-sizing:border-box;transition:all .2s;font-family:Lusail,sans-serif;font-size:14px;line-height:1.2;color:#888;font-weight:300}.paginator-button:hover:not(.disabled):not(.active){background:#fafafa}.paginator-button.disabled{cursor:not-allowed;opacity:.5}.paginator-page-button{font-weight:300}.paginator-page-button.active{border-color:#0d4261;background:#fff;color:#0d4261;font-weight:500;cursor:default}.paginator-page-number{font-family:Lusail,sans-serif;font-size:14px;line-height:1.2;font-weight:inherit;color:inherit;height:14px}.paginator-ellipsis{border:1px solid #f0eeee;background:#fff;cursor:default;color:#888}.paginator-ellipsis-text{font-family:Lusail,sans-serif;font-size:14px;line-height:1.2;font-weight:300;color:#888}.paginator-nav-button{border:1px solid #f0eeee;background:#fff}.paginator-icon{font-size:16px;width:16px;height:16px;color:#000;display:flex;align-items:center;justify-content:center}.paginator-button.disabled .paginator-icon{opacity:.5}.paginator-mobile{display:none;flex-direction:column;align-items:center;justify-content:center;gap:8px;width:100%}.paginator-load-more-button{background:#fff;border:1px solid #f0eeee;border-radius:8px;height:39px;padding:8px 16px 4px;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;width:100%;max-width:100%;box-sizing:border-box;font-family:Lusail,sans-serif;font-weight:400;font-size:14px;line-height:1.2;color:#000;margin-top:12px}.paginator-load-more-button:hover:not(:disabled){background:#fafafa}.paginator-load-more-button:disabled{cursor:not-allowed;opacity:.5}.paginator-load-more-text{font-family:Lusail,sans-serif;font-weight:400;font-size:14px;line-height:1.2;color:#000;text-align:center}.paginator-page-indicator{font-family:Lusail,sans-serif;font-weight:300;font-size:14px;line-height:1.2;color:#888;text-align:center;margin:0;width:auto}@media (max-width: 768px){.paginator-desktop{display:none}.paginator-mobile{display:flex}}@media (min-width: 769px){.paginator-desktop{display:flex}.paginator-mobile{display:none}}\n"] }]
162
+ }], ctorParameters: () => [{ type: i1.Directionality }, { type: i2.LiveAnnouncer }, { type: i3.TranslateService }], propDecorators: { currentPage: [{
163
+ type: Input
164
+ }], totalItems: [{
165
+ type: Input
166
+ }], pageSize: [{
167
+ type: Input
168
+ }], pageSizeOptions: [{
169
+ type: Input
170
+ }], mobileLoadMoreIncrement: [{
171
+ type: Input
172
+ }], displayedItems: [{
173
+ type: Input
174
+ }], pageChange: [{
175
+ type: Output
176
+ }], pageSizeChange: [{
177
+ type: Output
178
+ }], loadMore: [{
179
+ type: Output
180
+ }] } });
181
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnaW5hdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2ludm9pY2VxL3VpLWxpYi9zcmMvbGliL2NvbXBvbmVudHMvcGFnaW5hdG9yL3BhZ2luYXRvci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9pbnZvaWNlcS91aS1saWIvc3JjL2xpYi9jb21wb25lbnRzL3BhZ2luYXRvci9wYWdpbmF0b3IuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFDMUYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDOzs7Ozs7QUFZaEQsTUFBTSxPQUFPLGtCQUFrQjtJQWM3QixZQUNVLGNBQThCLEVBQ3JCLGFBQTRCLEVBQzVCLFNBQTJCO1FBRnBDLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUNyQixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUM1QixjQUFTLEdBQVQsU0FBUyxDQUFrQjtRQWhCckMsZ0JBQVcsR0FBRyxDQUFDLENBQUM7UUFDaEIsZUFBVSxHQUFHLENBQUMsQ0FBQztRQUNmLGFBQVEsR0FBRyxFQUFFLENBQUM7UUFDZCxvQkFBZSxHQUFhLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDNUMsNEJBQXVCLEdBQUcsQ0FBQyxDQUFDO1FBQzVCLG1CQUFjLEdBQUcsQ0FBQyxDQUFDO1FBRWxCLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBQ3hD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TyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDL0MsQ0FBQztJQUVELElBQUksaUJBQWlCO1FBQ25CLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1RSxDQUFDO0lBRUQsSUFBSSxnQkFBZ0I7UUFDbEIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDbkUsQ0FBQzsrR0FwS1Usa0JBQWtCO21HQUFsQixrQkFBa0IsK1lDZi9CLHF4REE4Q00saTlFRGpDTSxhQUFhLHVTQUFFLGVBQWUsK0JBQUUsSUFBSSw2RkFBRSxPQUFPOzs0RkFFNUMsa0JBQWtCO2tCQVA5QixTQUFTOytCQUNFLGVBQWUsY0FHYixJQUFJLFdBQ1AsQ0FBQyxhQUFhLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUM7OElBRy9DLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csdUJBQXVCO3NCQUEvQixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBRUksVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxjQUFjO3NCQUF2QixNQUFNO2dCQUNHLFFBQVE7c0JBQWpCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgT25Jbml0LCBPbkNoYW5nZXMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTWF0SWNvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2ljb24nO1xyXG5pbXBvcnQgeyBNYXRCdXR0b25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xyXG5pbXBvcnQgeyBOZ0lmLCBOZ0Zvck9mIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgRGlyZWN0aW9uYWxpdHkgfSBmcm9tICdAYW5ndWxhci9jZGsvYmlkaSc7XHJcbmltcG9ydCB7IExpdmVBbm5vdW5jZXIgfSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XHJcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnYXBwLXBhZ2luYXRvcicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3BhZ2luYXRvci5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vcGFnaW5hdG9yLmNvbXBvbmVudC5jc3MnXSxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtNYXRJY29uTW9kdWxlLCBNYXRCdXR0b25Nb2R1bGUsIE5nSWYsIE5nRm9yT2ZdLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgUGFnaW5hdG9yQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xyXG4gIEBJbnB1dCgpIGN1cnJlbnRQYWdlID0gMTtcclxuICBASW5wdXQoKSB0b3RhbEl0ZW1zID0gMDtcclxuICBASW5wdXQoKSBwYWdlU2l6ZSA9IDEwO1xyXG4gIEBJbnB1dCgpIHBhZ2VTaXplT3B0aW9uczogbnVtYmVyW10gPSBbNSwgMTAsIDI1LCA1MF07XHJcbiAgQElucHV0KCkgbW9iaWxlTG9hZE1vcmVJbmNyZW1lbnQgPSAyO1xyXG4gIEBJbnB1dCgpIGRpc3BsYXllZEl0ZW1zID0gMDtcclxuXHJcbiAgQE91dHB1dCgpIHBhZ2VDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcclxuICBAT3V0cHV0KCkgcGFnZVNpemVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcclxuICBAT3V0cHV0KCkgbG9hZE1vcmUgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcclxuXHJcbiAgY3VycmVudERpcmVjdGlvbjogJ2x0cicgfCAncnRsJyA9ICdsdHInO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgZGlyZWN0aW9uYWxpdHk6IERpcmVjdGlvbmFsaXR5LFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBsaXZlQW5ub3VuY2VyOiBMaXZlQW5ub3VuY2VyLFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2UsXHJcbiAgKSB7fVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIHRoaXMuY3VycmVudERpcmVjdGlvbiA9IHRoaXMuZGlyZWN0aW9uYWxpdHkudmFsdWU7XHJcbiAgICB0aGlzLmRpcmVjdGlvbmFsaXR5LmNoYW5nZT8uc3Vic2NyaWJlKCh2YWx1ZSkgPT4ge1xyXG4gICAgICB0aGlzLmN1cnJlbnREaXJlY3Rpb24gPSB2YWx1ZTtcclxuICAgIH0pO1xyXG4gICAgaWYgKCF0aGlzLnBhZ2VTaXplT3B0aW9ucy5pbmNsdWRlcyh0aGlzLnBhZ2VTaXplKSkge1xyXG4gICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcclxuICAgICAgICB0aGlzLnBhZ2VTaXplID0gdGhpcy5wYWdlU2l6ZU9wdGlvbnNbMV07XHJcbiAgICAgICAgdGhpcy5wYWdlU2l6ZUNoYW5nZS5lbWl0KHRoaXMucGFnZVNpemUpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmRpc3BsYXllZEl0ZW1zID09PSAwKSB7XHJcbiAgICAgIHRoaXMuZGlzcGxheWVkSXRlbXMgPSB0aGlzLnBhZ2VTaXplO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoKSB7XHJcbiAgICBpZiAodGhpcy5jdXJyZW50UGFnZSA+IHRoaXMudG90YWxQYWdlcykge1xyXG4gICAgICB0aGlzLmN1cnJlbnRQYWdlID0gdGhpcy50b3RhbFBhZ2VzIHx8IDE7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5kaXNwbGF5ZWRJdGVtcyA9PT0gMCB8fCAodGhpcy5kaXNwbGF5ZWRJdGVtcyA9PT0gdGhpcy5wYWdlU2l6ZSAmJiB0aGlzLmN1cnJlbnRQYWdlID4gMSkpIHtcclxuICAgICAgdGhpcy5kaXNwbGF5ZWRJdGVtcyA9IE1hdGgubWluKHRoaXMuY3VycmVudFBhZ2UgKiB0aGlzLnBhZ2VTaXplLCB0aGlzLnRvdGFsSXRlbXMpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0IHRvdGFsUGFnZXMoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiBNYXRoLmNlaWwodGhpcy50b3RhbEl0ZW1zIC8gdGhpcy5wYWdlU2l6ZSk7XHJcbiAgfVxyXG5cclxuICBnZXQgc3RhcnRJbmRleCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMudG90YWxJdGVtcyA9PT0gMCA/IDAgOiAodGhpcy5jdXJyZW50UGFnZSAtIDEpICogdGhpcy5wYWdlU2l6ZSArIDE7XHJcbiAgfVxyXG5cclxuICBnZXQgZW5kSW5kZXgoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiBNYXRoLm1pbih0aGlzLmN1cnJlbnRQYWdlICogdGhpcy5wYWdlU2l6ZSwgdGhpcy50b3RhbEl0ZW1zKTtcclxuICB9XHJcblxyXG4gIGdvVG9QYWdlKHBhZ2U6IG51bWJlcikge1xyXG4gICAgaWYgKHBhZ2UgPj0gMSAmJiBwYWdlIDw9IHRoaXMudG90YWxQYWdlcykge1xyXG4gICAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMuY3VycmVudFBhZ2U7XHJcbiAgICAgIHRoaXMuY3VycmVudFBhZ2UgPSBwYWdlO1xyXG4gICAgICB0aGlzLnBhZ2VDaGFuZ2UuZW1pdCh0aGlzLmN1cnJlbnRQYWdlKTtcclxuICAgICAgaWYgKHByZXZpb3VzICE9PSB0aGlzLmN1cnJlbnRQYWdlKSB7XHJcbiAgICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4gdGhpcy5hbm5vdW5jZVBhZ2luYXRpb24oKSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIG5leHRQYWdlKCkge1xyXG4gICAgaWYgKHRoaXMuY3VycmVudFBhZ2UgPCB0aGlzLnRvdGFsUGFnZXMpIHtcclxuICAgICAgdGhpcy5nb1RvUGFnZSh0aGlzLmN1cnJlbnRQYWdlICsgMSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcmV2aW91c1BhZ2UoKSB7XHJcbiAgICBpZiAodGhpcy5jdXJyZW50UGFnZSA+IDEpIHtcclxuICAgICAgdGhpcy5nb1RvUGFnZSh0aGlzLmN1cnJlbnRQYWdlIC0gMSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvblBhZ2VTaXplQ2hhbmdlKHNpemU6IG51bWJlcikge1xyXG4gICAgdGhpcy5wYWdlU2l6ZSA9IHNpemU7XHJcbiAgICB0aGlzLmN1cnJlbnRQYWdlID0gMTtcclxuICAgIHRoaXMucGFnZVNpemVDaGFuZ2UuZW1pdCh0aGlzLnBhZ2VTaXplKTtcclxuICAgIHRoaXMucGFnZUNoYW5nZS5lbWl0KHRoaXMuY3VycmVudFBhZ2UpO1xyXG4gICAgcXVldWVNaWNyb3Rhc2soKCkgPT4gdGhpcy5hbm5vdW5jZVBhZ2luYXRpb24oKSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFubm91bmNlUGFnaW5hdGlvbigpOiB2b2lkIHtcclxuICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdCQVNFX1RBQkxFLnBhZ2luYXRpb25TdGF0dXMnLCB7XHJcbiAgICAgIGN1cnJlbnQ6IHRoaXMuY3VycmVudFBhZ2UsXHJcbiAgICAgIHRvdGFsOiB0aGlzLnRvdGFsUGFnZXMsXHJcbiAgICAgIHN0YXJ0OiB0aGlzLnN0YXJ0SW5kZXgsXHJcbiAgICAgIGVuZDogdGhpcy5lbmRJbmRleCxcclxuICAgICAgaXRlbXM6IHRoaXMudG90YWxJdGVtcyxcclxuICAgIH0pO1xyXG4gICAgdm9pZCB0aGlzLmxpdmVBbm5vdW5jZXIuYW5ub3VuY2UobWVzc2FnZSwgJ3BvbGl0ZScpO1xyXG4gIH1cclxuXHJcbiAgZ2V0UGFnZU51bWJlcnMoKTogKG51bWJlciB8IHN0cmluZylbXSB7XHJcbiAgICBjb25zdCBUT1RBTCA9IHRoaXMudG90YWxQYWdlcztcclxuICAgIGNvbnN0IENVUlJFTlQgPSB0aGlzLmN1cnJlbnRQYWdlO1xyXG4gICAgY29uc3QgUEFHRVM6IChudW1iZXIgfCBzdHJpbmcpW10gPSBbXTtcclxuXHJcbiAgICBpZiAoVE9UQUwgPD0gNykge1xyXG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8PSBUT1RBTDsgaSsrKSB7XHJcbiAgICAgICAgUEFHRVMucHVzaChpKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgUEFHRVMucHVzaCgxKTtcclxuXHJcbiAgICAgIGlmIChDVVJSRU5UIDw9IDMpIHtcclxuICAgICAgICBmb3IgKGxldCBpID0gMjsgaSA8PSA0OyBpKyspIHtcclxuICAgICAgICAgIFBBR0VTLnB1c2goaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFBBR0VTLnB1c2goJy4uLicpO1xyXG4gICAgICAgIFBBR0VTLnB1c2goVE9UQUwgLSAxKTtcclxuICAgICAgICBQQUdFUy5wdXNoKFRPVEFMKTtcclxuICAgICAgfSBlbHNlIGlmIChDVVJSRU5UID49IFRPVEFMIC0gMikge1xyXG4gICAgICAgIFBBR0VTLnB1c2goMik7XHJcbiAgICAgICAgUEFHRVMucHVzaCgnLi4uJyk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IFRPVEFMIC0gMzsgaSA8PSBUT1RBTDsgaSsrKSB7XHJcbiAgICAgICAgICBQQUdFUy5wdXNoKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBQQUdFUy5wdXNoKDIpO1xyXG4gICAgICAgIFBBR0VTLnB1c2goJy4uLicpO1xyXG4gICAgICAgIFBBR0VTLnB1c2goQ1VSUkVOVCAtIDEpO1xyXG4gICAgICAgIFBBR0VTLnB1c2goQ1VSUkVOVCk7XHJcbiAgICAgICAgUEFHRVMucHVzaChDVVJSRU5UICsgMSk7XHJcbiAgICAgICAgUEFHRVMucHVzaCgnLi4uJyk7XHJcbiAgICAgICAgUEFHRVMucHVzaChUT1RBTCAtIDEpO1xyXG4gICAgICAgIFBBR0VTLnB1c2goVE9UQUwpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIFBBR0VTO1xyXG4gIH1cclxuXHJcbiAgaXNFbGxpcHNpcyhwYWdlOiBudW1iZXIgfCBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIHJldHVybiBwYWdlID09PSAnLi4uJztcclxuICB9XHJcblxyXG4gIGlzQWN0aXZlKHBhZ2U6IG51bWJlciB8IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHR5cGVvZiBwYWdlID09PSAnbnVtYmVyJyAmJiBwYWdlID09PSB0aGlzLmN1cnJlbnRQYWdlO1xyXG4gIH1cclxuXHJcbiAgb25Mb2FkTW9yZSgpIHtcclxuICAgIGlmICh0aGlzLmNhbkxvYWRNb3JlKSB7XHJcbiAgICAgIHRoaXMubG9hZE1vcmUuZW1pdCh0aGlzLm1vYmlsZUxvYWRNb3JlSW5jcmVtZW50KTtcclxuICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4gdGhpcy5hbm5vdW5jZVBhZ2luYXRpb24oKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgY2FuTG9hZE1vcmUoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5kaXNwbGF5ZWRJdGVtcyA8IHRoaXMudG90YWxJdGVtcztcclxuICB9XHJcblxyXG4gIGdldCBjdXJyZW50UGFnZU51bWJlcigpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIE1hdGguY2VpbCh0aGlzLmRpc3BsYXllZEl0ZW1zIC8gdGhpcy5tb2JpbGVMb2FkTW9yZUluY3JlbWVudCkgfHwgMTtcclxuICB9XHJcblxyXG4gIGdldCB0b3RhbFBhZ2VOdW1iZXJzKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gTWF0aC5jZWlsKHRoaXMudG90YWxJdGVtcyAvIHRoaXMubW9iaWxlTG9hZE1vcmVJbmNyZW1lbnQpO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IE1hdGggPSBNYXRoO1xyXG59XHJcbiIsIjwhLS0gRGVza3RvcCBQYWdpbmF0aW9uIC0tPlxyXG48ZGl2IGNsYXNzPVwicGFnaW5hdG9yLWNvbnRhaW5lciBwYWdpbmF0b3ItZGVza3RvcFwiIFtkaXJdPVwiY3VycmVudERpcmVjdGlvblwiIFtjbGFzcy5ydGxdPVwiY3VycmVudERpcmVjdGlvbiA9PT0gJ3J0bCdcIj5cclxuICA8YnV0dG9uXHJcbiAgICBjbGFzcz1cInBhZ2luYXRvci1idXR0b24gcGFnaW5hdG9yLW5hdi1idXR0b25cIlxyXG4gICAgW2NsYXNzLmRpc2FibGVkXT1cImN1cnJlbnRQYWdlID09PSAxXCJcclxuICAgIFtkaXNhYmxlZF09XCJjdXJyZW50UGFnZSA9PT0gMVwiXHJcbiAgICAoY2xpY2spPVwicHJldmlvdXNQYWdlKClcIlxyXG4gICAgdHlwZT1cImJ1dHRvblwiPlxyXG4gICAgPG1hdC1pY29uIGNsYXNzPVwicGFnaW5hdG9yLWljb24gcGFnaW5hdG9yLWljb24tbGVmdFwiPmNoZXZyb25fbGVmdDwvbWF0LWljb24+XHJcbiAgPC9idXR0b24+XHJcblxyXG4gIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHBhZ2Ugb2YgZ2V0UGFnZU51bWJlcnMoKVwiPlxyXG4gICAgPGJ1dHRvblxyXG4gICAgICAqbmdJZj1cIiFpc0VsbGlwc2lzKHBhZ2UpXCJcclxuICAgICAgY2xhc3M9XCJwYWdpbmF0b3ItYnV0dG9uIHBhZ2luYXRvci1wYWdlLWJ1dHRvblwiXHJcbiAgICAgIFtjbGFzcy5hY3RpdmVdPVwiaXNBY3RpdmUocGFnZSlcIlxyXG4gICAgICBbZGlzYWJsZWRdPVwiaXNBY3RpdmUocGFnZSlcIlxyXG4gICAgICAoY2xpY2spPVwiZ29Ub1BhZ2UoK3BhZ2UpXCJcclxuICAgICAgdHlwZT1cImJ1dHRvblwiPlxyXG4gICAgICA8c3BhbiBjbGFzcz1cInBhZ2luYXRvci1wYWdlLW51bWJlclwiPnt7IHBhZ2UgfX08L3NwYW4+XHJcbiAgICA8L2J1dHRvbj5cclxuICAgIDxkaXYgKm5nSWY9XCJpc0VsbGlwc2lzKHBhZ2UpXCIgY2xhc3M9XCJwYWdpbmF0b3ItYnV0dG9uIHBhZ2luYXRvci1lbGxpcHNpc1wiPlxyXG4gICAgICA8c3BhbiBjbGFzcz1cInBhZ2luYXRvci1lbGxpcHNpcy10ZXh0XCI+Li4uPC9zcGFuPlxyXG4gICAgPC9kaXY+XHJcbiAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gIDxidXR0b25cclxuICAgIGNsYXNzPVwicGFnaW5hdG9yLWJ1dHRvbiBwYWdpbmF0b3ItbmF2LWJ1dHRvblwiXHJcbiAgICBbY2xhc3MuZGlzYWJsZWRdPVwiY3VycmVudFBhZ2UgPT09IHRvdGFsUGFnZXNcIlxyXG4gICAgW2Rpc2FibGVkXT1cImN1cnJlbnRQYWdlID09PSB0b3RhbFBhZ2VzXCJcclxuICAgIChjbGljayk9XCJuZXh0UGFnZSgpXCJcclxuICAgIHR5cGU9XCJidXR0b25cIj5cclxuICAgIDxtYXQtaWNvbiBjbGFzcz1cInBhZ2luYXRvci1pY29uIHBhZ2luYXRvci1pY29uLXJpZ2h0XCI+Y2hldnJvbl9yaWdodDwvbWF0LWljb24+XHJcbiAgPC9idXR0b24+XHJcbjwvZGl2PlxyXG5cclxuPCEtLSBNb2JpbGUgXCJMb2FkIE1vcmVcIiBQYWdpbmF0aW9uIC0tPlxyXG48ZGl2IGNsYXNzPVwicGFnaW5hdG9yLW1vYmlsZVwiPlxyXG4gIDxidXR0b25cclxuICAgIGNsYXNzPVwicGFnaW5hdG9yLWxvYWQtbW9yZS1idXR0b25cIlxyXG4gICAgW2Rpc2FibGVkXT1cIiFjYW5Mb2FkTW9yZVwiXHJcbiAgICAoY2xpY2spPVwib25Mb2FkTW9yZSgpXCJcclxuICAgIHR5cGU9XCJidXR0b25cIj5cclxuICAgIDxzcGFuIGNsYXNzPVwicGFnaW5hdG9yLWxvYWQtbW9yZS10ZXh0XCI+TG9hZCBNb3JlPC9zcGFuPlxyXG4gIDwvYnV0dG9uPlxyXG4gIDxwIGNsYXNzPVwicGFnaW5hdG9yLXBhZ2UtaW5kaWNhdG9yXCI+e3sgY3VycmVudFBhZ2VOdW1iZXIgfX0gb2Yge3sgdG90YWxQYWdlTnVtYmVycyB9fTwvcD5cclxuPC9kaXY+Il19