@ai-table/grid 0.0.11 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (324) hide show
  1. package/angular-konva/components/container.component.d.ts +7 -0
  2. package/angular-konva/components/container.component.d.ts.map +1 -0
  3. package/angular-konva/components/container.token.d.ts +3 -0
  4. package/angular-konva/components/container.token.d.ts.map +1 -0
  5. package/angular-konva/components/index.d.ts +4 -0
  6. package/angular-konva/components/index.d.ts.map +1 -0
  7. package/angular-konva/components/shape.component.d.ts +61 -0
  8. package/angular-konva/components/shape.component.d.ts.map +1 -0
  9. package/angular-konva/components/stage.component.d.ts +40 -0
  10. package/angular-konva/components/stage.component.d.ts.map +1 -0
  11. package/angular-konva/index.d.ts +5 -0
  12. package/angular-konva/index.d.ts.map +1 -0
  13. package/angular-konva/interfaces/component.d.ts +49 -0
  14. package/angular-konva/interfaces/component.d.ts.map +1 -0
  15. package/angular-konva/interfaces/config.d.ts +26 -0
  16. package/angular-konva/interfaces/config.d.ts.map +1 -0
  17. package/angular-konva/interfaces/event-object.d.ts +7 -0
  18. package/angular-konva/interfaces/event-object.d.ts.map +1 -0
  19. package/angular-konva/interfaces/index.d.ts +5 -0
  20. package/angular-konva/interfaces/index.d.ts.map +1 -0
  21. package/angular-konva/interfaces/shape.d.ts +42 -0
  22. package/angular-konva/interfaces/shape.d.ts.map +1 -0
  23. package/angular-konva/utils/apply-node-props.d.ts +4 -0
  24. package/angular-konva/utils/apply-node-props.d.ts.map +1 -0
  25. package/angular-konva/utils/common.d.ts +8 -0
  26. package/angular-konva/utils/common.d.ts.map +1 -0
  27. package/angular-konva/utils/index.d.ts +5 -0
  28. package/angular-konva/utils/index.d.ts.map +1 -0
  29. package/angular-konva/utils/types.d.ts +4 -0
  30. package/angular-konva/utils/types.d.ts.map +1 -0
  31. package/angular-konva/utils/update-picture.d.ts +4 -0
  32. package/angular-konva/utils/update-picture.d.ts.map +1 -0
  33. package/components/cell-editors/abstract-cell-editor.component.d.ts +7 -5
  34. package/components/cell-editors/abstract-cell-editor.component.d.ts.map +1 -1
  35. package/components/cell-editors/cell-editor.scss +38 -25
  36. package/components/cell-editors/cell-editor.variables.scss +5 -0
  37. package/components/cell-editors/date/date-editor.component.d.ts.map +1 -1
  38. package/components/cell-editors/link/edit-link/edit-link.component.d.ts +33 -0
  39. package/components/cell-editors/link/edit-link/edit-link.component.d.ts.map +1 -0
  40. package/components/cell-editors/link/link-editor.component.d.ts +36 -0
  41. package/components/cell-editors/link/link-editor.component.d.ts.map +1 -0
  42. package/components/cell-editors/link/link-editor.component.scss +21 -0
  43. package/components/cell-editors/progress/progress-editor.component.d.ts +0 -1
  44. package/components/cell-editors/progress/progress-editor.component.d.ts.map +1 -1
  45. package/components/cell-editors/progress/progress-editor.component.scss +12 -4
  46. package/components/cell-editors/rating/rating-editor.component.d.ts +0 -1
  47. package/components/cell-editors/rating/rating-editor.component.d.ts.map +1 -1
  48. package/components/cell-editors/rating/rating-editor.component.scss +10 -0
  49. package/components/cell-editors/select/select-editor.component.d.ts +1 -3
  50. package/components/cell-editors/select/select-editor.component.d.ts.map +1 -1
  51. package/components/cell-editors/text/text-editor.component.d.ts +0 -1
  52. package/components/cell-editors/text/text-editor.component.d.ts.map +1 -1
  53. package/components/cell-views/select/option.component.d.ts.map +1 -1
  54. package/components/cell-views/select/option.scss +10 -0
  55. package/components/field-menu/field-menu.component.d.ts +8 -3
  56. package/components/field-menu/field-menu.component.d.ts.map +1 -1
  57. package/components/field-property-editor/field-property-editor.component.d.ts +4 -2
  58. package/components/field-property-editor/field-property-editor.component.d.ts.map +1 -1
  59. package/components/index.d.ts +3 -1
  60. package/components/index.d.ts.map +1 -1
  61. package/constants/colors.d.ts +18 -0
  62. package/constants/colors.d.ts.map +1 -0
  63. package/constants/grid.d.ts +17 -1
  64. package/constants/grid.d.ts.map +1 -1
  65. package/constants/icon.d.ts +19 -0
  66. package/constants/icon.d.ts.map +1 -0
  67. package/constants/index.d.ts +5 -1
  68. package/constants/index.d.ts.map +1 -1
  69. package/constants/table.d.ts +60 -0
  70. package/constants/table.d.ts.map +1 -0
  71. package/constants/text.d.ts +22 -0
  72. package/constants/text.d.ts.map +1 -0
  73. package/core/context.d.ts +14 -0
  74. package/core/context.d.ts.map +1 -0
  75. package/core/coordinate.d.ts +96 -0
  76. package/core/coordinate.d.ts.map +1 -0
  77. package/core/index.d.ts +3 -2
  78. package/core/index.d.ts.map +1 -1
  79. package/core/types/ai-table.d.ts +56 -0
  80. package/core/types/ai-table.d.ts.map +1 -0
  81. package/core/types/core.d.ts +29 -23
  82. package/core/types/core.d.ts.map +1 -1
  83. package/core/types/index.d.ts +1 -1
  84. package/core/types/index.d.ts.map +1 -1
  85. package/core/utils/common.d.ts +1 -2
  86. package/core/utils/common.d.ts.map +1 -1
  87. package/core/utils/field.d.ts +1 -1
  88. package/core/utils/field.d.ts.map +1 -1
  89. package/core/utils/index.d.ts +0 -1
  90. package/core/utils/index.d.ts.map +1 -1
  91. package/core/utils/queries.d.ts +5 -5
  92. package/core/utils/queries.d.ts.map +1 -1
  93. package/dom-grid.component.d.ts +11 -0
  94. package/dom-grid.component.d.ts.map +1 -0
  95. package/esm2022/angular-konva/components/container.component.mjs +29 -0
  96. package/esm2022/angular-konva/components/container.token.mjs +3 -0
  97. package/esm2022/angular-konva/components/index.mjs +4 -0
  98. package/esm2022/angular-konva/components/shape.component.mjs +142 -0
  99. package/esm2022/angular-konva/components/stage.component.mjs +123 -0
  100. package/esm2022/angular-konva/index.mjs +5 -0
  101. package/esm2022/angular-konva/interfaces/component.mjs +4 -0
  102. package/esm2022/angular-konva/interfaces/config.mjs +2 -0
  103. package/esm2022/angular-konva/interfaces/event-object.mjs +2 -0
  104. package/esm2022/angular-konva/interfaces/index.mjs +5 -0
  105. package/esm2022/angular-konva/interfaces/shape.mjs +42 -0
  106. package/esm2022/angular-konva/utils/apply-node-props.mjs +67 -0
  107. package/esm2022/angular-konva/utils/common.mjs +48 -0
  108. package/esm2022/angular-konva/utils/index.mjs +5 -0
  109. package/esm2022/angular-konva/utils/types.mjs +2 -0
  110. package/esm2022/angular-konva/utils/update-picture.mjs +7 -0
  111. package/esm2022/components/cell-editors/abstract-cell-editor.component.mjs +12 -7
  112. package/esm2022/components/cell-editors/date/date-editor.component.mjs +6 -3
  113. package/esm2022/components/cell-editors/link/edit-link/edit-link.component.mjs +66 -0
  114. package/esm2022/components/cell-editors/link/link-editor.component.mjs +117 -0
  115. package/esm2022/components/cell-editors/number/number-editor.component.mjs +2 -2
  116. package/esm2022/components/cell-editors/progress/progress-editor.component.mjs +3 -6
  117. package/esm2022/components/cell-editors/rating/rating-editor.component.mjs +4 -7
  118. package/esm2022/components/cell-editors/select/select-editor.component.mjs +11 -16
  119. package/esm2022/components/cell-editors/text/text-editor.component.mjs +10 -11
  120. package/esm2022/components/cell-views/select/option.component.mjs +6 -5
  121. package/esm2022/components/field-menu/field-menu.component.mjs +11 -8
  122. package/esm2022/components/field-property-editor/field-property-editor.component.mjs +17 -12
  123. package/esm2022/components/index.mjs +4 -2
  124. package/esm2022/constants/colors.mjs +18 -0
  125. package/esm2022/constants/editor.mjs +2 -3
  126. package/esm2022/constants/grid.mjs +22 -4
  127. package/esm2022/constants/icon.mjs +26 -0
  128. package/esm2022/constants/index.mjs +6 -2
  129. package/esm2022/constants/table.mjs +62 -0
  130. package/esm2022/constants/text.mjs +23 -0
  131. package/esm2022/core/context.mjs +25 -0
  132. package/esm2022/core/coordinate.mjs +222 -0
  133. package/esm2022/core/index.mjs +4 -3
  134. package/esm2022/core/types/ai-table.mjs +44 -0
  135. package/esm2022/core/types/core.mjs +6 -1
  136. package/esm2022/core/types/index.mjs +2 -2
  137. package/esm2022/core/utils/common.mjs +3 -20
  138. package/esm2022/core/utils/field.mjs +9 -5
  139. package/esm2022/core/utils/index.mjs +1 -2
  140. package/esm2022/core/utils/queries.mjs +4 -4
  141. package/esm2022/dom-grid.component.mjs +82 -0
  142. package/esm2022/grid-base.component.mjs +154 -0
  143. package/esm2022/grid.component.mjs +336 -160
  144. package/esm2022/public-api.mjs +9 -5
  145. package/esm2022/renderer/components/add-field-column.component.mjs +68 -0
  146. package/esm2022/renderer/components/cells.component.mjs +35 -0
  147. package/esm2022/renderer/components/field-head.component.mjs +130 -0
  148. package/esm2022/renderer/components/field-icon.component.mjs +66 -0
  149. package/esm2022/renderer/components/frozen-cells.component.mjs +36 -0
  150. package/esm2022/renderer/components/frozen-heads.component.mjs +117 -0
  151. package/esm2022/renderer/components/frozen-placeholder-cells.component.mjs +38 -0
  152. package/esm2022/renderer/components/heads.component.mjs +38 -0
  153. package/esm2022/renderer/components/hover-row-heads.component.mjs +107 -0
  154. package/esm2022/renderer/components/icon.component.mjs +80 -0
  155. package/esm2022/renderer/components/index.mjs +14 -0
  156. package/esm2022/renderer/components/other-rows.component.mjs +68 -0
  157. package/esm2022/renderer/components/placeholder-cells.component.mjs +33 -0
  158. package/esm2022/renderer/components/text.component.mjs +45 -0
  159. package/esm2022/renderer/creations/create-active-cell-border.mjs +68 -0
  160. package/esm2022/renderer/creations/create-cells.mjs +135 -0
  161. package/esm2022/renderer/creations/create-heads.mjs +45 -0
  162. package/esm2022/renderer/drawers/add-row-layout-drawer.mjs +97 -0
  163. package/esm2022/renderer/drawers/cell-drawer.mjs +586 -0
  164. package/esm2022/renderer/drawers/drawer.mjs +936 -0
  165. package/esm2022/renderer/drawers/layout-drawer.mjs +58 -0
  166. package/esm2022/renderer/drawers/record-row-layout-drawer.mjs +101 -0
  167. package/esm2022/renderer/index.mjs +4 -0
  168. package/esm2022/renderer/renderer.component.mjs +174 -0
  169. package/esm2022/services/event.service.mjs +115 -11
  170. package/esm2022/services/field.service.mjs +28 -5
  171. package/esm2022/services/index.mjs +4 -0
  172. package/esm2022/services/selection.service.mjs +8 -1
  173. package/esm2022/types/avatar.mjs +27 -0
  174. package/esm2022/types/canvas.mjs +2 -0
  175. package/esm2022/types/cell.mjs +2 -0
  176. package/esm2022/types/component-config.mjs +7 -0
  177. package/esm2022/types/field.mjs +1 -1
  178. package/esm2022/types/grid.mjs +16 -2
  179. package/esm2022/types/index.mjs +8 -2
  180. package/esm2022/types/layout.mjs +2 -0
  181. package/esm2022/types/row.mjs +6 -0
  182. package/esm2022/utils/build.mjs +39 -0
  183. package/esm2022/utils/cell.mjs +71 -0
  184. package/esm2022/utils/common.mjs +49 -0
  185. package/esm2022/utils/get-placeholder-cells.mjs +66 -0
  186. package/esm2022/utils/get-text-width.mjs +30 -0
  187. package/esm2022/utils/image-cache.mjs +57 -0
  188. package/esm2022/utils/index.mjs +12 -0
  189. package/esm2022/utils/os.mjs +16 -0
  190. package/esm2022/utils/position.mjs +48 -0
  191. package/esm2022/utils/style.mjs +25 -0
  192. package/esm2022/utils/text-measure.mjs +122 -0
  193. package/esm2022/utils/visible-range.mjs +38 -0
  194. package/fesm2022/ai-table-grid.mjs +5526 -693
  195. package/fesm2022/ai-table-grid.mjs.map +1 -1
  196. package/grid-base.component.d.ts +52 -0
  197. package/grid-base.component.d.ts.map +1 -0
  198. package/grid.component.d.ts +43 -40
  199. package/grid.component.d.ts.map +1 -1
  200. package/package.json +5 -2
  201. package/public-api.d.ts +8 -4
  202. package/public-api.d.ts.map +1 -1
  203. package/renderer/components/add-field-column.component.d.ts +16 -0
  204. package/renderer/components/add-field-column.component.d.ts.map +1 -0
  205. package/renderer/components/cells.component.d.ts +14 -0
  206. package/renderer/components/cells.component.d.ts.map +1 -0
  207. package/renderer/components/field-head.component.d.ts +73 -0
  208. package/renderer/components/field-head.component.d.ts.map +1 -0
  209. package/renderer/components/field-icon.component.d.ts +17 -0
  210. package/renderer/components/field-icon.component.d.ts.map +1 -0
  211. package/renderer/components/frozen-cells.component.d.ts +14 -0
  212. package/renderer/components/frozen-cells.component.d.ts.map +1 -0
  213. package/renderer/components/frozen-heads.component.d.ts +47 -0
  214. package/renderer/components/frozen-heads.component.d.ts.map +1 -0
  215. package/renderer/components/frozen-placeholder-cells.component.d.ts +22 -0
  216. package/renderer/components/frozen-placeholder-cells.component.d.ts.map +1 -0
  217. package/renderer/components/heads.component.d.ts +9 -0
  218. package/renderer/components/heads.component.d.ts.map +1 -0
  219. package/renderer/components/hover-row-heads.component.d.ts +11 -0
  220. package/renderer/components/hover-row-heads.component.d.ts.map +1 -0
  221. package/renderer/components/icon.component.d.ts +37 -0
  222. package/renderer/components/icon.component.d.ts.map +1 -0
  223. package/renderer/components/index.d.ts +14 -0
  224. package/renderer/components/index.d.ts.map +1 -0
  225. package/renderer/components/other-rows.component.d.ts +31 -0
  226. package/renderer/components/other-rows.component.d.ts.map +1 -0
  227. package/renderer/components/placeholder-cells.component.d.ts +22 -0
  228. package/renderer/components/placeholder-cells.component.d.ts.map +1 -0
  229. package/renderer/components/text.component.d.ts +99 -0
  230. package/renderer/components/text.component.d.ts.map +1 -0
  231. package/renderer/creations/create-active-cell-border.d.ts +7 -0
  232. package/renderer/creations/create-active-cell-border.d.ts.map +1 -0
  233. package/renderer/creations/create-cells.d.ts +8 -0
  234. package/renderer/creations/create-cells.d.ts.map +1 -0
  235. package/renderer/creations/create-heads.d.ts +3 -0
  236. package/renderer/creations/create-heads.d.ts.map +1 -0
  237. package/renderer/drawers/add-row-layout-drawer.d.ts +12 -0
  238. package/renderer/drawers/add-row-layout-drawer.d.ts.map +1 -0
  239. package/renderer/drawers/cell-drawer.d.ts +22 -0
  240. package/renderer/drawers/cell-drawer.d.ts.map +1 -0
  241. package/renderer/drawers/drawer.d.ts +136 -0
  242. package/renderer/drawers/drawer.d.ts.map +1 -0
  243. package/renderer/drawers/layout-drawer.d.ts +22 -0
  244. package/renderer/drawers/layout-drawer.d.ts.map +1 -0
  245. package/renderer/drawers/record-row-layout-drawer.d.ts +14 -0
  246. package/renderer/drawers/record-row-layout-drawer.d.ts.map +1 -0
  247. package/renderer/index.d.ts +4 -0
  248. package/renderer/index.d.ts.map +1 -0
  249. package/renderer/renderer.component.d.ts +64 -0
  250. package/renderer/renderer.component.d.ts.map +1 -0
  251. package/services/event.service.d.ts +17 -3
  252. package/services/event.service.d.ts.map +1 -1
  253. package/services/field.service.d.ts +5 -4
  254. package/services/field.service.d.ts.map +1 -1
  255. package/services/index.d.ts +4 -0
  256. package/services/index.d.ts.map +1 -0
  257. package/services/selection.service.d.ts.map +1 -1
  258. package/styles/styles.scss +71 -11
  259. package/types/avatar.d.ts +24 -0
  260. package/types/avatar.d.ts.map +1 -0
  261. package/types/canvas.d.ts +83 -0
  262. package/types/canvas.d.ts.map +1 -0
  263. package/types/cell.d.ts +43 -0
  264. package/types/cell.d.ts.map +1 -0
  265. package/types/component-config.d.ts +50 -0
  266. package/types/component-config.d.ts.map +1 -0
  267. package/types/field.d.ts +27 -1
  268. package/types/field.d.ts.map +1 -1
  269. package/types/grid.d.ts +80 -2
  270. package/types/grid.d.ts.map +1 -1
  271. package/types/index.d.ts +7 -1
  272. package/types/index.d.ts.map +1 -1
  273. package/types/layout.d.ts +11 -0
  274. package/types/layout.d.ts.map +1 -0
  275. package/types/row.d.ts +27 -0
  276. package/types/row.d.ts.map +1 -0
  277. package/utils/build.d.ts +5 -0
  278. package/utils/build.d.ts.map +1 -0
  279. package/utils/cell.d.ts +19 -0
  280. package/utils/cell.d.ts.map +1 -0
  281. package/utils/common.d.ts +20 -0
  282. package/utils/common.d.ts.map +1 -0
  283. package/utils/get-placeholder-cells.d.ts +16 -0
  284. package/utils/get-placeholder-cells.d.ts.map +1 -0
  285. package/utils/get-text-width.d.ts +9 -0
  286. package/utils/get-text-width.d.ts.map +1 -0
  287. package/utils/image-cache.d.ts +16 -0
  288. package/utils/image-cache.d.ts.map +1 -0
  289. package/utils/index.d.ts +12 -0
  290. package/utils/index.d.ts.map +1 -0
  291. package/utils/os.d.ts +4 -0
  292. package/utils/os.d.ts.map +1 -0
  293. package/utils/position.d.ts +20 -0
  294. package/utils/position.d.ts.map +1 -0
  295. package/utils/style.d.ts +4 -0
  296. package/utils/style.d.ts.map +1 -0
  297. package/utils/text-measure.d.ts +32 -0
  298. package/utils/text-measure.d.ts.map +1 -0
  299. package/utils/visible-range.d.ts +13 -0
  300. package/utils/visible-range.d.ts.map +1 -0
  301. package/components/cell-editors/link/number-editor.component.d.ts +0 -8
  302. package/components/cell-editors/link/number-editor.component.d.ts.map +0 -1
  303. package/constants/field.d.ts +0 -20
  304. package/constants/field.d.ts.map +0 -1
  305. package/core/action/field.d.ts +0 -12
  306. package/core/action/field.d.ts.map +0 -1
  307. package/core/action/general.d.ts +0 -5
  308. package/core/action/general.d.ts.map +0 -1
  309. package/core/action/index.d.ts +0 -12
  310. package/core/action/index.d.ts.map +0 -1
  311. package/core/action/record.d.ts +0 -12
  312. package/core/action/record.d.ts.map +0 -1
  313. package/core/types/action.d.ts +0 -64
  314. package/core/types/action.d.ts.map +0 -1
  315. package/core/utils/weak-map.d.ts +0 -3
  316. package/core/utils/weak-map.d.ts.map +0 -1
  317. package/esm2022/components/cell-editors/link/number-editor.component.mjs +0 -25
  318. package/esm2022/constants/field.mjs +0 -25
  319. package/esm2022/core/action/field.mjs +0 -57
  320. package/esm2022/core/action/general.mjs +0 -116
  321. package/esm2022/core/action/index.mjs +0 -9
  322. package/esm2022/core/action/record.mjs +0 -44
  323. package/esm2022/core/types/action.mjs +0 -18
  324. package/esm2022/core/utils/weak-map.mjs +0 -2
@@ -1,191 +1,367 @@
1
- import { CommonModule, NgClass, NgComponentOutlet, NgForOf, NgTemplateOutlet } from '@angular/common';
2
- import { ChangeDetectionStrategy, Component, computed, DestroyRef, ElementRef, inject, input, model, NgZone, output } from '@angular/core';
1
+ import { afterNextRender, ChangeDetectionStrategy, Component, computed, effect, signal, viewChild } from '@angular/core';
3
2
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
- import { FormsModule } from '@angular/forms';
5
- import { ThyAction } from 'ngx-tethys/action';
6
- import { ThyAvatarModule } from 'ngx-tethys/avatar';
7
- import { ThyCheckboxModule } from 'ngx-tethys/checkbox';
8
- import { ThyDatePickerFormatPipe } from 'ngx-tethys/date-picker';
9
- import { ThyDropdownDirective, ThyDropdownMenuComponent } from 'ngx-tethys/dropdown';
10
- import { ThyFlexibleText } from 'ngx-tethys/flexible-text';
11
- import { ThyIcon } from 'ngx-tethys/icon';
12
- import { ThyPopoverModule } from 'ngx-tethys/popover';
13
- import { ThyProgress } from 'ngx-tethys/progress';
14
- import { ThyRate } from 'ngx-tethys/rate';
15
- import { ThyStopPropagationDirective } from 'ngx-tethys/shared';
16
- import { ThyTag } from 'ngx-tethys/tag';
17
- import { mergeWith } from 'rxjs/operators';
18
- import { ProgressEditorComponent, SelectOptionComponent } from './components';
19
- import { FieldMenu } from './components/field-menu/field-menu.component';
20
- import { AITableFieldPropertyEditor } from './components/field-property-editor/field-property-editor.component';
21
- import { DBL_CLICK_EDIT_TYPE, DefaultFieldMenus, MOUSEOVER_EDIT_TYPE } from './constants';
22
- import { Actions, AITableFieldType, AITableSelectOptionStyle, createAITable, createDefaultField, getDefaultRecord } from './core';
23
- import { IsSelectRecordPipe, MemberSettingPipe, SelectOptionPipe, SelectOptionsPipe, SelectSettingPipe, UserPipe } from './pipes/grid.pipe';
3
+ import { filter, fromEvent } from 'rxjs';
4
+ import { AI_TABLE_CELL, AI_TABLE_FIELD_ADD_BUTTON, AI_TABLE_FIELD_ADD_BUTTON_WIDTH, AI_TABLE_FIELD_HEAD, AI_TABLE_FIELD_HEAD_HEIGHT, AI_TABLE_FIELD_HEAD_MORE, AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX, AI_TABLE_POPOVER_LEFT_OFFSET, AI_TABLE_ROW_ADD_BUTTON, AI_TABLE_ROW_HEAD_WIDTH, AI_TABLE_ROW_SELECT_CHECKBOX, DBL_CLICK_EDIT_TYPE, DEFAULT_POINT_POSITION, DEFAULT_SCROLL_STATE, MOUSEOVER_EDIT_TYPE } from './constants';
5
+ import { AITable, Coordinate, RendererContext } from './core';
6
+ import { AITableGridBase } from './grid-base.component';
7
+ import { AITableRenderer } from './renderer/renderer.component';
24
8
  import { AITableGridEventService } from './services/event.service';
25
- import { AI_TABLE_GRID_FIELD_SERVICE_MAP, AITableGridFieldService } from './services/field.service';
9
+ import { AITableGridFieldService } from './services/field.service';
26
10
  import { AITableGridSelectionService } from './services/selection.service';
11
+ import { AITableMouseDownType } from './types';
12
+ import { buildGridLinearRows, getColumnIndicesMap, getDetailByTargetName, handleMouseStyle, isWindows } from './utils';
13
+ import { getMousePosition } from './utils/position';
27
14
  import * as i0 from "@angular/core";
28
- import * as i1 from "@angular/common";
29
- import * as i2 from "@angular/forms";
30
- import * as i3 from "ngx-tethys/checkbox";
31
- import * as i4 from "ngx-tethys/avatar";
32
- export class AITableGrid {
15
+ export class AITableGrid extends AITableGridBase {
33
16
  constructor() {
34
- this.aiRecords = model.required();
35
- this.aiFields = model.required();
36
- this.aiFieldConfig = input();
37
- this.aiReadonly = input();
38
- this.aiPlugins = input();
39
- this.aiReferences = input();
40
- this.aiBuildRenderDataFn = input();
41
- this.AITableFieldType = AITableFieldType;
42
- this.AITableSelectOptionStyle = AITableSelectOptionStyle;
43
- this.gridData = computed(() => {
44
- if (this.aiBuildRenderDataFn && this.aiBuildRenderDataFn() && this.aiTable) {
45
- return this.aiBuildRenderDataFn()(this.aiTable);
46
- }
17
+ super();
18
+ this.fieldHeadHeight = AI_TABLE_FIELD_HEAD_HEIGHT;
19
+ this.ADD_BUTTON_WIDTH = AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
20
+ this.containerRect = signal({ width: 0, height: 0 });
21
+ this.hasContainerRect = computed(() => {
22
+ return this.containerRect().width > 0 && this.containerRect().height > 0;
23
+ });
24
+ this.container = viewChild('container');
25
+ this.verticalBarRef = viewChild('verticalBar');
26
+ this.horizontalBarRef = viewChild('horizontalBar');
27
+ this.linearRows = computed(() => {
28
+ return buildGridLinearRows(this.gridData().records);
29
+ });
30
+ this.visibleColumnsMap = computed(() => {
31
+ const columns = AITable.getVisibleFields(this.aiTable);
32
+ return new Map(columns?.map((item, index) => [item._id, index]));
33
+ });
34
+ this.visibleRowsIndexMap = computed(() => {
35
+ return new Map(this.linearRows().map((row, index) => [row._id, index]));
36
+ });
37
+ this.containerElement = computed(() => {
38
+ return this.container().nativeElement;
39
+ });
40
+ this.rendererConfig = computed(() => {
41
+ const fields = AITable.getVisibleFields(this.aiTable);
42
+ const coordinate = new Coordinate({
43
+ container: this.containerElement(),
44
+ rowHeight: AI_TABLE_FIELD_HEAD_HEIGHT,
45
+ rowCount: this.linearRows().length,
46
+ columnCount: fields.length,
47
+ rowInitSize: AI_TABLE_FIELD_HEAD_HEIGHT,
48
+ columnInitSize: AI_TABLE_ROW_HEAD_WIDTH,
49
+ rowIndicesMap: {},
50
+ columnIndicesMap: getColumnIndicesMap(fields),
51
+ frozenColumnCount: 1
52
+ });
47
53
  return {
48
- records: this.aiRecords(),
49
- fields: this.aiFields()
54
+ aiTable: this.aiTable,
55
+ container: this.containerElement(),
56
+ coordinate: coordinate,
57
+ containerWidth: this.containerRect().width,
58
+ containerHeight: this.containerRect().height,
59
+ references: this.aiReferences()
50
60
  };
51
61
  });
52
- this.isSelectedAll = computed(() => {
53
- return this.aiTable.selection().selectedRecords.size === this.aiRecords().length;
54
- });
55
- this.onChange = output();
56
- this.aiTableInitialized = output();
57
- this.ngZone = inject(NgZone);
58
- this.elementRef = inject(ElementRef);
59
- this.destroyRef = inject(DestroyRef);
60
- this.aiTableGridFieldService = inject(AITableGridFieldService);
61
- this.aiTableGridEventService = inject(AITableGridEventService);
62
- this.aiTableGridSelectionService = inject(AITableGridSelectionService);
63
- }
64
- ngOnInit() {
65
- this.initAITable();
66
- this.initService();
67
- this.buildFieldMenus();
68
- this.subscribeEvents();
69
- }
70
- initAITable() {
71
- this.aiTable = createAITable(this.aiRecords, this.aiFields);
72
- this.aiPlugins()?.forEach((plugin) => {
73
- this.aiTable = plugin(this.aiTable);
74
- });
75
- this.aiTableInitialized.emit(this.aiTable);
76
- this.aiTable.onChange = () => {
77
- this.onChange.emit({
78
- records: this.aiRecords(),
79
- fields: this.aiFields(),
80
- actions: this.aiTable.actions
62
+ this.coordinate = computed(() => {
63
+ return this.rendererConfig().coordinate;
64
+ });
65
+ this.scrollTotalHeight = computed(() => {
66
+ return Math.max(this.coordinate().totalHeight, this.containerRect().height - this.fieldHeadHeight);
67
+ });
68
+ this.scrollAction = (options) => {
69
+ if (this.timer) {
70
+ cancelAnimationFrame(this.timer);
71
+ }
72
+ this.timer = requestAnimationFrame(() => {
73
+ const { deltaX, deltaY, shiftKey } = options;
74
+ const fixedDeltaY = shiftKey && isWindows ? 0 : deltaY;
75
+ const fixedDeltaX = shiftKey && isWindows ? deltaY : deltaX;
76
+ const horizontalBar = this.horizontalBarRef()?.nativeElement;
77
+ const verticalBar = this.verticalBarRef()?.nativeElement;
78
+ if (horizontalBar) {
79
+ horizontalBar.scrollLeft = horizontalBar.scrollLeft + fixedDeltaX;
80
+ }
81
+ if (verticalBar) {
82
+ verticalBar.scrollTop = verticalBar.scrollTop + fixedDeltaY;
83
+ }
84
+ options.callback && options.callback();
85
+ this.timer = null;
86
+ });
87
+ };
88
+ this.resetScrolling = () => {
89
+ this.aiTable.context.setScrollState({
90
+ isScrolling: false
81
91
  });
82
92
  };
93
+ this.horizontalScroll = (e) => {
94
+ const { scrollLeft } = e.target;
95
+ this.aiTable.context.setScrollState({
96
+ scrollLeft,
97
+ isScrolling: true
98
+ });
99
+ this.resetScrolling();
100
+ };
101
+ afterNextRender(() => {
102
+ this.setContainerRect();
103
+ this.bindGlobalMousedown();
104
+ this.containerResizeListener();
105
+ this.bindWheel();
106
+ });
107
+ effect(() => {
108
+ if (this.hasContainerRect() && this.horizontalBarRef() && this.verticalBarRef()) {
109
+ this.bindScrollBarScroll();
110
+ }
111
+ });
112
+ effect(() => {
113
+ if (this.aiTable.context?.pointPosition()) {
114
+ this.toggleHoverCellEditor();
115
+ }
116
+ });
83
117
  }
84
- initService() {
85
- this.aiTableGridEventService.initialize(this.aiTable, this.aiFieldConfig()?.fieldPropertyEditor);
86
- this.aiTableGridSelectionService.initialize(this.aiTable);
87
- this.aiTableGridEventService.registerEvents(this.elementRef.nativeElement);
88
- this.aiTableGridFieldService.initAIFieldConfig(this.aiFieldConfig());
89
- AI_TABLE_GRID_FIELD_SERVICE_MAP.set(this.aiTable, this.aiTableGridFieldService);
118
+ ngOnInit() {
119
+ super.ngOnInit();
120
+ this.initContext();
90
121
  }
91
- buildFieldMenus() {
92
- this.fieldMenus = this.aiFieldConfig()?.fieldMenus ?? DefaultFieldMenus;
122
+ ngOnDestroy() {
123
+ this.resizeObserver?.disconnect();
93
124
  }
94
- addRecord() {
95
- Actions.addRecord(this.aiTable, getDefaultRecord(this.aiFields()), [this.aiRecords().length]);
125
+ initContext() {
126
+ this.aiTable.context = new RendererContext({
127
+ linearRows: this.linearRows,
128
+ visibleColumnsMap: this.visibleColumnsMap,
129
+ visibleRowsIndexMap: this.visibleRowsIndexMap,
130
+ pointPosition: signal(DEFAULT_POINT_POSITION),
131
+ scrollState: signal(DEFAULT_SCROLL_STATE),
132
+ scrollAction: this.scrollAction
133
+ });
96
134
  }
97
- selectRecord(recordId) {
98
- this.aiTableGridSelectionService.selectRecord(recordId);
135
+ stageMousemove(e) {
136
+ if (this.timer) {
137
+ cancelAnimationFrame(this.timer);
138
+ }
139
+ this.timer = requestAnimationFrame(() => {
140
+ const targetName = e.event.target.name();
141
+ const gridStage = e.event.currentTarget.getStage();
142
+ const pos = gridStage?.getPointerPosition();
143
+ if (pos == null)
144
+ return;
145
+ const { context } = this.aiTable;
146
+ const { x, y } = pos;
147
+ const curMousePosition = getMousePosition(x, y, this.coordinate(), AITable.getVisibleFields(this.aiTable), context, targetName);
148
+ handleMouseStyle(curMousePosition.realTargetName, curMousePosition.areaType, this.containerElement());
149
+ context.setPointPosition(curMousePosition);
150
+ this.timer = null;
151
+ });
99
152
  }
100
- toggleSelectAll(checked) {
101
- this.aiTableGridSelectionService.toggleSelectAll(checked);
153
+ stageMousedown(e) {
154
+ const mouseEvent = e.event.evt;
155
+ const _targetName = e.event.target.name();
156
+ const { targetName, fieldId, recordId } = getDetailByTargetName(_targetName);
157
+ switch (targetName) {
158
+ case AI_TABLE_FIELD_HEAD:
159
+ mouseEvent.preventDefault();
160
+ if (!fieldId)
161
+ return;
162
+ this.aiTableGridSelectionService.selectField(fieldId);
163
+ return;
164
+ case AI_TABLE_CELL:
165
+ if (!recordId || !fieldId)
166
+ return;
167
+ this.aiTableGridEventService.closeCellEditor();
168
+ this.aiTableGridSelectionService.selectCell(recordId, fieldId);
169
+ return;
170
+ case AI_TABLE_ROW_ADD_BUTTON:
171
+ case AI_TABLE_FIELD_ADD_BUTTON:
172
+ case AI_TABLE_ROW_SELECT_CHECKBOX:
173
+ case AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX:
174
+ return;
175
+ default:
176
+ this.aiTableGridSelectionService.clearSelection();
177
+ }
102
178
  }
103
- addField(gridColumnBlank) {
104
- const field = createDefaultField(this.aiTable, AITableFieldType.text);
105
- this.aiTableGridFieldService.editFieldProperty(gridColumnBlank, this.aiTable, field, false);
179
+ stageClick(e) {
180
+ const mouseEvent = e.event.evt;
181
+ mouseEvent.preventDefault();
182
+ const { context } = this.aiTable;
183
+ const { targetName, rowIndex: pointRowIndex } = context.pointPosition();
184
+ if (mouseEvent.button !== AITableMouseDownType.Left)
185
+ return;
186
+ switch (targetName) {
187
+ case AI_TABLE_ROW_ADD_BUTTON: {
188
+ this.aiTableGridSelectionService.clearSelection();
189
+ this.addRecord();
190
+ return;
191
+ }
192
+ case AI_TABLE_ROW_SELECT_CHECKBOX: {
193
+ const pointRecordId = context.linearRows()[pointRowIndex]?._id;
194
+ this.selectRecord(pointRecordId);
195
+ return;
196
+ }
197
+ case AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX: {
198
+ const isChecked = this.aiTable.selection().selectedRecords.size === this.aiTable.records().length;
199
+ this.toggleSelectAll(!isChecked);
200
+ return;
201
+ }
202
+ case AI_TABLE_FIELD_ADD_BUTTON: {
203
+ this.aiTableGridSelectionService.clearSelection();
204
+ const fieldGroupRect = e.event.target.getParent()?.getClientRect();
205
+ const containerRect = this.containerElement().getBoundingClientRect();
206
+ this.addField(this.containerElement(), {
207
+ x: fieldGroupRect.x + containerRect.x,
208
+ y: containerRect.y + fieldGroupRect.y + fieldGroupRect.height
209
+ });
210
+ return;
211
+ }
212
+ case AI_TABLE_FIELD_HEAD_MORE:
213
+ mouseEvent.preventDefault();
214
+ const _targetName = e.event.target.name();
215
+ const { fieldId } = getDetailByTargetName(_targetName);
216
+ if (fieldId) {
217
+ const moreRect = e.event.target.getClientRect();
218
+ const fieldGroupRect = e.event.target.getParent()?.getParent()?.getClientRect();
219
+ const containerRect = this.containerElement().getBoundingClientRect();
220
+ const position = {
221
+ x: containerRect.x + moreRect.x,
222
+ y: containerRect.y + moreRect.y + moreRect.height
223
+ };
224
+ const editOriginPosition = {
225
+ x: AI_TABLE_POPOVER_LEFT_OFFSET + fieldGroupRect.x,
226
+ y: containerRect.y + fieldGroupRect.y + fieldGroupRect.height
227
+ };
228
+ const editOrigin = this.containerElement().querySelector('.konvajs-content');
229
+ this.aiTableGridFieldService.openFieldMenu(this.aiTable, {
230
+ fieldId: fieldId,
231
+ fieldMenus: this.fieldMenus,
232
+ origin: this.containerElement(),
233
+ position,
234
+ editOrigin: editOrigin,
235
+ editOriginPosition
236
+ });
237
+ }
238
+ return;
239
+ }
106
240
  }
107
- subscribeEvents() {
108
- this.ngZone.runOutsideAngular(() => {
109
- this.aiTableGridEventService.dblClickEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
110
- this.dblClick(event);
111
- });
112
- this.aiTableGridEventService.mousedownEvent$
113
- .pipe(mergeWith(this.aiTableGridEventService.globalMousedownEvent$), takeUntilDestroyed(this.destroyRef))
114
- .subscribe((event) => {
115
- this.aiTableGridSelectionService.updateSelect(event);
116
- });
117
- this.aiTableGridEventService.mouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
118
- this.mouseoverHandle(event);
119
- });
120
- this.aiTableGridEventService.globalMouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
121
- this.closeHoverCellEditor(event);
241
+ stageDblclick(e) {
242
+ const _targetName = e.event.target.name();
243
+ const { fieldId, recordId } = getDetailByTargetName(_targetName);
244
+ if (!recordId || !fieldId) {
245
+ return;
246
+ }
247
+ const field = this.aiTable.fieldsMap()[fieldId];
248
+ const fieldType = field.type;
249
+ if (!DBL_CLICK_EDIT_TYPE.includes(fieldType)) {
250
+ return;
251
+ }
252
+ const popoverRef = this.aiTableGridEventService.openCellEditor(this.aiTable, {
253
+ container: this.containerElement(),
254
+ coordinate: this.coordinate(),
255
+ fieldId: fieldId,
256
+ recordId: recordId
257
+ });
258
+ if (popoverRef && !(this.aiFieldConfig()?.fieldPropertyEditor && this.aiFieldConfig()?.fieldPropertyEditor[fieldType])) {
259
+ popoverRef.componentInstance.updateFieldValue.subscribe((value) => {
260
+ this.aiUpdateFieldValue.emit(value);
122
261
  });
262
+ }
263
+ }
264
+ bindWheel() {
265
+ fromEvent(this.containerElement(), 'wheel', { passive: false })
266
+ .pipe(takeUntilDestroyed(this.destroyRef))
267
+ .subscribe((e) => {
268
+ e.preventDefault();
269
+ this.aiTableGridEventService.closeCellEditor();
270
+ this.scrollAction({ deltaX: e.deltaX, deltaY: e.deltaY, shiftKey: e.shiftKey });
123
271
  });
124
272
  }
125
- dblClick(event) {
126
- const cellDom = event.target.closest('.grid-cell');
127
- const type = cellDom && cellDom.getAttribute('type');
128
- if (type && DBL_CLICK_EDIT_TYPE.includes(type)) {
129
- this.aiTableGridEventService.openEdit(cellDom);
130
- }
273
+ bindScrollBarScroll() {
274
+ fromEvent(this.horizontalBarRef().nativeElement, 'scroll', { passive: true })
275
+ .pipe(takeUntilDestroyed(this.destroyRef))
276
+ .subscribe((e) => {
277
+ this.horizontalScroll(e);
278
+ });
279
+ fromEvent(this.verticalBarRef().nativeElement, 'scroll', { passive: true })
280
+ .pipe(takeUntilDestroyed(this.destroyRef))
281
+ .subscribe((e) => {
282
+ this.verticalScroll(e);
283
+ });
131
284
  }
132
- mouseoverHandle(event) {
133
- if (this.mouseoverRef) {
134
- this.mouseoverRef?.close();
135
- }
136
- const cellDom = event.target.closest('.grid-cell');
137
- const type = cellDom && cellDom.getAttribute('type');
138
- if (type && MOUSEOVER_EDIT_TYPE.includes(type)) {
139
- this.mouseoverRef = this.aiTableGridEventService.openEdit(cellDom);
140
- }
285
+ bindGlobalMousedown() {
286
+ fromEvent(document, 'mousedown', { passive: true })
287
+ .pipe(filter((e) => e.target instanceof Element && !this.containerElement().contains(e.target)), takeUntilDestroyed(this.destroyRef))
288
+ .subscribe(() => {
289
+ this.aiTableGridSelectionService.clearSelection();
290
+ });
291
+ }
292
+ verticalScroll(e) {
293
+ const { scrollTop } = e.target;
294
+ this.aiTable.context.setScrollState({
295
+ scrollTop,
296
+ isScrolling: true
297
+ });
298
+ this.resetScrolling();
299
+ }
300
+ setContainerRect() {
301
+ this.containerRect.set({
302
+ width: this.containerElement().offsetWidth,
303
+ height: this.containerElement().offsetHeight
304
+ });
305
+ }
306
+ containerResizeListener() {
307
+ this.resizeObserver = new ResizeObserver(() => {
308
+ const containerWidth = this.containerElement().offsetWidth;
309
+ const totalWidth = this.coordinate().totalWidth + this.ADD_BUTTON_WIDTH;
310
+ this.setContainerRect();
311
+ if (containerWidth >= totalWidth) {
312
+ this.aiTable.context.setScrollState({ scrollLeft: 0 });
313
+ return;
314
+ }
315
+ });
316
+ this.resizeObserver.observe(this.containerElement());
141
317
  }
142
- closeHoverCellEditor(e) {
143
- if (this.mouseoverRef) {
144
- const hasGrid = e.target && e.target.closest('.ai-table-grid');
145
- const hasCellEditor = e.target && e.target.closest('.grid-cell-editor');
146
- if (!hasGrid && !hasCellEditor) {
147
- this.mouseoverRef.close();
318
+ toggleHoverCellEditor() {
319
+ const { realTargetName } = this.aiTable.context?.pointPosition();
320
+ const { targetName, fieldId, recordId } = getDetailByTargetName(realTargetName);
321
+ const editingCell = this.aiTableGridEventService.getCurrentEditCell();
322
+ if (targetName === AI_TABLE_CELL && recordId && fieldId) {
323
+ const field = this.aiTable.fieldsMap()[fieldId];
324
+ if (!field) {
325
+ return;
326
+ }
327
+ const fieldType = field.type;
328
+ const editingFieldType = editingCell ? this.aiTable.fieldsMap()[editingCell.fieldId].type : null;
329
+ const isEditingFieldTypeHovered = editingFieldType ? MOUSEOVER_EDIT_TYPE.includes(editingFieldType) : false;
330
+ const isFieldTypeHovered = MOUSEOVER_EDIT_TYPE.includes(fieldType);
331
+ if (editingCell && isEditingFieldTypeHovered) {
332
+ this.aiTableGridEventService.closeCellEditor();
333
+ }
334
+ if (!editingCell && !isFieldTypeHovered) {
335
+ this.aiTableGridEventService.closeCellEditor();
336
+ return;
337
+ }
338
+ if (editingCell && ((!isEditingFieldTypeHovered && isFieldTypeHovered) || !isFieldTypeHovered)) {
339
+ return;
340
+ }
341
+ setTimeout(() => {
342
+ this.aiTableGridEventService.openCellEditor(this.aiTable, {
343
+ container: this.containerElement(),
344
+ coordinate: this.coordinate(),
345
+ fieldId: fieldId,
346
+ recordId: recordId,
347
+ isHoverEdit: true
348
+ });
349
+ });
350
+ }
351
+ else {
352
+ // 鼠标位于非单元格区域时,如果当前有 mouseover 编辑元素,则结束编辑
353
+ if (editingCell && MOUSEOVER_EDIT_TYPE.includes(this.aiTable.fieldsMap()[editingCell.fieldId].type)) {
354
+ this.aiTableGridEventService.closeCellEditor();
148
355
  }
149
356
  }
150
357
  }
151
358
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AITableGrid, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
152
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.0", type: AITableGrid, isStandalone: true, selector: "ai-table-grid", inputs: { aiRecords: { classPropertyName: "aiRecords", publicName: "aiRecords", isSignal: true, isRequired: true, transformFunction: null }, aiFields: { classPropertyName: "aiFields", publicName: "aiFields", isSignal: true, isRequired: true, transformFunction: null }, aiFieldConfig: { classPropertyName: "aiFieldConfig", publicName: "aiFieldConfig", isSignal: true, isRequired: false, transformFunction: null }, aiReadonly: { classPropertyName: "aiReadonly", publicName: "aiReadonly", isSignal: true, isRequired: false, transformFunction: null }, aiPlugins: { classPropertyName: "aiPlugins", publicName: "aiPlugins", isSignal: true, isRequired: false, transformFunction: null }, aiReferences: { classPropertyName: "aiReferences", publicName: "aiReferences", isSignal: true, isRequired: false, transformFunction: null }, aiBuildRenderDataFn: { classPropertyName: "aiBuildRenderDataFn", publicName: "aiBuildRenderDataFn", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiRecords: "aiRecordsChange", aiFields: "aiFieldsChange", onChange: "onChange", aiTableInitialized: "aiTableInitialized" }, host: { classAttribute: "ai-table-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], ngImport: i0, template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n class=\"grid-field-action\"\n thyAction\n thyActiveClass=\"active\"\n thyIcon=\"more-vertical\"\n [thyDropdown]=\"fieldMenu\"\n href=\"javascript:;\"\n >\n <thy-dropdown-menu #fieldMenu>\n <field-menu [origin]=\"fieldAction\" [fieldId]=\"field._id\" [aiTable]=\"aiTable\" [fieldMenus]=\"fieldMenus\"></field-menu>\n </thy-dropdown-menu>\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n #cell\n class=\"grid-cell\"\n [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: SelectOptionPipe, name: "selectOption" }, { kind: "pipe", type: SelectOptionsPipe, name: "selectOptions" }, { kind: "component", type: ThyTag, selector: "thy-tag,[thyTag]", inputs: ["thyTag", "thyShape", "thyColor", "thyTheme", "thySize", "thyHoverable"] }, { kind: "ngmodule", type: ThyPopoverModule }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyRate, selector: "thy-rate", inputs: ["thyCount", "thyDisabled", "thyAllowHalf", "thyAllowClear", "thyTooltips", "thyIconTemplate"], outputs: ["thyItemHoverChange"] }, { kind: "component", type: ThyProgress, selector: "thy-progress", inputs: ["thyType", "thySize", "thyValue", "thyMax", "thyTips", "thyShape", "thyGapDegree", "thyGapPosition", "thyStrokeWidth"] }, { kind: "pipe", type: ThyDatePickerFormatPipe, name: "thyDatePickerFormat" }, { kind: "component", type: ThyFlexibleText, selector: "thy-flexible-text,[thyFlexibleText]", inputs: ["thyTooltipTrigger", "thyContainerClass", "thyTooltipContent", "thyTooltipPlacement", "thyTooltipOffset"], exportAs: ["thyFlexibleText"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "component", type: FieldMenu, selector: "field-menu", inputs: ["fieldId", "aiTable", "fieldMenus", "origin"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "directive", type: ThyDropdownDirective, selector: "[thyDropdown]", inputs: ["thyDropdownMenu", "thyDropdown", "thyTrigger", "thyShowDelay", "thyHideDelay", "thyActiveClass", "thyPopoverOptions", "thyPlacement", "thyMenuInsideClosable", "thyPanelClass"], outputs: ["thyActiveChange"] }, { kind: "component", type: ThyDropdownMenuComponent, selector: "thy-dropdown-menu", inputs: ["thyWidth", "thyImmediateRender"] }, { kind: "ngmodule", type: ThyCheckboxModule }, { kind: "component", type: i3.ThyCheckbox, selector: "thy-checkbox,[thy-checkbox],[thyCheckbox]", inputs: ["thyIndeterminate"] }, { kind: "ngmodule", type: ThyAvatarModule }, { kind: "component", type: i4.ThyAvatar, selector: "thy-avatar", inputs: ["thyShowName", "thySrc", "thyName", "thySize", "thyShowRemove", "thyRemovable", "thyImgClass", "thyDisabled", "thyLoading", "thyFetchPriority"], outputs: ["thyOnRemove", "thyRemove", "thyError"] }, { kind: "component", type: i4.ThyAvatarList, selector: "thy-avatar-list", inputs: ["thyMode", "thyAvatarSize"] }, { kind: "pipe", type: IsSelectRecordPipe, name: "isSelectRecord" }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "pipe", type: UserPipe, name: "user" }, { kind: "pipe", type: SelectSettingPipe, name: "selectSetting" }, { kind: "pipe", type: MemberSettingPipe, name: "memberSetting" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
359
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.0", type: AITableGrid, isStandalone: true, selector: "ai-table-grid", host: { classAttribute: "ai-table-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "verticalBarRef", first: true, predicate: ["verticalBar"], descendants: true, isSignal: true }, { propertyName: "horizontalBarRef", first: true, predicate: ["horizontalBar"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div #container class=\"ai-table-grid-view\">\n @if (hasContainerRect()) {\n <ai-table-renderer\n [config]=\"rendererConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n >\n <div #horizontalBar class=\"ai-table-horizontal-scroll-bar-wrapper\" [style.width.px]=\"containerRect().width\">\n <div class=\"ai-table-scroll-bar-inner\" [style.width.px]=\"coordinate().totalWidth + ADD_BUTTON_WIDTH\"></div>\n </div>\n <div\n #verticalBar\n class=\"ai-table-vertical-scroll-bar-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n <div class=\"ai-table-scroll-bar-inner\" [style.height.px]=\"scrollTotalHeight()\"></div>\n </div>\n </ai-table-renderer>\n }\n</div>\n", dependencies: [{ kind: "component", type: AITableRenderer, selector: "ai-table-renderer", inputs: ["config"], outputs: ["koMousemove", "koMousedown", "koWheel", "koClick", "koDblclick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
153
360
  }
154
361
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AITableGrid, decorators: [{
155
362
  type: Component,
156
363
  args: [{ selector: 'ai-table-grid', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
157
364
  class: 'ai-table-grid'
158
- }, imports: [
159
- NgForOf,
160
- NgClass,
161
- NgComponentOutlet,
162
- CommonModule,
163
- FormsModule,
164
- SelectOptionPipe,
165
- SelectOptionsPipe,
166
- ThyTag,
167
- ThyPopoverModule,
168
- ThyIcon,
169
- ThyRate,
170
- ThyProgress,
171
- AITableFieldPropertyEditor,
172
- ThyDatePickerFormatPipe,
173
- ThyFlexibleText,
174
- ThyStopPropagationDirective,
175
- FieldMenu,
176
- ThyAction,
177
- ThyDropdownDirective,
178
- ThyDropdownMenuComponent,
179
- ThyCheckboxModule,
180
- ProgressEditorComponent,
181
- ThyAvatarModule,
182
- NgTemplateOutlet,
183
- IsSelectRecordPipe,
184
- ProgressEditorComponent,
185
- SelectOptionComponent,
186
- UserPipe,
187
- SelectSettingPipe,
188
- MemberSettingPipe
189
- ], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n class=\"grid-field-action\"\n thyAction\n thyActiveClass=\"active\"\n thyIcon=\"more-vertical\"\n [thyDropdown]=\"fieldMenu\"\n href=\"javascript:;\"\n >\n <thy-dropdown-menu #fieldMenu>\n <field-menu [origin]=\"fieldAction\" [fieldId]=\"field._id\" [aiTable]=\"aiTable\" [fieldMenus]=\"fieldMenus\"></field-menu>\n </thy-dropdown-menu>\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n #cell\n class=\"grid-cell\"\n [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n" }]
190
- }] });
191
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wYWNrYWdlcy9ncmlkL3NyYy9ncmlkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uL3BhY2thZ2VzL2dyaWQvc3JjL2dyaWQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdEcsT0FBTyxFQUNILHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsUUFBUSxFQUNSLFVBQVUsRUFDVixVQUFVLEVBQ1YsTUFBTSxFQUNOLEtBQUssRUFDTCxLQUFLLEVBQ0wsTUFBTSxFQUVOLE1BQU0sRUFFVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBaUIsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUJBQXFCLENB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QkFDZixnQkFBZ0I7d0JBQ2hCLGtCQUFrQjt3QkFDbEIsdUJBQXVCO3dCQUN2QixxQkFBcUI7d0JBQ3JCLFFBQVE7d0JBQ1IsaUJBQWlCO3dCQUNqQixpQkFBaUI7cUJBQ3BCLGFBQ1UsQ0FBQyx1QkFBdUIsRUFBRSx1QkFBdUIsRUFBRSwyQkFBMkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSwgTmdDbGFzcywgTmdDb21wb25lbnRPdXRsZXQsIE5nRm9yT2YsIE5nVGVtcGxhdGVPdXRsZXQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDb21wb25lbnQsXG4gICAgY29tcHV0ZWQsXG4gICAgRGVzdHJveVJlZixcbiAgICBFbGVtZW50UmVmLFxuICAgIGluamVjdCxcbiAgICBpbnB1dCxcbiAgICBtb2RlbCxcbiAgICBOZ1pvbmUsXG4gICAgT25Jbml0LFxuICAgIG91dHB1dCxcbiAgICBzaWduYWxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFRoeUFjdGlvbiB9IGZyb20gJ25neC10ZXRoeXMvYWN0aW9uJztcbmltcG9ydCB7IFRoeUF2YXRhck1vZHVsZSB9IGZyb20gJ25neC10ZXRoeXMvYXZhdGFyJztcbmltcG9ydCB7IFRoeUNoZWNrYm94TW9kdWxlIH0gZnJvbSAnbmd4LXRldGh5cy9jaGVja2JveCc7XG5pbXBvcnQgeyBUaHlEYXRlUGlja2VyRm9ybWF0UGlwZSB9IGZyb20gJ25neC10ZXRoeXMvZGF0ZS1waWNrZXInO1xuaW1wb3J0IHsgVGh5RHJvcGRvd25EaXJlY3RpdmUsIFRoeURyb3Bkb3duTWVudUNvbXBvbmVudCB9IGZyb20gJ25neC10ZXRoeXMvZHJvcGRvd24nO1xuaW1wb3J0IHsgVGh5RmxleGlibGVUZXh0IH0gZnJvbSAnbmd4LXRldGh5cy9mbGV4aWJsZS10ZXh0JztcbmltcG9ydCB7IFRoeUljb24gfSBmcm9tICduZ3gtdGV0aHlzL2ljb24nO1xuaW1wb3J0IHsgVGh5UG9wb3Zlck1vZHVsZSwgVGh5UG9wb3ZlclJlZiB9IGZyb20gJ25neC10ZXRoeXMvcG9wb3Zlcic7XG5pbXBvcnQgeyBUaHlQcm9ncmVzcyB9IGZyb20gJ25neC10ZXRoeXMvcHJvZ3Jlc3MnO1xuaW1wb3J0IHsgVGh5UmF0ZSB9IGZyb20gJ25neC10ZXRoeXMvcmF0ZSc7XG5pbXBvcnQgeyBUaHlTdG9wUHJvcGFnYXRpb25EaXJlY3RpdmUgfSBmcm9tICduZ3gtdGV0aHlzL3NoYXJlZCc7XG5pbXBvcnQgeyBUaHlUYWcgfSBmcm9tICduZ3gtdGV0aHlzL3RhZyc7XG5pbXBvcnQgeyBtZXJnZVdpdGggfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBQcm9ncmVzc0VkaXRvckNvbXBvbmVudCwgU2VsZWN0T3B0aW9uQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzJztcbmltcG9ydCB7IEZpZWxkTWVudSB9IGZyb20gJy4vY29tcG9uZW50cy9maWVsZC1tZW51L2ZpZWxkLW1lbnUuY29tcG9uZW50JztcbmltcG9ydCB7IEFJVGFibGVGaWVsZFByb3BlcnR5RWRpdG9yIH0gZnJvbSAnLi9jb21wb25lbnRzL2ZpZWxkLXByb3BlcnR5LWVkaXRvci9maWVsZC1wcm9wZXJ0eS1lZGl0b3IuY29tcG9uZW50JztcbmltcG9ydCB7IERCTF9DTElDS19FRElUX1RZUEUsIERlZmF1bHRGaWVsZE1lbnVzLCBNT1VTRU9WRVJfRURJVF9UWVBFIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IHtcbiAgICBBY3Rpb25zLFxuICAgIEFJUGx1Z2luLFxuICAgIEFJVGFibGUsXG4gICAgQUlUYWJsZUNoYW5nZU9wdGlvbnMsXG4gICAgQUlUYWJsZUZpZWxkcyxcbiAgICBBSVRhYmxlRmllbGRUeXBlLFxuICAgIEFJVGFibGVSZWNvcmRzLFxuICAgIEFJVGFibGVTZWxlY3RPcHRpb25TdHlsZSxcbiAgICBBSVRhYmxlVmFsdWUsXG4gICAgY3JlYXRlQUlUYWJsZSxcbiAgICBjcmVhdGVEZWZhdWx0RmllbGQsXG4gICAgZ2V0RGVmYXVsdFJlY29yZFxufSBmcm9tICcuL2NvcmUnO1xuaW1wb3J0IHsgSXNTZWxlY3RSZWNvcmRQaXBlLCBNZW1iZXJTZXR0aW5nUGlwZSwgU2VsZWN0T3B0aW9uUGlwZSwgU2VsZWN0T3B0aW9uc1BpcGUsIFNlbGVjdFNldHRpbmdQaXBlLCBVc2VyUGlwZSB9IGZyb20gJy4vcGlwZXMvZ3JpZC5waXBlJztcbmltcG9ydCB7IEFJVGFibGVHcmlkRXZlbnRTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9ldmVudC5zZXJ2aWNlJztcbmltcG9ydCB7IEFJX1RBQkxFX0dSSURfRklFTERfU0VSVklDRV9NQVAsIEFJVGFibGVHcmlkRmllbGRTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9maWVsZC5zZXJ2aWNlJztcbmltcG9ydCB7IEFJVGFibGVHcmlkU2VsZWN0aW9uU2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvc2VsZWN0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgQUlGaWVsZENvbmZpZywgQUlUYWJsZUZpZWxkTWVudUl0ZW0sIEFJVGFibGVSZWZlcmVuY2VzIH0gZnJvbSAnLi90eXBlcyc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnYWktdGFibGUtZ3JpZCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2dyaWQuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gICAgaG9zdDoge1xuICAgICAgICBjbGFzczogJ2FpLXRhYmxlLWdyaWQnXG4gICAgfSxcbiAgICBpbXBvcnRzOiBbXG4gICAgICAgIE5nRm9yT2YsXG4gICAgICAgIE5nQ2xhc3MsXG4gICAgICAgIE5nQ29tcG9uZW50T3V0bGV0LFxuICAgICAgICBDb21tb25Nb2R1bGUsXG4gICAgICAgIEZvcm1zTW9kdWxlLFxuICAgICAgICBTZWxlY3RPcHRpb25QaXBlLFxuICAgICAgICBTZWxlY3RPcHRpb25zUGlwZSxcbiAgICAgICAgVGh5VGFnLFxuICAgICAgICBUaHlQb3BvdmVyTW9kdWxlLFxuICAgICAgICBUaHlJY29uLFxuICAgICAgICBUaHlSYXRlLFxuICAgICAgICBUaHlQcm9ncmVzcyxcbiAgICAgICAgQUlUYWJsZUZpZWxkUHJvcGVydHlFZGl0b3IsXG4gICAgICAgIFRoeURhdGVQaWNrZXJGb3JtYXRQaXBlLFxuICAgICAgICBUaHlGbGV4aWJsZVRleHQsXG4gICAgICAgIFRoeVN0b3BQcm9wYWdhdGlvbkRpcmVjdGl2ZSxcbiAgICAgICAgRmllbGRNZW51LFxuICAgICAgICBUaHlBY3Rpb24sXG4gICAgICAgIFRoeURyb3Bkb3duRGlyZWN0aXZlLFxuICAgICAgICBUaHlEcm9wZG93bk1lbnVDb21wb25lbnQsXG4gICAgICAgIFRoeUNoZWNrYm94TW9kdWxlLFxuICAgICAgICBQcm9ncmVzc0VkaXRvckNvbXBvbmVudCxcbiAgICAgICAgVGh5QXZhdGFyTW9kdWxlLFxuICAgICAgICBOZ1RlbXBsYXRlT3V0bGV0LFxuICAgICAgICBJc1NlbGVjdFJlY29yZFBpcGUsXG4gICAgICAgIFByb2dyZXNzRWRpdG9yQ29tcG9uZW50LFxuICAgICAgICBTZWxlY3RPcHRpb25Db21wb25lbnQsXG4gICAgICAgIFVzZXJQaXBlLFxuICAgICAgICBTZWxlY3RTZXR0aW5nUGlwZSxcbiAgICAgICAgTWVtYmVyU2V0dGluZ1BpcGVcbiAgICBdLFxuICAgIHByb3ZpZGVyczogW0FJVGFibGVHcmlkRXZlbnRTZXJ2aWNlLCBBSVRhYmxlR3JpZEZpZWxkU2VydmljZSwgQUlUYWJsZUdyaWRTZWxlY3Rpb25TZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBBSVRhYmxlR3JpZCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gICAgYWlSZWNvcmRzID0gbW9kZWwucmVxdWlyZWQ8QUlUYWJsZVJlY29yZHM+KCk7XG5cbiAgICBhaUZpZWxkcyA9IG1vZGVsLnJlcXVpcmVkPEFJVGFibGVGaWVsZHM+KCk7XG5cbiAgICBhaUZpZWxkQ29uZmlnID0gaW5wdXQ8QUlGaWVsZENvbmZpZz4oKTtcblxuICAgIGFpUmVhZG9ubHkgPSBpbnB1dDxib29sZWFuPigpO1xuXG4gICAgYWlQbHVnaW5zID0gaW5wdXQ8QUlQbHVnaW5bXT4oKTtcblxuICAgIGFpUmVmZXJlbmNlcyA9IGlucHV0PEFJVGFibGVSZWZlcmVuY2VzPigpO1xuXG4gICAgYWlCdWlsZFJlbmRlckRhdGFGbiA9IGlucHV0PChhaVRhYmxlOiBBSVRhYmxlKSA9PiBBSVRhYmxlVmFsdWU+KCk7XG5cbiAgICBBSVRhYmxlRmllbGRUeXBlID0gQUlUYWJsZUZpZWxkVHlwZTtcblxuICAgIEFJVGFibGVTZWxlY3RPcHRpb25TdHlsZSA9IEFJVGFibGVTZWxlY3RPcHRpb25TdHlsZTtcblxuICAgIGFpVGFibGUhOiBBSVRhYmxlO1xuXG4gICAgZ3JpZERhdGEgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLmFpQnVpbGRSZW5kZXJEYXRhRm4gJiYgdGhpcy5haUJ1aWxkUmVuZGVyRGF0YUZuKCkgJiYgdGhpcy5haVRhYmxlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5haUJ1aWxkUmVuZGVyRGF0YUZuKCkhKHRoaXMuYWlUYWJsZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlY29yZHM6IHRoaXMuYWlSZWNvcmRzKCksXG4gICAgICAgICAgICBmaWVsZHM6IHRoaXMuYWlGaWVsZHMoKVxuICAgICAgICB9O1xuICAgIH0pO1xuXG4gICAgaXNTZWxlY3RlZEFsbCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWlUYWJsZS5zZWxlY3Rpb24oKS5zZWxlY3RlZFJlY29yZHMuc2l6ZSA9PT0gdGhpcy5haVJlY29yZHMoKS5sZW5ndGg7XG4gICAgfSk7XG5cbiAgICBvbkNoYW5nZSA9IG91dHB1dDxBSVRhYmxlQ2hhbmdlT3B0aW9ucz4oKTtcblxuICAgIGFpVGFibGVJbml0aWFsaXplZCA9IG91dHB1dDxBSVRhYmxlPigpO1xuXG4gICAgZmllbGRNZW51cyE6IEFJVGFibGVGaWVsZE1lbnVJdGVtW107XG5cbiAgICBtb3VzZW92ZXJSZWYhOiBUaHlQb3BvdmVyUmVmPGFueT47XG5cbiAgICBwcml2YXRlIG5nWm9uZSA9IGluamVjdChOZ1pvbmUpO1xuXG4gICAgcHJpdmF0ZSBlbGVtZW50UmVmID0gaW5qZWN0KEVsZW1lbnRSZWYpO1xuXG4gICAgcHJpdmF0ZSBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gICAgcHJpdmF0ZSBhaVRhYmxlR3JpZEZpZWxkU2VydmljZSA9IGluamVjdChBSVRhYmxlR3JpZEZpZWxkU2VydmljZSk7XG5cbiAgICBwcml2YXRlIGFpVGFibGVHcmlkRXZlbnRTZXJ2aWNlID0gaW5qZWN0KEFJVGFibGVHcmlkRXZlbnRTZXJ2aWNlKTtcblxuICAgIHB1YmxpYyBhaVRhYmxlR3JpZFNlbGVjdGlvblNlcnZpY2UgPSBpbmplY3QoQUlUYWJsZUdyaWRTZWxlY3Rpb25TZXJ2aWNlKTtcblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmluaXRBSVRhYmxlKCk7XG4gICAgICAgIHRoaXMuaW5pdFNlcnZpY2UoKTtcbiAgICAgICAgdGhpcy5idWlsZEZpZWxkTWVudXMoKTtcbiAgICAgICAgdGhpcy5zdWJzY3JpYmVFdmVudHMoKTtcbiAgICB9XG5cbiAgICBpbml0QUlUYWJsZSgpIHtcbiAgICAgICAgdGhpcy5haVRhYmxlID0gY3JlYXRlQUlUYWJsZSh0aGlzLmFpUmVjb3JkcywgdGhpcy5haUZpZWxkcyk7XG4gICAgICAgIHRoaXMuYWlQbHVnaW5zKCk/LmZvckVhY2goKHBsdWdpbikgPT4ge1xuICAgICAgICAgICAgdGhpcy5haVRhYmxlID0gcGx1Z2luKHRoaXMuYWlUYWJsZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmFpVGFibGVJbml0aWFsaXplZC5lbWl0KHRoaXMuYWlUYWJsZSk7XG4gICAgICAgIHRoaXMuYWlUYWJsZS5vbkNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UuZW1pdCh7XG4gICAgICAgICAgICAgICAgcmVjb3JkczogdGhpcy5haVJlY29yZHMoKSxcbiAgICAgICAgICAgICAgICBmaWVsZHM6IHRoaXMuYWlGaWVsZHMoKSxcbiAgICAgICAgICAgICAgICBhY3Rpb25zOiB0aGlzLmFpVGFibGUuYWN0aW9uc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaW5pdFNlcnZpY2UoKSB7XG4gICAgICAgIHRoaXMuYWlUYWJsZUdyaWRFdmVudFNlcnZpY2UuaW5pdGlhbGl6ZSh0aGlzLmFpVGFibGUsIHRoaXMuYWlGaWVsZENvbmZpZygpPy5maWVsZFByb3BlcnR5RWRpdG9yKTtcbiAgICAgICAgdGhpcy5haVRhYmxlR3JpZFNlbGVjdGlvblNlcnZpY2UuaW5pdGlhbGl6ZSh0aGlzLmFpVGFibGUpO1xuICAgICAgICB0aGlzLmFpVGFibGVHcmlkRXZlbnRTZXJ2aWNlLnJlZ2lzdGVyRXZlbnRzKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcbiAgICAgICAgdGhpcy5haVRhYmxlR3JpZEZpZWxkU2VydmljZS5pbml0QUlGaWVsZENvbmZpZyh0aGlzLmFpRmllbGRDb25maWcoKSk7XG4gICAgICAgIEFJX1RBQkxFX0dSSURfRklFTERfU0VSVklDRV9NQVAuc2V0KHRoaXMuYWlUYWJsZSwgdGhpcy5haVRhYmxlR3JpZEZpZWxkU2VydmljZSk7XG4gICAgfVxuXG4gICAgYnVpbGRGaWVsZE1lbnVzKCkge1xuICAgICAgICB0aGlzLmZpZWxkTWVudXMgPSB0aGlzLmFpRmllbGRDb25maWcoKT8uZmllbGRNZW51cyA/PyBEZWZhdWx0RmllbGRNZW51cztcbiAgICB9XG5cbiAgICBhZGRSZWNvcmQoKSB7XG4gICAgICAgIEFjdGlvbnMuYWRkUmVjb3JkKHRoaXMuYWlUYWJsZSwgZ2V0RGVmYXVsdFJlY29yZCh0aGlzLmFpRmllbGRzKCkpLCBbdGhpcy5haVJlY29yZHMoKS5sZW5ndGhdKTtcbiAgICB9XG5cbiAgICBzZWxlY3RSZWNvcmQocmVjb3JkSWQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLmFpVGFibGVHcmlkU2VsZWN0aW9uU2VydmljZS5zZWxlY3RSZWNvcmQocmVjb3JkSWQpO1xuICAgIH1cblxuICAgIHRvZ2dsZVNlbGVjdEFsbChjaGVja2VkOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuYWlUYWJsZUdyaWRTZWxlY3Rpb25TZXJ2aWNlLnRvZ2dsZVNlbGVjdEFsbChjaGVja2VkKTtcbiAgICB9XG5cbiAgICBhZGRGaWVsZChncmlkQ29sdW1uQmxhbms6IEhUTUxFbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGZpZWxkID0gY3JlYXRlRGVmYXVsdEZpZWxkKHRoaXMuYWlUYWJsZSwgQUlUYWJsZUZpZWxkVHlwZS50ZXh0KTtcbiAgICAgICAgdGhpcy5haVRhYmxlR3JpZEZpZWxkU2VydmljZS5lZGl0RmllbGRQcm9wZXJ0eShncmlkQ29sdW1uQmxhbmssIHRoaXMuYWlUYWJsZSwgZmllbGQsIGZhbHNlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN1YnNjcmliZUV2ZW50cygpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5haVRhYmxlR3JpZEV2ZW50U2VydmljZS5kYmxDbGlja0V2ZW50JC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKS5zdWJzY3JpYmUoKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5kYmxDbGljayhldmVudCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuYWlUYWJsZUdyaWRFdmVudFNlcnZpY2UubW91c2Vkb3duRXZlbnQkXG4gICAgICAgICAgICAgICAgLnBpcGUobWVyZ2VXaXRoKHRoaXMuYWlUYWJsZUdyaWRFdmVudFNlcnZpY2UuZ2xvYmFsTW91c2Vkb3duRXZlbnQkKSwgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSgoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5haVRhYmxlR3JpZFNlbGVjdGlvblNlcnZpY2UudXBkYXRlU2VsZWN0KGV2ZW50KTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdGhpcy5haVRhYmxlR3JpZEV2ZW50U2VydmljZS5tb3VzZW92ZXJFdmVudCQucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSkuc3Vic2NyaWJlKChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubW91c2VvdmVySGFuZGxlKGV2ZW50KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5haVRhYmxlR3JpZEV2ZW50U2VydmljZS5nbG9iYWxNb3VzZW92ZXJFdmVudCQucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSkuc3Vic2NyaWJlKChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2VIb3ZlckNlbGxFZGl0b3IoZXZlbnQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgZGJsQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICAgICAgY29uc3QgY2VsbERvbSA9IChldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLmNsb3Nlc3QoJy5ncmlkLWNlbGwnKSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgY29uc3QgdHlwZSA9IGNlbGxEb20gJiYgKGNlbGxEb20uZ2V0QXR0cmlidXRlKCd0eXBlJykhIGFzIEFJVGFibGVGaWVsZFR5cGUpO1xuICAgICAgICBpZiAodHlwZSAmJiBEQkxfQ0xJQ0tfRURJVF9UWVBFLmluY2x1ZGVzKHR5cGUpKSB7XG4gICAgICAgICAgICB0aGlzLmFpVGFibGVHcmlkRXZlbnRTZXJ2aWNlLm9wZW5FZGl0KGNlbGxEb20pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtb3VzZW92ZXJIYW5kbGUoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMubW91c2VvdmVyUmVmKSB7XG4gICAgICAgICAgICB0aGlzLm1vdXNlb3ZlclJlZj8uY2xvc2UoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjZWxsRG9tID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCkuY2xvc2VzdCgnLmdyaWQtY2VsbCcpIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICBjb25zdCB0eXBlID0gY2VsbERvbSAmJiAoY2VsbERvbS5nZXRBdHRyaWJ1dGUoJ3R5cGUnKSEgYXMgQUlUYWJsZUZpZWxkVHlwZSk7XG4gICAgICAgIGlmICh0eXBlICYmIE1PVVNFT1ZFUl9FRElUX1RZUEUuaW5jbHVkZXModHlwZSkpIHtcbiAgICAgICAgICAgIHRoaXMubW91c2VvdmVyUmVmID0gdGhpcy5haVRhYmxlR3JpZEV2ZW50U2VydmljZS5vcGVuRWRpdChjZWxsRG9tKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgY2xvc2VIb3ZlckNlbGxFZGl0b3IoZTogTW91c2VFdmVudCkge1xuICAgICAgICBpZiAodGhpcy5tb3VzZW92ZXJSZWYpIHtcbiAgICAgICAgICAgIGNvbnN0IGhhc0dyaWQgPSBlLnRhcmdldCAmJiAoZS50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLmNsb3Nlc3QoJy5haS10YWJsZS1ncmlkJyk7XG4gICAgICAgICAgICBjb25zdCBoYXNDZWxsRWRpdG9yID0gZS50YXJnZXQgJiYgKGUudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5jbG9zZXN0KCcuZ3JpZC1jZWxsLWVkaXRvcicpO1xuICAgICAgICAgICAgaWYgKCFoYXNHcmlkICYmICFoYXNDZWxsRWRpdG9yKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tb3VzZW92ZXJSZWYuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJncmlkLWhlYWRlciBkLWZsZXhcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZ3JpZC1jb2x1bW4tY2hlY2tib3ggZ3JpZC1jZWxsIGdyaWQtY2hlY2tib3hcIj5cbiAgICAgICAgPGxhYmVsIHRoeUNoZWNrYm94IHRoeUxhYmVsVGV4dD1cIlwiIFtuZ01vZGVsXT1cImlzU2VsZWN0ZWRBbGwoKVwiIChuZ01vZGVsQ2hhbmdlKT1cInRvZ2dsZVNlbGVjdEFsbCgkZXZlbnQpXCI+PC9sYWJlbD5cbiAgICA8L2Rpdj5cbiAgICBAZm9yIChmaWVsZCBvZiBncmlkRGF0YSgpLmZpZWxkczsgdHJhY2sgZmllbGQuX2lkKSB7XG4gICAgICAgIDxkaXZcbiAgICAgICAgICAgIGNsYXNzPVwiZ3JpZC1jZWxsIGdyaWQtZmllbGRcIlxuICAgICAgICAgICAgI2ZpZWxkQWN0aW9uXG4gICAgICAgICAgICBbYXR0ci5maWVsZElkXT1cImZpZWxkLl9pZFwiXG4gICAgICAgICAgICBbbmdDbGFzc109XCJ7IGhpZ2hsaWdodDogYWlUYWJsZS5zZWxlY3Rpb24oKS5zZWxlY3RlZEZpZWxkcy5oYXMoZmllbGQuX2lkKSB9XCJcbiAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsgd2lkdGg6IGZpZWxkLndpZHRoICsgJ3B4JyB9XCJcbiAgICAgICAgPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCI+XG4gICAgICAgICAgICAgICAgPHRoeS1pY29uIFt0aHlJY29uTmFtZV09XCJmaWVsZC5pY29uIVwiIGNsYXNzPVwibXItMiB0ZXh0LW11dGVkXCI+PC90aHktaWNvbj5cbiAgICAgICAgICAgICAgICA8c3Bhbj57eyBmaWVsZC5uYW1lIH19PC9zcGFuPlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICBjbGFzcz1cImdyaWQtZmllbGQtYWN0aW9uXCJcbiAgICAgICAgICAgICAgICB0aHlBY3Rpb25cbiAgICAgICAgICAgICAgICB0aHlBY3RpdmVDbGFzcz1cImFjdGl2ZVwiXG4gICAgICAgICAgICAgICAgdGh5SWNvbj1cIm1vcmUtdmVydGljYWxcIlxuICAgICAgICAgICAgICAgIFt0aHlEcm9wZG93bl09XCJmaWVsZE1lbnVcIlxuICAgICAgICAgICAgICAgIGhyZWY9XCJqYXZhc2NyaXB0OjtcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDx0aHktZHJvcGRvd24tbWVudSAjZmllbGRNZW51PlxuICAgICAgICAgICAgICAgICAgICA8ZmllbGQtbWVudSBbb3JpZ2luXT1cImZpZWxkQWN0aW9uXCIgW2ZpZWxkSWRdPVwiZmllbGQuX2lkXCIgW2FpVGFibGVdPVwiYWlUYWJsZVwiIFtmaWVsZE1lbnVzXT1cImZpZWxkTWVudXNcIj48L2ZpZWxkLW1lbnU+XG4gICAgICAgICAgICAgICAgPC90aHktZHJvcGRvd24tbWVudT5cbiAgICAgICAgICAgIDwvYT5cbiAgICAgICAgPC9kaXY+XG4gICAgfVxuICAgIDxkaXYgY2xhc3M9XCJncmlkLWNvbHVtbi1ibGFuayBjdXJzb3ItcG9pbnRlclwiICNncmlkQ29sdW1uQmxhbmsgKGNsaWNrKT1cImFkZEZpZWxkKGdyaWRDb2x1bW5CbGFuaylcIj5cbiAgICAgICAgPHRoeS1pY29uIHRoeUljb25OYW1lPVwicGx1c1wiPjwvdGh5LWljb24+XG4gICAgPC9kaXY+XG48L2Rpdj5cbjxkaXYgY2xhc3M9XCJncmlkLWJvZHkgZC1mbGV4XCI+XG4gICAgQGZvciAocmVjb3JkIG9mIGdyaWREYXRhKCkucmVjb3JkczsgdHJhY2sgcmVjb3JkLl9pZDsgbGV0IGluZGV4ID0gJGluZGV4KSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJncmlkLXJvdyBkLWZsZXhcIiBbbmdDbGFzc109XCJ7IGhpZ2hsaWdodDogKHJlY29yZC5faWQgfCBpc1NlbGVjdFJlY29yZDogYWlUYWJsZS5zZWxlY3Rpb24oKSkgfVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQtcm93LWluZGV4IGdyaWQtY2hlY2tib3hcIj5cbiAgICAgICAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiKHJlY29yZC5faWQgfCBpc1NlbGVjdFJlY29yZDogYWlUYWJsZS5zZWxlY3Rpb24oKSkgPyAnY2hlY2tlZC1ib3gnIDogJ3VuY2hlY2tlZC1ib3gnXCJcbiAgICAgICAgICAgICAgICAgICAgdGh5Q2hlY2tib3hcbiAgICAgICAgICAgICAgICAgICAgdGh5TGFiZWxUZXh0PVwiXCJcbiAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwicmVjb3JkLl9pZCB8IGlzU2VsZWN0UmVjb3JkOiBhaVRhYmxlLnNlbGVjdGlvbigpXCJcbiAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic2VsZWN0UmVjb3JkKHJlY29yZC5faWQpXCJcbiAgICAgICAgICAgICAgICA+PC9sYWJlbD5cbiAgICAgICAgICAgICAgICA8c3BhbiBbbmdDbGFzc109XCIocmVjb3JkLl9pZCB8IGlzU2VsZWN0UmVjb3JkOiBhaVRhYmxlLnNlbGVjdGlvbigpKSA/ICdncmlkLXJvdy1uby1udW1iZXInIDogJ2dyaWQtcm93LW51bWJlcidcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgaW5kZXggKyAxIH19XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICBAZm9yIChmaWVsZCBvZiBncmlkRGF0YSgpLmZpZWxkczsgdHJhY2sgZmllbGQuX2lkKSB7XG4gICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAjY2VsbFxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImdyaWQtY2VsbFwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAgICAgICAgICAgICAgIGhpZ2hsaWdodDogYWlUYWJsZS5zZWxlY3Rpb24oKS5zZWxlY3RlZENlbGxzLmhhcyhyZWNvcmQuX2lkKSB8fCBhaVRhYmxlLnNlbGVjdGlvbigpLnNlbGVjdGVkRmllbGRzLmhhcyhmaWVsZC5faWQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IGFpVGFibGUuc2VsZWN0aW9uKCkuc2VsZWN0ZWRDZWxscy5nZXQocmVjb3JkLl9pZCk/Lmhhc093blByb3BlcnR5KGZpZWxkLl9pZClcbiAgICAgICAgICAgICAgICAgICAgfVwiXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLnR5cGVdPVwiW2ZpZWxkLnR5cGVdXCJcbiAgICAgICAgICAgICAgICAgICAgW2F0dHIuZmllbGRJZF09XCJbZmllbGQuX2lkXVwiXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLnJlY29yZElkXT1cIltyZWNvcmQuX2lkXVwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsgd2lkdGg6IGZpZWxkLndpZHRoICsgJ3B4JyB9XCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIEBzd2l0Y2ggKGZpZWxkLnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEBjYXNlIChBSVRhYmxlRmllbGRUeXBlLnNlbGVjdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBsZXQgZmllbGRWYWx1ZSA9IHJlY29yZC52YWx1ZXNbZmllbGQuX2lkXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAbGV0IHNldHRpbmdzID0gZmllbGQuc2V0dGluZ3MhIHwgc2VsZWN0U2V0dGluZztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAbGV0IG9wdGlvbnMgPSBzZXR0aW5nc1snb3B0aW9ucyddO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBsZXQgb3B0aW9uU3R5bGUgPSBzZXR0aW5nc1snb3B0aW9uX3N0eWxlJ10gfHwgQUlUYWJsZVNlbGVjdE9wdGlvblN0eWxlLnRhZztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAbGV0IGlzVGFnU3R5bGUgPSBvcHRpb25TdHlsZSA9PT0gQUlUYWJsZVNlbGVjdE9wdGlvblN0eWxlLnRhZztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoIXNldHRpbmdzWydpc19tdWx0aXBsZSddICYmIGZpZWxkVmFsdWUgfCBzZWxlY3RPcHRpb246IG9wdGlvbnM7IGFzIHNlbGVjdGVkT3B0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoaXNUYWdTdHlsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdC1vcHRpb24gY2xhc3M9XCJtYi0xIG1yLTFcIiBbZmllbGRdPVwiZmllbGRcIiBbZGlzcGxheU9wdGlvbl09XCJzZWxlY3RlZE9wdGlvblwiPjwvc2VsZWN0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHRoeVRhZyBjbGFzcz1cIm1iLTEgbXItMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3Qtb3B0aW9uIFtmaWVsZF09XCJmaWVsZFwiIFtkaXNwbGF5T3B0aW9uXT1cInNlbGVjdGVkT3B0aW9uXCI+PC9zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGxldCBtYXhTaG93Q291bnQgPSAyO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoZmllbGRWYWx1ZSB8IHNlbGVjdE9wdGlvbnM6IG9wdGlvbnM7IGFzIHNlbGVjdGVkT3B0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiBzZWxlY3RlZE9wdGlvbnM7IHRyYWNrIG9wdGlvbiEuX2lkOyBsZXQgaSA9ICRpbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGkgKyAxIDw9IG1heFNob3dDb3VudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChpc1RhZ1N0eWxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdC1vcHRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtYi0xIG1yLTFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZmllbGRdPVwiZmllbGRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzcGxheU9wdGlvbl09XCJvcHRpb24hXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiB0aHlUYWcgY2xhc3M9XCJtYi0xIG1yLTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdC1vcHRpb24gW2ZpZWxkXT1cImZpZWxkXCIgW2Rpc3BsYXlPcHRpb25dPVwib3B0aW9uIVwiPjwvc2VsZWN0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBsZXQgc2VsZWN0ZWRMZW5ndGggPSBzZWxlY3RlZE9wdGlvbnMubGVuZ3RoIHx8IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChzZWxlY3RlZE9wdGlvbnMgJiYgbWF4U2hvd0NvdW50IDwgc2VsZWN0ZWRMZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGxldCBzaGFwZSA9IGlzVGFnU3R5bGUgPyAncGlsbCcgOiAncmVjdGFuZ2xlJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGxldCBpc0hpZGRlbiA9IG1heFNob3dDb3VudCA+PSBzZWxlY3RlZExlbmd0aDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGh5LXRhZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjdXJzb3ItcG9pbnRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MubXVsdGktcHJvcGVydHktdmFsdWUtaGlkZGVuXT1cImlzSGlkZGVuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0aHlTaGFwZV09XCJzaGFwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC10cnVuY2F0ZVwiPiAre3sgc2VsZWN0ZWRMZW5ndGggLSBtYXhTaG93Q291bnQgfX0gPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoeS10YWc+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBAY2FzZSAoQUlUYWJsZUZpZWxkVHlwZS5kYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgcmVjb3JkLnZhbHVlc1tmaWVsZC5faWRdLnRpbWVzdGFtcCB8IHRoeURhdGVQaWNrZXJGb3JtYXQgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBjYXNlIChBSVRhYmxlRmllbGRUeXBlLnVwZGF0ZWRBdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWJsb2NrIHVzZXItc2VsZWN0LW5vbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyByZWNvcmQudmFsdWVzW2ZpZWxkLl9pZF0gfCB0aHlEYXRlUGlja2VyRm9ybWF0OiAneXl5eS1NTS1kZCBISDptbScgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgQGNhc2UgKEFJVGFibGVGaWVsZFR5cGUuY3JlYXRlZEF0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtYmxvY2sgdXNlci1zZWxlY3Qtbm9uZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHJlY29yZC52YWx1ZXNbZmllbGQuX2lkXSB8IHRoeURhdGVQaWNrZXJGb3JtYXQ6ICd5eXl5LU1NLWRkIEhIOm1tJyB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBAY2FzZSAoQUlUYWJsZUZpZWxkVHlwZS5yYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoeS1yYXRlIFtuZ01vZGVsXT1cInJlY29yZC52YWx1ZXNbZmllbGQuX2lkXVwiPjwvdGh5LXJhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBAY2FzZSAoQUlUYWJsZUZpZWxkVHlwZS5saW5rKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkLWJsb2NrXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2hyZWZdPVwicmVjb3JkLnZhbHVlc1tmaWVsZC5faWRdPy51cmxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHlTdG9wUHJvcGFnYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGh5RmxleGlibGVUZXh0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0aHlUb29sdGlwQ29udGVudF09XCJyZWNvcmQudmFsdWVzW2ZpZWxkLl9pZF0/LnRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgcmVjb3JkLnZhbHVlc1tmaWVsZC5faWRdPy50ZXh0IH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgQGNhc2UgKEFJVGFibGVGaWVsZFR5cGUucHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGh5LXByb2dyZXNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy0xMDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdGh5VmFsdWVdPVwicmVjb3JkLnZhbHVlc1tmaWVsZC5faWRdIHx8IDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdGh5U2l6ZV09XCJyZWNvcmQudmFsdWVzW2ZpZWxkLl9pZF0/LmNvbmZpZz8uc2l6ZSB8fCAnbWQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RoeU1heF09XCJyZWNvcmQudmFsdWVzW2ZpZWxkLl9pZF0/LmNvbmZpZz8ubWF4IHx8IDEwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0aHlUeXBlXT1cInJlY29yZC52YWx1ZXNbZmllbGQuX2lkXT8uY29uZmlnPy5wcm9ncmVzc1R5cGUgfHwgJ3N1Y2Nlc3MnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPiB7eyByZWNvcmQudmFsdWVzW2ZpZWxkLl9pZF0gfHwgMCB9fXt7IHJlY29yZC52YWx1ZXNbZmllbGQuX2lkXT8uY29uZmlnPy5zdWZmaXggfHwgJyUnIH19IDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoeS1wcm9ncmVzcz5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBjYXNlIChBSVRhYmxlRmllbGRUeXBlLm1lbWJlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBsZXQgc2V0dGluZ3MgPSBmaWVsZC5zZXR0aW5ncyEgfCBtZW1iZXJTZXR0aW5nO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmICghc2V0dGluZ3MhWydpc19tdWx0aXBsZSddKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBsZXQgcmVjb3JkVmFsdWVzID0gcmVjb3JkLnZhbHVlc1tmaWVsZC5faWRdIHwgdXNlcjogYWlSZWZlcmVuY2VzKCkhO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAocmVjb3JkVmFsdWVzICYmIHJlY29yZFZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aHktYXZhdGFyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RoeU5hbWVdPVwicmVjb3JkVmFsdWVzWzBdLmRpc3BsYXlfbmFtZSFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0aHlTcmNdPVwicmVjb3JkVmFsdWVzWzBdLmF2YXRhciFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoeVNpemU9XCJ4c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGh5U2hvd05hbWU9XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L3RoeS1hdmF0YXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGxldCByZWNvcmRWYWx1ZXMgPSByZWNvcmQudmFsdWVzW2ZpZWxkLl9pZF0gfCB1c2VyOiBhaVJlZmVyZW5jZXMoKSE7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoeS1hdmF0YXItbGlzdCB0aHlBdmF0YXJTaXplPVwieHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBmb3IgKGl0ZW0gb2YgcmVjb3JkVmFsdWVzOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGh5LWF2YXRhciBbdGh5TmFtZV09XCJpdGVtLmRpc3BsYXlfbmFtZSFcIiBbdGh5U3JjXT1cIml0ZW0uYXZhdGFyIVwiPjwvdGh5LWF2YXRhcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90aHktYXZhdGFyLWxpc3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgQGNhc2UgKEFJVGFibGVGaWVsZFR5cGUuY3JlYXRlZEJ5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGxldCByZWNvcmRWYWx1ZXMgPSByZWNvcmQudmFsdWVzW2ZpZWxkLl9pZF0gfCB1c2VyOiBhaVJlZmVyZW5jZXMoKSE7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKHJlY29yZFZhbHVlcyAmJiByZWNvcmRWYWx1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aHktYXZhdGFyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdGh5TmFtZV09XCJyZWNvcmRWYWx1ZXNbMF0uZGlzcGxheV9uYW1lIVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdGh5U3JjXT1cInJlY29yZFZhbHVlc1swXS5hdmF0YXIhXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoeVNpemU9XCJ4c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHlTaG93TmFtZT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC90aHktYXZhdGFyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBjYXNlIChBSVRhYmxlRmllbGRUeXBlLnVwZGF0ZWRCeSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBsZXQgcmVjb3JkVmFsdWVzID0gcmVjb3JkLnZhbHVlc1tmaWVsZC5faWRdIHwgdXNlcjogYWlSZWZlcmVuY2VzKCkhO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChyZWNvcmRWYWx1ZXMgJiYgcmVjb3JkVmFsdWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGh5LWF2YXRhclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RoeU5hbWVdPVwicmVjb3JkVmFsdWVzWzBdLmRpc3BsYXlfbmFtZSFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RoeVNyY109XCJyZWNvcmRWYWx1ZXNbMF0uYXZhdGFyIVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHlTaXplPVwieHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGh5U2hvd05hbWU9XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvdGh5LWF2YXRhcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBAZGVmYXVsdCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCI+IHt7IHJlY29yZC52YWx1ZXNbZmllbGQuX2lkXSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYXV0b2ZpbGwtY29udGFpbmVyXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ3JpZC1jb2x1bW4tYmxhbmtcIj48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgfVxuICAgIDxkaXYgY2xhc3M9XCJncmlkLXJvdy1pbnNlcnQgZ3JpZC1yb3cgY3Vyc29yLXBvaW50ZXJcIiAoY2xpY2spPVwiYWRkUmVjb3JkKClcIj5cbiAgICAgICAgPHRoeS1pY29uIHRoeUljb25OYW1lPVwicGx1c1wiPjwvdGh5LWljb24+XG4gICAgPC9kaXY+XG48L2Rpdj5cblxuPGRpdiAjYWN0aXZlQm9yZGVyIGNsYXNzPVwiYWN0aXZlLWJvcmRlclwiPjwvZGl2PlxuIl19
365
+ }, imports: [AITableRenderer], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], template: "<div #container class=\"ai-table-grid-view\">\n @if (hasContainerRect()) {\n <ai-table-renderer\n [config]=\"rendererConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n >\n <div #horizontalBar class=\"ai-table-horizontal-scroll-bar-wrapper\" [style.width.px]=\"containerRect().width\">\n <div class=\"ai-table-scroll-bar-inner\" [style.width.px]=\"coordinate().totalWidth + ADD_BUTTON_WIDTH\"></div>\n </div>\n <div\n #verticalBar\n class=\"ai-table-vertical-scroll-bar-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n <div class=\"ai-table-scroll-bar-inner\" [style.height.px]=\"scrollTotalHeight()\"></div>\n </div>\n </ai-table-renderer>\n }\n</div>\n" }]
366
+ }], ctorParameters: () => [] });
367
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wYWNrYWdlcy9ncmlkL3NyYy9ncmlkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uL3BhY2thZ2VzL2dyaWQvc3JjL2dyaWQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNILGVBQWUsRUFDZix1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFFBQVEsRUFDUixNQUFNLEVBS04sTUFBTSxFQUNOLFNBQVMsRUFDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUd6QyxPQUFPLEVBQ0gsYUFBYSxFQUNiLHlCQUF5QixFQUN6QiwrQkFBK0IsRUFDL0IsbUJBQW1CLEVBQ25CLDBCQUEwQixFQUMxQix3QkFBd0IsRUFDeEIsbUNBQW1DLEVBQ25DLDRCQUE0QixFQUM1Qix1QkFBdUIsRUFDdkIsdUJBQXVCLEVBQ3ZCLDRCQUE0QixFQUM1QixtQkFBbUIsRUFDbkIsc0JBQXNCLEVBQ3RCLG9CQUFvQixFQUNwQixtQkFBbUIsRUFDdEIsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsZUFBZSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQzlELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDbkUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDbkUsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDM0UsT0FB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RSxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7b0JBQ2xDLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFO29CQUM3QixPQUFPLEVBQUUsT0FBUTtvQkFDakIsUUFBUSxFQUFFLFFBQVM7b0JBQ25CLFdBQVcsRUFBRSxJQUFJO2lCQUNwQixDQUFDLENBQUM7WUFDUCxDQUFDLENBQUMsQ0FBQztRQUNQLENBQUM7YUFBTSxDQUFDO1lBQ0oseUNBQXlDO1lBQ3pDLElBQUksV0FBVyxJQUFJLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNsRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDbkQsQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDOzhHQXpZUSxXQUFXO2tHQUFYLFdBQVcsdUdBRlQsQ0FBQyx1QkFBdUIsRUFBRSx1QkFBdUIsRUFBRSwyQkFBMkIsQ0FBQyw2WUNyRDlGLG1qQ0F1QkEsNENENkJjLGVBQWU7OzJGQUdoQixXQUFXO2tCQVh2QixTQUFTOytCQUNJLGVBQWUsY0FFYixJQUFJLG1CQUNDLHVCQUF1QixDQUFDLE1BQU0sUUFDekM7d0JBQ0YsS0FBSyxFQUFFLGVBQWU7cUJBQ3pCLFdBQ1EsQ0FBQyxlQUFlLENBQUMsYUFDZixDQUFDLHVCQUF1QixFQUFFLHVCQUF1QixFQUFFLDJCQUEyQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBhZnRlck5leHRSZW5kZXIsXG4gICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICAgQ29tcG9uZW50LFxuICAgIGNvbXB1dGVkLFxuICAgIGVmZmVjdCxcbiAgICBFbGVtZW50UmVmLFxuICAgIE9uRGVzdHJveSxcbiAgICBPbkluaXQsXG4gICAgU2lnbmFsLFxuICAgIHNpZ25hbCxcbiAgICB2aWV3Q2hpbGRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQgeyBmaWx0ZXIsIGZyb21FdmVudCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgS29FdmVudE9iamVjdCB9IGZyb20gJy4vYW5ndWxhci1rb252YSc7XG5pbXBvcnQgeyBBYnN0cmFjdEVkaXRDZWxsRWRpdG9yIH0gZnJvbSAnLi9jb21wb25lbnRzL2NlbGwtZWRpdG9ycy9hYnN0cmFjdC1jZWxsLWVkaXRvci5jb21wb25lbnQnO1xuaW1wb3J0IHtcbiAgICBBSV9UQUJMRV9DRUxMLFxuICAgIEFJX1RBQkxFX0ZJRUxEX0FERF9CVVRUT04sXG4gICAgQUlfVEFCTEVfRklFTERfQUREX0JVVFRPTl9XSURUSCxcbiAgICBBSV9UQUJMRV9GSUVMRF9IRUFELFxuICAgIEFJX1RBQkxFX0ZJRUxEX0hFQURfSEVJR0hULFxuICAgIEFJX1RBQkxFX0ZJRUxEX0hFQURfTU9SRSxcbiAgICBBSV9UQUJMRV9GSUVMRF9IRUFEX1NFTEVDVF9DSEVDS0JPWCxcbiAgICBBSV9UQUJMRV9QT1BPVkVSX0xFRlRfT0ZGU0VULFxuICAgIEFJX1RBQkxFX1JPV19BRERfQlVUVE9OLFxuICAgIEFJX1RBQkxFX1JPV19IRUFEX1dJRFRILFxuICAgIEFJX1RBQkxFX1JPV19TRUxFQ1RfQ0hFQ0tCT1gsXG4gICAgREJMX0NMSUNLX0VESVRfVFlQRSxcbiAgICBERUZBVUxUX1BPSU5UX1BPU0lUSU9OLFxuICAgIERFRkFVTFRfU0NST0xMX1NUQVRFLFxuICAgIE1PVVNFT1ZFUl9FRElUX1RZUEVcbn0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgQUlUYWJsZSwgQ29vcmRpbmF0ZSwgUmVuZGVyZXJDb250ZXh0IH0gZnJvbSAnLi9jb3JlJztcbmltcG9ydCB7IEFJVGFibGVHcmlkQmFzZSB9IGZyb20gJy4vZ3JpZC1iYXNlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBBSVRhYmxlUmVuZGVyZXIgfSBmcm9tICcuL3JlbmRlcmVyL3JlbmRlcmVyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBBSVRhYmxlR3JpZEV2ZW50U2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvZXZlbnQuc2VydmljZSc7XG5pbXBvcnQgeyBBSVRhYmxlR3JpZEZpZWxkU2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvZmllbGQuc2VydmljZSc7XG5pbXBvcnQgeyBBSVRhYmxlR3JpZFNlbGVjdGlvblNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL3NlbGVjdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IEFJVGFibGVNb3VzZURvd25UeXBlLCBBSVRhYmxlUmVuZGVyZXJDb25maWcsIFNjcm9sbEFjdGlvbk9wdGlvbnMgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IGJ1aWxkR3JpZExpbmVhclJvd3MsIGdldENvbHVtbkluZGljZXNNYXAsIGdldERldGFpbEJ5VGFyZ2V0TmFtZSwgaGFuZGxlTW91c2VTdHlsZSwgaXNXaW5kb3dzIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyBnZXRNb3VzZVBvc2l0aW9uIH0gZnJvbSAnLi91dGlscy9wb3NpdGlvbic7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnYWktdGFibGUtZ3JpZCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2dyaWQuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gICAgaG9zdDoge1xuICAgICAgICBjbGFzczogJ2FpLXRhYmxlLWdyaWQnXG4gICAgfSxcbiAgICBpbXBvcnRzOiBbQUlUYWJsZVJlbmRlcmVyXSxcbiAgICBwcm92aWRlcnM6IFtBSVRhYmxlR3JpZEV2ZW50U2VydmljZSwgQUlUYWJsZUdyaWRGaWVsZFNlcnZpY2UsIEFJVGFibGVHcmlkU2VsZWN0aW9uU2VydmljZV1cbn0pXG5leHBvcnQgY2xhc3MgQUlUYWJsZUdyaWQgZXh0ZW5kcyBBSVRhYmxlR3JpZEJhc2UgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gICAgdGltZXIhOiBudW1iZXIgfCBudWxsO1xuXG4gICAgcmVzaXplT2JzZXJ2ZXIhOiBSZXNpemVPYnNlcnZlcjtcblxuICAgIGZpZWxkSGVhZEhlaWdodCA9IEFJX1RBQkxFX0ZJRUxEX0hFQURfSEVJR0hUO1xuXG4gICAgQUREX0JVVFRPTl9XSURUSCA9IEFJX1RBQkxFX0ZJRUxEX0FERF9CVVRUT05fV0lEVEg7XG5cbiAgICBjb250YWluZXJSZWN0ID0gc2lnbmFsKHsgd2lkdGg6IDAsIGhlaWdodDogMCB9KTtcblxuICAgIGhhc0NvbnRhaW5lclJlY3QgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRhaW5lclJlY3QoKS53aWR0aCA+IDAgJiYgdGhpcy5jb250YWluZXJSZWN0KCkuaGVpZ2h0ID4gMDtcbiAgICB9KTtcblxuICAgIGNvbnRhaW5lciA9IHZpZXdDaGlsZDxFbGVtZW50UmVmPignY29udGFpbmVyJyk7XG5cbiAgICB2ZXJ0aWNhbEJhclJlZiA9IHZpZXdDaGlsZDxFbGVtZW50UmVmPigndmVydGljYWxCYXInKTtcblxuICAgIGhvcml6b250YWxCYXJSZWYgPSB2aWV3Q2hpbGQ8RWxlbWVudFJlZj4oJ2hvcml6b250YWxCYXInKTtcblxuICAgIGxpbmVhclJvd3MgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIHJldHVybiBidWlsZEdyaWRMaW5lYXJSb3dzKHRoaXMuZ3JpZERhdGEoKS5yZWNvcmRzKTtcbiAgICB9KTtcblxuICAgIHZpc2libGVDb2x1bW5zTWFwID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCBjb2x1bW5zID0gQUlUYWJsZS5nZXRWaXNpYmxlRmllbGRzKHRoaXMuYWlUYWJsZSk7XG4gICAgICAgIHJldHVybiBuZXcgTWFwKGNvbHVtbnM/Lm1hcCgoaXRlbSwgaW5kZXgpID0+IFtpdGVtLl9pZCwgaW5kZXhdKSk7XG4gICAgfSk7XG5cbiAgICB2aXNpYmxlUm93c0luZGV4TWFwID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICByZXR1cm4gbmV3IE1hcCh0aGlzLmxpbmVhclJvd3MoKS5tYXAoKHJvdywgaW5kZXgpID0+IFtyb3cuX2lkLCBpbmRleF0pKTtcbiAgICB9KTtcblxuICAgIGNvbnRhaW5lckVsZW1lbnQgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRhaW5lcigpIS5uYXRpdmVFbGVtZW50O1xuICAgIH0pO1xuXG4gICAgcmVuZGVyZXJDb25maWc6IFNpZ25hbDxBSVRhYmxlUmVuZGVyZXJDb25maWc+ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCBmaWVsZHMgPSBBSVRhYmxlLmdldFZpc2libGVGaWVsZHModGhpcy5haVRhYmxlKTtcbiAgICAgICAgY29uc3QgY29vcmRpbmF0ZSA9IG5ldyBDb29yZGluYXRlKHtcbiAgICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5jb250YWluZXJFbGVtZW50KCksXG4gICAgICAgICAgICByb3dIZWlnaHQ6IEFJX1RBQkxFX0ZJRUxEX0hFQURfSEVJR0hULFxuICAgICAgICAgICAgcm93Q291bnQ6IHRoaXMubGluZWFyUm93cygpLmxlbmd0aCxcbiAgICAgICAgICAgIGNvbHVtbkNvdW50OiBmaWVsZHMubGVuZ3RoLFxuICAgICAgICAgICAgcm93SW5pdFNpemU6IEFJX1RBQkxFX0ZJRUxEX0hFQURfSEVJR0hULFxuICAgICAgICAgICAgY29sdW1uSW5pdFNpemU6IEFJX1RBQkxFX1JPV19IRUFEX1dJRFRILFxuICAgICAgICAgICAgcm93SW5kaWNlc01hcDoge30sXG4gICAgICAgICAgICBjb2x1bW5JbmRpY2VzTWFwOiBnZXRDb2x1bW5JbmRpY2VzTWFwKGZpZWxkcyksXG4gICAgICAgICAgICBmcm96ZW5Db2x1bW5Db3VudDogMVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGFpVGFibGU6IHRoaXMuYWlUYWJsZSxcbiAgICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5jb250YWluZXJFbGVtZW50KCksXG4gICAgICAgICAgICBjb29yZGluYXRlOiBjb29yZGluYXRlLFxuICAgICAgICAgICAgY29udGFpbmVyV2lkdGg6IHRoaXMuY29udGFpbmVyUmVjdCgpLndpZHRoLFxuICAgICAgICAgICAgY29udGFpbmVySGVpZ2h0OiB0aGlzLmNvbnRhaW5lclJlY3QoKS5oZWlnaHQsXG4gICAgICAgICAgICByZWZlcmVuY2VzOiB0aGlzLmFpUmVmZXJlbmNlcygpXG4gICAgICAgIH07XG4gICAgfSk7XG5cbiAgICBjb29yZGluYXRlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZW5kZXJlckNvbmZpZygpLmNvb3JkaW5hdGU7XG4gICAgfSk7XG5cbiAgICBzY3JvbGxUb3RhbEhlaWdodCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KHRoaXMuY29vcmRpbmF0ZSgpLnRvdGFsSGVpZ2h0LCB0aGlzLmNvbnRhaW5lclJlY3QoKS5oZWlnaHQgLSB0aGlzLmZpZWxkSGVhZEhlaWdodCk7XG4gICAgfSk7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgYWZ0ZXJOZXh0UmVuZGVyKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2V0Q29udGFpbmVyUmVjdCgpO1xuICAgICAgICAgICAgdGhpcy5iaW5kR2xvYmFsTW91c2Vkb3duKCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lclJlc2l6ZUxpc3RlbmVyKCk7XG4gICAgICAgICAgICB0aGlzLmJpbmRXaGVlbCgpO1xuICAgICAgICB9KTtcbiAgICAgICAgZWZmZWN0KCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0NvbnRhaW5lclJlY3QoKSAmJiB0aGlzLmhvcml6b250YWxCYXJSZWYoKSAmJiB0aGlzLnZlcnRpY2FsQmFyUmVmKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmJpbmRTY3JvbGxCYXJTY3JvbGwoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5haVRhYmxlLmNvbnRleHQ/LnBvaW50UG9zaXRpb24oKSkge1xuICAgICAgICAgICAgICAgIHRoaXMudG9nZ2xlSG92ZXJDZWxsRWRpdG9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG92ZXJyaWRlIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICBzdXBlci5uZ09uSW5pdCgpO1xuICAgICAgICB0aGlzLmluaXRDb250ZXh0KCk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXI/LmRpc2Nvbm5lY3QoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRDb250ZXh0KCkge1xuICAgICAgICB0aGlzLmFpVGFibGUuY29udGV4dCA9IG5ldyBSZW5kZXJlckNvbnRleHQoe1xuICAgICAgICAgICAgbGluZWFyUm93czogdGhpcy5saW5lYXJSb3dzLFxuICAgICAgICAgICAgdmlzaWJsZUNvbHVtbnNNYXA6IHRoaXMudmlzaWJsZUNvbHVtbnNNYXAsXG4gICAgICAgICAgICB2aXNpYmxlUm93c0luZGV4TWFwOiB0aGlzLnZpc2libGVSb3dzSW5kZXhNYXAsXG4gICAgICAgICAgICBwb2ludFBvc2l0aW9uOiBzaWduYWwoREVGQVVMVF9QT0lOVF9QT1NJVElPTiksXG4gICAgICAgICAgICBzY3JvbGxTdGF0ZTogc2lnbmFsKERFRkFVTFRfU0NST0xMX1NUQVRFKSxcbiAgICAgICAgICAgIHNjcm9sbEFjdGlvbjogdGhpcy5zY3JvbGxBY3Rpb25cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RhZ2VNb3VzZW1vdmUoZTogS29FdmVudE9iamVjdDxNb3VzZUV2ZW50Pikge1xuICAgICAgICBpZiAodGhpcy50aW1lcikge1xuICAgICAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy50aW1lcik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50aW1lciA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0YXJnZXROYW1lID0gZS5ldmVudC50YXJnZXQubmFtZSgpO1xuICAgICAgICAgICAgY29uc3QgZ3JpZFN0YWdlID0gZS5ldmVudC5jdXJyZW50VGFyZ2V0LmdldFN0YWdlKCk7XG4gICAgICAgICAgICBjb25zdCBwb3MgPSBncmlkU3RhZ2U/LmdldFBvaW50ZXJQb3NpdGlvbigpO1xuICAgICAgICAgICAgaWYgKHBvcyA9PSBudWxsKSByZXR1cm47XG4gICAgICAgICAgICBjb25zdCB7IGNvbnRleHQgfSA9IHRoaXMuYWlUYWJsZTtcbiAgICAgICAgICAgIGNvbnN0IHsgeCwgeSB9ID0gcG9zO1xuICAgICAgICAgICAgY29uc3QgY3VyTW91c2VQb3NpdGlvbiA9IGdldE1vdXNlUG9zaXRpb24oXG4gICAgICAgICAgICAgICAgeCxcbiAgICAgICAgICAgICAgICB5LFxuICAgICAgICAgICAgICAgIHRoaXMuY29vcmRpbmF0ZSgpLFxuICAgICAgICAgICAgICAgIEFJVGFibGUuZ2V0VmlzaWJsZUZpZWxkcyh0aGlzLmFpVGFibGUpLFxuICAgICAgICAgICAgICAgIGNvbnRleHQhLFxuICAgICAgICAgICAgICAgIHRhcmdldE5hbWVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBoYW5kbGVNb3VzZVN0eWxlKGN1ck1vdXNlUG9zaXRpb24ucmVhbFRhcmdldE5hbWUsIGN1ck1vdXNlUG9zaXRpb24uYXJlYVR5cGUsIHRoaXMuY29udGFpbmVyRWxlbWVudCgpKTtcbiAgICAgICAgICAgIGNvbnRleHQhLnNldFBvaW50UG9zaXRpb24oY3VyTW91c2VQb3NpdGlvbik7XG4gICAgICAgICAgICB0aGlzLnRpbWVyID0gbnVsbDtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RhZ2VNb3VzZWRvd24oZTogS29FdmVudE9iamVjdDxNb3VzZUV2ZW50Pikge1xuICAgICAgICBjb25zdCBtb3VzZUV2ZW50ID0gZS5ldmVudC5ldnQ7XG4gICAgICAgIGNvbnN0IF90YXJnZXROYW1lID0gZS5ldmVudC50YXJnZXQubmFtZSgpO1xuXG4gICAgICAgIGNvbnN0IHsgdGFyZ2V0TmFtZSwgZmllbGRJZCwgcmVjb3JkSWQgfSA9IGdldERldGFpbEJ5VGFyZ2V0TmFtZShfdGFyZ2V0TmFtZSk7XG4gICAgICAgIHN3aXRjaCAodGFyZ2V0TmFtZSkge1xuICAgICAgICAgICAgY2FzZSBBSV9UQUJMRV9GSUVMRF9IRUFEOlxuICAgICAgICAgICAgICAgIG1vdXNlRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICBpZiAoIWZpZWxkSWQpIHJldHVybjtcbiAgICAgICAgICAgICAgICB0aGlzLmFpVGFibGVHcmlkU2VsZWN0aW9uU2VydmljZS5zZWxlY3RGaWVsZChmaWVsZElkKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICBjYXNlIEFJX1RBQkxFX0NFTEw6XG4gICAgICAgICAgICAgICAgaWYgKCFyZWNvcmRJZCB8fCAhZmllbGRJZCkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIHRoaXMuYWlUYWJsZUdyaWRFdmVudFNlcnZpY2UuY2xvc2VDZWxsRWRpdG9yKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5haVRhYmxlR3JpZFNlbGVjdGlvblNlcnZpY2Uuc2VsZWN0Q2VsbChyZWNvcmRJZCwgZmllbGRJZCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgY2FzZSBBSV9UQUJMRV9ST1dfQUREX0JVVFRPTjpcbiAgICAgICAgICAgIGNhc2UgQUlfVEFCTEVfRklFTERfQUREX0JVVFRPTjpcbiAgICAgICAgICAgIGNhc2UgQUlfVEFCTEVfUk9XX1NFTEVDVF9DSEVDS0JPWDpcbiAgICAgICAgICAgIGNhc2UgQUlfVEFCTEVfRklFTERfSEVBRF9TRUxFQ1RfQ0hFQ0tCT1g6XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aGlzLmFpVGFibGVHcmlkU2VsZWN0aW9uU2VydmljZS5jbGVhclNlbGVjdGlvbigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhZ2VDbGljayhlOiBLb0V2ZW50T2JqZWN0PE1vdXNlRXZlbnQ+KSB7XG4gICAgICAgIGNvbnN0IG1vdXNlRXZlbnQgPSBlLmV2ZW50LmV2dDtcbiAgICAgICAgbW91c2VFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBjb25zdCB7IGNvbnRleHQgfSA9IHRoaXMuYWlUYWJsZTtcbiAgICAgICAgY29uc3QgeyB0YXJnZXROYW1lLCByb3dJbmRleDogcG9pbnRSb3dJbmRleCB9ID0gY29udGV4dCEucG9pbnRQb3NpdGlvbigpO1xuICAgICAgICBpZiAobW91c2VFdmVudC5idXR0b24gIT09IEFJVGFibGVNb3VzZURvd25UeXBlLkxlZnQpIHJldHVybjtcbiAgICAgICAgc3dpdGNoICh0YXJnZXROYW1lKSB7XG4gICAgICAgICAgICBjYXNlIEFJX1RBQkxFX1JPV19BRERfQlVUVE9OOiB7XG4gICAgICAgICAgICAgICAgdGhpcy5haVRhYmxlR3JpZFNlbGVjdGlvblNlcnZpY2UuY2xlYXJTZWxlY3Rpb24oKTtcbiAgICAgICAgICAgICAgICB0aGlzLmFkZFJlY29yZCgpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgQUlfVEFCTEVfUk9XX1NFTEVDVF9DSEVDS0JPWDoge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBvaW50UmVjb3JkSWQgPSBjb250ZXh0IS5saW5lYXJSb3dzKClbcG9pbnRSb3dJbmRleF0/Ll9pZDtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdFJlY29yZChwb2ludFJlY29yZElkKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIEFJX1RBQkxFX0ZJRUxEX0hFQURfU0VMRUNUX0NIRUNLQk9YOiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaXNDaGVja2VkID0gdGhpcy5haVRhYmxlLnNlbGVjdGlvbigpLnNlbGVjdGVkUmVjb3Jkcy5zaXplID09PSB0aGlzLmFpVGFibGUucmVjb3JkcygpLmxlbmd0aDtcbiAgICAgICAgICAgICAgICB0aGlzLnRvZ2dsZVNlbGVjdEFsbCghaXNDaGVja2VkKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIEFJX1RBQkxFX0ZJRUxEX0FERF9CVVRUT046IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFpVGFibGVHcmlkU2VsZWN0aW9uU2VydmljZS5jbGVhclNlbGVjdGlvbigpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpZWxkR3JvdXBSZWN0ID0gZS5ldmVudC50YXJnZXQuZ2V0UGFyZW50KCk/LmdldENsaWVudFJlY3QoKSE7XG4gICAgICAgICAgICAgICAgY29uc3QgY29udGFpbmVyUmVjdCA9IHRoaXMuY29udGFpbmVyRWxlbWVudCgpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkRmllbGQodGhpcy5jb250YWluZXJFbGVtZW50KCksIHtcbiAgICAgICAgICAgICAgICAgICAgeDogZmllbGRHcm91cFJlY3QueCArIGNvbnRhaW5lclJlY3QueCxcbiAgICAgICAgICAgICAgICAgICAgeTogY29udGFpbmVyUmVjdC55ICsgZmllbGRHcm91cFJlY3QueSArIGZpZWxkR3JvdXBSZWN0LmhlaWdodFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgQUlfVEFCTEVfRklFTERfSEVBRF9NT1JFOlxuICAgICAgICAgICAgICAgIG1vdXNlRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBfdGFyZ2V0TmFtZSA9IGUuZXZlbnQudGFyZ2V0Lm5hbWUoKTtcbiAgICAgICAgICAgICAgICBjb25zdCB7IGZpZWxkSWQgfSA9IGdldERldGFpbEJ5VGFyZ2V0TmFtZShfdGFyZ2V0TmFtZSk7XG4gICAgICAgICAgICAgICAgaWYgKGZpZWxkSWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbW9yZVJlY3QgPSBlLmV2ZW50LnRhcmdldC5nZXRDbGllbnRSZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpZWxkR3JvdXBSZWN0ID0gZS5ldmVudC50YXJnZXQuZ2V0UGFyZW50KCk/LmdldFBhcmVudCgpPy5nZXRDbGllbnRSZWN0KCkhO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb250YWluZXJSZWN0ID0gdGhpcy5jb250YWluZXJFbGVtZW50KCkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zaXRpb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBjb250YWluZXJSZWN0LnggKyBtb3JlUmVjdC54LFxuICAgICAgICAgICAgICAgICAgICAgICAgeTogY29udGFpbmVyUmVjdC55ICsgbW9yZVJlY3QueSArIG1vcmVSZWN0LmhlaWdodFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlZGl0T3JpZ2luUG9zaXRpb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBBSV9UQUJMRV9QT1BPVkVSX0xFRlRfT0ZGU0VUICsgZmllbGRHcm91cFJlY3QueCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IGNvbnRhaW5lclJlY3QueSArIGZpZWxkR3JvdXBSZWN0LnkgKyBmaWVsZEdyb3VwUmVjdC5oZWlnaHRcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBlZGl0T3JpZ2luID0gdGhpcy5jb250YWluZXJFbGVtZW50KCkucXVlcnlTZWxlY3RvcignLmtvbnZhanMtY29udGVudCcpIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFpVGFibGVHcmlkRmllbGRTZXJ2aWNlLm9wZW5GaWVsZE1lbnUodGhpcy5haVRhYmxlLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaWVsZElkOiBmaWVsZElkLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRNZW51czogdGhpcy5maWVsZE1lbnVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luOiB0aGlzLmNvbnRhaW5lckVsZW1lbnQoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgZWRpdE9yaWdpbjogZWRpdE9yaWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgIGVkaXRPcmlnaW5Qb3NpdGlvblxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhZ2VEYmxjbGljayhlOiBLb0V2ZW50T2JqZWN0PE1vdXNlRXZlbnQ+KSB7XG4gICAgICAgIGNvbnN0IF90YXJnZXROYW1lID0gZS5ldmVudC50YXJnZXQubmFtZSgpO1xuICAgICAgICBjb25zdCB7IGZpZWxkSWQsIHJlY29yZElkIH0gPSBnZXREZXRhaWxCeVRhcmdldE5hbWUoX3RhcmdldE5hbWUpO1xuICAgICAgICBpZiAoIXJlY29yZElkIHx8ICFmaWVsZElkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZmllbGQgPSB0aGlzLmFpVGFibGUuZmllbGRzTWFwKClbZmllbGRJZF07XG4gICAgICAgIGNvbnN0IGZpZWxkVHlwZSA9IGZpZWxkLnR5cGU7XG4gICAgICAgIGlmICghREJMX0NMSUNLX0VESVRfVFlQRS5pbmNsdWRlcyhmaWVsZFR5cGUpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcG9wb3ZlclJlZiA9IHRoaXMuYWlUYWJsZUdyaWRFdmVudFNlcnZpY2Uub3BlbkNlbGxFZGl0b3IodGhpcy5haVRhYmxlLCB7XG4gICAgICAgICAgICBjb250YWluZXI6IHRoaXMuY29udGFpbmVyRWxlbWVudCgpLFxuICAgICAgICAgICAgY29vcmRpbmF0ZTogdGhpcy5jb29yZGluYXRlKCksXG4gICAgICAgICAgICBmaWVsZElkOiBmaWVsZElkISxcbiAgICAgICAgICAgIHJlY29yZElkOiByZWNvcmRJZCFcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChwb3BvdmVyUmVmICYmICEodGhpcy5haUZpZWxkQ29uZmlnKCk/LmZpZWxkUHJvcGVydHlFZGl0b3IgJiYgdGhpcy5haUZpZWxkQ29uZmlnKCk/LmZpZWxkUHJvcGVydHlFZGl0b3JbZmllbGRUeXBlXSkpIHtcbiAgICAgICAgICAgIChwb3BvdmVyUmVmLmNvbXBvbmVudEluc3RhbmNlIGFzIEFic3RyYWN0RWRpdENlbGxFZGl0b3I8YW55PikudXBkYXRlRmllbGRWYWx1ZS5zdWJzY3JpYmUoKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5haVVwZGF0ZUZpZWxkVmFsdWUuZW1pdCh2YWx1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYmluZFdoZWVsKCkge1xuICAgICAgICBmcm9tRXZlbnQ8V2hlZWxFdmVudD4odGhpcy5jb250YWluZXJFbGVtZW50KCksICd3aGVlbCcsIHsgcGFzc2l2ZTogZmFsc2UgfSlcbiAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoZTogV2hlZWxFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmFpVGFibGVHcmlkRXZlbnRTZXJ2aWNlLmNsb3NlQ2VsbEVkaXRvcigpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2Nyb2xsQWN0aW9uKHsgZGVsdGFYOiBlLmRlbHRhWCwgZGVsdGFZOiBlLmRlbHRhWSwgc2hpZnRLZXk6IGUuc2hpZnRLZXkgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzY3JvbGxBY3Rpb24gPSAob3B0aW9uczogU2Nyb2xsQWN0aW9uT3B0aW9ucykgPT4ge1xuICAgICAgICBpZiAodGhpcy50aW1lcikge1xuICAgICAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy50aW1lcik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50aW1lciA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGRlbHRhWCwgZGVsdGFZLCBzaGlmdEtleSB9ID0gb3B0aW9ucztcbiAgICAgICAgICAgIGNvbnN0IGZpeGVkRGVsdGFZID0gc2hpZnRLZXkgJiYgaXNXaW5kb3dzID8gMCA6IGRlbHRhWTtcbiAgICAgICAgICAgIGNvbnN0IGZpeGVkRGVsdGFYID0gc2hpZnRLZXkgJiYgaXNXaW5kb3dzID8gZGVsdGFZIDogZGVsdGFYO1xuICAgICAgICAgICAgY29uc3QgaG9yaXpvbnRhbEJhciA9IHRoaXMuaG9yaXpvbnRhbEJhclJlZigpPy5uYXRpdmVFbGVtZW50O1xuICAgICAgICAgICAgY29uc3QgdmVydGljYWxCYXIgPSB0aGlzLnZlcnRpY2FsQmFyUmVmKCk/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICBpZiAoaG9yaXpvbnRhbEJhcikge1xuICAgICAgICAgICAgICAgIGhvcml6b250YWxCYXIuc2Nyb2xsTGVmdCA9IGhvcml6b250YWxCYXIuc2Nyb2xsTGVmdCArIGZpeGVkRGVsdGFYO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZlcnRpY2FsQmFyKSB7XG4gICAgICAgICAgICAgICAgdmVydGljYWxCYXIuc2Nyb2xsVG9wID0gdmVydGljYWxCYXIuc2Nyb2xsVG9wICsgZml4ZWREZWx0YVk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvcHRpb25zLmNhbGxiYWNrICYmIG9wdGlvbnMuY2FsbGJhY2soKTtcbiAgICAgICAgICAgIHRoaXMudGltZXIgPSBudWxsO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBiaW5kU2Nyb2xsQmFyU2Nyb2xsKCkge1xuICAgICAgICBmcm9tRXZlbnQ8V2hlZWxFdmVudD4odGhpcy5ob3Jpem9udGFsQmFyUmVmKCkhLm5hdGl2ZUVsZW1lbnQsICdzY3JvbGwnLCB7IHBhc3NpdmU6IHRydWUgfSlcbiAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuaG9yaXpvbnRhbFNjcm9sbChlKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIGZyb21FdmVudDxXaGVlbEV2ZW50Pih0aGlzLnZlcnRpY2FsQmFyUmVmKCkhLm5hdGl2ZUVsZW1lbnQsICdzY3JvbGwnLCB7IHBhc3NpdmU6IHRydWUgfSlcbiAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMudmVydGljYWxTY3JvbGwoZSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGJpbmRHbG9iYWxNb3VzZWRvd24oKSB7XG4gICAgICAgIGZyb21FdmVudDxNb3VzZUV2ZW50Pihkb2N1bWVudCwgJ21vdXNlZG93bicsIHsgcGFzc2l2ZTogdHJ1ZSB9KVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgZmlsdGVyKChlKSA9PiBlLnRhcmdldCBpbnN0YW5jZW9mIEVsZW1lbnQgJiYgIXRoaXMuY29udGFpbmVyRWxlbWVudCgpLmNvbnRhaW5zKGUudGFyZ2V0KSksXG4gICAgICAgICAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZilcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuYWlUYWJsZUdyaWRTZWxlY3Rpb25TZXJ2aWNlLmNsZWFyU2VsZWN0aW9uKCk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlc2V0U2Nyb2xsaW5nID0gKCkgPT4ge1xuICAgICAgICB0aGlzLmFpVGFibGUuY29udGV4dCEuc2V0U2Nyb2xsU3RhdGUoe1xuICAgICAgICAgICAgaXNTY3JvbGxpbmc6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBwcml2YXRlIGhvcml6b250YWxTY3JvbGwgPSAoZTogYW55KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgc2Nyb2xsTGVmdCB9ID0gZS50YXJnZXQ7XG4gICAgICAgIHRoaXMuYWlUYWJsZS5jb250ZXh0IS5zZXRTY3JvbGxTdGF0ZSh7XG4gICAgICAgICAgICBzY3JvbGxMZWZ0LFxuICAgICAgICAgICAgaXNTY3JvbGxpbmc6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucmVzZXRTY3JvbGxpbmcoKTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSB2ZXJ0aWNhbFNjcm9sbChlOiBhbnkpIHtcbiAgICAgICAgY29uc3QgeyBzY3JvbGxUb3AgfSA9IGUudGFyZ2V0O1xuICAgICAgICB0aGlzLmFpVGFibGUuY29udGV4dCEuc2V0U2Nyb2xsU3RhdGUoe1xuICAgICAgICAgICAgc2Nyb2xsVG9wLFxuICAgICAgICAgICAgaXNTY3JvbGxpbmc6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucmVzZXRTY3JvbGxpbmcoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNldENvbnRhaW5lclJlY3QoKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyUmVjdC5zZXQoe1xuICAgICAgICAgICAgd2lkdGg6IHRoaXMuY29udGFpbmVyRWxlbWVudCgpLm9mZnNldFdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLmNvbnRhaW5lckVsZW1lbnQoKS5vZmZzZXRIZWlnaHRcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb250YWluZXJSZXNpemVMaXN0ZW5lcigpIHtcbiAgICAgICAgdGhpcy5yZXNpemVPYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb250YWluZXJXaWR0aCA9IHRoaXMuY29udGFpbmVyRWxlbWVudCgpLm9mZnNldFdpZHRoO1xuICAgICAgICAgICAgY29uc3QgdG90YWxXaWR0aCA9IHRoaXMuY29vcmRpbmF0ZSgpLnRvdGFsV2lkdGggKyB0aGlzLkFERF9CVVRUT05fV0lEVEg7XG4gICAgICAgICAgICB0aGlzLnNldENvbnRhaW5lclJlY3QoKTtcbiAgICAgICAgICAgIGlmIChjb250YWluZXJXaWR0aCA+PSB0b3RhbFdpZHRoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5haVRhYmxlLmNvbnRleHQhLnNldFNjcm9sbFN0YXRlKHsgc2Nyb2xsTGVmdDogMCB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyLm9ic2VydmUodGhpcy5jb250YWluZXJFbGVtZW50KCkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgdG9nZ2xlSG92ZXJDZWxsRWRpdG9yKCkge1xuICAgICAgICBjb25zdCB7IHJlYWxUYXJnZXROYW1lIH0gPSB0aGlzLmFpVGFibGUuY29udGV4dD8ucG9pbnRQb3NpdGlvbigpITtcbiAgICAgICAgY29uc3QgeyB0YXJnZXROYW1lLCBmaWVsZElkLCByZWNvcmRJZCB9ID0gZ2V0RGV0YWlsQnlUYXJnZXROYW1lKHJlYWxUYXJnZXROYW1lISk7XG4gICAgICAgIGNvbnN0IGVkaXRpbmdDZWxsID0gdGhpcy5haVRhYmxlR3JpZEV2ZW50U2VydmljZS5nZXRDdXJyZW50RWRpdENlbGwoKTtcblxuICAgICAgICBpZiAodGFyZ2V0TmFtZSA9PT0gQUlfVEFCTEVfQ0VMTCAmJiByZWNvcmRJZCAmJiBmaWVsZElkKSB7XG4gICAgICAgICAgICBjb25zdCBmaWVsZCA9IHRoaXMuYWlUYWJsZS5maWVsZHNNYXAoKVtmaWVsZElkXTtcblxuICAgICAgICAgICAgaWYgKCFmaWVsZCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZmllbGRUeXBlID0gZmllbGQudHlwZTtcbiAgICAgICAgICAgIGNvbnN0IGVkaXRpbmdGaWVsZFR5cGUgPSBlZGl0aW5nQ2VsbCA/IHRoaXMuYWlUYWJsZS5maWVsZHNNYXAoKVtlZGl0aW5nQ2VsbC5maWVsZElkXS50eXBlIDogbnVsbDtcbiAgICAgICAgICAgIGNvbnN0IGlzRWRpdGluZ0ZpZWxkVHlwZUhvdmVyZWQgPSBlZGl0aW5nRmllbGRUeXBlID8gTU9VU0VPVkVSX0VESVRfVFlQRS5pbmNsdWRlcyhlZGl0aW5nRmllbGRUeXBlKSA6IGZhbHNlO1xuICAgICAgICAgICAgY29uc3QgaXNGaWVsZFR5cGVIb3ZlcmVkID0gTU9VU0VPVkVSX0VESVRfVFlQRS5pbmNsdWRlcyhmaWVsZFR5cGUpO1xuXG4gICAgICAgICAgICBpZiAoZWRpdGluZ0NlbGwgJiYgaXNFZGl0aW5nRmllbGRUeXBlSG92ZXJlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWlUYWJsZUdyaWRFdmVudFNlcnZpY2UuY2xvc2VDZWxsRWRpdG9yKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghZWRpdGluZ0NlbGwgJiYgIWlzRmllbGRUeXBlSG92ZXJlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWlUYWJsZUdyaWRFdmVudFNlcnZpY2UuY2xvc2VDZWxsRWRpdG9yKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZWRpdGluZ0NlbGwgJiYgKCghaXNFZGl0aW5nRmllbGRUeXBlSG92ZXJlZCAmJiBpc0ZpZWxkVHlwZUhvdmVyZWQpIHx8ICFpc0ZpZWxkVHlwZUhvdmVyZWQpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFpVGFibGVHcmlkRXZlbnRTZXJ2aWNlLm9wZW5DZWxsRWRpdG9yKHRoaXMuYWlUYWJsZSwge1xuICAgICAgICAgICAgICAgICAgICBjb250YWluZXI6IHRoaXMuY29udGFpbmVyRWxlbWVudCgpLFxuICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlOiB0aGlzLmNvb3JkaW5hdGUoKSxcbiAgICAgICAgICAgICAgICAgICAgZmllbGRJZDogZmllbGRJZCEsXG4gICAgICAgICAgICAgICAgICAgIHJlY29yZElkOiByZWNvcmRJZCEsXG4gICAgICAgICAgICAgICAgICAgIGlzSG92ZXJFZGl0OiB0cnVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIOm8oOagh+S9jeS6jumdnuWNleWFg+agvOWMuuWfn+aXtu+8jOWmguaenOW9k+WJjeaciSBtb3VzZW92ZXIg57yW6L6R5YWD57Sg77yM5YiZ57uT5p2f57yW6L6RXG4gICAgICAgICAgICBpZiAoZWRpdGluZ0NlbGwgJiYgTU9VU0VPVkVSX0VESVRfVFlQRS5pbmNsdWRlcyh0aGlzLmFpVGFibGUuZmllbGRzTWFwKClbZWRpdGluZ0NlbGwuZmllbGRJZF0udHlwZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFpVGFibGVHcmlkRXZlbnRTZXJ2aWNlLmNsb3NlQ2VsbEVkaXRvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuIiwiPGRpdiAjY29udGFpbmVyIGNsYXNzPVwiYWktdGFibGUtZ3JpZC12aWV3XCI+XG4gICAgQGlmIChoYXNDb250YWluZXJSZWN0KCkpIHtcbiAgICAgICAgPGFpLXRhYmxlLXJlbmRlcmVyXG4gICAgICAgICAgICBbY29uZmlnXT1cInJlbmRlcmVyQ29uZmlnKClcIlxuICAgICAgICAgICAgKGtvTW91c2Vtb3ZlKT1cInN0YWdlTW91c2Vtb3ZlKCRldmVudClcIlxuICAgICAgICAgICAgKGtvTW91c2Vkb3duKT1cInN0YWdlTW91c2Vkb3duKCRldmVudClcIlxuICAgICAgICAgICAgKGtvQ2xpY2spPVwic3RhZ2VDbGljaygkZXZlbnQpXCJcbiAgICAgICAgICAgIChrb0RibGNsaWNrKT1cInN0YWdlRGJsY2xpY2soJGV2ZW50KVwiXG4gICAgICAgID5cbiAgICAgICAgICAgIDxkaXYgI2hvcml6b250YWxCYXIgY2xhc3M9XCJhaS10YWJsZS1ob3Jpem9udGFsLXNjcm9sbC1iYXItd3JhcHBlclwiIFtzdHlsZS53aWR0aC5weF09XCJjb250YWluZXJSZWN0KCkud2lkdGhcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWktdGFibGUtc2Nyb2xsLWJhci1pbm5lclwiIFtzdHlsZS53aWR0aC5weF09XCJjb29yZGluYXRlKCkudG90YWxXaWR0aCArIEFERF9CVVRUT05fV0lEVEhcIj48L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICN2ZXJ0aWNhbEJhclxuICAgICAgICAgICAgICAgIGNsYXNzPVwiYWktdGFibGUtdmVydGljYWwtc2Nyb2xsLWJhci13cmFwcGVyXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cImNvbnRhaW5lclJlY3QoKS5oZWlnaHQgLSBmaWVsZEhlYWRIZWlnaHRcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS50b3AucHhdPVwiZmllbGRIZWFkSGVpZ2h0XCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWktdGFibGUtc2Nyb2xsLWJhci1pbm5lclwiIFtzdHlsZS5oZWlnaHQucHhdPVwic2Nyb2xsVG90YWxIZWlnaHQoKVwiPjwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvYWktdGFibGUtcmVuZGVyZXI+XG4gICAgfVxuPC9kaXY+XG4iXX0=