ngx-register-base 1.2.3 → 1.3.1

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 (479) hide show
  1. package/ng-package.json +15 -0
  2. package/package.json +12 -15
  3. package/schematics/ng-update/replace-menu-state-token/index.ts +33 -0
  4. package/schematics/ng-update/update-prefix/index.ts +38 -0
  5. package/schematics/utils/{utils.d.ts → utils.ts} +9 -2
  6. package/src/lib/components/checkbox-selector/checkbox-selector.component.html +91 -0
  7. package/src/lib/components/checkbox-selector/checkbox-selector.component.less +67 -0
  8. package/src/lib/components/checkbox-selector/checkbox-selector.component.ts +176 -0
  9. package/src/lib/components/checkbox-selector/checkbox-selector.types.ts +8 -0
  10. package/src/lib/components/column-settings/column-settings.component.html +160 -0
  11. package/src/lib/components/column-settings/column-settings.component.less +131 -0
  12. package/src/lib/components/column-settings/column-settings.component.ts +352 -0
  13. package/src/lib/components/column-settings/components/column-settings-template/column-settings-template.component.html +65 -0
  14. package/src/lib/components/column-settings/components/column-settings-template/column-settings-template.component.less +79 -0
  15. package/src/lib/components/column-settings/components/column-settings-template/column-settings-template.component.ts +114 -0
  16. package/src/lib/components/column-settings/consts/column-settings.consts.ts +9 -0
  17. package/src/lib/components/column-settings/types/column-settings.types.ts +26 -0
  18. package/src/lib/components/divider/divider.component.html +4 -0
  19. package/src/lib/components/divider/divider.component.less +10 -0
  20. package/src/lib/components/divider/divider.component.ts +12 -0
  21. package/src/lib/components/filter-button/filter-button.component.html +20 -0
  22. package/src/lib/components/filter-button/filter-button.component.less +41 -0
  23. package/src/lib/components/filter-button/filter-button.component.ts +18 -0
  24. package/src/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.html +22 -0
  25. package/src/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.less +23 -0
  26. package/src/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.ts +31 -0
  27. package/src/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.html +49 -0
  28. package/src/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.less +37 -0
  29. package/src/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.ts +66 -0
  30. package/src/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.html +147 -0
  31. package/src/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.less +45 -0
  32. package/src/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.ts +114 -0
  33. package/src/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.html +44 -0
  34. package/src/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.less +49 -0
  35. package/src/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.ts +167 -0
  36. package/src/lib/components/filters/components/filter-list/filter-list.service.ts +97 -0
  37. package/src/lib/components/filters/components/filter-list/filters-section/filters-section.component.html +18 -0
  38. package/src/lib/components/filters/components/filter-list/filters-section/filters-section.component.less +55 -0
  39. package/src/lib/components/filters/components/filter-list/filters-section/filters-section.component.ts +69 -0
  40. package/src/lib/components/filters/components/filter-list.module.ts +29 -0
  41. package/src/lib/components/filters/register-table-filter.component.html +53 -0
  42. package/src/lib/components/filters/register-table-filter.component.less +17 -0
  43. package/src/lib/components/filters/register-table-filter.component.ts +167 -0
  44. package/src/lib/components/filters/register-table-filter.module.ts +22 -0
  45. package/src/lib/components/inputs/inputs.module.ts +104 -0
  46. package/src/lib/components/inputs/param-calendar-year/param-calendar-year.component.html +49 -0
  47. package/src/lib/components/inputs/param-calendar-year/param-calendar-year.component.less +70 -0
  48. package/src/lib/components/inputs/param-calendar-year/param-calendar-year.component.ts +52 -0
  49. package/src/lib/components/inputs/param-custom/param-custom.component.html +1 -0
  50. package/src/lib/components/inputs/param-custom/param-custom.component.ts +9 -0
  51. package/src/lib/components/inputs/param-date/param-date.component.html +55 -0
  52. package/src/lib/components/inputs/param-date/param-date.component.less +67 -0
  53. package/src/lib/components/inputs/param-date/param-date.component.ts +77 -0
  54. package/src/lib/components/inputs/param-date-range/param-date-range.component.html +45 -0
  55. package/src/lib/components/inputs/param-date-range/param-date-range.component.less +75 -0
  56. package/src/lib/components/inputs/param-date-range/param-date-range.component.ts +67 -0
  57. package/src/lib/components/inputs/param-date-time/param-date-time.component.html +70 -0
  58. package/src/lib/components/inputs/param-date-time/param-date-time.component.less +72 -0
  59. package/src/lib/components/inputs/param-date-time/param-date-time.component.ts +101 -0
  60. package/src/lib/components/inputs/param-date-time-range/param-date-time-range.component.html +67 -0
  61. package/src/lib/components/inputs/param-date-time-range/param-date-time-range.component.less +103 -0
  62. package/src/lib/components/inputs/param-date-time-range/param-date-time-range.component.ts +128 -0
  63. package/src/lib/components/inputs/param-month/param-month.component.html +46 -0
  64. package/src/lib/components/inputs/param-month/param-month.component.less +72 -0
  65. package/src/lib/components/inputs/param-month/param-month.component.ts +55 -0
  66. package/src/lib/components/inputs/param-month-range/param-month-range.component.html +39 -0
  67. package/src/lib/components/inputs/param-month-range/param-month-range.component.less +71 -0
  68. package/src/lib/components/inputs/param-month-range/param-month-range.component.ts +76 -0
  69. package/src/lib/components/inputs/param-multi-select/param-multi-select.component.html +84 -0
  70. package/src/lib/components/inputs/param-multi-select/param-multi-select.component.less +108 -0
  71. package/src/lib/components/inputs/param-multi-select/param-multi-select.component.ts +448 -0
  72. package/src/lib/components/inputs/param-select/param-select.component.html +106 -0
  73. package/src/lib/components/inputs/param-select/param-select.component.less +26 -0
  74. package/src/lib/components/inputs/param-select/param-select.component.ts +318 -0
  75. package/src/lib/components/inputs/param-switcher/param-switcher.component.html +8 -0
  76. package/src/lib/components/inputs/param-switcher/param-switcher.component.less +53 -0
  77. package/src/lib/components/inputs/param-switcher/param-switcher.component.ts +13 -0
  78. package/src/lib/components/inputs/param-switcher-date-time-range/consts/param-switcher-date-time-range.consts.ts +29 -0
  79. package/src/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.html +19 -0
  80. package/src/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.less +76 -0
  81. package/src/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.ts +134 -0
  82. package/src/lib/components/inputs/param-switcher-date-time-range/types/param-switcher-date-time-range.types.ts +8 -0
  83. package/src/lib/components/inputs/param-text/param-text.component.html +59 -0
  84. package/src/lib/components/inputs/param-text/param-text.component.less +33 -0
  85. package/src/lib/components/inputs/param-text/param-text.component.ts +36 -0
  86. package/src/lib/components/inputs/param-textarea/param-textarea.component.html +61 -0
  87. package/src/lib/components/inputs/param-textarea/param-textarea.component.less +21 -0
  88. package/src/lib/components/inputs/param-textarea/param-textarea.component.ts +33 -0
  89. package/src/lib/components/inputs/param-toggle/param-toggle.component.html +40 -0
  90. package/src/lib/components/inputs/param-toggle/param-toggle.component.less +69 -0
  91. package/src/lib/components/inputs/param-toggle/param-toggle.component.ts +14 -0
  92. package/src/lib/components/inputs/param-tree/consts/param-tree.consts.ts +59 -0
  93. package/src/lib/components/inputs/param-tree/param-tree.component.html +51 -0
  94. package/src/lib/components/inputs/param-tree/param-tree.component.less +3 -0
  95. package/src/lib/components/inputs/param-tree/param-tree.component.ts +282 -0
  96. package/src/lib/components/inputs/param-tree/services/param-tree.service.ts +176 -0
  97. package/src/lib/components/inputs/param-tree/services/sync-tree-loader.service.ts +18 -0
  98. package/{lib/components/inputs/param-tree/tokens/param-tree.tokens.d.ts → src/lib/components/inputs/param-tree/tokens/param-tree.tokens.ts} +2 -1
  99. package/src/lib/components/inputs/param-tree/types/param-tree.types.ts +39 -0
  100. package/src/lib/components/inputs/param-tree/utils/param-tree.utils.ts +18 -0
  101. package/src/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.html +78 -0
  102. package/src/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.less +109 -0
  103. package/src/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.ts +89 -0
  104. package/src/lib/components/inputs/param-tree-select/param-tree-select.component.html +54 -0
  105. package/src/lib/components/inputs/param-tree-select/param-tree-select.component.less +56 -0
  106. package/src/lib/components/inputs/param-tree-select/param-tree-select.component.ts +91 -0
  107. package/src/lib/components/inputs/sub-components/param-delete-content-icon/param-delete-content-btn.component.html +5 -0
  108. package/src/lib/components/inputs/sub-components/param-delete-content-icon/param-delete-content-btn.component.ts +13 -0
  109. package/src/lib/components/inputs/sub-components/param-invalid-icon/param-invalid-icon.component.html +4 -0
  110. package/src/lib/components/inputs/sub-components/param-invalid-icon/param-invalid-icon.component.ts +11 -0
  111. package/src/lib/components/menu-constructor/sproc-menu-constructor.component.html +95 -0
  112. package/src/lib/components/menu-constructor/sproc-menu-constructor.component.less +183 -0
  113. package/src/lib/components/menu-constructor/sproc-menu-constructor.component.ts +687 -0
  114. package/src/lib/components/menu-constructor/store/sproc-abstract-menu-constructor.store.ts +32 -0
  115. package/src/lib/components/menu-constructor/store/sproc-menu-constructor.consts.ts +46 -0
  116. package/{lib/components/menu-constructor/store/sproc-menu.tokens.d.ts → src/lib/components/menu-constructor/store/sproc-menu.tokens.ts} +4 -1
  117. package/src/lib/components/page-menu/README.md +60 -0
  118. package/src/lib/components/page-menu/schema/sproc-page-menu.consts.ts +8 -0
  119. package/src/lib/components/page-menu/schema/sproc-page-menu.schema.ts +35 -0
  120. package/src/lib/components/page-menu/schema/sproc-page-menu.tokens.ts +5 -0
  121. package/src/lib/components/page-menu/schema/sproc-page-menu.types.ts +42 -0
  122. package/src/lib/components/page-menu/sproc-page-menu.component.html +166 -0
  123. package/src/lib/components/page-menu/sproc-page-menu.component.less +228 -0
  124. package/src/lib/components/page-menu/sproc-page-menu.component.ts +337 -0
  125. package/src/lib/components/paginator/paginator.component.html +97 -0
  126. package/src/lib/components/paginator/paginator.component.less +101 -0
  127. package/src/lib/components/paginator/paginator.component.ts +192 -0
  128. package/src/lib/components/paginator/types/paginator.types.ts +16 -0
  129. package/src/lib/components/register-table/consts/register-table.consts.ts +3 -0
  130. package/src/lib/components/register-table/directives/cell-template.directive.ts +11 -0
  131. package/src/lib/components/register-table/directives/header-template.directive.ts +11 -0
  132. package/src/lib/components/register-table/model/schema.ts +62 -0
  133. package/src/lib/components/register-table/pipes/class-by-type.pipe.ts +28 -0
  134. package/src/lib/components/register-table/pipes/sticky-column.pipe.ts +11 -0
  135. package/src/lib/components/register-table/register-table.component.html +257 -0
  136. package/src/lib/components/register-table/register-table.component.less +151 -0
  137. package/src/lib/components/register-table/register-table.component.ts +743 -0
  138. package/src/lib/components/reset-settings-form/reset-settings-form.component.html +14 -0
  139. package/src/lib/components/reset-settings-form/reset-settings-form.component.less +26 -0
  140. package/src/lib/components/reset-settings-form/reset-settings-form.component.ts +15 -0
  141. package/src/lib/components/search-input/search-input.component.html +6 -0
  142. package/src/lib/components/search-input/search-input.component.less +17 -0
  143. package/src/lib/components/search-input/search-input.component.ts +31 -0
  144. package/src/lib/components/sliding-panel/sliding-panel.component.html +13 -0
  145. package/src/lib/components/sliding-panel/sliding-panel.component.less +112 -0
  146. package/src/lib/components/sliding-panel/sliding-panel.component.ts +36 -0
  147. package/src/lib/components/sliding-panel/sliding-panel.module.ts +11 -0
  148. package/src/lib/consts/date-time.consts.ts +1 -0
  149. package/src/lib/consts/index.ts +8 -0
  150. package/src/lib/consts/inputs.consts.ts +9 -0
  151. package/src/lib/consts/month.consts.ts +82 -0
  152. package/src/lib/consts/params.consts.ts +1 -0
  153. package/src/lib/consts/register-base.consts.ts +40 -0
  154. package/src/lib/core/form-group-wrapper/errors-consts.ts +6 -0
  155. package/src/lib/core/form-group-wrapper/form-group-wrapper.ts +109 -0
  156. package/src/lib/core/input-control/input-control.ts +30 -0
  157. package/src/lib/core/param/param-base.ts +262 -0
  158. package/src/lib/core/param/param-date-base.ts +30 -0
  159. package/src/lib/core/param/param-select-base.ts +118 -0
  160. package/src/lib/core/param/param-text-base.ts +23 -0
  161. package/{lib/core/param/param.tokens.d.ts → src/lib/core/param/param.tokens.ts} +2 -1
  162. package/src/lib/core/register-base/register-base.store.ts +84 -0
  163. package/src/lib/core/register-base/register-base.ts +854 -0
  164. package/src/lib/directives/date/date-time.types.ts +36 -0
  165. package/src/lib/directives/date/format-date.pipe.ts +28 -0
  166. package/src/lib/directives/number/number-only.directive.ts +36 -0
  167. package/src/lib/directives/sticky/sticky-relative.directive.ts +30 -0
  168. package/src/lib/directives/sticky/sticky-relative.service.ts +34 -0
  169. package/src/lib/directives/sticky/sticky.directive.ts +189 -0
  170. package/src/lib/services/date-time.service.ts +399 -0
  171. package/src/lib/services/dialog/dialog.service.ts +62 -0
  172. package/{lib/services/dialog/dialog.types.d.ts → src/lib/services/dialog/dialog.types.ts} +8 -4
  173. package/src/lib/services/dom-intersection.service.ts +23 -0
  174. package/src/lib/services/filter/filters-state.service.ts +83 -0
  175. package/src/lib/services/filter/filters-transmit.service.ts +105 -0
  176. package/src/lib/services/filter/filters.service.ts +21 -0
  177. package/src/lib/services/inputs-state.service.ts +157 -0
  178. package/src/lib/services/inputs.service.ts +114 -0
  179. package/src/lib/services/key-pressed.service.ts +40 -0
  180. package/src/lib/services/resize-window-observer.service.ts +37 -0
  181. package/src/lib/services/selected-objects-state.service.ts +159 -0
  182. package/src/lib/store/fast-query-store.service.ts +132 -0
  183. package/{lib/types/event.types.d.ts → src/lib/types/event.types.ts} +1 -1
  184. package/src/lib/types/hasura.types.ts +41 -0
  185. package/src/lib/types/inputs.types.ts +63 -0
  186. package/src/lib/types/params.types.ts +42 -0
  187. package/src/lib/types/register-base.types.ts +161 -0
  188. package/src/lib/types/sub-types.ts +15 -0
  189. package/src/lib/types/user-profile.types.ts +18 -0
  190. package/src/lib/utils/functions.ts +11 -0
  191. package/src/lib/utils/get-url-segment.ts +46 -0
  192. package/src/lib/utils/prizm.shared.module.ts +176 -0
  193. package/src/lib/utils/rxjs.ts +33 -0
  194. package/src/lib/utils/select-all-utils.ts +16 -0
  195. package/tsconfig.lib.json +16 -0
  196. package/tsconfig.lib.prod.json +11 -0
  197. package/tsconfig.schematics.json +26 -0
  198. package/tsconfig.spec.json +15 -0
  199. package/esm2022/lib/components/checkbox-selector/checkbox-selector.component.mjs +0 -129
  200. package/esm2022/lib/components/checkbox-selector/checkbox-selector.types.mjs +0 -8
  201. package/esm2022/lib/components/column-settings/column-settings.component.mjs +0 -249
  202. package/esm2022/lib/components/column-settings/components/column-settings-template/column-settings-template.component.mjs +0 -80
  203. package/esm2022/lib/components/column-settings/consts/column-settings.consts.mjs +0 -10
  204. package/esm2022/lib/components/column-settings/index.mjs +0 -3
  205. package/esm2022/lib/components/column-settings/types/column-settings.types.mjs +0 -7
  206. package/esm2022/lib/components/divider/divider.component.mjs +0 -16
  207. package/esm2022/lib/components/filter-button/filter-button.component.mjs +0 -19
  208. package/esm2022/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.mjs +0 -31
  209. package/esm2022/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.mjs +0 -57
  210. package/esm2022/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.mjs +0 -110
  211. package/esm2022/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.mjs +0 -130
  212. package/esm2022/lib/components/filters/components/filter-list/filter-list.service.mjs +0 -89
  213. package/esm2022/lib/components/filters/components/filter-list/filters-section/filters-section.component.mjs +0 -41
  214. package/esm2022/lib/components/filters/components/filter-list.module.mjs +0 -45
  215. package/esm2022/lib/components/filters/index.mjs +0 -3
  216. package/esm2022/lib/components/filters/register-table-filter.component.mjs +0 -155
  217. package/esm2022/lib/components/filters/register-table-filter.module.mjs +0 -39
  218. package/esm2022/lib/components/index.mjs +0 -11
  219. package/esm2022/lib/components/inputs/index.mjs +0 -20
  220. package/esm2022/lib/components/inputs/inputs.module.mjs +0 -166
  221. package/esm2022/lib/components/inputs/param-calendar-year/param-calendar-year.component.mjs +0 -45
  222. package/esm2022/lib/components/inputs/param-custom/param-custom.component.mjs +0 -12
  223. package/esm2022/lib/components/inputs/param-date/param-date.component.mjs +0 -76
  224. package/esm2022/lib/components/inputs/param-date-range/param-date-range.component.mjs +0 -61
  225. package/esm2022/lib/components/inputs/param-date-time/param-date-time.component.mjs +0 -86
  226. package/esm2022/lib/components/inputs/param-date-time-range/param-date-time-range.component.mjs +0 -96
  227. package/esm2022/lib/components/inputs/param-month/param-month.component.mjs +0 -50
  228. package/esm2022/lib/components/inputs/param-month-range/param-month-range.component.mjs +0 -62
  229. package/esm2022/lib/components/inputs/param-multi-select/param-multi-select.component.mjs +0 -309
  230. package/esm2022/lib/components/inputs/param-select/param-select.component.mjs +0 -209
  231. package/esm2022/lib/components/inputs/param-switcher/param-switcher.component.mjs +0 -21
  232. package/esm2022/lib/components/inputs/param-switcher-date-time-range/consts/param-switcher-date-time-range.consts.mjs +0 -28
  233. package/esm2022/lib/components/inputs/param-switcher-date-time-range/index.mjs +0 -3
  234. package/esm2022/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.mjs +0 -105
  235. package/esm2022/lib/components/inputs/param-switcher-date-time-range/types/param-switcher-date-time-range.types.mjs +0 -10
  236. package/esm2022/lib/components/inputs/param-text/param-text.component.mjs +0 -40
  237. package/esm2022/lib/components/inputs/param-textarea/param-textarea.component.mjs +0 -38
  238. package/esm2022/lib/components/inputs/param-toggle/param-toggle.component.mjs +0 -20
  239. package/esm2022/lib/components/inputs/param-tree/consts/param-tree.consts.mjs +0 -37
  240. package/esm2022/lib/components/inputs/param-tree/index.mjs +0 -8
  241. package/esm2022/lib/components/inputs/param-tree/param-tree.component.mjs +0 -207
  242. package/esm2022/lib/components/inputs/param-tree/services/param-tree.service.mjs +0 -116
  243. package/esm2022/lib/components/inputs/param-tree/services/sync-tree-loader.service.mjs +0 -20
  244. package/esm2022/lib/components/inputs/param-tree/tokens/param-tree.tokens.mjs +0 -3
  245. package/esm2022/lib/components/inputs/param-tree/types/param-tree.types.mjs +0 -2
  246. package/esm2022/lib/components/inputs/param-tree/utils/param-tree.utils.mjs +0 -9
  247. package/esm2022/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.mjs +0 -80
  248. package/esm2022/lib/components/inputs/param-tree-select/param-tree-select.component.mjs +0 -85
  249. package/esm2022/lib/components/inputs/sub-components/param-delete-content-icon/param-delete-content-btn.component.mjs +0 -15
  250. package/esm2022/lib/components/inputs/sub-components/param-invalid-icon/param-invalid-icon.component.mjs +0 -12
  251. package/esm2022/lib/components/menu-constructor/index.mjs +0 -5
  252. package/esm2022/lib/components/menu-constructor/sproc-menu-constructor.component.mjs +0 -559
  253. package/esm2022/lib/components/menu-constructor/store/sproc-abstract-menu-constructor.store.mjs +0 -3
  254. package/esm2022/lib/components/menu-constructor/store/sproc-menu-constructor.consts.mjs +0 -5
  255. package/esm2022/lib/components/menu-constructor/store/sproc-menu.tokens.mjs +0 -3
  256. package/esm2022/lib/components/page-menu/index.mjs +0 -6
  257. package/esm2022/lib/components/page-menu/schema/sproc-page-menu.consts.mjs +0 -9
  258. package/esm2022/lib/components/page-menu/schema/sproc-page-menu.schema.mjs +0 -2
  259. package/esm2022/lib/components/page-menu/schema/sproc-page-menu.tokens.mjs +0 -4
  260. package/esm2022/lib/components/page-menu/schema/sproc-page-menu.types.mjs +0 -3
  261. package/esm2022/lib/components/page-menu/sproc-page-menu.component.mjs +0 -275
  262. package/esm2022/lib/components/paginator/paginator.component.mjs +0 -159
  263. package/esm2022/lib/components/paginator/types/paginator.types.mjs +0 -2
  264. package/esm2022/lib/components/register-table/consts/register-table.consts.mjs +0 -4
  265. package/esm2022/lib/components/register-table/directives/cell-template.directive.mjs +0 -19
  266. package/esm2022/lib/components/register-table/directives/header-template.directive.mjs +0 -18
  267. package/esm2022/lib/components/register-table/index.mjs +0 -4
  268. package/esm2022/lib/components/register-table/model/schema.mjs +0 -10
  269. package/esm2022/lib/components/register-table/pipes/class-by-type.pipe.mjs +0 -33
  270. package/esm2022/lib/components/register-table/pipes/sticky-column.pipe.mjs +0 -17
  271. package/esm2022/lib/components/register-table/register-table.component.mjs +0 -544
  272. package/esm2022/lib/components/reset-settings-form/reset-settings-form.component.mjs +0 -18
  273. package/esm2022/lib/components/search-input/search-input.component.mjs +0 -28
  274. package/esm2022/lib/components/sliding-panel/sliding-panel.component.mjs +0 -48
  275. package/esm2022/lib/components/sliding-panel/sliding-panel.module.mjs +0 -19
  276. package/esm2022/lib/consts/date-time.consts.mjs +0 -2
  277. package/esm2022/lib/consts/index.mjs +0 -4
  278. package/esm2022/lib/consts/inputs.consts.mjs +0 -4
  279. package/esm2022/lib/consts/month.consts.mjs +0 -77
  280. package/esm2022/lib/consts/params.consts.mjs +0 -2
  281. package/esm2022/lib/consts/register-base.consts.mjs +0 -26
  282. package/esm2022/lib/core/form-group-wrapper/errors-consts.mjs +0 -8
  283. package/esm2022/lib/core/form-group-wrapper/form-group-wrapper.mjs +0 -81
  284. package/esm2022/lib/core/form-group-wrapper/index.mjs +0 -2
  285. package/esm2022/lib/core/index.mjs +0 -5
  286. package/esm2022/lib/core/input-control/index.mjs +0 -2
  287. package/esm2022/lib/core/input-control/input-control.mjs +0 -11
  288. package/esm2022/lib/core/param/index.mjs +0 -6
  289. package/esm2022/lib/core/param/param-base.mjs +0 -215
  290. package/esm2022/lib/core/param/param-date-base.mjs +0 -26
  291. package/esm2022/lib/core/param/param-select-base.mjs +0 -114
  292. package/esm2022/lib/core/param/param-text-base.mjs +0 -25
  293. package/esm2022/lib/core/param/param.tokens.mjs +0 -4
  294. package/esm2022/lib/core/register-base/index.mjs +0 -3
  295. package/esm2022/lib/core/register-base/register-base.mjs +0 -575
  296. package/esm2022/lib/core/register-base/register-base.store.mjs +0 -43
  297. package/esm2022/lib/directives/date/date-time.types.mjs +0 -34
  298. package/esm2022/lib/directives/date/format-date.pipe.mjs +0 -33
  299. package/esm2022/lib/directives/index.mjs +0 -3
  300. package/esm2022/lib/directives/number/number-only.directive.mjs +0 -41
  301. package/esm2022/lib/directives/sticky/index.mjs +0 -3
  302. package/esm2022/lib/directives/sticky/sticky-relative.directive.mjs +0 -32
  303. package/esm2022/lib/directives/sticky/sticky-relative.service.mjs +0 -32
  304. package/esm2022/lib/directives/sticky/sticky.directive.mjs +0 -169
  305. package/esm2022/lib/services/date-time.service.mjs +0 -314
  306. package/esm2022/lib/services/dialog/dialog.service.mjs +0 -53
  307. package/esm2022/lib/services/dialog/dialog.types.mjs +0 -2
  308. package/esm2022/lib/services/dialog/index.mjs +0 -3
  309. package/esm2022/lib/services/dom-intersection.service.mjs +0 -22
  310. package/esm2022/lib/services/filter/filters-state.service.mjs +0 -65
  311. package/esm2022/lib/services/filter/filters-transmit.service.mjs +0 -82
  312. package/esm2022/lib/services/filter/filters.service.mjs +0 -23
  313. package/esm2022/lib/services/index.mjs +0 -8
  314. package/esm2022/lib/services/inputs-state.service.mjs +0 -130
  315. package/esm2022/lib/services/inputs.service.mjs +0 -88
  316. package/esm2022/lib/services/key-pressed.service.mjs +0 -37
  317. package/esm2022/lib/services/resize-window-observer.service.mjs +0 -33
  318. package/esm2022/lib/services/selected-objects-state.service.mjs +0 -123
  319. package/esm2022/lib/store/fast-query-store.service.mjs +0 -110
  320. package/esm2022/lib/store/index.mjs +0 -2
  321. package/esm2022/lib/types/event.types.mjs +0 -2
  322. package/esm2022/lib/types/hasura.types.mjs +0 -2
  323. package/esm2022/lib/types/index.mjs +0 -7
  324. package/esm2022/lib/types/inputs.types.mjs +0 -19
  325. package/esm2022/lib/types/params.types.mjs +0 -2
  326. package/esm2022/lib/types/register-base.types.mjs +0 -6
  327. package/esm2022/lib/types/sub-types.mjs +0 -2
  328. package/esm2022/lib/types/user-profile.types.mjs +0 -2
  329. package/esm2022/lib/utils/functions.mjs +0 -10
  330. package/esm2022/lib/utils/get-url-segment.mjs +0 -35
  331. package/esm2022/lib/utils/index.mjs +0 -5
  332. package/esm2022/lib/utils/prizm.shared.module.mjs +0 -284
  333. package/esm2022/lib/utils/rxjs.mjs +0 -28
  334. package/esm2022/lib/utils/select-all-utils.mjs +0 -11
  335. package/esm2022/ngx-register-base.mjs +0 -5
  336. package/esm2022/public-api.mjs +0 -9
  337. package/fesm2022/ngx-register-base.mjs +0 -7465
  338. package/fesm2022/ngx-register-base.mjs.map +0 -1
  339. package/index.d.ts +0 -5
  340. package/lib/components/checkbox-selector/checkbox-selector.component.d.ts +0 -33
  341. package/lib/components/checkbox-selector/checkbox-selector.types.d.ts +0 -7
  342. package/lib/components/column-settings/column-settings.component.d.ts +0 -80
  343. package/lib/components/column-settings/components/column-settings-template/column-settings-template.component.d.ts +0 -24
  344. package/lib/components/column-settings/consts/column-settings.consts.d.ts +0 -8
  345. package/lib/components/column-settings/types/column-settings.types.d.ts +0 -22
  346. package/lib/components/divider/divider.component.d.ts +0 -6
  347. package/lib/components/filter-button/filter-button.component.d.ts +0 -8
  348. package/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.d.ts +0 -14
  349. package/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.d.ts +0 -25
  350. package/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.d.ts +0 -39
  351. package/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.d.ts +0 -41
  352. package/lib/components/filters/components/filter-list/filter-list.service.d.ts +0 -20
  353. package/lib/components/filters/components/filter-list/filters-section/filters-section.component.d.ts +0 -15
  354. package/lib/components/filters/components/filter-list.module.d.ts +0 -15
  355. package/lib/components/filters/register-table-filter.component.d.ts +0 -40
  356. package/lib/components/filters/register-table-filter.module.d.ts +0 -13
  357. package/lib/components/inputs/inputs.module.d.ts +0 -31
  358. package/lib/components/inputs/param-calendar-year/param-calendar-year.component.d.ts +0 -19
  359. package/lib/components/inputs/param-custom/param-custom.component.d.ts +0 -6
  360. package/lib/components/inputs/param-date/param-date.component.d.ts +0 -20
  361. package/lib/components/inputs/param-date-range/param-date-range.component.d.ts +0 -26
  362. package/lib/components/inputs/param-date-time/param-date-time.component.d.ts +0 -25
  363. package/lib/components/inputs/param-date-time-range/param-date-time-range.component.d.ts +0 -28
  364. package/lib/components/inputs/param-month/param-month.component.d.ts +0 -18
  365. package/lib/components/inputs/param-month-range/param-month-range.component.d.ts +0 -21
  366. package/lib/components/inputs/param-multi-select/param-multi-select.component.d.ts +0 -46
  367. package/lib/components/inputs/param-select/param-select.component.d.ts +0 -30
  368. package/lib/components/inputs/param-switcher/param-switcher.component.d.ts +0 -8
  369. package/lib/components/inputs/param-switcher-date-time-range/consts/param-switcher-date-time-range.consts.d.ts +0 -2
  370. package/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.d.ts +0 -19
  371. package/lib/components/inputs/param-switcher-date-time-range/types/param-switcher-date-time-range.types.d.ts +0 -8
  372. package/lib/components/inputs/param-text/param-text.component.d.ts +0 -10
  373. package/lib/components/inputs/param-textarea/param-textarea.component.d.ts +0 -10
  374. package/lib/components/inputs/param-toggle/param-toggle.component.d.ts +0 -9
  375. package/lib/components/inputs/param-tree/consts/param-tree.consts.d.ts +0 -7
  376. package/lib/components/inputs/param-tree/param-tree.component.d.ts +0 -41
  377. package/lib/components/inputs/param-tree/services/param-tree.service.d.ts +0 -37
  378. package/lib/components/inputs/param-tree/services/sync-tree-loader.service.d.ts +0 -10
  379. package/lib/components/inputs/param-tree/types/param-tree.types.d.ts +0 -32
  380. package/lib/components/inputs/param-tree/utils/param-tree.utils.d.ts +0 -7
  381. package/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.d.ts +0 -31
  382. package/lib/components/inputs/param-tree-select/param-tree-select.component.d.ts +0 -30
  383. package/lib/components/inputs/sub-components/param-delete-content-icon/param-delete-content-btn.component.d.ts +0 -6
  384. package/lib/components/inputs/sub-components/param-invalid-icon/param-invalid-icon.component.d.ts +0 -5
  385. package/lib/components/menu-constructor/sproc-menu-constructor.component.d.ts +0 -113
  386. package/lib/components/menu-constructor/store/sproc-abstract-menu-constructor.store.d.ts +0 -24
  387. package/lib/components/menu-constructor/store/sproc-menu-constructor.consts.d.ts +0 -36
  388. package/lib/components/page-menu/schema/sproc-page-menu.consts.d.ts +0 -7
  389. package/lib/components/page-menu/schema/sproc-page-menu.schema.d.ts +0 -30
  390. package/lib/components/page-menu/schema/sproc-page-menu.tokens.d.ts +0 -3
  391. package/lib/components/page-menu/schema/sproc-page-menu.types.d.ts +0 -36
  392. package/lib/components/page-menu/sproc-page-menu.component.d.ts +0 -48
  393. package/lib/components/paginator/paginator.component.d.ts +0 -52
  394. package/lib/components/paginator/types/paginator.types.d.ts +0 -15
  395. package/lib/components/register-table/consts/register-table.consts.d.ts +0 -3
  396. package/lib/components/register-table/directives/cell-template.directive.d.ts +0 -9
  397. package/lib/components/register-table/directives/header-template.directive.d.ts +0 -9
  398. package/lib/components/register-table/model/schema.d.ts +0 -52
  399. package/lib/components/register-table/pipes/class-by-type.pipe.d.ts +0 -8
  400. package/lib/components/register-table/pipes/sticky-column.pipe.d.ts +0 -7
  401. package/lib/components/register-table/register-table.component.d.ts +0 -165
  402. package/lib/components/reset-settings-form/reset-settings-form.component.d.ts +0 -9
  403. package/lib/components/search-input/search-input.component.d.ts +0 -11
  404. package/lib/components/sliding-panel/sliding-panel.component.d.ts +0 -14
  405. package/lib/components/sliding-panel/sliding-panel.module.d.ts +0 -9
  406. package/lib/consts/date-time.consts.d.ts +0 -1
  407. package/lib/consts/index.d.ts +0 -3
  408. package/lib/consts/inputs.consts.d.ts +0 -4
  409. package/lib/consts/month.consts.d.ts +0 -49
  410. package/lib/consts/params.consts.d.ts +0 -1
  411. package/lib/consts/register-base.consts.d.ts +0 -19
  412. package/lib/core/form-group-wrapper/errors-consts.d.ts +0 -5
  413. package/lib/core/form-group-wrapper/form-group-wrapper.d.ts +0 -15
  414. package/lib/core/input-control/input-control.d.ts +0 -11
  415. package/lib/core/param/param-base.d.ts +0 -68
  416. package/lib/core/param/param-date-base.d.ts +0 -18
  417. package/lib/core/param/param-select-base.d.ts +0 -42
  418. package/lib/core/param/param-text-base.d.ts +0 -15
  419. package/lib/core/register-base/register-base.d.ts +0 -168
  420. package/lib/core/register-base/register-base.store.d.ts +0 -35
  421. package/lib/directives/date/date-time.types.d.ts +0 -32
  422. package/lib/directives/date/format-date.pipe.d.ts +0 -10
  423. package/lib/directives/number/number-only.directive.d.ts +0 -10
  424. package/lib/directives/sticky/sticky-relative.directive.d.ts +0 -13
  425. package/lib/directives/sticky/sticky-relative.service.d.ts +0 -15
  426. package/lib/directives/sticky/sticky.directive.d.ts +0 -27
  427. package/lib/services/date-time.service.d.ts +0 -80
  428. package/lib/services/dialog/dialog.service.d.ts +0 -22
  429. package/lib/services/dom-intersection.service.d.ts +0 -8
  430. package/lib/services/filter/filters-state.service.d.ts +0 -21
  431. package/lib/services/filter/filters-transmit.service.d.ts +0 -28
  432. package/lib/services/filter/filters.service.d.ts +0 -12
  433. package/lib/services/inputs-state.service.d.ts +0 -57
  434. package/lib/services/inputs.service.d.ts +0 -28
  435. package/lib/services/key-pressed.service.d.ts +0 -15
  436. package/lib/services/resize-window-observer.service.d.ts +0 -11
  437. package/lib/services/selected-objects-state.service.d.ts +0 -47
  438. package/lib/store/fast-query-store.service.d.ts +0 -19
  439. package/lib/types/hasura.types.d.ts +0 -35
  440. package/lib/types/inputs.types.d.ts +0 -41
  441. package/lib/types/params.types.d.ts +0 -27
  442. package/lib/types/register-base.types.d.ts +0 -123
  443. package/lib/types/sub-types.d.ts +0 -8
  444. package/lib/types/user-profile.types.d.ts +0 -17
  445. package/lib/utils/functions.d.ts +0 -3
  446. package/lib/utils/get-url-segment.d.ts +0 -7
  447. package/lib/utils/prizm.shared.module.d.ts +0 -14
  448. package/lib/utils/rxjs.d.ts +0 -10
  449. package/lib/utils/select-all-utils.d.ts +0 -8
  450. package/schematics/ng-update/replace-menu-state-token/index.d.ts +0 -2
  451. package/schematics/ng-update/replace-menu-state-token/index.js +0 -29
  452. package/schematics/ng-update/replace-menu-state-token/index.js.map +0 -1
  453. package/schematics/ng-update/update-prefix/index.d.ts +0 -2
  454. package/schematics/ng-update/update-prefix/index.js +0 -33
  455. package/schematics/ng-update/update-prefix/index.js.map +0 -1
  456. package/schematics/utils/utils.js +0 -25
  457. package/schematics/utils/utils.js.map +0 -1
  458. /package/{lib/components/column-settings/index.d.ts → src/lib/components/column-settings/index.ts} +0 -0
  459. /package/{lib/components/filters/index.d.ts → src/lib/components/filters/index.ts} +0 -0
  460. /package/{lib/components/index.d.ts → src/lib/components/index.ts} +0 -0
  461. /package/{lib/components/inputs/index.d.ts → src/lib/components/inputs/index.ts} +0 -0
  462. /package/{lib/components/inputs/param-switcher-date-time-range/index.d.ts → src/lib/components/inputs/param-switcher-date-time-range/index.ts} +0 -0
  463. /package/{lib/components/inputs/param-tree/index.d.ts → src/lib/components/inputs/param-tree/index.ts} +0 -0
  464. /package/{lib/components/menu-constructor/index.d.ts → src/lib/components/menu-constructor/index.ts} +0 -0
  465. /package/{lib/components/page-menu/index.d.ts → src/lib/components/page-menu/index.ts} +0 -0
  466. /package/{lib/components/register-table/index.d.ts → src/lib/components/register-table/index.ts} +0 -0
  467. /package/{lib/core/form-group-wrapper/index.d.ts → src/lib/core/form-group-wrapper/index.ts} +0 -0
  468. /package/{lib/core/index.d.ts → src/lib/core/index.ts} +0 -0
  469. /package/{lib/core/input-control/index.d.ts → src/lib/core/input-control/index.ts} +0 -0
  470. /package/{lib/core/param/index.d.ts → src/lib/core/param/index.ts} +0 -0
  471. /package/{lib/core/register-base/index.d.ts → src/lib/core/register-base/index.ts} +0 -0
  472. /package/{lib/directives/index.d.ts → src/lib/directives/index.ts} +0 -0
  473. /package/{lib/directives/sticky/index.d.ts → src/lib/directives/sticky/index.ts} +0 -0
  474. /package/{lib/services/dialog/index.d.ts → src/lib/services/dialog/index.ts} +0 -0
  475. /package/{lib/services/index.d.ts → src/lib/services/index.ts} +0 -0
  476. /package/{lib/store/index.d.ts → src/lib/store/index.ts} +0 -0
  477. /package/{lib/types/index.d.ts → src/lib/types/index.ts} +0 -0
  478. /package/{lib/utils/index.d.ts → src/lib/utils/index.ts} +0 -0
  479. /package/{public-api.d.ts → src/public-api.ts} +0 -0
@@ -1,559 +0,0 @@
1
- import { Component, computed, DestroyRef, inject, output, signal } from '@angular/core';
2
- import { FormsModule } from '@angular/forms';
3
- import { CdkDrag, CdkDragHandle, CdkDragPreview, CdkDropList, } from '@angular/cdk/drag-drop';
4
- import { AsyncPipe, NgForOf } from '@angular/common';
5
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
- import { filter } from 'rxjs';
7
- import { EMPTY_UUID, MIGRATION_HINT, NEW_ITEM_PREFIX, ROOT_TITLE, } from './store/sproc-menu-constructor.consts';
8
- import { MENU_CONSTRUCTOR_STORE_TOKEN } from './store/sproc-menu.tokens';
9
- import * as i0 from "@angular/core";
10
- import * as i1 from "@angular/forms";
11
- export class SprocMenuConstructorComponent {
12
- constructor() {
13
- this._store = inject(MENU_CONSTRUCTOR_STORE_TOKEN);
14
- this._ref = inject(DestroyRef);
15
- this.ROOT_TITLE = ROOT_TITLE;
16
- this.loading$ = this._store.loading$;
17
- this.originalTree = new Map([]);
18
- this.MIGRATION_HINT = MIGRATION_HINT;
19
- this.deletedIds = [];
20
- this.errorMsgOutput = output();
21
- // плоское представление иерархического меню
22
- this.flatTree = signal([]);
23
- // ветка элементов, которая перетаскивается
24
- this.draggedBranch = signal([]);
25
- // вычисляемое свойство, возвращающее только видимые (не свернутые) элементы
26
- this.visibleFlatTree = computed(() => {
27
- const flatTree = this.flatTree();
28
- return this._getVisibleFrom(flatTree);
29
- });
30
- this._pendingRecalc = false;
31
- }
32
- ngOnInit() {
33
- this._store.menuItems$
34
- .pipe(filter((arr) => Array.isArray(arr) && arr.length > 0), takeUntilDestroyed(this._ref))
35
- .subscribe((value) => {
36
- this.flatTree.set(this._convertToFlatNode(value));
37
- this.originalTree = new Map(this.flatTree().map((item) => [item.id, { ...item }]));
38
- });
39
- }
40
- /**
41
- * Переключает состояние свернутости узла (collapse/expand)
42
- * После изменения создает новый массив для триггера обновления сигнала
43
- */
44
- toggleCollapse(node) {
45
- node.collapsed = !node.collapsed;
46
- this.flatTree.set([...this.flatTree()]);
47
- }
48
- /**
49
- * Начало перетаскивания: сохраняет всю ветку узла, которую тянут
50
- */
51
- dragStarted(node) {
52
- const branch = this._collectBranch(this.flatTree(), node);
53
- this.draggedBranch.set(branch);
54
- }
55
- /**
56
- * Завершение перетаскивания: очищает информацию о текущей ветке
57
- */
58
- dragEnded() {
59
- this.draggedBranch.set([]);
60
- }
61
- /**
62
- * Основная логика drag&drop при отпускании элемента
63
- * Определяет новую позицию узла, пересчитывает глубины и связи
64
- */
65
- drop(event) {
66
- const before = [...this.flatTree()];
67
- const visibleBefore = this._getVisibleFrom(before);
68
- const prevIdx = event.previousIndex;
69
- const currIdx = event.currentIndex;
70
- // Получает перетаскиваемый элемент из списка видимых
71
- const draggedVisible = visibleBefore[prevIdx];
72
- if (!draggedVisible) {
73
- return;
74
- }
75
- // Находит индекс узла в полном массиве
76
- const start = before.findIndex((n) => n.id === draggedVisible.id);
77
- if (start < 0) {
78
- return;
79
- }
80
- // Собирает всю ветку, начинающуюся с перетаскиваемого узла
81
- const branch = this._collectBranch(before, before[start]);
82
- const branchIds = new Set(branch.map((n) => n.id));
83
- // Убирает ветку из исходного списка
84
- const full = before.filter((n) => !branchIds.has(n.id));
85
- // Определяет видимые элементы после удаления ветки
86
- const visible = this._getVisibleFrom(full);
87
- const prevVisible = visible[currIdx - 1] ?? null;
88
- const nextVisible = visible[currIdx] ?? null;
89
- // Индекс вставки ветки в новый список
90
- const insert = nextVisible ? full.findIndex((n) => n.id === nextVisible.id) : full.length;
91
- // Рассчитывает глубину вставляемой ветки в зависимости от соседей
92
- let targetDepth;
93
- if (prevVisible && nextVisible) {
94
- targetDepth =
95
- prevVisible.depth < nextVisible.depth ? prevVisible.depth + 1 : nextVisible.depth;
96
- }
97
- else if (prevVisible && !nextVisible) {
98
- targetDepth = prevVisible.depth;
99
- }
100
- else if (!prevVisible && nextVisible) {
101
- targetDepth = nextVisible.depth;
102
- }
103
- else {
104
- targetDepth = 0;
105
- }
106
- // Вставляет ветку в новое место
107
- full.splice(insert, 0, ...branch);
108
- // Сдвигает глубину всей ветки
109
- this._applyDepthShift(branch, targetDepth - branch[0].depth);
110
- // Планирует пересчет структуры дерева
111
- this._scheduleRecalc(full);
112
- }
113
- /**
114
- * Увеличивает глубину (depth) конкретного узла, если возможно
115
- */
116
- indent(node) {
117
- const arr = [...this.flatTree()];
118
- const index = arr.indexOf(node);
119
- if (index === -1) {
120
- return;
121
- }
122
- const proposedDepth = node.depth + 1;
123
- // Ищет подходящего родителя с нужной глубиной
124
- const parentCandidate = [...arr]
125
- .slice(0, index)
126
- .reverse()
127
- .find((n) => n.depth === proposedDepth - 1);
128
- if (!parentCandidate) {
129
- return;
130
- }
131
- node.depth = proposedDepth;
132
- this._scheduleRecalc(arr);
133
- }
134
- /**
135
- * Уменьшает глубину (depth) узла + по возможности превращает его в родителя
136
- */
137
- outdent(node) {
138
- const arr = [...this.flatTree()];
139
- const index = arr.indexOf(node);
140
- if (index === -1 || node.depth <= 0) {
141
- return;
142
- }
143
- node.depth = Math.max(0, node.depth - 1);
144
- this._scheduleRecalc(arr);
145
- }
146
- /**
147
- * Увеличивает глубину всей ветки узла (вместе с потомками)
148
- */
149
- indentBranch(node) {
150
- const arr = [...this.flatTree()];
151
- const index = arr.indexOf(node);
152
- if (index === -1) {
153
- return;
154
- }
155
- const proposedDepth = node.depth + 1;
156
- const parentCandidate = [...arr]
157
- .slice(0, index)
158
- .reverse()
159
- .find((n) => n.depth === proposedDepth - 1);
160
- if (!parentCandidate) {
161
- return;
162
- }
163
- const branch = this._collectBranch(arr, node);
164
- this._applyDepthShift(branch, 1);
165
- this._scheduleRecalc(arr);
166
- }
167
- /**
168
- * Уменьшает глубину всей ветки узла
169
- */
170
- outdentBranch(node) {
171
- const arr = [...this.flatTree()];
172
- const branch = this._collectBranch(arr, node);
173
- this._applyDepthShift(branch, -1);
174
- this._scheduleRecalc(arr);
175
- }
176
- /**
177
- * Проверяет, есть ли у узла дочерние элементы
178
- */
179
- hasChildren(node) {
180
- const arr = this.flatTree();
181
- const idx = arr.indexOf(node);
182
- if (idx === -1) {
183
- return false;
184
- }
185
- for (let i = idx + 1; i < arr.length; i++) {
186
- const next = arr[i];
187
- if (next.depth <= node.depth) {
188
- break;
189
- }
190
- if (next.depth === node.depth + 1) {
191
- return true;
192
- }
193
- }
194
- return false;
195
- }
196
- save() {
197
- // Флаг для логгирования на время отладки
198
- const logging = false;
199
- const changedElements = this.flatTree().filter((newItem) => {
200
- const originalItem = this.originalTree.get(newItem.id);
201
- // Новый элемент
202
- if (!originalItem) {
203
- if (logging) {
204
- console.log(`Новый элемент ${newItem.title}`);
205
- }
206
- return true;
207
- }
208
- const { order_num: originalOrderNum, id_parent: originalIdParent, title: originalTitle, allowed_roles: originalRoles, code: originalCode, route: originalRoute, icon: originalIcon, } = originalItem;
209
- const { order_num: newOrderNum, id_parent: newIdParent, title: newTitle, allowed_roles: newRoles, code: newCode, route: newRoute, icon: newIcon, } = newItem;
210
- const changedFields = [];
211
- if (originalOrderNum !== newOrderNum) {
212
- changedFields.push(`order_num: ${originalOrderNum} → ${newOrderNum}`);
213
- }
214
- if (originalIdParent !== newIdParent) {
215
- changedFields.push(`id_parent: ${originalIdParent} → ${newIdParent}`);
216
- }
217
- if (originalTitle !== newTitle) {
218
- changedFields.push(`title: ${originalTitle} → ${newTitle}`);
219
- }
220
- if (originalCode !== newCode) {
221
- changedFields.push(`code: ${originalCode} → ${newCode}`);
222
- }
223
- if (originalRoute !== newRoute) {
224
- changedFields.push(`route: ${originalRoute} → ${newRoute}`);
225
- }
226
- if (originalIcon !== newIcon) {
227
- changedFields.push(`icon: ${originalIcon} → ${newIcon}`);
228
- }
229
- if (JSON.stringify(originalRoles) !== JSON.stringify(newRoles)) {
230
- changedFields.push(`allowed_roles: ${originalRoles} → ${newRoles}`);
231
- }
232
- return changedFields.length > 0;
233
- });
234
- const isBlank = (s) => typeof s !== 'string' || s.trim() === '';
235
- const isRouteValid = ({ route, code }) => {
236
- // route считается заданным, только если это непустая строка
237
- const hasRoute = route.trim() !== '';
238
- return !hasRoute || route === code;
239
- };
240
- const invalidCodeTitles = [];
241
- const invalidRouteTitles = [];
242
- for (const el of changedElements) {
243
- if (isBlank(el.code)) {
244
- invalidCodeTitles.push(el.title ?? '(без названия)');
245
- }
246
- if (!isRouteValid(el)) {
247
- invalidRouteTitles.push(el);
248
- }
249
- }
250
- if (invalidCodeTitles.length > 0) {
251
- this.errorMsgOutput.emit({
252
- label: 'Конструктор меню',
253
- appearance: 'negative',
254
- // eslint-disable-next-line xss/no-mixed-html
255
- content: `Все поля code должны быть заполнены. </br>
256
- Исправьте следующие поля: </br>
257
- ${invalidCodeTitles.map((t) => `- ${t}`).join('</br>')}
258
- `,
259
- });
260
- return;
261
- }
262
- if (invalidRouteTitles.length > 0) {
263
- this.errorMsgOutput.emit({
264
- label: 'Конструктор меню',
265
- appearance: 'negative',
266
- // eslint-disable-next-line xss/no-mixed-html
267
- content: `Все поля code должны быть равны полю route. </br>
268
- Исправьте следующие поля: </br>
269
- ${invalidRouteTitles.map((t) => `- ${t.title} (${t.code} | ${t.route})`).join('</br>')}
270
- `,
271
- });
272
- return;
273
- }
274
- const elRoute = (route) => (route === '' ? null : route);
275
- const normalizeElement = (el) => ({
276
- title: el.title.trim(),
277
- route: elRoute(el.route.trim()),
278
- code: el.code,
279
- icon: el.icon,
280
- order_num: el.order_num,
281
- allowed_roles: el.allowed_roles
282
- ? el.allowed_roles.split(',').map((value) => value.trim())
283
- : null,
284
- id_parent: el.id_parent,
285
- });
286
- const objectsToSave = changedElements
287
- .filter(({ id }) => !id.includes(NEW_ITEM_PREFIX))
288
- .map((el) => ({
289
- _set: normalizeElement(el),
290
- where: { id: { _eq: el.id } },
291
- }));
292
- const objectsToInsert = changedElements
293
- .filter(({ id }) => id.includes(NEW_ITEM_PREFIX))
294
- .map((element) => {
295
- element.id = EMPTY_UUID;
296
- return normalizeElement(element);
297
- });
298
- const objectsToDelete = [...this.deletedIds];
299
- if (logging) {
300
- console.log(`Измененные элементы`, objectsToSave);
301
- console.log(`Новые элементы`, objectsToInsert);
302
- console.log('Удалённые элементы:', objectsToDelete);
303
- }
304
- this._store.updateMenu(objectsToSave, objectsToInsert, objectsToDelete);
305
- this.deletedIds = [];
306
- }
307
- handleFold(state) {
308
- for (const element of this.flatTree()) {
309
- if (element.title !== ROOT_TITLE) {
310
- element.collapsed = state;
311
- }
312
- }
313
- this.flatTree.set([...this.flatTree()]);
314
- }
315
- /**
316
- * Удаляет один элемент из дерева.
317
- * Потомки становятся дочерними элементами родителя удалённого узла.
318
- */
319
- deleteItem(node) {
320
- const arr = [...this.flatTree()];
321
- const index = arr.indexOf(node);
322
- if (index === -1) {
323
- return;
324
- }
325
- const parentId = node.id_parent;
326
- const nodeDepth = node.depth;
327
- // Находим потомков, которые были напрямую под этим узлом
328
- for (let i = index + 1; i < arr.length; i++) {
329
- const next = arr[i];
330
- if (next.depth <= nodeDepth) {
331
- break;
332
- }
333
- if (next.depth === nodeDepth + 1) {
334
- // потомок становится ребёнком родителя удалённого узла
335
- next.id_parent = parentId ?? null;
336
- next.depth = nodeDepth; // поднимаем на один уровень вверх
337
- }
338
- else if (next.depth > nodeDepth + 1) {
339
- // поднимаем остальные на один уровень вверх
340
- next.depth -= 1;
341
- }
342
- }
343
- // Удаляем сам элемент
344
- arr.splice(index, 1);
345
- // Если id не временный — добавляем в список на удаление
346
- if (!node.id.includes(NEW_ITEM_PREFIX)) {
347
- this.deletedIds.push(node.id);
348
- }
349
- this._scheduleRecalc(arr);
350
- }
351
- /**
352
- * Добавляет новый элемент в дерево.
353
- * По умолчанию он создаётся как дочерний элемент root.
354
- */
355
- addNewItem() {
356
- const arr = [...this.flatTree()];
357
- const rootNode = arr.find((n) => n.title === this.ROOT_TITLE);
358
- if (!rootNode) {
359
- console.error('Root элемент не найден. Новый пункт не может быть добавлен.');
360
- return;
361
- }
362
- const newNode = {
363
- id: `${NEW_ITEM_PREFIX}${crypto.randomUUID()}`,
364
- id_parent: rootNode.id,
365
- title: 'Новый пункт меню',
366
- route: '',
367
- icon: '',
368
- order_num: 1,
369
- allowed_roles: null,
370
- collapsed: true,
371
- code: '',
372
- depth: rootNode.depth + 1,
373
- };
374
- const insertIndex = arr.findIndex((n) => n.id === rootNode.id) + 1;
375
- arr.splice(insertIndex, 0, newNode);
376
- this._scheduleRecalc(arr);
377
- }
378
- /**
379
- * Сбрасывает текущее состояние в исходное
380
- */
381
- reset() {
382
- const originalMenu = structuredClone(this._store.originalMenu);
383
- this.flatTree.set(this._convertToFlatNode(originalMenu));
384
- this.deletedIds = [];
385
- }
386
- /**
387
- * Проверяет, находится ли элемент в текущей перетаскиваемой ветке
388
- */
389
- isDragged(node) {
390
- return this.draggedBranch().some((n) => n.id === node.id);
391
- }
392
- /**
393
- * Собирает всю ветку элементов начиная с указанного узла (включая потомков)
394
- */
395
- _collectBranch(arr, root) {
396
- const start = arr.indexOf(root);
397
- if (start < 0) {
398
- return [];
399
- }
400
- const branch = [{ ...root }];
401
- for (let i = start + 1; i < arr.length; i++) {
402
- const n = arr[i];
403
- if (n.depth > root.depth) {
404
- branch.push(n);
405
- }
406
- else {
407
- break;
408
- }
409
- }
410
- return branch;
411
- }
412
- /**
413
- * Сдвигает глубину всех элементов ветки на указанную разницу
414
- * Не допускает отрицательных глубин
415
- */
416
- _applyDepthShift(branch, diff) {
417
- if (diff === 0) {
418
- return;
419
- }
420
- for (const n of branch) {
421
- n.depth = Math.max(0, n.depth + diff);
422
- }
423
- }
424
- /**
425
- * Преобразует иерархический JSON в плоский массив FlatNode[]
426
- * Сохраняет порядок элементов и их вложенность
427
- */
428
- _convertToFlatNode(data) {
429
- // Глубокая копия, чтобы не портить оригинал
430
- const cloned = structuredClone(data);
431
- const map = new Map();
432
- const roots = [];
433
- for (const item of cloned) {
434
- map.set(item.id, item);
435
- }
436
- for (const item of cloned) {
437
- if (item.id_parent && map.has(item.id_parent)) {
438
- const parent = map.get(item.id_parent);
439
- if (!parent.children) {
440
- parent.children = [];
441
- }
442
- parent.children.push(item);
443
- }
444
- else {
445
- roots.push(item);
446
- }
447
- }
448
- const flat = [];
449
- const walk = (node, depth) => {
450
- flat.push({
451
- id: node.id,
452
- id_parent: node.id_parent,
453
- title: node.title ?? '',
454
- route: node.route ?? '',
455
- icon: node.icon ?? '',
456
- order_num: node.order_num ?? 0,
457
- allowed_roles: node.allowed_roles?.join(',') ?? null,
458
- collapsed: node.title !== ROOT_TITLE,
459
- code: node.code ?? '',
460
- depth,
461
- });
462
- if (node.children?.length) {
463
- const sortedChildren = [...node.children].sort((a, b) => (a.order_num ?? 0) - (b.order_num ?? 0));
464
- for (const child of sortedChildren) {
465
- walk(child, depth + 1);
466
- }
467
- }
468
- };
469
- const sortedRoots = [...roots].sort((a, b) => (a.order_num ?? 0) - (b.order_num ?? 0));
470
- for (const root of sortedRoots) {
471
- walk(root, 0);
472
- }
473
- return flat;
474
- }
475
- /**
476
- * Возвращает список видимых элементов на основе флагов collapsed
477
- * Использует стек для отслеживания свернутости на каждом уровне
478
- */
479
- _getVisibleFrom(arr) {
480
- const source = typeof arr === 'function' ? arr() : arr;
481
- const out = [];
482
- const collapsedStack = [];
483
- for (const n of source) {
484
- while (collapsedStack.length > n.depth) {
485
- collapsedStack.pop();
486
- }
487
- if (!collapsedStack.includes(true)) {
488
- out.push(n);
489
- collapsedStack[n.depth] = !!n.collapsed;
490
- }
491
- }
492
- return out;
493
- }
494
- /**
495
- * Пересчитывает order_num и id_parent у всех элементов массива
496
- * После перемещений поддерживает корректную структуру дерева
497
- * order_num назначается относительно родителя (1..N)
498
- */
499
- _recalculateTree(arr) {
500
- const parents = [];
501
- const childCounters = new Map();
502
- for (const node of arr) {
503
- while (parents.length > 0 && parents[parents.length - 1].depth >= node.depth) {
504
- parents.pop();
505
- }
506
- const parent = parents.length > 0 ? parents[parents.length - 1] : null;
507
- node.id_parent = parent ? parent.id : null;
508
- // вычисляем порядковый номер среди братьев
509
- if (node.title !== ROOT_TITLE) {
510
- const parentId = node.id_parent ?? null;
511
- const currentCount = childCounters.get(parentId) ?? 1;
512
- node.order_num = currentCount;
513
- childCounters.set(parentId, currentCount + 1);
514
- }
515
- parents.push(node);
516
- }
517
- }
518
- /**
519
- * Асинхронно планирует пересчет дерева через requestAnimationFrame
520
- * Это предотвращает множественные лишние пересчеты при частых изменениях
521
- */
522
- _scheduleRecalc(arr) {
523
- if (this._pendingRecalc) {
524
- return;
525
- }
526
- this._pendingRecalc = true;
527
- requestAnimationFrame(() => {
528
- this._recalculateTree([...arr]);
529
- const current = this.flatTree();
530
- if (!this._arraysEqual(current, arr)) {
531
- this.flatTree.set([...arr]);
532
- }
533
- this._pendingRecalc = false;
534
- });
535
- }
536
- /**
537
- * Проверяет равенство двух массивов FlatNode по ключевым свойствам
538
- */
539
- _arraysEqual(a, b) {
540
- if (a.length !== b.length) {
541
- return false;
542
- }
543
- for (const [i, element] of a.entries()) {
544
- if (element.id !== b[i].id ||
545
- element.depth !== b[i].depth ||
546
- element.order_num !== b[i].order_num) {
547
- return false;
548
- }
549
- }
550
- return true;
551
- }
552
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SprocMenuConstructorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
553
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SprocMenuConstructorComponent, isStandalone: true, selector: "sproc-menu-constructor", outputs: { errorMsgOutput: "errorMsgOutput" }, ngImport: i0, template: "<div class=\"menu-constructor\">\n <div class=\"pane editor\">\n <div class=\"pane-header\">\n <h2>\u0420\u0435\u0434\u0430\u043A\u0442\u043E\u0440 \u043C\u0435\u043D\u044E</h2>\n <div class=\"buttons\">\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn secondary\" (click)=\"addNewItem()\">\n +\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn secondary\" (click)=\"reset()\">\n \u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"save()\">\n \u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"handleFold(false)\">\n \u0420\u0430\u0441\u043A\u0440\u044B\u0442\u044C \u0432\u0441\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"handleFold(true)\">\n \u0421\u043A\u0440\u044B\u0442\u044C \u0432\u0441\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\n </button>\n </div>\n </div>\n\n <div\n class=\"list-wrapper\"\n cdkDropList\n [cdkDropListData]=\"visibleFlatTree()\"\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListLockAxis]=\"'y'\"\n >\n @for (node of visibleFlatTree(); track node.id + '-' + node.order_num) {\n <div\n class=\"node\"\n [style.marginLeft.px]=\"node.depth * 24\"\n [class.dragged]=\"isDragged(node)\"\n cdkDrag\n (cdkDragStarted)=\"dragStarted(node)\"\n (cdkDragEnded)=\"dragEnded()\"\n >\n <div class=\"node-bar\" cdkDragHandle>\n @if (hasChildren(node)) {\n <button\n class=\"collapse-btn\"\n (click)=\"toggleCollapse(node); $event.stopPropagation()\"\n [title]=\"node.collapsed ? '\u0420\u0430\u0437\u0432\u0435\u0440\u043D\u0443\u0442\u044C' : '\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C'\"\n >\n {{ node.collapsed ? '\u25B6' : '\u25BC' }}\n </button>\n }\n\n @if (node.title === ROOT_TITLE) {\n <span class=\"root-title\">\u041A\u043E\u0440\u043D\u0435\u0432\u043E\u0439 \u044D\u043B\u0435\u043C\u0435\u043D\u0442</span>\n } @else {\n <div class=\"left-control\">\n <span class=\"grip\">\u22EE\u22EE</span>\n <input class=\"inp title\" [(ngModel)]=\"node.title\" placeholder=\"\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435\" />\n <input\n class=\"inp code\"\n [required]=\"true\"\n [(ngModel)]=\"node.code\"\n placeholder=\"code\"\n />\n <input class=\"inp route\" [(ngModel)]=\"node.route\" placeholder=\"route\" />\n <input class=\"inp icon\" [(ngModel)]=\"node.icon\" placeholder=\"icon\" />\n <input class=\"inp roles\" [(ngModel)]=\"node.allowed_roles\" placeholder=\"\u0420\u043E\u043B\u0438\" />\n </div>\n\n <div class=\"depth-controls\">\n <button class=\"btn small\" (click)=\"outdent(node)\">\u2190</button>\n <button class=\"btn small\" (click)=\"indent(node)\">\u2192</button>\n @if (hasChildren(node)) {\n <button class=\"btn small\" (click)=\"outdentBranch(node)\">\u21D0</button>\n <button class=\"btn small\" (click)=\"indentBranch(node)\">\u21D2</button>\n }\n <button class=\"btn small\" (click)=\"deleteItem(node)\">\u0423\u0434\u0430\u043B\u0438\u0442\u044C</button>\n </div>\n }\n </div>\n\n <ng-template cdkDragPreview>\n <div class=\"drag-branch-preview\">\n <div\n class=\"preview-bar\"\n *ngFor=\"let n of draggedBranch()\"\n [style.marginLeft.px]=\"(n.depth - node.depth) * 20\"\n >\n {{ n.title }}\n </div>\n </div>\n </ng-template>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".menu-constructor{display:flex;flex-direction:column;gap:16px;padding:16px;height:calc(100vh - var(--header-height))}.pane{border:1px solid #e2e8f0;border-radius:12px;padding:12px;background:#fff;display:flex;flex-direction:column}.pane.editor{height:100%}.hidden{display:none}.root-title{width:100%}.collapse-btn{background:none;border:none;cursor:pointer;font-size:12px;color:#334155;margin-right:4px;transition:transform .2s ease}.collapse-btn:hover{color:#1e3a8a}.pane-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.pane-header h2{margin:0;font-size:16px}.pane-header .buttons{display:flex;gap:6px}.btn{padding:6px 10px;border-radius:6px;border:1px solid #94a3b8;background:#f8fafc;cursor:pointer;font-size:12px;line-height:1}.btn.primary{border-color:#3b82f6;background:#e0f2fe}.btn.secondary{border-color:#b5b5b5;background:#d1d1d1}.btn.small{padding:2px 6px;margin-left:2px}.btn:hover{background:#e2e8f0}.list-wrapper{flex:1;overflow:auto;min-height:200px}.left-control{gap:6px;display:flex;flex-direction:row;align-items:center;justify-content:center;width:100%}.node{border:1px dashed #cbd5e1;border-radius:8px;margin:6px 0;background:#fafafa;padding:4px}.node-bar{display:flex;flex-direction:row;justify-content:space-between;gap:6px;align-items:center;background:#f1f5f9;padding:4px 6px;border-radius:6px}.grip{cursor:grab;text-align:center;color:#475569}.inp{border:1px solid #cbd5e1;width:100%;border-radius:6px;padding:3px 6px;font-size:12px}.depth-controls{display:flex;gap:2px}.node.dragged{background:#e0f2fe;border-color:#3b82f6;opacity:.85}.drag-branch-preview{background:#fff;border:1px solid #94a3b8;box-shadow:0 6px 18px #00000026;border-radius:8px;padding:6px;min-width:160px}.preview-bar{background:#f8fafc;border-left:3px solid #3b82f6;border-radius:4px;margin:3px 0;padding:4px 8px;font-size:12px}.drag-branch-placeholder{padding:6px 0}.placeholder-row{height:32px;margin:3px 0;background:repeating-linear-gradient(-45deg,#e2e8f0,#e2e8f0 6px,#f1f5f9 6px 12px);border-radius:4px}\n"], dependencies: [{ kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
554
- }
555
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SprocMenuConstructorComponent, decorators: [{
556
- type: Component,
557
- args: [{ standalone: true, selector: 'sproc-menu-constructor', imports: [CdkDrag, CdkDropList, NgForOf, FormsModule, CdkDragPreview, CdkDragHandle, AsyncPipe], template: "<div class=\"menu-constructor\">\n <div class=\"pane editor\">\n <div class=\"pane-header\">\n <h2>\u0420\u0435\u0434\u0430\u043A\u0442\u043E\u0440 \u043C\u0435\u043D\u044E</h2>\n <div class=\"buttons\">\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn secondary\" (click)=\"addNewItem()\">\n +\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn secondary\" (click)=\"reset()\">\n \u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"save()\">\n \u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"handleFold(false)\">\n \u0420\u0430\u0441\u043A\u0440\u044B\u0442\u044C \u0432\u0441\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"handleFold(true)\">\n \u0421\u043A\u0440\u044B\u0442\u044C \u0432\u0441\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\n </button>\n </div>\n </div>\n\n <div\n class=\"list-wrapper\"\n cdkDropList\n [cdkDropListData]=\"visibleFlatTree()\"\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListLockAxis]=\"'y'\"\n >\n @for (node of visibleFlatTree(); track node.id + '-' + node.order_num) {\n <div\n class=\"node\"\n [style.marginLeft.px]=\"node.depth * 24\"\n [class.dragged]=\"isDragged(node)\"\n cdkDrag\n (cdkDragStarted)=\"dragStarted(node)\"\n (cdkDragEnded)=\"dragEnded()\"\n >\n <div class=\"node-bar\" cdkDragHandle>\n @if (hasChildren(node)) {\n <button\n class=\"collapse-btn\"\n (click)=\"toggleCollapse(node); $event.stopPropagation()\"\n [title]=\"node.collapsed ? '\u0420\u0430\u0437\u0432\u0435\u0440\u043D\u0443\u0442\u044C' : '\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C'\"\n >\n {{ node.collapsed ? '\u25B6' : '\u25BC' }}\n </button>\n }\n\n @if (node.title === ROOT_TITLE) {\n <span class=\"root-title\">\u041A\u043E\u0440\u043D\u0435\u0432\u043E\u0439 \u044D\u043B\u0435\u043C\u0435\u043D\u0442</span>\n } @else {\n <div class=\"left-control\">\n <span class=\"grip\">\u22EE\u22EE</span>\n <input class=\"inp title\" [(ngModel)]=\"node.title\" placeholder=\"\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435\" />\n <input\n class=\"inp code\"\n [required]=\"true\"\n [(ngModel)]=\"node.code\"\n placeholder=\"code\"\n />\n <input class=\"inp route\" [(ngModel)]=\"node.route\" placeholder=\"route\" />\n <input class=\"inp icon\" [(ngModel)]=\"node.icon\" placeholder=\"icon\" />\n <input class=\"inp roles\" [(ngModel)]=\"node.allowed_roles\" placeholder=\"\u0420\u043E\u043B\u0438\" />\n </div>\n\n <div class=\"depth-controls\">\n <button class=\"btn small\" (click)=\"outdent(node)\">\u2190</button>\n <button class=\"btn small\" (click)=\"indent(node)\">\u2192</button>\n @if (hasChildren(node)) {\n <button class=\"btn small\" (click)=\"outdentBranch(node)\">\u21D0</button>\n <button class=\"btn small\" (click)=\"indentBranch(node)\">\u21D2</button>\n }\n <button class=\"btn small\" (click)=\"deleteItem(node)\">\u0423\u0434\u0430\u043B\u0438\u0442\u044C</button>\n </div>\n }\n </div>\n\n <ng-template cdkDragPreview>\n <div class=\"drag-branch-preview\">\n <div\n class=\"preview-bar\"\n *ngFor=\"let n of draggedBranch()\"\n [style.marginLeft.px]=\"(n.depth - node.depth) * 20\"\n >\n {{ n.title }}\n </div>\n </div>\n </ng-template>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".menu-constructor{display:flex;flex-direction:column;gap:16px;padding:16px;height:calc(100vh - var(--header-height))}.pane{border:1px solid #e2e8f0;border-radius:12px;padding:12px;background:#fff;display:flex;flex-direction:column}.pane.editor{height:100%}.hidden{display:none}.root-title{width:100%}.collapse-btn{background:none;border:none;cursor:pointer;font-size:12px;color:#334155;margin-right:4px;transition:transform .2s ease}.collapse-btn:hover{color:#1e3a8a}.pane-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.pane-header h2{margin:0;font-size:16px}.pane-header .buttons{display:flex;gap:6px}.btn{padding:6px 10px;border-radius:6px;border:1px solid #94a3b8;background:#f8fafc;cursor:pointer;font-size:12px;line-height:1}.btn.primary{border-color:#3b82f6;background:#e0f2fe}.btn.secondary{border-color:#b5b5b5;background:#d1d1d1}.btn.small{padding:2px 6px;margin-left:2px}.btn:hover{background:#e2e8f0}.list-wrapper{flex:1;overflow:auto;min-height:200px}.left-control{gap:6px;display:flex;flex-direction:row;align-items:center;justify-content:center;width:100%}.node{border:1px dashed #cbd5e1;border-radius:8px;margin:6px 0;background:#fafafa;padding:4px}.node-bar{display:flex;flex-direction:row;justify-content:space-between;gap:6px;align-items:center;background:#f1f5f9;padding:4px 6px;border-radius:6px}.grip{cursor:grab;text-align:center;color:#475569}.inp{border:1px solid #cbd5e1;width:100%;border-radius:6px;padding:3px 6px;font-size:12px}.depth-controls{display:flex;gap:2px}.node.dragged{background:#e0f2fe;border-color:#3b82f6;opacity:.85}.drag-branch-preview{background:#fff;border:1px solid #94a3b8;box-shadow:0 6px 18px #00000026;border-radius:8px;padding:6px;min-width:160px}.preview-bar{background:#f8fafc;border-left:3px solid #3b82f6;border-radius:4px;margin:3px 0;padding:4px 8px;font-size:12px}.drag-branch-placeholder{padding:6px 0}.placeholder-row{height:32px;margin:3px 0;background:repeating-linear-gradient(-45deg,#e2e8f0,#e2e8f0 6px,#f1f5f9 6px 12px);border-radius:4px}\n"] }]
558
- }] });
559
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Byb2MtbWVudS1jb25zdHJ1Y3Rvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtcmVnaXN0ZXItYmFzZS9zcmMvbGliL2NvbXBvbmVudHMvbWVudS1jb25zdHJ1Y3Rvci9zcHJvYy1tZW51LWNvbnN0cnVjdG9yLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1yZWdpc3Rlci1iYXNlL3NyYy9saWIvY29tcG9uZW50cy9tZW51LWNvbnN0cnVjdG9yL3Nwcm9jLW1lbnUtY29uc3RydWN0b3IuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBVSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hHLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQ0wsT0FBTyxFQUVQLGFBQWEsRUFDYixjQUFjLEVBQ2QsV0FBVyxHQUNaLE1BQU0sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTlCLE9BQU8sRUFDTCxVQUFVLEVBSVYsY0FBYyxFQUNkLGVBQWUsRUFDZixVQUFVLEdBQ1gsTUFBTSx1Q0FBdUMsQ0FBQztBQUUvQyxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7O0FBU3pFLE1BQU0sT0FBTyw2QkFBNkI7SUFQMUM7UUFRVSxXQUFNLEdBQUcsTUFBTSxDQUFDLDRCQUE0QixDQUFDLENBQUM7UUFDOUMsU0FBSSxHQUFH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Q0FBQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGNvbXB1dGVkLCBEZXN0cm95UmVmLCBpbmplY3QsIE9uSW5pdCwgb3V0cHV0LCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtcbiAgQ2RrRHJhZyxcbiAgQ2RrRHJhZ0Ryb3AsXG4gIENka0RyYWdIYW5kbGUsXG4gIENka0RyYWdQcmV2aWV3LFxuICBDZGtEcm9wTGlzdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XG5pbXBvcnQgeyBBc3luY1BpcGUsIE5nRm9yT2YgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgZmlsdGVyIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBTcHJvY0Fic3RyYWN0TWVudUNvbnN0cnVjdG9yU3RvcmUgfSBmcm9tICcuL3N0b3JlL3Nwcm9jLWFic3RyYWN0LW1lbnUtY29uc3RydWN0b3Iuc3RvcmUnO1xuaW1wb3J0IHtcbiAgRU1QVFlfVVVJRCxcbiAgRmxhdE5vZGUsXG4gIElDbHNNZW51SXRlbUlucHV0LFxuICBJTWVudUNvbnN0cnVjdG9yRXJyb3IsXG4gIE1JR1JBVElPTl9ISU5ULFxuICBORVdfSVRFTV9QUkVGSVgsXG4gIFJPT1RfVElUTEUsXG59IGZyb20gJy4vc3RvcmUvc3Byb2MtbWVudS1jb25zdHJ1Y3Rvci5jb25zdHMnO1xuaW1wb3J0IHsgSUNsc01lbnVJdGVtIH0gZnJvbSAnLi4vcGFnZS1tZW51JztcbmltcG9ydCB7IE1FTlVfQ09OU1RSVUNUT1JfU1RPUkVfVE9LRU4gfSBmcm9tICcuL3N0b3JlL3Nwcm9jLW1lbnUudG9rZW5zJztcblxuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHNlbGVjdG9yOiAnc3Byb2MtbWVudS1jb25zdHJ1Y3RvcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9zcHJvYy1tZW51LWNvbnN0cnVjdG9yLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc3Byb2MtbWVudS1jb25zdHJ1Y3Rvci5jb21wb25lbnQubGVzcyddLFxuICBpbXBvcnRzOiBbQ2RrRHJhZywgQ2RrRHJvcExpc3QsIE5nRm9yT2YsIEZvcm1zTW9kdWxlLCBDZGtEcmFnUHJldmlldywgQ2RrRHJhZ0hhbmRsZSwgQXN5bmNQaXBlXSxcbn0pXG5leHBvcnQgY2xhc3MgU3Byb2NNZW51Q29uc3RydWN0b3JDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBwcml2YXRlIF9zdG9yZSA9IGluamVjdChNRU5VX0NPTlNUUlVDVE9SX1NUT1JFX1RPS0VOKTtcbiAgcHJpdmF0ZSBfcmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gIHByb3RlY3RlZCBST09UX1RJVExFID0gUk9PVF9USVRMRTtcbiAgcHJvdGVjdGVkIGxvYWRpbmckID0gdGhpcy5fc3RvcmUubG9hZGluZyQ7XG4gIHByb3RlY3RlZCBvcmlnaW5hbFRyZWU6IE1hcDxzdHJpbmcsIEZsYXROb2RlPiA9IG5ldyBNYXAoW10pO1xuICBwcm90ZWN0ZWQgTUlHUkFUSU9OX0hJTlQgPSBNSUdSQVRJT05fSElOVDtcbiAgcHJpdmF0ZSBkZWxldGVkSWRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIHB1YmxpYyBlcnJvck1zZ091dHB1dCA9IG91dHB1dDxJTWVudUNvbnN0cnVjdG9yRXJyb3I+KCk7XG5cbiAgLy8g0L/Qu9C+0YHQutC+0LUg0L/RgNC10LTRgdGC0LDQstC70LXQvdC40LUg0LjQtdGA0LDRgNGF0LjRh9C10YHQutC+0LPQviDQvNC10L3RjlxuICBwcm90ZWN0ZWQgZmxhdFRyZWUgPSBzaWduYWw8RmxhdE5vZGVbXT4oW10pO1xuXG4gIC8vINCy0LXRgtC60LAg0Y3Qu9C10LzQtdC90YLQvtCyLCDQutC+0YLQvtGA0LDRjyDQv9C10YDQtdGC0LDRgdC60LjQstCw0LXRgtGB0Y9cbiAgcHJvdGVjdGVkIGRyYWdnZWRCcmFuY2ggPSBzaWduYWw8RmxhdE5vZGVbXT4oW10pO1xuXG4gIC8vINCy0YvRh9C40YHQu9GP0LXQvNC+0LUg0YHQstC+0LnRgdGC0LLQviwg0LLQvtC30LLRgNCw0YnQsNGO0YnQtdC1INGC0L7Qu9GM0LrQviDQstC40LTQuNC80YvQtSAo0L3QtSDRgdCy0LXRgNC90YPRgtGL0LUpINGN0LvQtdC80LXQvdGC0YtcbiAgcHJvdGVjdGVkIHZpc2libGVGbGF0VHJlZSA9IGNvbXB1dGVkPEZsYXROb2RlW10+KCgpID0+IHtcbiAgICBjb25zdCBmbGF0VHJlZSA9IHRoaXMuZmxhdFRyZWUoKTtcbiAgICByZXR1cm4gdGhpcy5fZ2V0VmlzaWJsZUZyb20oZmxhdFRyZWUpO1xuICB9KTtcblxuICBwcml2YXRlIF9wZW5kaW5nUmVjYWxjID0gZmFsc2U7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5fc3RvcmUubWVudUl0ZW1zJFxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcigoYXJyKSA9PiBBcnJheS5pc0FycmF5KGFycikgJiYgYXJyLmxlbmd0aCA+IDApLFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fcmVmKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgodmFsdWUpID0+IHtcbiAgICAgICAgdGhpcy5mbGF0VHJlZS5zZXQodGhpcy5fY29udmVydFRvRmxhdE5vZGUodmFsdWUpKTtcbiAgICAgICAgdGhpcy5vcmlnaW5hbFRyZWUgPSBuZXcgTWFwKHRoaXMuZmxhdFRyZWUoKS5tYXAoKGl0ZW0pID0+IFtpdGVtLmlkLCB7IC4uLml0ZW0gfV0pKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqINCf0LXRgNC10LrQu9GO0YfQsNC10YIg0YHQvtGB0YLQvtGP0L3QuNC1INGB0LLQtdGA0L3Rg9GC0L7RgdGC0Lgg0YPQt9C70LAgKGNvbGxhcHNlL2V4cGFuZClcbiAgICog0J/QvtGB0LvQtSDQuNC30LzQtdC90LXQvdC40Y8g0YHQvtC30LTQsNC10YIg0L3QvtCy0YvQuSDQvNCw0YHRgdC40LIg0LTQu9GPINGC0YDQuNCz0LPQtdGA0LAg0L7QsdC90L7QstC70LXQvdC40Y8g0YHQuNCz0L3QsNC70LBcbiAgICovXG4gIHByb3RlY3RlZCB0b2dnbGVDb2xsYXBzZShub2RlOiBGbGF0Tm9kZSk6IHZvaWQge1xuICAgIG5vZGUuY29sbGFwc2VkID0gIW5vZGUuY29sbGFwc2VkO1xuICAgIHRoaXMuZmxhdFRyZWUuc2V0KFsuLi50aGlzLmZsYXRUcmVlKCldKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQndCw0YfQsNC70L4g0L/QtdGA0LXRgtCw0YHQutC40LLQsNC90LjRjzog0YHQvtGF0YDQsNC90Y/QtdGCINCy0YHRjiDQstC10YLQutGDINGD0LfQu9CwLCDQutC+0YLQvtGA0YPRjiDRgtGP0L3Rg9GCXG4gICAqL1xuICBwcm90ZWN0ZWQgZHJhZ1N0YXJ0ZWQobm9kZTogRmxhdE5vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBicmFuY2ggPSB0aGlzLl9jb2xsZWN0QnJhbmNoKHRoaXMuZmxhdFRyZWUoKSwgbm9kZSk7XG4gICAgdGhpcy5kcmFnZ2VkQnJhbmNoLnNldChicmFuY2gpO1xuICB9XG5cbiAgLyoqXG4gICAqINCX0LDQstC10YDRiNC10L3QuNC1INC/0LXRgNC10YLQsNGB0LrQuNCy0LDQvdC40Y86INC+0YfQuNGJ0LDQtdGCINC40L3RhNC+0YDQvNCw0YbQuNGOINC+INGC0LXQutGD0YnQtdC5INCy0LXRgtC60LVcbiAgICovXG4gIHByb3RlY3RlZCBkcmFnRW5kZWQoKTogdm9pZCB7XG4gICAgdGhpcy5kcmFnZ2VkQnJhbmNoLnNldChbXSk7XG4gIH1cblxuICAvKipcbiAgICog0J7RgdC90L7QstC90LDRjyDQu9C+0LPQuNC60LAgZHJhZyZkcm9wINC/0YDQuCDQvtGC0L/Rg9GB0LrQsNC90LjQuCDRjdC70LXQvNC10L3RgtCwXG4gICAqINCe0L/RgNC10LTQtdC70Y/QtdGCINC90L7QstGD0Y4g0L/QvtC30LjRhtC40Y4g0YPQt9C70LAsINC/0LXRgNC10YHRh9C40YLRi9Cy0LDQtdGCINCz0LvRg9Cx0LjQvdGLINC4INGB0LLRj9C30LhcbiAgICovXG4gIHByb3RlY3RlZCBkcm9wKGV2ZW50OiBDZGtEcmFnRHJvcDxGbGF0Tm9kZVtdPik6IHZvaWQge1xuICAgIGNvbnN0IGJlZm9yZSA9IFsuLi50aGlzLmZsYXRUcmVlKCldO1xuICAgIGNvbnN0IHZpc2libGVCZWZvcmUgPSB0aGlzLl9nZXRWaXNpYmxlRnJvbShiZWZvcmUpO1xuICAgIGNvbnN0IHByZXZJZHggPSBldmVudC5wcmV2aW91c0luZGV4O1xuICAgIGNvbnN0IGN1cnJJZHggPSBldmVudC5jdXJyZW50SW5kZXg7XG5cbiAgICAvLyDQn9C+0LvRg9GH0LDQtdGCINC/0LXRgNC10YLQsNGB0LrQuNCy0LDQtdC80YvQuSDRjdC70LXQvNC10L3RgiDQuNC3INGB0L/QuNGB0LrQsCDQstC40LTQuNC80YvRhVxuICAgIGNvbnN0IGRyYWdnZWRWaXNpYmxlID0gdmlzaWJsZUJlZm9yZVtwcmV2SWR4XTtcbiAgICBpZiAoIWRyYWdnZWRWaXNpYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8g0J3QsNGF0L7QtNC40YIg0LjQvdC00LXQutGBINGD0LfQu9CwINCyINC/0L7Qu9C90L7QvCDQvNCw0YHRgdC40LLQtVxuICAgIGNvbnN0IHN0YXJ0ID0gYmVmb3JlLmZpbmRJbmRleCgobikgPT4gbi5pZCA9PT0gZHJhZ2dlZFZpc2libGUuaWQpO1xuICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyDQodC+0LHQuNGA0LDQtdGCINCy0YHRjiDQstC10YLQutGDLCDQvdCw0YfQuNC90LDRjtGJ0YPRjtGB0Y8g0YEg0L/QtdGA0LXRgtCw0YHQutC40LLQsNC10LzQvtCz0L4g0YPQt9C70LBcbiAgICBjb25zdCBicmFuY2ggPSB0aGlzLl9jb2xsZWN0QnJhbmNoKGJlZm9yZSwgYmVmb3JlW3N0YXJ0XSk7XG4gICAgY29uc3QgYnJhbmNoSWRzID0gbmV3IFNldChicmFuY2gubWFwKChuKSA9PiBuLmlkKSk7XG5cbiAgICAvLyDQo9Cx0LjRgNCw0LXRgiDQstC10YLQutGDINC40Lcg0LjRgdGF0L7QtNC90L7Qs9C+INGB0L/QuNGB0LrQsFxuICAgIGNvbnN0IGZ1bGwgPSBiZWZvcmUuZmlsdGVyKChuKSA9PiAhYnJhbmNoSWRzLmhhcyhuLmlkKSk7XG5cbiAgICAvLyDQntC/0YDQtdC00LXQu9GP0LXRgiDQstC40LTQuNC80YvQtSDRjdC70LXQvNC10L3RgtGLINC/0L7RgdC70LUg0YPQtNCw0LvQtdC90LjRjyDQstC10YLQutC4XG4gICAgY29uc3QgdmlzaWJsZSA9IHRoaXMuX2dldFZpc2libGVGcm9tKGZ1bGwpO1xuICAgIGNvbnN0IHByZXZWaXNpYmxlID0gdmlzaWJsZVtjdXJySWR4IC0gMV0gPz8gbnVsbDtcbiAgICBjb25zdCBuZXh0VmlzaWJsZSA9IHZpc2libGVbY3VycklkeF0gPz8gbnVsbDtcblxuICAgIC8vINCY0L3QtNC10LrRgSDQstGB0YLQsNCy0LrQuCDQstC10YLQutC4INCyINC90L7QstGL0Lkg0YHQv9C40YHQvtC6XG4gICAgY29uc3QgaW5zZXJ0ID0gbmV4dFZpc2libGUgPyBmdWxsLmZpbmRJbmRleCgobikgPT4gbi5pZCA9PT0gbmV4dFZpc2libGUuaWQpIDogZnVsbC5sZW5ndGg7XG5cbiAgICAvLyDQoNCw0YHRgdGH0LjRgtGL0LLQsNC10YIg0LPQu9GD0LHQuNC90YMg0LLRgdGC0LDQstC70Y/QtdC80L7QuSDQstC10YLQutC4INCyINC30LDQstC40YHQuNC80L7RgdGC0Lgg0L7RgiDRgdC+0YHQtdC00LXQuVxuICAgIGxldCB0YXJnZXREZXB0aDtcbiAgICBpZiAocHJldlZpc2libGUgJiYgbmV4dFZpc2libGUpIHtcbiAgICAgIHRhcmdldERlcHRoID1cbiAgICAgICAgcHJldlZpc2libGUuZGVwdGggPCBuZXh0VmlzaWJsZS5kZXB0aCA/IHByZXZWaXNpYmxlLmRlcHRoICsgMSA6IG5leHRWaXNpYmxlLmRlcHRoO1xuICAgIH0gZWxzZSBpZiAocHJldlZpc2libGUgJiYgIW5leHRWaXNpYmxlKSB7XG4gICAgICB0YXJnZXREZXB0aCA9IHByZXZWaXNpYmxlLmRlcHRoO1xuICAgIH0gZWxzZSBpZiAoIXByZXZWaXNpYmxlICYmIG5leHRWaXNpYmxlKSB7XG4gICAgICB0YXJnZXREZXB0aCA9IG5leHRWaXNpYmxlLmRlcHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICB0YXJnZXREZXB0aCA9IDA7XG4gICAgfVxuXG4gICAgLy8g0JLRgdGC0LDQstC70Y/QtdGCINCy0LXRgtC60YMg0LIg0L3QvtCy0L7QtSDQvNC10YHRgtC+XG4gICAgZnVsbC5zcGxpY2UoaW5zZXJ0LCAwLCAuLi5icmFuY2gpO1xuICAgIC8vINCh0LTQstC40LPQsNC10YIg0LPQu9GD0LHQuNC90YMg0LLRgdC10Lkg0LLQtdGC0LrQuFxuICAgIHRoaXMuX2FwcGx5RGVwdGhTaGlmdChicmFuY2gsIHRhcmdldERlcHRoIC0gYnJhbmNoWzBdLmRlcHRoKTtcblxuICAgIC8vINCf0LvQsNC90LjRgNGD0LXRgiDQv9C10YDQtdGB0YfQtdGCINGB0YLRgNGD0LrRgtGD0YDRiyDQtNC10YDQtdCy0LBcbiAgICB0aGlzLl9zY2hlZHVsZVJlY2FsYyhmdWxsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQo9Cy0LXQu9C40YfQuNCy0LDQtdGCINCz0LvRg9Cx0LjQvdGDIChkZXB0aCkg0LrQvtC90LrRgNC10YLQvdC+0LPQviDRg9C30LvQsCwg0LXRgdC70Lgg0LLQvtC30LzQvtC20L3QvlxuICAgKi9cbiAgcHJvdGVjdGVkIGluZGVudChub2RlOiBGbGF0Tm9kZSk6IHZvaWQge1xuICAgIGNvbnN0IGFyciA9IFsuLi50aGlzLmZsYXRUcmVlKCldO1xuICAgIGNvbnN0IGluZGV4ID0gYXJyLmluZGV4T2Yobm9kZSk7XG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHByb3Bvc2VkRGVwdGggPSBub2RlLmRlcHRoICsgMTtcbiAgICAvLyDQmNGJ0LXRgiDQv9C+0LTRhdC+0LTRj9GJ0LXQs9C+INGA0L7QtNC40YLQtdC70Y8g0YEg0L3Rg9C20L3QvtC5INCz0LvRg9Cx0LjQvdC+0LlcbiAgICBjb25zdCBwYXJlbnRDYW5kaWRhdGUgPSBbLi4uYXJyXVxuICAgICAgLnNsaWNlKDAsIGluZGV4KVxuICAgICAgLnJldmVyc2UoKVxuICAgICAgLmZpbmQoKG4pID0+IG4uZGVwdGggPT09IHByb3Bvc2VkRGVwdGggLSAxKTtcblxuICAgIGlmICghcGFyZW50Q2FuZGlkYXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbm9kZS5kZXB0aCA9IHByb3Bvc2VkRGVwdGg7XG4gICAgdGhpcy5fc2NoZWR1bGVSZWNhbGMoYXJyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQo9C80LXQvdGM0YjQsNC10YIg0LPQu9GD0LHQuNC90YMgKGRlcHRoKSDRg9C30LvQsCArINC/0L4g0LLQvtC30LzQvtC20L3QvtGB0YLQuCDQv9GA0LXQstGA0LDRidCw0LXRgiDQtdCz0L4g0LIg0YDQvtC00LjRgtC10LvRj1xuICAgKi9cbiAgcHJvdGVjdGVkIG91dGRlbnQobm9kZTogRmxhdE5vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBhcnIgPSBbLi4udGhpcy5mbGF0VHJlZSgpXTtcbiAgICBjb25zdCBpbmRleCA9IGFyci5pbmRleE9mKG5vZGUpO1xuICAgIGlmIChpbmRleCA9PT0gLTEgfHwgbm9kZS5kZXB0aCA8PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIG5vZGUuZGVwdGggPSBNYXRoLm1heCgwLCBub2RlLmRlcHRoIC0gMSk7XG4gICAgdGhpcy5fc2NoZWR1bGVSZWNhbGMoYXJyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQo9Cy0LXQu9C40YfQuNCy0LDQtdGCINCz0LvRg9Cx0LjQvdGDINCy0YHQtdC5INCy0LXRgtC60Lgg0YPQt9C70LAgKNCy0LzQtdGB0YLQtSDRgSDQv9C+0YLQvtC80LrQsNC80LgpXG4gICAqL1xuICBwcm90ZWN0ZWQgaW5kZW50QnJhbmNoKG5vZGU6IEZsYXROb2RlKTogdm9pZCB7XG4gICAgY29uc3QgYXJyID0gWy4uLnRoaXMuZmxhdFRyZWUoKV07XG4gICAgY29uc3QgaW5kZXggPSBhcnIuaW5kZXhPZihub2RlKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHByb3Bvc2VkRGVwdGggPSBub2RlLmRlcHRoICsgMTtcbiAgICBjb25zdCBwYXJlbnRDYW5kaWRhdGUgPSBbLi4uYXJyXVxuICAgICAgLnNsaWNlKDAsIGluZGV4KVxuICAgICAgLnJldmVyc2UoKVxuICAgICAgLmZpbmQoKG4pID0+IG4uZGVwdGggPT09IHByb3Bvc2VkRGVwdGggLSAxKTtcblxuICAgIGlmICghcGFyZW50Q2FuZGlkYXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYnJhbmNoID0gdGhpcy5fY29sbGVjdEJyYW5jaChhcnIsIG5vZGUpO1xuICAgIHRoaXMuX2FwcGx5RGVwdGhTaGlmdChicmFuY2gsIDEpO1xuXG4gICAgdGhpcy5fc2NoZWR1bGVSZWNhbGMoYXJyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQo9C80LXQvdGM0YjQsNC10YIg0LPQu9GD0LHQuNC90YMg0LLRgdC10Lkg0LLQtdGC0LrQuCDRg9C30LvQsFxuICAgKi9cbiAgcHJvdGVjdGVkIG91dGRlbnRCcmFuY2gobm9kZTogRmxhdE5vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBhcnIgPSBbLi4udGhpcy5mbGF0VHJlZSgpXTtcbiAgICBjb25zdCBicmFuY2ggPSB0aGlzLl9jb2xsZWN0QnJhbmNoKGFyciwgbm9kZSk7XG4gICAgdGhpcy5fYXBwbHlEZXB0aFNoaWZ0KGJyYW5jaCwgLTEpO1xuICAgIHRoaXMuX3NjaGVkdWxlUmVjYWxjKGFycik7XG4gIH1cblxuICAvKipcbiAgICog0J/RgNC+0LLQtdGA0Y/QtdGCLCDQtdGB0YLRjCDQu9C4INGDINGD0LfQu9CwINC00L7Rh9C10YDQvdC40LUg0Y3Qu9C10LzQtdC90YLRi1xuICAgKi9cbiAgcHJvdGVjdGVkIGhhc0NoaWxkcmVuKG5vZGU6IEZsYXROb2RlKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYXJyID0gdGhpcy5mbGF0VHJlZSgpO1xuICAgIGNvbnN0IGlkeCA9IGFyci5pbmRleE9mKG5vZGUpO1xuICAgIGlmIChpZHggPT09IC0xKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSBpZHggKyAxOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBuZXh0ID0gYXJyW2ldO1xuICAgICAgaWYgKG5leHQuZGVwdGggPD0gbm9kZS5kZXB0aCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChuZXh0LmRlcHRoID09PSBub2RlLmRlcHRoICsgMSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNhdmUoKTogdm9pZCB7XG4gICAgLy8g0KTQu9Cw0LMg0LTQu9GPINC70L7Qs9Cz0LjRgNC+0LLQsNC90LjRjyDQvdCwINCy0YDQtdC80Y8g0L7RgtC70LDQtNC60LhcbiAgICBjb25zdCBsb2dnaW5nID0gZmFsc2U7XG5cbiAgICBjb25zdCBjaGFuZ2VkRWxlbWVudHMgPSB0aGlzLmZsYXRUcmVlKCkuZmlsdGVyKChuZXdJdGVtKSA9PiB7XG4gICAgICBjb25zdCBvcmlnaW5hbEl0ZW0gPSB0aGlzLm9yaWdpbmFsVHJlZS5nZXQobmV3SXRlbS5pZCk7XG5cbiAgICAgIC8vINCd0L7QstGL0Lkg0Y3Qu9C10LzQtdC90YJcbiAgICAgIGlmICghb3JpZ2luYWxJdGVtKSB7XG4gICAgICAgIGlmIChsb2dnaW5nKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYNCd0L7QstGL0Lkg0Y3Qu9C10LzQtdC90YIgJHtuZXdJdGVtLnRpdGxlfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgb3JkZXJfbnVtOiBvcmlnaW5hbE9yZGVyTnVtLFxuICAgICAgICBpZF9wYXJlbnQ6IG9yaWdpbmFsSWRQYXJlbnQsXG4gICAgICAgIHRpdGxlOiBvcmlnaW5hbFRpdGxlLFxuICAgICAgICBhbGxvd2VkX3JvbGVzOiBvcmlnaW5hbFJvbGVzLFxuICAgICAgICBjb2RlOiBvcmlnaW5hbENvZGUsXG4gICAgICAgIHJvdXRlOiBvcmlnaW5hbFJvdXRlLFxuICAgICAgICBpY29uOiBvcmlnaW5hbEljb24sXG4gICAgICB9ID0gb3JpZ2luYWxJdGVtO1xuXG4gICAgICBjb25zdCB7XG4gICAgICAgIG9yZGVyX251bTogbmV3T3JkZXJOdW0sXG4gICAgICAgIGlkX3BhcmVudDogbmV3SWRQYXJlbnQsXG4gICAgICAgIHRpdGxlOiBuZXdUaXRsZSxcbiAgICAgICAgYWxsb3dlZF9yb2xlczogbmV3Um9sZXMsXG4gICAgICAgIGNvZGU6IG5ld0NvZGUsXG4gICAgICAgIHJvdXRlOiBuZXdSb3V0ZSxcbiAgICAgICAgaWNvbjogbmV3SWNvbixcbiAgICAgIH0gPSBuZXdJdGVtO1xuXG4gICAgICBjb25zdCBjaGFuZ2VkRmllbGRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBpZiAob3JpZ2luYWxPcmRlck51bSAhPT0gbmV3T3JkZXJOdW0pIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGBvcmRlcl9udW06ICR7b3JpZ2luYWxPcmRlck51bX0g4oaSICR7bmV3T3JkZXJOdW19YCk7XG4gICAgICB9XG4gICAgICBpZiAob3JpZ2luYWxJZFBhcmVudCAhPT0gbmV3SWRQYXJlbnQpIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGBpZF9wYXJlbnQ6ICR7b3JpZ2luYWxJZFBhcmVudH0g4oaSICR7bmV3SWRQYXJlbnR9YCk7XG4gICAgICB9XG4gICAgICBpZiAob3JpZ2luYWxUaXRsZSAhPT0gbmV3VGl0bGUpIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGB0aXRsZTogJHtvcmlnaW5hbFRpdGxlfSDihpIgJHtuZXdUaXRsZX1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcmlnaW5hbENvZGUgIT09IG5ld0NvZGUpIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGBjb2RlOiAke29yaWdpbmFsQ29kZX0g4oaSICR7bmV3Q29kZX1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcmlnaW5hbFJvdXRlICE9PSBuZXdSb3V0ZSkge1xuICAgICAgICBjaGFuZ2VkRmllbGRzLnB1c2goYHJvdXRlOiAke29yaWdpbmFsUm91dGV9IOKGkiAke25ld1JvdXRlfWApO1xuICAgICAgfVxuICAgICAgaWYgKG9yaWdpbmFsSWNvbiAhPT0gbmV3SWNvbikge1xuICAgICAgICBjaGFuZ2VkRmllbGRzLnB1c2goYGljb246ICR7b3JpZ2luYWxJY29ufSDihpIgJHtuZXdJY29ufWApO1xuICAgICAgfVxuICAgICAgaWYgKEpTT04uc3RyaW5naWZ5KG9yaWdpbmFsUm9sZXMpICE9PSBKU09OLnN0cmluZ2lmeShuZXdSb2xlcykpIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGBhbGxvd2VkX3JvbGVzOiAke29yaWdpbmFsUm9sZXN9IOKGkiAke25ld1JvbGVzfWApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY2hhbmdlZEZpZWxkcy5sZW5ndGggPiAwO1xuICAgIH0pO1xuXG4gICAgY29uc3QgaXNCbGFuayA9IChzOiB1bmtub3duKTogYm9vbGVhbiA9PiB0eXBlb2YgcyAhPT0gJ3N0cmluZycgfHwgcy50cmltKCkgPT09ICcnO1xuXG4gICAgY29uc3QgaXNSb3V0ZVZhbGlkID0gKHsgcm91dGUsIGNvZGUgfTogRmxhdE5vZGUpOiBib29sZWFuID0+IHtcbiAgICAgIC8vIHJvdXRlINGB0YfQuNGC0LDQtdGC0YHRjyDQt9Cw0LTQsNC90L3Ri9C8LCDRgtC+0LvRjNC60L4g0LXRgdC70Lgg0Y3RgtC+INC90LXQv9GD0YHRgtCw0Y8g0YHRgtGA0L7QutCwXG4gICAgICBjb25zdCBoYXNSb3V0ZSA9IHJvdXRlLnRyaW0oKSAhPT0gJyc7XG5cbiAgICAgIHJldHVybiAhaGFzUm91dGUgfHwgcm91dGUgPT09IGNvZGU7XG4gICAgfTtcblxuICAgIGNvbnN0IGludmFsaWRDb2RlVGl0bGVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IGludmFsaWRSb3V0ZVRpdGxlczogRmxhdE5vZGVbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBlbCBvZiBjaGFuZ2VkRWxlbWVudHMpIHtcbiAgICAgIGlmIChpc0JsYW5rKGVsLmNvZGUpKSB7XG4gICAgICAgIGludmFsaWRDb2RlVGl0bGVzLnB1c2goZWwudGl0bGUgPz8gJyjQsdC10Lcg0L3QsNC30LLQsNC90LjRjyknKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc1JvdXRlVmFsaWQoZWwpKSB7XG4gICAgICAgIGludmFsaWRSb3V0ZVRpdGxlcy5wdXNoKGVsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaW52YWxpZENvZGVUaXRsZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5lcnJvck1zZ091dHB1dC5lbWl0KHtcbiAgICAgICAgbGFiZWw6ICfQmtC+0L3RgdGC0YDRg9C60YLQvtGAINC80LXQvdGOJyxcbiAgICAgICAgYXBwZWFyYW5jZTogJ25lZ2F0aXZlJyxcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHhzcy9uby1taXhlZC1odG1sXG4gICAgICAgIGNvbnRlbnQ6IGDQktGB0LUg0L/QvtC70Y8gY29kZSDQtNC+0LvQttC90Ysg0LHRi9GC0Ywg0LfQsNC/0L7Qu9C90LXQvdGLLiA8L2JyPlxuICAgICAgICDQmNGB0L/RgNCw0LLRjNGC0LUg0YHQu9C10LTRg9GO0YnQuNC1INC/0L7Qu9GPOiA8L2JyPlxuICAgICAgICAke2ludmFsaWRDb2RlVGl0bGVzLm1hcCgodCkgPT4gYC0gJHt0fWApLmpvaW4oJzwvYnI+Jyl9XG4gICAgICAgIGAsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChpbnZhbGlkUm91dGVUaXRsZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5lcnJvck1zZ091dHB1dC5lbWl0KHtcbiAgICAgICAgbGFiZWw6ICfQmtC+0L3RgdGC0YDRg9C60YLQvtGAINC80LXQvdGOJyxcbiAgICAgICAgYXBwZWFyYW5jZTogJ25lZ2F0aXZlJyxcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHhzcy9uby1taXhlZC1odG1sXG4gICAgICAgIGNvbnRlbnQ6IGDQktGB0LUg0L/QvtC70Y8gY29kZSDQtNC+0LvQttC90Ysg0LHRi9GC0Ywg0YDQsNCy0L3RiyDQv9C+0LvRjiByb3V0ZS4gPC9icj5cbiAgICAgICAg0JjRgdC/0YDQsNCy0YzRgtC1INGB0LvQtdC00YPRjtGJ0LjQtSDQv9C+0LvRjzogPC9icj5cbiAgICAgICAgJHtpbnZhbGlkUm91dGVUaXRsZXMubWFwKCh0KSA9PiBgLSAke3QudGl0bGV9ICgke3QuY29kZX0gfCAke3Qucm91dGV9KWApLmpvaW4oJzwvYnI+Jyl9XG4gICAgICAgIGAsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVsUm91dGUgPSAocm91dGU6IHN0cmluZyk6IHN0cmluZyB8IG51bGwgPT4gKHJvdXRlID09PSAnJyA/IG51bGwgOiByb3V0ZSk7XG5cbiAgICBjb25zdCBub3JtYWxpemVFbGVtZW50ID0gKGVsOiBGbGF0Tm9kZSk6IElDbHNNZW51SXRlbUlucHV0ID0+ICh7XG4gICAgICB0aXRsZTogZWwudGl0bGUudHJpbSgpLFxuICAgICAgcm91dGU6IGVsUm91dGUoZWwucm91dGUudHJpbSgpKSxcbiAgICAgIGNvZGU6IGVsLmNvZGUsXG4gICAgICBpY29uOiBlbC5pY29uLFxuICAgICAgb3JkZXJfbnVtOiBlbC5vcmRlcl9udW0sXG4gICAgICBhbGxvd2VkX3JvbGVzOiBlbC5hbGxvd2VkX3JvbGVzXG4gICAgICAgID8gZWwuYWxsb3dlZF9yb2xlcy5zcGxpdCgnLCcpLm1hcCgodmFsdWUpID0+IHZhbHVlLnRyaW0oKSlcbiAgICAgICAgOiBudWxsLFxuICAgICAgaWRfcGFyZW50OiBlbC5pZF9wYXJlbnQsXG4gICAgfSk7XG5cbiAgICBjb25zdCBvYmplY3RzVG9TYXZlID0gY2hhbmdlZEVsZW1lbnRzXG4gICAgICAuZmlsdGVyKCh7IGlkIH0pID0+ICFpZC5pbmNsdWRlcyhORVdfSVRFTV9QUkVGSVgpKVxuICAgICAgLm1hcCgoZWwpID0+ICh7XG4gICAgICAgIF9zZXQ6IG5vcm1hbGl6ZUVsZW1lbnQoZWwpLFxuICAgICAgICB3aGVyZTogeyBpZDogeyBfZXE6IGVsLmlkIH0gfSxcbiAgICAgIH0pKTtcblxuICAgIGNvbnN0IG9iamVjdHNUb0luc2VydCA9IGNoYW5nZWRFbGVtZW50c1xuICAgICAgLmZpbHRlcigoeyBpZCB9KSA9PiBpZC5pbmNsdWRlcyhORVdfSVRFTV9QUkVGSVgpKVxuICAgICAgLm1hcCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBlbGVtZW50LmlkID0gRU1QVFlfVVVJRDtcblxuICAgICAgICByZXR1cm4gbm9ybWFsaXplRWxlbWVudChlbGVtZW50KTtcbiAgICAgIH0pO1xuXG4gICAgY29uc3Qgb2JqZWN0c1RvRGVsZXRlID0gWy4uLnRoaXMuZGVsZXRlZElkc107XG5cbiAgICBpZiAobG9nZ2luZykge1xuICAgICAgY29uc29sZS5sb2coYNCY0LfQvNC10L3QtdC90L3Ri9C1INGN0LvQtdC80LXQvdGC0YtgLCBvYmplY3RzVG9TYXZlKTtcbiAgICAgIGNvbnNvbGUubG9nKGDQndC+0LLRi9C1INGN0LvQtdC80LXQvdGC0YtgLCBvYmplY3RzVG9JbnNlcnQpO1xuICAgICAgY29uc29sZS5sb2coJ9Cj0LTQsNC70ZHQvdC90YvQtSDRjdC70LXQvNC10L3RgtGLOicsIG9iamVjdHNUb0RlbGV0ZSk7XG4gICAgfVxuXG4gICAgdGhpcy5fc3RvcmUudXBkYXRlTWVudShvYmplY3RzVG9TYXZlLCBvYmplY3RzVG9JbnNlcnQsIG9iamVjdHNUb0RlbGV0ZSk7XG5cbiAgICB0aGlzLmRlbGV0ZWRJZHMgPSBbXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVGb2xkKHN0YXRlOiBib29sZWFuKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIHRoaXMuZmxhdFRyZWUoKSkge1xuICAgICAgaWYgKGVsZW1lbnQudGl0bGUgIT09IFJPT1RfVElUTEUpIHtcbiAgICAgICAgZWxlbWVudC5jb2xsYXBzZWQgPSBzdGF0ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmZsYXRUcmVlLnNldChbLi4udGhpcy5mbGF0VHJlZSgpXSk7XG4gIH1cblxuICAvKipcbiAgICog0KPQtNCw0LvRj9C10YIg0L7QtNC40L0g0Y3Qu9C10LzQtdC90YIg0LjQtyDQtNC10YDQtdCy0LAuXG4gICAqINCf0L7RgtC+0LzQutC4INGB0YLQsNC90L7QstGP0YLRgdGPINC00L7Rh9C10YDQvdC40LzQuCDRjdC70LXQvNC10L3RgtCw0LzQuCDRgNC+0LTQuNGC0LXQu9GPINGD0LTQsNC70ZHQvdC90L7Qs9C+INGD0LfQu9CwLlxuICAgKi9cbiAgcHJvdGVjdGVkIGRlbGV0ZUl0ZW0obm9kZTogRmxhdE5vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBhcnIgPSBbLi4udGhpcy5mbGF0VHJlZSgpXTtcbiAgICBjb25zdCBpbmRleCA9IGFyci5pbmRleE9mKG5vZGUpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJlbnRJZCA9IG5vZGUuaWRfcGFyZW50O1xuICAgIGNvbnN0IG5vZGVEZXB0aCA9IG5vZGUuZGVwdGg7XG5cbiAgICAvLyDQndCw0YXQvtC00LjQvCDQv9C+0YLQvtC80LrQvtCyLCDQutC+0YLQvtGA0YvQtSDQsdGL0LvQuCDQvdCw0L/RgNGP0LzRg9GOINC/0L7QtCDRjdGC0LjQvCDRg9C30LvQvtC8XG4gICAgZm9yIChsZXQgaSA9IGluZGV4ICsgMTsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgbmV4dCA9IGFycltpXTtcbiAgICAgIGlmIChuZXh0LmRlcHRoIDw9IG5vZGVEZXB0aCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChuZXh0LmRlcHRoID09PSBub2RlRGVwdGggKyAxKSB7XG4gICAgICAgIC8vINC/0L7RgtC+0LzQvtC6INGB0YLQsNC90L7QstC40YLRgdGPINGA0LXQsdGR0L3QutC+0Lwg0YDQvtC00LjRgtC10LvRjyDRg9C00LDQu9GR0L3QvdC+0LPQviDRg9C30LvQsFxuICAgICAgICBuZXh0LmlkX3BhcmVudCA9IHBhcmVudElkID8/IG51bGw7XG4gICAgICAgIG5leHQuZGVwdGggPSBub2RlRGVwdGg7IC8vINC/0L7QtNC90LjQvNCw0LXQvCDQvdCwINC+0LTQuNC9INGD0YDQvtCy0LXQvdGMINCy0LLQtdGA0YVcbiAgICAgIH0gZWxzZSBpZiAobmV4dC5kZXB0aCA+IG5vZGVEZXB0aCArIDEpIHtcbiAgICAgICAgLy8g0L/QvtC00L3QuNC80LDQtdC8INC+0YHRgtCw0LvRjNC90YvQtSDQvdCwINC+0LTQuNC9INGD0YDQvtCy0LXQvdGMINCy0LLQtdGA0YVcbiAgICAgICAgbmV4dC5kZXB0aCAtPSAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vINCj0LTQsNC70Y/QtdC8INGB0LDQvCDRjdC70LXQvNC10L3RglxuICAgIGFyci5zcGxpY2UoaW5kZXgsIDEpO1xuXG4gICAgLy8g0JXRgdC70LggaWQg0L3QtSDQstGA0LXQvNC10L3QvdGL0Lkg4oCUINC00L7QsdCw0LLQu9GP0LXQvCDQsiDRgdC/0LjRgdC+0Log0L3QsCDRg9C00LDQu9C10L3QuNC1XG4gICAgaWYgKCFub2RlLmlkLmluY2x1ZGVzKE5FV19JVEVNX1BSRUZJWCkpIHtcbiAgICAgIHRoaXMuZGVsZXRlZElkcy5wdXNoKG5vZGUuaWQpO1xuICAgIH1cblxuICAgIHRoaXMuX3NjaGVkdWxlUmVjYWxjKGFycik7XG4gIH1cblxuICAvKipcbiAgICog0JTQvtCx0LDQstC70Y/QtdGCINC90L7QstGL0Lkg0Y3Qu9C10LzQtdC90YIg0LIg0LTQtdGA0LXQstC+LlxuICAgKiDQn9C+INGD0LzQvtC70YfQsNC90LjRjiDQvtC9INGB0L7Qt9C00LDRkdGC0YHRjyDQutCw0Log0LTQvtGH0LXRgNC90LjQuSDRjdC70LXQvNC10L3RgiByb290LlxuICAgKi9cbiAgcHJvdGVjdGVkIGFkZE5ld0l0ZW0oKTogdm9pZCB7XG4gICAgY29uc3QgYXJyID0gWy4uLnRoaXMuZmxhdFRyZWUoKV07XG5cbiAgICBjb25zdCByb290Tm9kZSA9IGFyci5maW5kKChuKSA9PiBuLnRpdGxlID09PSB0aGlzLlJPT1RfVElUTEUpO1xuXG4gICAgaWYgKCFyb290Tm9kZSkge1xuICAgICAgY29uc29sZS5lcnJvcignUm9vdCDRjdC70LXQvNC10L3RgiDQvdC1INC90LDQudC00LXQvS4g0J3QvtCy0YvQuSDQv9GD0L3QutGCINC90LUg0LzQvtC20LXRgiDQsdGL0YLRjCDQtNC+0LHQsNCy0LvQtdC9LicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG5ld05vZGU6IEZsYXROb2RlID0ge1xuICAgICAgaWQ6IGAke05FV19JVEVNX1BSRUZJWH0ke2NyeXB0by5yYW5kb21VVUlEKCl9YCxcbiAgICAgIGlkX3BhcmVudDogcm9vdE5vZGUuaWQsXG4gICAgICB0aXRsZTogJ9Cd0L7QstGL0Lkg0L/Rg9C90LrRgiDQvNC10L3RjicsXG4gICAgICByb3V0ZTogJycsXG4gICAgICBpY29uOiAnJyxcbiAgICAgIG9yZGVyX251bTogMSxcbiAgICAgIGFsbG93ZWRfcm9sZXM6IG51bGwsXG4gICAgICBjb2xsYXBzZWQ6IHRydWUsXG4gICAgICBjb2RlOiAnJyxcbiAgICAgIGRlcHRoOiByb290Tm9kZS5kZXB0aCArIDEsXG4gICAgfTtcblxuICAgIGNvbnN0IGluc2VydEluZGV4ID0gYXJyLmZpbmRJbmRleCgobikgPT4gbi5pZCA9PT0gcm9vdE5vZGUuaWQpICsgMTtcbiAgICBhcnIuc3BsaWNlKGluc2VydEluZGV4LCAwLCBuZXdOb2RlKTtcblxuICAgIHRoaXMuX3NjaGVkdWxlUmVjYWxjKGFycik7XG4gIH1cblxuICAvKipcbiAgICog0KHQsdGA0LDRgdGL0LLQsNC10YIg0YLQtdC60YPRidC10LUg0YHQvtGB0YLQvtGP0L3QuNC1INCyINC40YHRhdC+0LTQvdC+0LVcbiAgICovXG4gIHByb3RlY3RlZCByZXNldCgpOiB2b2lkIHtcbiAgICBjb25zdCBvcmlnaW5hbE1lbnUgPSBzdHJ1Y3R1cmVkQ2xvbmUodGhpcy5fc3RvcmUub3JpZ2luYWxNZW51KTtcbiAgICB0aGlzLmZsYXRUcmVlLnNldCh0aGlzLl9jb252ZXJ0VG9GbGF0Tm9kZShvcmlnaW5hbE1lbnUpKTtcbiAgICB0aGlzLmRlbGV0ZWRJZHMgPSBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQn9GA0L7QstC10YDRj9C10YIsINC90LDRhdC+0LTQuNGC0YHRjyDQu9C4INGN0LvQtdC80LXQvdGCINCyINGC0LXQutGD0YnQtdC5INC/0LXRgNC10YLQsNGB0LrQuNCy0LDQtdC80L7QuSDQstC10YLQutC1XG4gICAqL1xuICBwcm90ZWN0ZWQgaXNEcmFnZ2VkKG5vZGU6IEZsYXROb2RlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZHJhZ2dlZEJyYW5jaCgpLnNvbWUoKG4pID0+IG4uaWQgPT09IG5vZGUuaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqINCh0L7QsdC40YDQsNC10YIg0LLRgdGOINCy0LXRgtC60YMg0Y3Qu9C10LzQtdC90YLQvtCyINC90LDRh9C40L3QsNGPINGBINGD0LrQsNC30LDQvdC90L7Qs9C+INGD0LfQu9CwICjQstC60LvRjtGH0LDRjyDQv9C+0YLQvtC80LrQvtCyKVxuICAgKi9cbiAgcHJpdmF0ZSBfY29sbGVjdEJyYW5jaChhcnI6IEZsYXROb2RlW10sIHJvb3Q6IEZsYXROb2RlKTogRmxhdE5vZGVbXSB7XG4gICAgY29uc3Qgc3RhcnQgPSBhcnIuaW5kZXhPZihyb290KTtcbiAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IGJyYW5jaDogRmxhdE5vZGVbXSA9IFt7IC4uLnJvb3QgfV07XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0ICsgMTsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgbiA9IGFycltpXTtcbiAgICAgIGlmIChuLmRlcHRoID4gcm9vdC5kZXB0aCkge1xuICAgICAgICBicmFuY2gucHVzaChuKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYnJhbmNoO1xuICB9XG5cbiAgLyoqXG4gICAqINCh0LTQstC40LPQsNC10YIg0LPQu9GD0LHQuNC90YMg0LLRgdC10YUg0Y3Qu9C10LzQtdC90YLQvtCyINCy0LXRgtC60Lgg0L3QsCDRg9C60LDQt9Cw0L3QvdGD0Y4g0YDQsNC30L3QuNGG0YNcbiAgICog0J3QtSDQtNC+0L/Rg9GB0LrQsNC10YIg0L7RgtGA0LjRhtCw0YLQtdC70YzQvdGL0YUg0LPQu9GD0LHQuNC9XG4gICAqL1xuICBwcml2YXRlIF9hcHBseURlcHRoU2hpZnQoYnJhbmNoOiBGbGF0Tm9kZVtdLCBkaWZmOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoZGlmZiA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IG4gb2YgYnJhbmNoKSB7XG4gICAgICBuLmRlcHRoID0gTWF0aC5tYXgoMCwgbi5kZXB0aCArIGRpZmYpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDQn9GA0LXQvtCx0YDQsNC30YPQtdGCINC40LXRgNCw0YDRhdC40YfQtdGB0LrQuNC5IEpTT04g0LIg0L/Qu9C+0YHQutC40Lkg0LzQsNGB0YHQuNCyIEZsYXROb2RlW11cbiAgICog0KHQvtGF0YDQsNC90Y/QtdGCINC/0L7RgNGP0LTQvtC6INGN0LvQtdC80LXQvdGC0L7QsiDQuCDQuNGFINCy0LvQvtC20LXQvdC90L7RgdGC0YxcbiAgICovXG4gIHByaXZhdGUgX2NvbnZlcnRUb0ZsYXROb2RlKGRhdGE6IElDbHNNZW51SXRlbVtdKTogRmxhdE5vZGVbXSB7XG4gICAgLy8g0JPQu9GD0LHQvtC60LDRjyDQutC+0L/QuNGPLCDRh9GC0L7QsdGLINC90LUg0L/QvtGA0YLQuNGC0Ywg0L7RgNC40LPQuNC90LDQu1xuICAgIGNvbnN0IGNsb25lZCA9IHN0cnVjdHVyZWRDbG9uZShkYXRhKTtcblxuICAgIGNvbnN0IG1hcCA9IG5ldyBNYXA8c3RyaW5nLCBJQ2xzTWVudUl0ZW0+KCk7XG4gICAgY29uc3Qgcm9vdHM6IElDbHNNZW51SXRlbVtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgY2xvbmVkKSB7XG4gICAgICBtYXAuc2V0KGl0ZW0uaWQsIGl0ZW0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBjbG9uZWQpIHtcbiAgICAgIGlmIChpdGVtLmlkX3BhcmVudCAmJiBtYXAuaGFzKGl0ZW0uaWRfcGFyZW50KSkge1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBtYXAuZ2V0KGl0ZW0uaWRfcGFyZW50KSE7XG4gICAgICAgIGlmICghcGFyZW50LmNoaWxkcmVuKSB7XG4gICAgICAgICAgcGFyZW50LmNoaWxkcmVuID0gW107XG4gICAgICAgIH1cbiAgICAgICAgcGFyZW50LmNoaWxkcmVuLnB1c2goaXRlbSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByb290cy5wdXNoKGl0ZW0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGZsYXQ6IEZsYXROb2RlW10gPSBbXTtcbiAgICBjb25zdCB3YWxrID0gKG5vZGU6IElDbHNNZW51SXRlbSwgZGVwdGg6IG51bWJlcik6IHZvaWQgPT4ge1xuICAgICAgZmxhdC5wdXNoKHtcbiAgICAgICAgaWQ6IG5vZGUuaWQsXG4gICAgICAgIGlkX3BhcmVudDogbm9kZS5pZF9wYXJlbnQsXG4gICAgICAgIHRpdGxlOiBub2RlLnRpdGxlID8/ICcnLFxuICAgICAgICByb3V0ZTogbm9kZS5yb3V0ZSA/PyAnJyxcbiAgICAgICAgaWNvbjogbm9kZS5pY29uID8/ICcnLFxuICAgICAgICBvcmRlcl9udW06IG5vZGUub3JkZXJfbnVtID8/IDAsXG4gICAgICAgIGFsbG93ZWRfcm9sZXM6IG5vZGUuYWxsb3dlZF9yb2xlcz8uam9pbignLCcpID8/IG51bGwsXG4gICAgICAgIGNvbGxhcHNlZDogbm9kZS50aXRsZSAhPT0gUk9PVF9USVRMRSxcbiAgICAgICAgY29kZTogbm9kZS5jb2RlID8/ICcnLFxuICAgICAgICBkZXB0aCxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAobm9kZS5jaGlsZHJlbj8ubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IHNvcnRlZENoaWxkcmVuID0gWy4uLm5vZGUuY2hpbGRyZW5dLnNvcnQoXG4gICAgICAgICAgKGEsIGIpID0+IChhLm9yZGVyX251bSA/PyAwKSAtIChiLm9yZGVyX251bSA/PyAwKVxuICAgICAgICApO1xuICAgICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIHNvcnRlZENoaWxkcmVuKSB7XG4gICAgICAgICAgd2FsayhjaGlsZCwgZGVwdGggKyAxKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBzb3J0ZWRSb290cyA9IFsuLi5yb290c10uc29ydCgoYSwgYikgPT4gKGEub3JkZXJfbnVtID8/IDApIC0gKGIub3JkZXJfbnVtID8/IDApKTtcbiAgICBmb3IgKGNvbnN0IHJvb3Qgb2Ygc29ydGVkUm9vdHMpIHtcbiAgICAgIHdhbGsocm9vdCwgMCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZsYXQ7XG4gIH1cblxuICAvKipcbiAgICog0JLQvtC30LLRgNCw0YnQsNC10YIg0YHQv9C40YHQvtC6INCy0LjQtNC40LzRi9GFINGN0LvQtdC80LXQvdGC0L7QsiDQvdCwINC+0YHQvdC+0LLQtSDRhNC70LDQs9C+0LIgY29sbGFwc2VkXG4gICAqINCY0YHQv9C+0LvRjNC30YPQtdGCINGB0YLQtdC6INC00LvRjyDQvtGC0YHQu9C10LbQuNCy0LDQvdC40Y8g0YHQstC10YDQvdGD0YLQvtGB0YLQuCDQvdCwINC60LDQttC00L7QvCDRg9GA0L7QstC90LVcbiAgICovXG4gIHByaXZhdGUgX2dldFZpc2libGVGcm9tKGFycjogRmxhdE5vZGVbXSB8ICgoKSA9PiBGbGF0Tm9kZVtdKSk6IEZsYXROb2RlW10ge1xuICAgIGNvbnN0IHNvdXJjZSA9IHR5cGVvZiBhcnIgPT09ICdmdW5jdGlvbicgPyBhcnIoKSA6IGFycjtcbiAgICBjb25zdCBvdXQ6IEZsYXROb2RlW10gPSBbXTtcbiAgICBjb25zdCBjb2xsYXBzZWRTdGFjazogYm9vbGVhbltdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IG4gb2Ygc291cmNlKSB7XG4gICAgICB3aGlsZSAoY29sbGFwc2VkU3RhY2subGVuZ3RoID4gbi5kZXB0aCkge1xuICAgICAgICBjb2xsYXBzZWRTdGFjay5wb3AoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFjb2xsYXBzZWRTdGFjay5pbmNsdWRlcyh0cnVlKSkge1xuICAgICAgICBvdXQucHVzaChuKTtcbiAgICAgICAgY29sbGFwc2VkU3RhY2tbbi5kZXB0aF0gPSAhIW4uY29sbGFwc2VkO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICAvKipcbiAgICog0J/QtdGA0LXRgdGH0LjRgtGL0LLQsNC10YIgb3JkZXJfbnVtINC4IGlkX3BhcmVudCDRgyDQstGB0LXRhSDRjdC70LXQvNC10L3RgtC+0LIg0LzQsNGB0YHQuNCy0LBcbiAgICog0J/QvtGB0LvQtSDQv9C10YDQtdC80LXRidC10L3QuNC5INC/0L7QtNC00LXRgNC20LjQstCw0LXRgiDQutC+0YDRgNC10LrRgtC90YPRjiDRgdGC0YDRg9C60YLRg9GA0YMg0LTQtdGA0LXQstCwXG4gICAqIG9yZGVyX251bSDQvdCw0LfQvdCw0YfQsNC10YLRgdGPINC+0YLQvdC+0YHQuNGC0LXQu9GM0L3QviDRgNC+0LTQuNGC0LXQu9GPICgxLi5OKVxuICAgKi9cbiAgcHJpdmF0ZSBfcmVjYWxjdWxhdGVUcmVlKGFycjogRmxhdE5vZGVbXSk6IHZvaWQge1xuICAgIGNvbnN0IHBhcmVudHM6IEZsYXROb2RlW10gPSBbXTtcbiAgICBjb25zdCBjaGlsZENvdW50ZXJzID0gbmV3IE1hcDxzdHJpbmcgfCBudWxsLCBudW1iZXI+KCk7XG5cbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgYXJyKSB7XG4gICAgICB3aGlsZSAocGFyZW50cy5sZW5ndGggPiAwICYmIHBhcmVudHNbcGFyZW50cy5sZW5ndGggLSAxXS5kZXB0aCA+PSBub2RlLmRlcHRoKSB7XG4gICAgICAgIHBhcmVudHMucG9wKCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhcmVudCA9IHBhcmVudHMubGVuZ3RoID4gMCA/IHBhcmVudHNbcGFyZW50cy5sZW5ndGggLSAxXSA6IG51bGw7XG4gICAgICBub2RlLmlkX3BhcmVudCA9IHBhcmVudCA/IHBhcmVudC5pZCA6IG51bGw7XG5cbiAgICAgIC8vINCy0YvRh9C40YHQu9GP0LXQvCDQv9C+0YDRj9C00LrQvtCy0YvQuSDQvdC+0LzQtdGAINGB0YDQtdC00Lgg0LHRgNCw0YLRjNC10LJcbiAgICAgIGlmIChub2RlLnRpdGxlICE9PSBST09UX1RJVExFKSB7XG4gICAgICAgIGNvbnN0IHBhcmVudElkID0gbm9kZS5pZF9wYXJlbnQgPz8gbnVsbDtcbiAgICAgICAgY29uc3QgY3VycmVudENvdW50ID0gY2hpbGRDb3VudGVycy5nZXQocGFyZW50SWQpID8/IDE7XG4gICAgICAgIG5vZGUub3JkZXJfbnVtID0gY3VycmVudENvdW50O1xuICAgICAgICBjaGlsZENvdW50ZXJzLnNldChwYXJlbnRJZCwgY3VycmVudENvdW50ICsgMSk7XG4gICAgICB9XG5cbiAgICAgIHBhcmVudHMucHVzaChub2RlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog0JDRgdC40L3RhdGA0L7QvdC90L4g0L/Qu9Cw0L3QuNGA0YPQtdGCINC/0LXRgNC10YHRh9C10YIg0LTQtdGA0LXQstCwINGH0LXRgNC10LcgcmVxdWVzdEFuaW1hdGlvbkZyYW1lXG4gICAqINCt0YLQviDQv9GA0LXQtNC+0YLQstGA0LDRidCw0LXRgiDQvNC90L7QttC10YHRgtCy0LXQvdC90YvQtSDQu9C40YjQvdC40LUg0L/QtdGA0LXRgdGH0LXRgtGLINC/0YDQuCDRh9Cw0YHRgtGL0YUg0LjQt9C80LXQvdC10L3QuNGP0YVcbiAgICovXG4gIHByaXZhdGUgX3NjaGVkdWxlUmVjYWxjKGFycjogRmxhdE5vZGVbXSk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9wZW5kaW5nUmVjYWxjKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fcGVuZGluZ1JlY2FsYyA9IHRydWU7XG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgIHRoaXMuX3JlY2FsY3VsYXRlVHJlZShbLi4uYXJyXSk7XG4gICAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5mbGF0VHJlZSgpO1xuICAgICAgaWYgKCF0aGlzLl9hcnJheXNFcXVhbChjdXJyZW50LCBhcnIpKSB7XG4gICAgICAgIHRoaXMuZmxhdFRyZWUuc2V0KFsuLi5hcnJdKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3BlbmRpbmdSZWNhbGMgPSBmYWxzZTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQn9GA0L7QstC10YDRj9C10YIg0YDQsNCy0LXQvdGB0YLQstC+INC00LLRg9GFINC80LDRgdGB0LjQstC+0LIgRmxhdE5vZGUg0L/QviDQutC70Y7Rh9C10LLRi9C8INGB0LLQvtC50YHRgtCy0LDQvFxuICAgKi9cbiAgcHJpdmF0ZSBfYXJyYXlzRXF1YWwoYTogRmxhdE5vZGVbXSwgYjogRmxhdE5vZGVbXSk6IGJvb2xlYW4ge1xuICAgIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBbaSwgZWxlbWVudF0gb2YgYS5lbnRyaWVzKCkpIHtcbiAgICAgIGlmIChcbiAgICAgICAgZWxlbWVudC5pZCAhPT0gYltpXS5pZCB8fFxuICAgICAgICBlbGVtZW50LmRlcHRoICE9PSBiW2ldLmRlcHRoIHx8XG4gICAgICAgIGVsZW1lbnQub3JkZXJfbnVtICE9PSBiW2ldLm9yZGVyX251bVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cIm1lbnUtY29uc3RydWN0b3JcIj5cbiAgPGRpdiBjbGFzcz1cInBhbmUgZWRpdG9yXCI+XG4gICAgPGRpdiBjbGFzcz1cInBhbmUtaGVhZGVyXCI+XG4gICAgICA8aDI+0KDQtdC00LDQutGC0L7RgCDQvNC10L3RjjwvaDI+XG4gICAgICA8ZGl2IGNsYXNzPVwiYnV0dG9uc1wiPlxuICAgICAgICA8YnV0dG9uIFtkaXNhYmxlZF09XCIkYW55KGxvYWRpbmckIHwgYXN5bmMpXCIgY2xhc3M9XCJidG4gc2Vjb25kYXJ5XCIgKGNsaWNrKT1cImFkZE5ld0l0ZW0oKVwiPlxuICAgICAgICAgICtcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gW2Rpc2FibGVkXT1cIiRhbnkobG9hZGluZyQgfCBhc3luYylcIiBjbGFzcz1cImJ0biBzZWNvbmRhcnlcIiAoY2xpY2spPVwicmVzZXQoKVwiPlxuICAgICAgICAgINCh0LHRgNC+0YHQuNGC0YxcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gW2Rpc2FibGVkXT1cIiRhbnkobG9hZGluZyQgfCBhc3luYylcIiBjbGFzcz1cImJ0biBwcmltYXJ5XCIgKGNsaWNrKT1cInNhdmUoKVwiPlxuICAgICAgICAgINCh0L7RhdGA0LDQvdC40YLRjFxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBbZGlzYWJsZWRdPVwiJGFueShsb2FkaW5nJCB8IGFzeW5jKVwiIGNsYXNzPVwiYnRuIHByaW1hcnlcIiAoY2xpY2spPVwiaGFuZGxlRm9sZChmYWxzZSlcIj5cbiAgICAgICAgICDQoNCw0YHQutGA0YvRgtGMINCy0YHQtSDRjdC70LXQvNC10L3RgtGLXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIFtkaXNhYmxlZF09XCIkYW55KGxvYWRpbmckIHwgYXN5bmMpXCIgY2xhc3M9XCJidG4gcHJpbWFyeVwiIChjbGljayk9XCJoYW5kbGVGb2xkKHRydWUpXCI+XG4gICAgICAgICAg0KHQutGA0YvRgtGMINCy0YHQtSDRjdC70LXQvNC10L3RgtGLXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImxpc3Qtd3JhcHBlclwiXG4gICAgICBjZGtEcm9wTGlzdFxuICAgICAgW2Nka0Ryb3BMaXN0RGF0YV09XCJ2aXNpYmxlRmxhdFRyZWUoKVwiXG4gICAgICAoY2RrRHJvcExpc3REcm9wcGVkKT1cImRyb3AoJGV2ZW50KVwiXG4gICAgICBbY2RrRHJvcExpc3RMb2NrQXhpc109XCIneSdcIlxuICAgID5cbiAgICAgIEBmb3IgKG5vZGUgb2YgdmlzaWJsZUZsYXRUcmVlKCk7IHRyYWNrIG5vZGUuaWQgKyAnLScgKyBub2RlLm9yZGVyX251bSkge1xuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJub2RlXCJcbiAgICAgICAgICBbc3R5bGUubWFyZ2luTGVmdC5weF09XCJub2RlLmRlcHRoICogMjRcIlxuICAgICAgICAgIFtjbGFzcy5kcmFnZ2VkXT1cImlzRHJhZ2dlZChub2RlKVwiXG4gICAgICAgICAgY2RrRHJhZ1xuICAgICAgICAgIChjZGtEcmFnU3RhcnRlZCk9XCJkcmFnU3RhcnRlZChub2RlKVwiXG4gICAgICAgICAgKGNka0RyYWdFbmRlZCk9XCJkcmFnRW5kZWQoKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibm9kZS1iYXJcIiBjZGtEcmFnSGFuZGxlPlxuICAgICAgICAgICAgQGlmIChoYXNDaGlsZHJlbihub2RlKSkge1xuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJjb2xsYXBzZS1idG5cIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVDb2xsYXBzZShub2RlKTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAgICAgICBbdGl0bGVdPVwibm9kZS5jb2xsYXBzZWQgPyAn0KDQsNC30LLQtdGA0L3Rg9GC0YwnIDogJ9Ch0LLQtdGA0L3Rg9GC0YwnXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7IG5vZGUuY29sbGFwc2VkID8gJ+KWticgOiAn4pa8JyB9fVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgQGlmIChub2RlLnRpdGxlID09PSBST09UX1RJVExFKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicm9vdC10aXRsZVwiPtCa0L7RgNC90LXQstC+0Lkg0Y3Qu9C10LzQtdC90YI8L3NwYW4+XG4gICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxlZnQtY29udHJvbFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JpcFwiPuKLruKLrjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJpbnAgdGl0bGVcIiBbKG5nTW9kZWwpXT1cIm5vZGUudGl0bGVcIiBwbGFjZWhvbGRlcj1cItCd0LDQt9Cy0LDQvdC40LVcIiAvPlxuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbnAgY29kZVwiXG4gICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm5vZGUuY29kZVwiXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cImNvZGVcIlxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiaW5wIHJvdXRlXCIgWyhuZ01vZGVsKV09XCJub2RlLnJvdXRlXCIgcGxhY2Vob2xkZXI9XCJyb3V0ZVwiIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiaW5wIGljb25cIiBbKG5nTW9kZWwpXT1cIm5vZGUuaWNvblwiIHBsYWNlaG9sZGVyPVwiaWNvblwiIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiaW5wIHJvbGVzXCIgWyhuZ01vZGVsKV09XCJub2RlLmFsbG93ZWRfcm9sZXNcIiBwbGFjZWhvbGRlcj1cItCg0L7Qu9C4XCIgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRlcHRoLWNvbnRyb2xzXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBzbWFsbFwiIChjbGljayk9XCJvdXRkZW50KG5vZGUpXCI+4oaQPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBzbWFsbFwiIChjbGljayk9XCJpbmRlbnQobm9kZSlcIj7ihpI8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICBAaWYgKGhhc0NoaWxkcmVuKG5vZGUpKSB7XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIHNtYWxsXCIgKGNsaWNrKT1cIm91dGRlbnRCcmFuY2gobm9kZSlcIj7ih5A8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gc21hbGxcIiAoY2xpY2spPVwiaW5kZW50QnJhbmNoKG5vZGUpXCI+4oeSPC9idXR0b24+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gc21hbGxcIiAoY2xpY2spPVwiZGVsZXRlSXRlbShub2RlKVwiPtCj0LTQsNC70LjRgtGMPC9idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPG5nLXRlbXBsYXRlIGNka0RyYWdQcmV2aWV3PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRyYWctYnJhbmNoLXByZXZpZXdcIj5cbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgIGNsYXNzPVwicHJldmlldy1iYXJcIlxuICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBuIG9mIGRyYWdnZWRCcmFuY2goKVwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLm1hcmdpbkxlZnQucHhdPVwiKG4uZGVwdGggLSBub2RlLmRlcHRoKSAqIDIwXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7IG4udGl0bGUgfX1cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==