@tolle_/tolle-ui 18.2.29 → 18.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/esm2022/lib/accordion-item.component.mjs +5 -11
  2. package/esm2022/lib/accordion.component.mjs +4 -9
  3. package/esm2022/lib/alert-dialog-dynamic.component.mjs +12 -12
  4. package/esm2022/lib/alert-dialog.component.mjs +82 -64
  5. package/esm2022/lib/alert-dialog.service.mjs +38 -6
  6. package/esm2022/lib/alert.component.mjs +5 -11
  7. package/esm2022/lib/aspect-ratio.component.mjs +119 -0
  8. package/esm2022/lib/attachment.component.mjs +334 -0
  9. package/esm2022/lib/avatar-fallback.component.mjs +3 -3
  10. package/esm2022/lib/avatar.component.mjs +4 -9
  11. package/esm2022/lib/badge.component.mjs +4 -9
  12. package/esm2022/lib/breadcrumb-item.component.mjs +3 -3
  13. package/esm2022/lib/breadcrumb-link.component.mjs +3 -3
  14. package/esm2022/lib/breadcrumb-separator.component.mjs +3 -3
  15. package/esm2022/lib/breadcrumb.component.mjs +3 -3
  16. package/esm2022/lib/bubble.component.mjs +301 -0
  17. package/esm2022/lib/button.component.mjs +5 -11
  18. package/esm2022/lib/calendar.component.mjs +5 -11
  19. package/esm2022/lib/card.component.mjs +14 -43
  20. package/esm2022/lib/carousel/carousel.component.mjs +5 -12
  21. package/esm2022/lib/chain-of-thought.component.mjs +380 -0
  22. package/esm2022/lib/chart-pie.component.mjs +386 -0
  23. package/esm2022/lib/chart.component.mjs +1146 -0
  24. package/esm2022/lib/chart.service.mjs +555 -0
  25. package/esm2022/lib/checkbox.component.mjs +5 -11
  26. package/esm2022/lib/checkpoint.component.mjs +134 -0
  27. package/esm2022/lib/collapsible.component.mjs +4 -11
  28. package/esm2022/lib/combobox.component.mjs +372 -0
  29. package/esm2022/lib/command-dialog.component.mjs +164 -0
  30. package/esm2022/lib/command.component.mjs +514 -0
  31. package/esm2022/lib/command.service.mjs +130 -0
  32. package/esm2022/lib/confirmation.component.mjs +219 -0
  33. package/esm2022/lib/context-menu-trigger.directive.mjs +36 -0
  34. package/esm2022/lib/context-menu.component.mjs +460 -0
  35. package/esm2022/lib/context-menu.service.mjs +125 -0
  36. package/esm2022/lib/context.component.mjs +377 -0
  37. package/esm2022/lib/conversation.component.mjs +442 -0
  38. package/esm2022/lib/country-selector.component.mjs +5 -11
  39. package/esm2022/lib/data-table.component.mjs +59 -12
  40. package/esm2022/lib/date-picker.component.mjs +251 -198
  41. package/esm2022/lib/date-range-picker.component.mjs +224 -116
  42. package/esm2022/lib/date-time-picker.component.mjs +506 -0
  43. package/esm2022/lib/direction.component.mjs +79 -0
  44. package/esm2022/lib/dropdown-item.component.mjs +3 -3
  45. package/esm2022/lib/dropdown-label.component.mjs +3 -3
  46. package/esm2022/lib/dropdown-menu.component.mjs +3 -3
  47. package/esm2022/lib/dropdown-separator.component.mjs +3 -3
  48. package/esm2022/lib/dropdown-trigger.directive.mjs +6 -4
  49. package/esm2022/lib/empty-state.component.mjs +4 -9
  50. package/esm2022/lib/field.component.mjs +394 -0
  51. package/esm2022/lib/hover-card.component.mjs +6 -16
  52. package/esm2022/lib/inline-citation.component.mjs +263 -0
  53. package/esm2022/lib/input-group.component.mjs +418 -0
  54. package/esm2022/lib/input.component.mjs +5 -11
  55. package/esm2022/lib/item.component.mjs +243 -0
  56. package/esm2022/lib/kbd.component.mjs +82 -0
  57. package/esm2022/lib/label.component.mjs +4 -9
  58. package/esm2022/lib/marker.component.mjs +135 -0
  59. package/esm2022/lib/masked-input.component.mjs +5 -11
  60. package/esm2022/lib/menubar.component.mjs +683 -0
  61. package/esm2022/lib/message-scroller.component.mjs +353 -0
  62. package/esm2022/lib/message-scroller.service.mjs +157 -0
  63. package/esm2022/lib/message.component.mjs +228 -0
  64. package/esm2022/lib/modal-ref.mjs +36 -7
  65. package/esm2022/lib/modal.component.mjs +42 -28
  66. package/esm2022/lib/modal.mjs +2 -29
  67. package/esm2022/lib/modal.service.mjs +26 -4
  68. package/esm2022/lib/model-selector.component.mjs +310 -0
  69. package/esm2022/lib/multi-select.component.mjs +155 -72
  70. package/esm2022/lib/native-select.component.mjs +201 -0
  71. package/esm2022/lib/navigation-menu.component.mjs +642 -0
  72. package/esm2022/lib/otp-group.component.mjs +3 -3
  73. package/esm2022/lib/otp-slot.component.mjs +4 -9
  74. package/esm2022/lib/otp.component.mjs +5 -11
  75. package/esm2022/lib/pagination.component.mjs +7 -10
  76. package/esm2022/lib/plan.component.mjs +335 -0
  77. package/esm2022/lib/popover-content.component.mjs +4 -9
  78. package/esm2022/lib/popover.component.mjs +15 -13
  79. package/esm2022/lib/progress.component.mjs +4 -9
  80. package/esm2022/lib/prompt-input.component.mjs +526 -0
  81. package/esm2022/lib/queue.component.mjs +280 -0
  82. package/esm2022/lib/radio-group.component.mjs +6 -13
  83. package/esm2022/lib/radio-item.component.mjs +4 -9
  84. package/esm2022/lib/range-calendar.component.mjs +5 -11
  85. package/esm2022/lib/reasoning.component.mjs +335 -0
  86. package/esm2022/lib/resizable-panel.component.mjs +5 -5
  87. package/esm2022/lib/resizable.component.mjs +219 -0
  88. package/esm2022/lib/segment.component.mjs +19 -9
  89. package/esm2022/lib/select-group.component.mjs +4 -8
  90. package/esm2022/lib/select-item.component.mjs +4 -9
  91. package/esm2022/lib/select-separator.component.mjs +4 -8
  92. package/esm2022/lib/select.component.mjs +133 -49
  93. package/esm2022/lib/separator.component.mjs +4 -9
  94. package/esm2022/lib/sheet.component.mjs +38 -56
  95. package/esm2022/lib/shimmer.component.mjs +84 -0
  96. package/esm2022/lib/sidebar.component.mjs +11 -1
  97. package/esm2022/lib/skeleton.component.mjs +4 -9
  98. package/esm2022/lib/sources.component.mjs +452 -0
  99. package/esm2022/lib/spinner.component.mjs +68 -0
  100. package/esm2022/lib/suggestion.component.mjs +207 -0
  101. package/esm2022/lib/switch.component.mjs +5 -11
  102. package/esm2022/lib/table.component.mjs +213 -0
  103. package/esm2022/lib/tabs.component.mjs +4 -11
  104. package/esm2022/lib/tag-input.component.mjs +5 -11
  105. package/esm2022/lib/task.component.mjs +359 -0
  106. package/esm2022/lib/textarea.component.mjs +5 -11
  107. package/esm2022/lib/theme.service.mjs +17 -6
  108. package/esm2022/lib/time-picker.component.mjs +923 -0
  109. package/esm2022/lib/toast.service.mjs +3 -2
  110. package/esm2022/lib/toaster.component.mjs +76 -39
  111. package/esm2022/lib/toggle-group.component.mjs +4 -9
  112. package/esm2022/lib/toggle.component.mjs +5 -11
  113. package/esm2022/lib/tool.component.mjs +462 -0
  114. package/esm2022/lib/typography.component.mjs +83 -0
  115. package/esm2022/lib/utils/color.mjs +140 -19
  116. package/esm2022/public-api.mjs +61 -1
  117. package/fesm2022/tolle-ui.mjs +16642 -1105
  118. package/fesm2022/tolle-ui.mjs.map +1 -1
  119. package/lib/alert-dialog-dynamic.component.d.ts +5 -0
  120. package/lib/alert-dialog.component.d.ts +23 -2
  121. package/lib/aspect-ratio.component.d.ts +20 -0
  122. package/lib/attachment.component.d.ts +101 -0
  123. package/lib/bubble.component.d.ts +112 -0
  124. package/lib/chain-of-thought.component.d.ts +166 -0
  125. package/lib/chart-pie.component.d.ts +108 -0
  126. package/lib/chart.component.d.ts +369 -0
  127. package/lib/chart.service.d.ts +222 -0
  128. package/lib/checkpoint.component.d.ts +51 -0
  129. package/lib/combobox.component.d.ts +90 -0
  130. package/lib/command-dialog.component.d.ts +53 -0
  131. package/lib/command.component.d.ts +189 -0
  132. package/lib/command.service.d.ts +67 -0
  133. package/lib/confirmation.component.d.ts +70 -0
  134. package/lib/context-menu-trigger.directive.d.ts +12 -0
  135. package/lib/context-menu.component.d.ts +41 -0
  136. package/lib/context-menu.service.d.ts +38 -0
  137. package/lib/context.component.d.ts +134 -0
  138. package/lib/conversation.component.d.ts +165 -0
  139. package/lib/data-table.component.d.ts +26 -1
  140. package/lib/date-picker.component.d.ts +72 -11
  141. package/lib/date-range-picker.component.d.ts +63 -6
  142. package/lib/date-time-picker.component.d.ts +119 -0
  143. package/lib/direction.component.d.ts +45 -0
  144. package/lib/field.component.d.ts +201 -0
  145. package/lib/inline-citation.component.d.ts +103 -0
  146. package/lib/input-group.component.d.ts +150 -0
  147. package/lib/item.component.d.ts +154 -0
  148. package/lib/kbd.component.d.ts +50 -0
  149. package/lib/marker.component.d.ts +58 -0
  150. package/lib/menubar.component.d.ts +247 -0
  151. package/lib/message-scroller.component.d.ts +159 -0
  152. package/lib/message-scroller.service.d.ts +73 -0
  153. package/lib/message.component.d.ts +128 -0
  154. package/lib/modal-ref.d.ts +6 -1
  155. package/lib/modal.component.d.ts +7 -4
  156. package/lib/modal.d.ts +9 -3
  157. package/lib/model-selector.component.d.ts +103 -0
  158. package/lib/multi-select.component.d.ts +66 -14
  159. package/lib/native-select.component.d.ts +57 -0
  160. package/lib/navigation-menu.component.d.ts +230 -0
  161. package/lib/plan.component.d.ts +120 -0
  162. package/lib/popover.component.d.ts +1 -0
  163. package/lib/prompt-input.component.d.ts +194 -0
  164. package/lib/queue.component.d.ts +106 -0
  165. package/lib/reasoning.component.d.ts +127 -0
  166. package/lib/resizable.component.d.ts +43 -0
  167. package/lib/segment.component.d.ts +13 -3
  168. package/lib/select.component.d.ts +37 -5
  169. package/lib/sheet.component.d.ts +3 -0
  170. package/lib/shimmer.component.d.ts +38 -0
  171. package/lib/sidebar.component.d.ts +2 -0
  172. package/lib/sources.component.d.ts +156 -0
  173. package/lib/spinner.component.d.ts +29 -0
  174. package/lib/suggestion.component.d.ts +96 -0
  175. package/lib/table.component.d.ts +106 -0
  176. package/lib/task.component.d.ts +151 -0
  177. package/lib/theme.service.d.ts +9 -0
  178. package/lib/time-picker.component.d.ts +243 -0
  179. package/lib/toast.service.d.ts +3 -1
  180. package/lib/toaster.component.d.ts +26 -9
  181. package/lib/tool.component.d.ts +158 -0
  182. package/lib/typography.component.d.ts +32 -0
  183. package/lib/utils/color.d.ts +19 -5
  184. package/package.json +3 -2
  185. package/preset.js +7 -1
  186. package/public-api.d.ts +50 -0
  187. package/registry/docs-content.json +8480 -1542
  188. package/registry/llms-full.txt +2679 -319
  189. package/registry/llms.txt +43 -4
  190. package/registry/manifest.json +9090 -1742
  191. package/registry/r/accordion-item.json +1 -1
  192. package/registry/r/accordion.json +1 -1
  193. package/registry/r/alert-dialog-dynamic.json +1 -1
  194. package/registry/r/alert-dialog.json +1 -1
  195. package/registry/r/alert.json +1 -1
  196. package/registry/r/attachment.json +23 -0
  197. package/registry/r/avatar-fallback.json +1 -1
  198. package/registry/r/avatar.json +1 -1
  199. package/registry/r/badge.json +1 -1
  200. package/registry/r/breadcrumb-item.json +1 -1
  201. package/registry/r/breadcrumb-link.json +1 -1
  202. package/registry/r/breadcrumb-separator.json +1 -1
  203. package/registry/r/breadcrumb.json +1 -1
  204. package/registry/r/bubble.json +23 -0
  205. package/registry/r/button.json +1 -1
  206. package/registry/r/calendar.json +1 -1
  207. package/registry/r/card.json +1 -1
  208. package/registry/r/carousel.json +1 -1
  209. package/registry/r/chain-of-thought.json +23 -0
  210. package/registry/r/chart-pie.json +30 -0
  211. package/registry/r/chart.json +28 -0
  212. package/registry/r/checkbox.json +1 -1
  213. package/registry/r/checkpoint.json +23 -0
  214. package/registry/r/collapsible.json +1 -1
  215. package/registry/r/combobox.json +31 -0
  216. package/registry/r/command-dialog.json +21 -0
  217. package/registry/r/command.json +26 -0
  218. package/registry/r/confirmation.json +23 -0
  219. package/registry/r/context-menu-trigger.json +1 -1
  220. package/registry/r/context-menu.json +1 -1
  221. package/registry/r/context.json +26 -0
  222. package/registry/r/conversation.json +23 -0
  223. package/registry/r/country-selector.json +1 -1
  224. package/registry/r/data-table.json +1 -1
  225. package/registry/r/date-picker.json +4 -4
  226. package/registry/r/date-range-picker.json +3 -3
  227. package/registry/r/date-time-picker.json +28 -0
  228. package/registry/r/direction.json +16 -0
  229. package/registry/r/dropdown-item.json +1 -1
  230. package/registry/r/dropdown-label.json +1 -1
  231. package/registry/r/dropdown-menu.json +1 -1
  232. package/registry/r/dropdown-separator.json +1 -1
  233. package/registry/r/dropdown-trigger.json +1 -1
  234. package/registry/r/empty-state.json +1 -1
  235. package/registry/r/field.json +23 -0
  236. package/registry/r/hover-card.json +1 -1
  237. package/registry/r/inline-citation.json +26 -0
  238. package/registry/r/input-group.json +23 -0
  239. package/registry/r/input.json +1 -1
  240. package/registry/r/item.json +23 -0
  241. package/registry/r/kbd.json +23 -0
  242. package/registry/r/label.json +1 -1
  243. package/registry/r/marker.json +23 -0
  244. package/registry/r/masked-input.json +1 -1
  245. package/registry/r/menubar.json +24 -0
  246. package/registry/r/message-scroller.json +26 -0
  247. package/registry/r/message.json +23 -0
  248. package/registry/r/modal.json +3 -3
  249. package/registry/r/model-selector.json +32 -0
  250. package/registry/r/multi-select.json +2 -2
  251. package/registry/r/native-select.json +23 -0
  252. package/registry/r/navigation-menu.json +24 -0
  253. package/registry/r/otp-group.json +1 -1
  254. package/registry/r/otp-slot.json +1 -1
  255. package/registry/r/otp.json +1 -1
  256. package/registry/r/pagination.json +3 -2
  257. package/registry/r/plan.json +23 -0
  258. package/registry/r/popover-content.json +1 -1
  259. package/registry/r/popover.json +1 -1
  260. package/registry/r/progress.json +1 -1
  261. package/registry/r/prompt-input.json +23 -0
  262. package/registry/r/queue.json +23 -0
  263. package/registry/r/radio-group.json +1 -1
  264. package/registry/r/radio-item.json +1 -1
  265. package/registry/r/range-calendar.json +1 -1
  266. package/registry/r/reasoning.json +23 -0
  267. package/registry/r/resizable-panel.json +1 -1
  268. package/registry/r/segment.json +1 -1
  269. package/registry/r/select-group.json +1 -1
  270. package/registry/r/select-item.json +1 -1
  271. package/registry/r/select-separator.json +1 -1
  272. package/registry/r/select.json +4 -3
  273. package/registry/r/separator.json +1 -1
  274. package/registry/r/sheet.json +1 -1
  275. package/registry/r/shimmer.json +23 -0
  276. package/registry/r/sidebar.json +1 -1
  277. package/registry/r/skeleton.json +1 -1
  278. package/registry/r/sources.json +23 -0
  279. package/registry/r/spinner.json +23 -0
  280. package/registry/r/suggestion.json +23 -0
  281. package/registry/r/switch.json +1 -1
  282. package/registry/r/table.json +21 -0
  283. package/registry/r/tabs.json +1 -1
  284. package/registry/r/tag-input.json +1 -1
  285. package/registry/r/task.json +23 -0
  286. package/registry/r/textarea.json +1 -1
  287. package/registry/r/time-picker.json +24 -0
  288. package/registry/r/toaster.json +2 -2
  289. package/registry/r/toggle-group.json +1 -1
  290. package/registry/r/toggle.json +1 -1
  291. package/registry/r/tool.json +23 -0
  292. package/registry/r/typography.json +23 -0
  293. package/registry/registry.json +915 -22
  294. package/theme.css +121 -8
@@ -0,0 +1,555 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { BehaviorSubject } from 'rxjs';
3
+ import * as i0 from "@angular/core";
4
+ /** Number of chart palette steps that exist. A 6th series does not get a colour. */
5
+ export const CHART_COLOR_LIMIT = 5;
6
+ /**
7
+ * The paint used for a series past `CHART_COLOR_LIMIT`.
8
+ *
9
+ * The palette is validated for lightness, chroma and colour-blind separation at
10
+ * exactly five steps; generating a sixth would land outside that validation, and
11
+ * wrapping back to step 1 would make two series share an identity. Both are
12
+ * worse than dropping to a neutral, so the overflow is explicitly uncoloured.
13
+ */
14
+ export const CHART_OVERFLOW_COLOR = 'rgb(var(--muted-foreground))';
15
+ /**
16
+ * Hands out palette steps by entity key rather than by position.
17
+ *
18
+ * A key keeps its slot for the lifetime of the scale, which is what makes
19
+ * colour follow the entity: filtering a series out and back in, or removing an
20
+ * earlier one, must never repaint the survivors. Past the fifth distinct key
21
+ * the scale stops colouring rather than inventing a step or wrapping around.
22
+ */
23
+ export class ChartColorScale {
24
+ slots = new Map();
25
+ next = 0;
26
+ /** Reserves slots for `keys` in order, leaving already-known keys alone. */
27
+ register(keys) {
28
+ for (const key of keys) {
29
+ if (!this.slots.has(key))
30
+ this.slots.set(key, this.next++);
31
+ }
32
+ }
33
+ /** Paint for `key`, registering it on first sight. */
34
+ colorFor(key) {
35
+ let slot = this.slots.get(key);
36
+ if (slot === undefined) {
37
+ slot = this.next++;
38
+ this.slots.set(key, slot);
39
+ }
40
+ if (slot >= CHART_COLOR_LIMIT)
41
+ return CHART_OVERFLOW_COLOR;
42
+ return 'rgb(var(--chart-' + (slot + 1) + '))';
43
+ }
44
+ /** True when `key` fell past the palette and renders neutral. */
45
+ isOverflow(key) {
46
+ const slot = this.slots.get(key);
47
+ return slot !== undefined && slot >= CHART_COLOR_LIMIT;
48
+ }
49
+ /** Slot index assigned to `key`, or undefined when it is unknown. */
50
+ slotOf(key) {
51
+ return this.slots.get(key);
52
+ }
53
+ }
54
+ /**
55
+ * Owns layout, scales and colour assignment for one `tolle-chart`, so every
56
+ * child draws into the same coordinate space. Renders nothing itself.
57
+ *
58
+ * Provided on `ChartComponent`, so each chart gets its own instance.
59
+ */
60
+ export class ChartService {
61
+ /** Rows being plotted, in x order. */
62
+ data = [];
63
+ /** Series definitions, in the order they should take palette steps. */
64
+ series = [];
65
+ /** Row key holding the x category/label. */
66
+ xKey = '';
67
+ /** Whether marks stack on a shared baseline rather than sitting side by side. */
68
+ stacked = false;
69
+ /** Full svg width in px, tracked from the container's ResizeObserver. */
70
+ width = 0;
71
+ /** Full svg height in px. */
72
+ height = 260;
73
+ /** Space reserved around the plot area. */
74
+ margin = { top: 8, right: 8, bottom: 24, left: 40 };
75
+ /** Fraction of a band's step spent on padding, split either side. */
76
+ bandPadding = 0.2;
77
+ scaleMode = 'point';
78
+ zeroRequired = false;
79
+ domainMin = 0;
80
+ domainMax = 1;
81
+ tickValues = [];
82
+ tickStep = 1;
83
+ /** Palette assignment, keyed by series identity. */
84
+ colors = new ChartColorScale();
85
+ layoutSubject = new BehaviorSubject(0);
86
+ /** Emits a version number whenever scales, dimensions or data change. */
87
+ layout$ = this.layoutSubject.asObservable();
88
+ activeIndexSubject = new BehaviorSubject(null);
89
+ /** Index of the x position under the pointer, or null when not hovering. */
90
+ activeIndex$ = this.activeIndexSubject.asObservable();
91
+ layoutVersion = 0;
92
+ emitScheduled = false;
93
+ // ---------------------------------------------------------------- geometry
94
+ get plotLeft() {
95
+ return this.margin.left;
96
+ }
97
+ get plotTop() {
98
+ return this.margin.top;
99
+ }
100
+ get plotWidth() {
101
+ return Math.max(0, this.width - this.margin.left - this.margin.right);
102
+ }
103
+ get plotHeight() {
104
+ return Math.max(0, this.height - this.margin.top - this.margin.bottom);
105
+ }
106
+ get plotRight() {
107
+ return this.plotLeft + this.plotWidth;
108
+ }
109
+ get plotBottom() {
110
+ return this.plotTop + this.plotHeight;
111
+ }
112
+ /** Number of x positions. */
113
+ get count() {
114
+ return this.data.length;
115
+ }
116
+ /** How x is currently resolved. Bars flip this to 'band'. */
117
+ get mode() {
118
+ return this.scaleMode;
119
+ }
120
+ /** Resolved y ticks, with svg coordinates and formatted labels. */
121
+ get ticks() {
122
+ return this.tickValues.map((value) => ({
123
+ value,
124
+ y: this.yFor(value),
125
+ label: this.formatValue(value),
126
+ }));
127
+ }
128
+ /** Current y domain as [min, max]. */
129
+ get domain() {
130
+ return [this.domainMin, this.domainMax];
131
+ }
132
+ /** The x-axis category labels, one per row. */
133
+ get xLabels() {
134
+ return this.data.map((row) => {
135
+ const raw = row?.[this.xKey];
136
+ return raw == null ? '' : String(raw);
137
+ });
138
+ }
139
+ // ------------------------------------------------------------ registration
140
+ /**
141
+ * Replaces the chart's configuration and recomputes the scales.
142
+ * Called by the container on input changes and on resize.
143
+ */
144
+ configure(config) {
145
+ Object.assign(this, config);
146
+ if (config.series)
147
+ this.syncColorSlots(config.series);
148
+ this.recompute();
149
+ }
150
+ /** Switches x to a band scale. Bars call this; it also forces zero into the domain. */
151
+ useBandScale() {
152
+ if (this.scaleMode === 'band' && this.zeroRequired)
153
+ return;
154
+ this.scaleMode = 'band';
155
+ this.zeroRequired = true;
156
+ this.recompute();
157
+ }
158
+ /** Forces zero into the y domain, for marks anchored to a baseline. */
159
+ requireZero() {
160
+ if (this.zeroRequired)
161
+ return;
162
+ this.zeroRequired = true;
163
+ this.recompute();
164
+ }
165
+ /** Reserves palette slots in series order, leaving known keys untouched. */
166
+ syncColorSlots(series) {
167
+ this.colors.register(series.map((item) => item.key));
168
+ }
169
+ /**
170
+ * Paint for a series, keyed by identity rather than by index in the visible
171
+ * array. Past the fifth distinct key this returns the neutral overflow colour.
172
+ */
173
+ colorFor(seriesKey) {
174
+ return this.colors.colorFor(seriesKey);
175
+ }
176
+ /** True when this series fell past the palette and renders neutral. */
177
+ isOverflowSeries(seriesKey) {
178
+ return this.colors.isOverflow(seriesKey);
179
+ }
180
+ // -------------------------------------------------------------- the scales
181
+ /** Reads a series value off a row, or null when it is missing/non-numeric. */
182
+ valueAt(seriesKey, index) {
183
+ const raw = this.data[index]?.[seriesKey];
184
+ if (raw == null || raw === '')
185
+ return null;
186
+ const num = Number(raw);
187
+ return Number.isFinite(num) ? num : null;
188
+ }
189
+ /** Sum of every series below `seriesKey` at `index`, for stacked marks. */
190
+ stackBase(seriesKey, index) {
191
+ if (!this.stacked)
192
+ return 0;
193
+ let base = 0;
194
+ for (const item of this.series) {
195
+ if (item.key === seriesKey)
196
+ break;
197
+ base += this.valueAt(item.key, index) ?? 0;
198
+ }
199
+ return base;
200
+ }
201
+ /** Sum of every series at `index`. */
202
+ stackTotal(index) {
203
+ let total = 0;
204
+ for (const item of this.series)
205
+ total += this.valueAt(item.key, index) ?? 0;
206
+ return total;
207
+ }
208
+ /**
209
+ * Maps a data value to an svg y. SVG y grows downward, so the domain maximum
210
+ * lands on `plotTop` and the minimum on `plotBottom`.
211
+ */
212
+ yFor(value) {
213
+ const span = this.domainMax - this.domainMin;
214
+ if (span <= 0)
215
+ return this.plotBottom;
216
+ const ratio = (value - this.domainMin) / span;
217
+ return this.plotBottom - ratio * this.plotHeight;
218
+ }
219
+ /** The svg y of the zero line, clamped into the plot. */
220
+ get baselineY() {
221
+ const zero = Math.min(Math.max(0, this.domainMin), this.domainMax);
222
+ return this.yFor(zero);
223
+ }
224
+ /** Width of one band, excluding its padding. Meaningful in band mode. */
225
+ get bandWidth() {
226
+ if (this.count === 0)
227
+ return 0;
228
+ return this.bandStep * (1 - this.bandPadding);
229
+ }
230
+ /** Distance between adjacent band starts. Bands tile the plot exactly. */
231
+ get bandStep() {
232
+ if (this.count === 0)
233
+ return 0;
234
+ return this.plotWidth / this.count;
235
+ }
236
+ /** Geometry of the band at `index`. */
237
+ bandFor(index) {
238
+ const step = this.bandStep;
239
+ const width = this.bandWidth;
240
+ const start = this.plotLeft + index * step + (step - width) / 2;
241
+ return { start, centre: start + width / 2, width };
242
+ }
243
+ /** x of the data point at `index` on the point scale. */
244
+ pointX(index) {
245
+ if (this.count === 0)
246
+ return this.plotLeft;
247
+ if (this.count === 1)
248
+ return this.plotLeft + this.plotWidth / 2;
249
+ return this.plotLeft + (index * this.plotWidth) / (this.count - 1);
250
+ }
251
+ /** x of `index` under whichever scale the chart is currently using. */
252
+ xFor(index) {
253
+ return this.scaleMode === 'band' ? this.bandFor(index).centre : this.pointX(index);
254
+ }
255
+ /**
256
+ * The pointer catchment area for `index` — deliberately wider than the mark.
257
+ * In band mode it is the whole band step; on the point scale it runs to the
258
+ * midpoints of the neighbouring points, so the pointer only has to be nearest.
259
+ */
260
+ hitBandFor(index) {
261
+ if (this.scaleMode === 'band') {
262
+ const step = this.bandStep;
263
+ const start = this.plotLeft + index * step;
264
+ return { start, centre: start + step / 2, width: step };
265
+ }
266
+ const x = this.pointX(index);
267
+ const prev = index > 0 ? this.pointX(index - 1) : this.plotLeft - (this.plotRight - this.plotLeft);
268
+ const next = index < this.count - 1 ? this.pointX(index + 1) : this.plotRight + (this.plotRight - this.plotLeft);
269
+ const start = Math.max(this.plotLeft, (prev + x) / 2);
270
+ const end = Math.min(this.plotRight, (x + next) / 2);
271
+ return { start, centre: x, width: Math.max(0, end - start) };
272
+ }
273
+ // --------------------------------------------------------------- hovering
274
+ /** Index currently under the pointer, or null. */
275
+ get activeIndex() {
276
+ return this.activeIndexSubject.value;
277
+ }
278
+ setActiveIndex(index) {
279
+ if (this.activeIndexSubject.value === index)
280
+ return;
281
+ this.activeIndexSubject.next(index);
282
+ }
283
+ // ----------------------------------------------------------------- domains
284
+ recompute() {
285
+ const values = [];
286
+ if (this.stacked) {
287
+ for (let i = 0; i < this.count; i++)
288
+ values.push(this.stackTotal(i));
289
+ // A stack still has to show its own floor when a series goes negative.
290
+ for (const item of this.series) {
291
+ for (let i = 0; i < this.count; i++) {
292
+ const v = this.valueAt(item.key, i);
293
+ if (v != null && v < 0)
294
+ values.push(v);
295
+ }
296
+ }
297
+ }
298
+ else {
299
+ for (const item of this.series) {
300
+ for (let i = 0; i < this.count; i++) {
301
+ const v = this.valueAt(item.key, i);
302
+ if (v != null)
303
+ values.push(v);
304
+ }
305
+ }
306
+ }
307
+ if (this.zeroRequired)
308
+ values.push(0);
309
+ const [min, max, step, ticks] = niceScale(values);
310
+ this.domainMin = min;
311
+ this.domainMax = max;
312
+ this.tickStep = step;
313
+ this.tickValues = ticks;
314
+ // Only tell subscribers when something they would draw differently actually
315
+ // changed. `configure()` is called from ngOnChanges, and an app binding
316
+ // `[data]="items.filter(...)"` hands us a fresh array reference on every
317
+ // change-detection pass — an ordinary thing to write. Emitting on every call
318
+ // made subscribers markForCheck, which scheduled another pass, which called
319
+ // configure again: the cycle never closed and the page locked up.
320
+ const signature = this.layoutSignature(values);
321
+ if (signature === this.lastSignature)
322
+ return;
323
+ this.lastSignature = signature;
324
+ this.scheduleEmit();
325
+ }
326
+ /** Everything a subscriber would render differently, flattened for comparison. */
327
+ lastSignature = '';
328
+ layoutSignature(values) {
329
+ return [
330
+ this.count,
331
+ this.xKey,
332
+ this.stacked,
333
+ this.width,
334
+ this.height,
335
+ this.bandPadding,
336
+ this.scaleMode,
337
+ this.zeroRequired,
338
+ this.margin.top, this.margin.right, this.margin.bottom, this.margin.left,
339
+ this.domainMin, this.domainMax, this.tickStep,
340
+ this.tickValues.join(','),
341
+ this.series.map((s) => s.key + ':' + s.label).join(','),
342
+ this.xLabels.join(''),
343
+ values.join(','),
344
+ ].join('');
345
+ }
346
+ /**
347
+ * Coalesces layout notifications into a microtask, so several children
348
+ * registering in the same change-detection pass produce one emission after
349
+ * they have all settled rather than one each mid-pass.
350
+ */
351
+ scheduleEmit() {
352
+ this.layoutVersion++;
353
+ if (this.emitScheduled)
354
+ return;
355
+ this.emitScheduled = true;
356
+ queueMicrotask(() => {
357
+ this.emitScheduled = false;
358
+ this.layoutSubject.next(this.layoutVersion);
359
+ });
360
+ }
361
+ /** Formats a value for a tick label at the current tick step's precision. */
362
+ formatValue(value) {
363
+ const decimals = decimalsFor(this.tickStep);
364
+ return value.toLocaleString('en-US', {
365
+ minimumFractionDigits: decimals,
366
+ maximumFractionDigits: decimals,
367
+ });
368
+ }
369
+ // ------------------------------------------------------------------- paths
370
+ /** Straight-segment path through the series' defined points. */
371
+ linePath(seriesKey) {
372
+ return buildPath(this.pointsFor(seriesKey), false);
373
+ }
374
+ /** Monotone-cubic path through the series' defined points. */
375
+ smoothPath(seriesKey) {
376
+ return buildPath(this.pointsFor(seriesKey), true);
377
+ }
378
+ /**
379
+ * Filled-area path: the series' line, closed back along its baseline. When
380
+ * stacked, the floor is the top of the series below rather than zero.
381
+ */
382
+ areaPath(seriesKey, smooth) {
383
+ const points = this.pointsFor(seriesKey);
384
+ if (points.length === 0)
385
+ return '';
386
+ const top = buildPath(points, smooth);
387
+ const floor = points
388
+ .map((p) => {
389
+ const base = this.stacked ? this.stackBase(seriesKey, p.index) : 0;
390
+ return { x: p.x, y: this.yFor(base), index: p.index };
391
+ })
392
+ .reverse();
393
+ const bottom = buildPath(floor, smooth);
394
+ // Re-enter the reversed floor with a line, then close.
395
+ return top + ' L ' + floor[0].x + ' ' + floor[0].y + ' ' + bottom.replace(/^M/, 'L') + ' Z';
396
+ }
397
+ /** Resolved svg points for a series, skipping rows where it has no value. */
398
+ pointsFor(seriesKey) {
399
+ const points = [];
400
+ for (let i = 0; i < this.count; i++) {
401
+ const v = this.valueAt(seriesKey, i);
402
+ if (v == null)
403
+ continue;
404
+ const stacked = this.stacked ? this.stackBase(seriesKey, i) + v : v;
405
+ points.push({ x: this.xFor(i), y: this.yFor(stacked), index: i });
406
+ }
407
+ return points;
408
+ }
409
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChartService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
410
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChartService });
411
+ }
412
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChartService, decorators: [{
413
+ type: Injectable
414
+ }] });
415
+ // ------------------------------------------------------------- pure helpers
416
+ /** Decimal places worth showing for a given tick step. */
417
+ export function decimalsFor(step) {
418
+ if (!Number.isFinite(step) || step <= 0)
419
+ return 0;
420
+ return Math.max(0, Math.min(6, -Math.floor(Math.log10(step))));
421
+ }
422
+ /**
423
+ * Rounds a raw step up to the next 1/2/5 x 10^n.
424
+ *
425
+ * Dividing the range by a tick count instead would produce steps like 19.4 and
426
+ * so axis labels like 19.4 / 38.8 / 58.2, which nobody can read a value off.
427
+ */
428
+ export function niceStep(rawStep) {
429
+ if (!Number.isFinite(rawStep) || rawStep <= 0)
430
+ return 1;
431
+ const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));
432
+ const normalised = rawStep / magnitude;
433
+ let multiplier;
434
+ if (normalised <= 1)
435
+ multiplier = 1;
436
+ else if (normalised <= 2)
437
+ multiplier = 2;
438
+ else if (normalised <= 5)
439
+ multiplier = 5;
440
+ else
441
+ multiplier = 10;
442
+ return multiplier * magnitude;
443
+ }
444
+ /**
445
+ * Builds a readable y scale over `values`: returns `[min, max, step, ticks]`
446
+ * with the domain snapped outward to whole steps.
447
+ *
448
+ * Degenerate inputs (empty, all-identical) still produce a usable one-unit
449
+ * domain rather than a zero-height plot.
450
+ */
451
+ export function niceScale(values, targetTicks = 5) {
452
+ const finite = values.filter((v) => Number.isFinite(v));
453
+ let min = finite.length ? Math.min(...finite) : 0;
454
+ let max = finite.length ? Math.max(...finite) : 1;
455
+ if (min === max) {
456
+ // A flat or single-point domain has no span to divide; open it to one unit
457
+ // around the value so the mark sits on a real axis instead of on the floor.
458
+ if (min === 0) {
459
+ min = 0;
460
+ max = 1;
461
+ }
462
+ else if (min > 0) {
463
+ min = Math.min(0, min);
464
+ max = max === 0 ? 1 : max;
465
+ if (min === max)
466
+ max = min + 1;
467
+ }
468
+ else {
469
+ max = Math.max(0, max);
470
+ if (min === max)
471
+ min = max - 1;
472
+ }
473
+ }
474
+ const step = niceStep((max - min) / targetTicks);
475
+ // Nudge before rounding outward: 100/20 lands a hair above 5 in binary
476
+ // floating point, which would otherwise add a phantom tick at 120.
477
+ const epsilon = 1e-9;
478
+ const niceMin = Math.floor(min / step + epsilon) * step;
479
+ const niceMax = Math.ceil(max / step - epsilon) * step;
480
+ const decimals = decimalsFor(step);
481
+ const ticks = [];
482
+ const total = Math.round((niceMax - niceMin) / step);
483
+ for (let i = 0; i <= total; i++) {
484
+ ticks.push(Number((niceMin + i * step).toFixed(decimals)));
485
+ }
486
+ return [Number(niceMin.toFixed(decimals)), Number(niceMax.toFixed(decimals)), step, ticks];
487
+ }
488
+ /**
489
+ * Monotone-cubic tangents (Fritsch-Carlson). Limiting each tangent to the
490
+ * neighbouring secants is what stops the curve overshooting: a plain
491
+ * Catmull-Rom spline bulges past the data and invents peaks that were never
492
+ * measured, which on a chart is a false statement about the numbers.
493
+ */
494
+ export function monotoneTangents(xs, ys) {
495
+ const n = xs.length;
496
+ if (n < 2)
497
+ return new Array(n).fill(0);
498
+ const secants = [];
499
+ for (let i = 0; i < n - 1; i++) {
500
+ const dx = xs[i + 1] - xs[i];
501
+ secants.push(dx === 0 ? 0 : (ys[i + 1] - ys[i]) / dx);
502
+ }
503
+ const m = new Array(n);
504
+ m[0] = secants[0];
505
+ m[n - 1] = secants[n - 2];
506
+ for (let i = 1; i < n - 1; i++)
507
+ m[i] = (secants[i - 1] + secants[i]) / 2;
508
+ for (let i = 0; i < n - 1; i++) {
509
+ if (secants[i] === 0) {
510
+ // Flat segment: both ends must be flat or the curve leaves the data range.
511
+ m[i] = 0;
512
+ m[i + 1] = 0;
513
+ continue;
514
+ }
515
+ const a = m[i] / secants[i];
516
+ const b = m[i + 1] / secants[i];
517
+ // Negative ratios mean the tangent points away from the secant.
518
+ if (a < 0)
519
+ m[i] = 0;
520
+ if (b < 0)
521
+ m[i + 1] = 0;
522
+ const sum = a * a + b * b;
523
+ if (sum > 9) {
524
+ const t = 3 / Math.sqrt(sum);
525
+ m[i] = t * a * secants[i];
526
+ m[i + 1] = t * b * secants[i];
527
+ }
528
+ }
529
+ return m;
530
+ }
531
+ /** Turns resolved points into an svg path, optionally monotone-smoothed. */
532
+ export function buildPath(points, smooth) {
533
+ if (points.length === 0)
534
+ return '';
535
+ if (points.length === 1)
536
+ return 'M ' + points[0].x + ' ' + points[0].y;
537
+ const head = 'M ' + points[0].x + ' ' + points[0].y;
538
+ if (!smooth) {
539
+ return head + points.slice(1).map((p) => ' L ' + p.x + ' ' + p.y).join('');
540
+ }
541
+ const xs = points.map((p) => p.x);
542
+ const ys = points.map((p) => p.y);
543
+ const m = monotoneTangents(xs, ys);
544
+ let d = head;
545
+ for (let i = 0; i < points.length - 1; i++) {
546
+ const dx = xs[i + 1] - xs[i];
547
+ const c1x = xs[i] + dx / 3;
548
+ const c1y = ys[i] + (m[i] * dx) / 3;
549
+ const c2x = xs[i + 1] - dx / 3;
550
+ const c2y = ys[i + 1] - (m[i + 1] * dx) / 3;
551
+ d += ' C ' + c1x + ' ' + c1y + ' ' + c2x + ' ' + c2y + ' ' + xs[i + 1] + ' ' + ys[i + 1];
552
+ }
553
+ return d;
554
+ }
555
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhcnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RvbGxlL3NyYy9saWIvY2hhcnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxNQUFNLENBQUM7O0FBaUN2QyxvRkFBb0Y7QUFDcEYsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxDQUFDO0FBRW5DOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyw4QkFBOEIsQ0FBQztBQUVuRTs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFDVCxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7SUFDM0MsSUFBSSxHQUFHLENBQUMsQ0FBQztJQUVqQiw0RUFBNEU7SUFDNUUsUUFBUSxDQUFDLElBQWM7UUFDckIsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO2dCQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUM3RCxDQUFDO0lBQ0gsQ0FBQztJQUVELHNEQUFzRDtJQUN0RCxRQUFRLENBQUMsR0FBVztRQUNsQixJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvQixJQUFJLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN2QixJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ25CLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENB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QzVFLE1BQU0sVUFBVSxTQUFTLENBQUMsTUFBa0MsRUFBRSxNQUFlO0lBQzNFLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDbkMsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxPQUFPLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRXZFLE1BQU0sSUFBSSxHQUFHLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLE9BQU8sSUFBSSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM3RSxDQUFDO0lBRUQsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xDLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsQyxNQUFNLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFFbkMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDO0lBQ2IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDM0MsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0IsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDM0IsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNwQyxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDL0IsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzVDLENBQUMsSUFBSSxLQUFLLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzNGLENBQUM7SUFDRCxPQUFPLENBQUMsQ0FBQztBQUNYLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuLyoqIE9uZSBwbG90dGVkIHNlcmllczogd2hpY2gga2V5IHRvIHJlYWQgb2ZmIGVhY2ggcm93LCBhbmQgaG93IHRvIG5hbWUgaXQuICovXG5leHBvcnQgaW50ZXJmYWNlIENoYXJ0U2VyaWVzIHtcbiAga2V5OiBzdHJpbmc7XG4gIGxhYmVsOiBzdHJpbmc7XG59XG5cbi8qKiBTcGFjZSByZXNlcnZlZCBhcm91bmQgdGhlIHBsb3QgYXJlYSBmb3IgYXhlcyBhbmQgbGFiZWxzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBDaGFydE1hcmdpbiB7XG4gIHRvcDogbnVtYmVyO1xuICByaWdodDogbnVtYmVyO1xuICBib3R0b206IG51bWJlcjtcbiAgbGVmdDogbnVtYmVyO1xufVxuXG4vKiogQSB5LWF4aXMgdGljazogaXRzIGRhdGEgdmFsdWUsIGl0cyByZXNvbHZlZCBzdmcgeSwgYW5kIGl0cyBmb3JtYXR0ZWQgbGFiZWwuICovXG5leHBvcnQgaW50ZXJmYWNlIENoYXJ0VGljayB7XG4gIHZhbHVlOiBudW1iZXI7XG4gIHk6IG51bWJlcjtcbiAgbGFiZWw6IHN0cmluZztcbn1cblxuLyoqIEEgaG9yaXpvbnRhbCBzbGljZSBvZiB0aGUgcGxvdCBiZWxvbmdpbmcgdG8gb25lIHggcG9zaXRpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIENoYXJ0QmFuZCB7XG4gIHN0YXJ0OiBudW1iZXI7XG4gIGNlbnRyZTogbnVtYmVyO1xuICB3aWR0aDogbnVtYmVyO1xufVxuXG4vKiogSG93IHggcG9zaXRpb25zIGFyZSByZXNvbHZlZDogZGlzY3JldGUgYmFuZHMgKGJhcnMpIG9yIHBvaW50cyAobGluZS9hcmVhKS4gKi9cbmV4cG9ydCB0eXBlIENoYXJ0U2NhbGVNb2RlID0gJ3BvaW50JyB8ICdiYW5kJztcblxuLyoqIE51bWJlciBvZiBjaGFydCBwYWxldHRlIHN0ZXBzIHRoYXQgZXhpc3QuIEEgNnRoIHNlcmllcyBkb2VzIG5vdCBnZXQgYSBjb2xvdXIuICovXG5leHBvcnQgY29uc3QgQ0hBUlRfQ09MT1JfTElNSVQgPSA1O1xuXG4vKipcbiAqIFRoZSBwYWludCB1c2VkIGZvciBhIHNlcmllcyBwYXN0IGBDSEFSVF9DT0xPUl9MSU1JVGAuXG4gKlxuICogVGhlIHBhbGV0dGUgaXMgdmFsaWRhdGVkIGZvciBsaWdodG5lc3MsIGNocm9tYSBhbmQgY29sb3VyLWJsaW5kIHNlcGFyYXRpb24gYXRcbiAqIGV4YWN0bHkgZml2ZSBzdGVwczsgZ2VuZXJhdGluZyBhIHNpeHRoIHdvdWxkIGxhbmQgb3V0c2lkZSB0aGF0IHZhbGlkYXRpb24sIGFuZFxuICogd3JhcHBpbmcgYmFjayB0byBzdGVwIDEgd291bGQgbWFrZSB0d28gc2VyaWVzIHNoYXJlIGFuIGlkZW50aXR5LiBCb3RoIGFyZVxuICogd29yc2UgdGhhbiBkcm9wcGluZyB0byBhIG5ldXRyYWwsIHNvIHRoZSBvdmVyZmxvdyBpcyBleHBsaWNpdGx5IHVuY29sb3VyZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBDSEFSVF9PVkVSRkxPV19DT0xPUiA9ICdyZ2IodmFyKC0tbXV0ZWQtZm9yZWdyb3VuZCkpJztcblxuLyoqXG4gKiBIYW5kcyBvdXQgcGFsZXR0ZSBzdGVwcyBieSBlbnRpdHkga2V5IHJhdGhlciB0aGFuIGJ5IHBvc2l0aW9uLlxuICpcbiAqIEEga2V5IGtlZXBzIGl0cyBzbG90IGZvciB0aGUgbGlmZXRpbWUgb2YgdGhlIHNjYWxlLCB3aGljaCBpcyB3aGF0IG1ha2VzXG4gKiBjb2xvdXIgZm9sbG93IHRoZSBlbnRpdHk6IGZpbHRlcmluZyBhIHNlcmllcyBvdXQgYW5kIGJhY2sgaW4sIG9yIHJlbW92aW5nIGFuXG4gKiBlYXJsaWVyIG9uZSwgbXVzdCBuZXZlciByZXBhaW50IHRoZSBzdXJ2aXZvcnMuIFBhc3QgdGhlIGZpZnRoIGRpc3RpbmN0IGtleVxuICogdGhlIHNjYWxlIHN0b3BzIGNvbG91cmluZyByYXRoZXIgdGhhbiBpbnZlbnRpbmcgYSBzdGVwIG9yIHdyYXBwaW5nIGFyb3VuZC5cbiAqL1xuZXhwb3J0IGNsYXNzIENoYXJ0Q29sb3JTY2FsZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2xvdHMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICBwcml2YXRlIG5leHQgPSAwO1xuXG4gIC8qKiBSZXNlcnZlcyBzbG90cyBmb3IgYGtleXNgIGluIG9yZGVyLCBsZWF2aW5nIGFscmVhZHkta25vd24ga2V5cyBhbG9uZS4gKi9cbiAgcmVnaXN0ZXIoa2V5czogc3RyaW5nW10pOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgICBpZiAoIXRoaXMuc2xvdHMuaGFzKGtleSkpIHRoaXMuc2xvdHMuc2V0KGtleSwgdGhpcy5uZXh0KyspO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBQYWludCBmb3IgYGtleWAsIHJlZ2lzdGVyaW5nIGl0IG9uIGZpcnN0IHNpZ2h0LiAqL1xuICBjb2xvckZvcihrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgbGV0IHNsb3QgPSB0aGlzLnNsb3RzLmdldChrZXkpO1xuICAgIGlmIChzbG90ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHNsb3QgPSB0aGlzLm5leHQrKztcbiAgICAgIHRoaXMuc2xvdHMuc2V0KGtleSwgc2xvdCk7XG4gICAgfVxuICAgIGlmIChzbG90ID49IENIQVJUX0NPTE9SX0xJTUlUKSByZXR1cm4gQ0hBUlRfT1ZFUkZMT1dfQ09MT1I7XG4gICAgcmV0dXJuICdyZ2IodmFyKC0tY2hhcnQtJyArIChzbG90ICsgMSkgKyAnKSknO1xuICB9XG5cbiAgLyoqIFRydWUgd2hlbiBga2V5YCBmZWxsIHBhc3QgdGhlIHBhbGV0dGUgYW5kIHJlbmRlcnMgbmV1dHJhbC4gKi9cbiAgaXNPdmVyZmxvdyhrZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHNsb3QgPSB0aGlzLnNsb3RzLmdldChrZXkpO1xuICAgIHJldHVybiBzbG90ICE9PSB1bmRlZmluZWQgJiYgc2xvdCA+PSBDSEFSVF9DT0xPUl9MSU1JVDtcbiAgfVxuXG4gIC8qKiBTbG90IGluZGV4IGFzc2lnbmVkIHRvIGBrZXlgLCBvciB1bmRlZmluZWQgd2hlbiBpdCBpcyB1bmtub3duLiAqL1xuICBzbG90T2Yoa2V5OiBzdHJpbmcpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnNsb3RzLmdldChrZXkpO1xuICB9XG59XG5cbi8qKlxuICogT3ducyBsYXlvdXQsIHNjYWxlcyBhbmQgY29sb3VyIGFzc2lnbm1lbnQgZm9yIG9uZSBgdG9sbGUtY2hhcnRgLCBzbyBldmVyeVxuICogY2hpbGQgZHJhd3MgaW50byB0aGUgc2FtZSBjb29yZGluYXRlIHNwYWNlLiBSZW5kZXJzIG5vdGhpbmcgaXRzZWxmLlxuICpcbiAqIFByb3ZpZGVkIG9uIGBDaGFydENvbXBvbmVudGAsIHNvIGVhY2ggY2hhcnQgZ2V0cyBpdHMgb3duIGluc3RhbmNlLlxuICovXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQ2hhcnRTZXJ2aWNlIHtcbiAgLyoqIFJvd3MgYmVpbmcgcGxvdHRlZCwgaW4geCBvcmRlci4gKi9cbiAgZGF0YTogUmVjb3JkPHN0cmluZywgYW55PltdID0gW107XG4gIC8qKiBTZXJpZXMgZGVmaW5pdGlvbnMsIGluIHRoZSBvcmRlciB0aGV5IHNob3VsZCB0YWtlIHBhbGV0dGUgc3RlcHMuICovXG4gIHNlcmllczogQ2hhcnRTZXJpZXNbXSA9IFtdO1xuICAvKiogUm93IGtleSBob2xkaW5nIHRoZSB4IGNhdGVnb3J5L2xhYmVsLiAqL1xuICB4S2V5ID0gJyc7XG4gIC8qKiBXaGV0aGVyIG1hcmtzIHN0YWNrIG9uIGEgc2hhcmVkIGJhc2VsaW5lIHJhdGhlciB0aGFuIHNpdHRpbmcgc2lkZSBieSBzaWRlLiAqL1xuICBzdGFja2VkID0gZmFsc2U7XG4gIC8qKiBGdWxsIHN2ZyB3aWR0aCBpbiBweCwgdHJhY2tlZCBmcm9tIHRoZSBjb250YWluZXIncyBSZXNpemVPYnNlcnZlci4gKi9cbiAgd2lkdGggPSAwO1xuICAvKiogRnVsbCBzdmcgaGVpZ2h0IGluIHB4LiAqL1xuICBoZWlnaHQgPSAyNjA7XG4gIC8qKiBTcGFjZSByZXNlcnZlZCBhcm91bmQgdGhlIHBsb3QgYXJlYS4gKi9cbiAgbWFyZ2luOiBDaGFydE1hcmdpbiA9IHsgdG9wOiA4LCByaWdodDogOCwgYm90dG9tOiAyNCwgbGVmdDogNDAgfTtcbiAgLyoqIEZyYWN0aW9uIG9mIGEgYmFuZCdzIHN0ZXAgc3BlbnQgb24gcGFkZGluZywgc3BsaXQgZWl0aGVyIHNpZGUuICovXG4gIGJhbmRQYWRkaW5nID0gMC4yO1xuXG4gIHByaXZhdGUgc2NhbGVNb2RlOiBDaGFydFNjYWxlTW9kZSA9ICdwb2ludCc7XG4gIHByaXZhdGUgemVyb1JlcXVpcmVkID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBkb21haW5NaW4gPSAwO1xuICBwcml2YXRlIGRvbWFpbk1heCA9IDE7XG4gIHByaXZhdGUgdGlja1ZhbHVlczogbnVtYmVyW10gPSBbXTtcbiAgcHJpdmF0ZSB0aWNrU3RlcCA9IDE7XG5cbiAgLyoqIFBhbGV0dGUgYXNzaWdubWVudCwga2V5ZWQgYnkgc2VyaWVzIGlkZW50aXR5LiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbG9ycyA9IG5ldyBDaGFydENvbG9yU2NhbGUoKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGxheW91dFN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oMCk7XG4gIC8qKiBFbWl0cyBhIHZlcnNpb24gbnVtYmVyIHdoZW5ldmVyIHNjYWxlcywgZGltZW5zaW9ucyBvciBkYXRhIGNoYW5nZS4gKi9cbiAgcmVhZG9ubHkgbGF5b3V0JCA9IHRoaXMubGF5b3V0U3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGFjdGl2ZUluZGV4U3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyIHwgbnVsbD4obnVsbCk7XG4gIC8qKiBJbmRleCBvZiB0aGUgeCBwb3NpdGlvbiB1bmRlciB0aGUgcG9pbnRlciwgb3IgbnVsbCB3aGVuIG5vdCBob3ZlcmluZy4gKi9cbiAgcmVhZG9ubHkgYWN0aXZlSW5kZXgkID0gdGhpcy5hY3RpdmVJbmRleFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgcHJpdmF0ZSBsYXlvdXRWZXJzaW9uID0gMDtcbiAgcHJpdmF0ZSBlbWl0U2NoZWR1bGVkID0gZmFsc2U7XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBnZW9tZXRyeVxuXG4gIGdldCBwbG90TGVmdCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm1hcmdpbi5sZWZ0O1xuICB9XG5cbiAgZ2V0IHBsb3RUb3AoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5tYXJnaW4udG9wO1xuICB9XG5cbiAgZ2V0IHBsb3RXaWR0aCgpOiBudW1iZXIge1xuICAgIHJldHVybiBNYXRoLm1heCgwLCB0aGlzLndpZHRoIC0gdGhpcy5tYXJnaW4ubGVmdCAtIHRoaXMubWFyZ2luLnJpZ2h0KTtcbiAgfVxuXG4gIGdldCBwbG90SGVpZ2h0KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGgubWF4KDAsIHRoaXMuaGVpZ2h0IC0gdGhpcy5tYXJnaW4udG9wIC0gdGhpcy5tYXJnaW4uYm90dG9tKTtcbiAgfVxuXG4gIGdldCBwbG90UmlnaHQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5wbG90TGVmdCArIHRoaXMucGxvdFdpZHRoO1xuICB9XG5cbiAgZ2V0IHBsb3RCb3R0b20oKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5wbG90VG9wICsgdGhpcy5wbG90SGVpZ2h0O1xuICB9XG5cbiAgLyoqIE51bWJlciBvZiB4IHBvc2l0aW9ucy4gKi9cbiAgZ2V0IGNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGg7XG4gIH1cblxuICAvKiogSG93IHggaXMgY3VycmVudGx5IHJlc29sdmVkLiBCYXJzIGZsaXAgdGhpcyB0byAnYmFuZCcuICovXG4gIGdldCBtb2RlKCk6IENoYXJ0U2NhbGVNb2RlIHtcbiAgICByZXR1cm4gdGhpcy5zY2FsZU1vZGU7XG4gIH1cblxuICAvKiogUmVzb2x2ZWQgeSB0aWNrcywgd2l0aCBzdmcgY29vcmRpbmF0ZXMgYW5kIGZvcm1hdHRlZCBsYWJlbHMuICovXG4gIGdldCB0aWNrcygpOiBDaGFydFRpY2tbXSB7XG4gICAgcmV0dXJuIHRoaXMudGlja1ZhbHVlcy5tYXAoKHZhbHVlKSA9PiAoe1xuICAgICAgdmFsdWUsXG4gICAgICB5OiB0aGlzLnlGb3IodmFsdWUpLFxuICAgICAgbGFiZWw6IHRoaXMuZm9ybWF0VmFsdWUodmFsdWUpLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8qKiBDdXJyZW50IHkgZG9tYWluIGFzIFttaW4sIG1heF0uICovXG4gIGdldCBkb21haW4oKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgcmV0dXJuIFt0aGlzLmRvbWFpbk1pbiwgdGhpcy5kb21haW5NYXhdO1xuICB9XG5cbiAgLyoqIFRoZSB4LWF4aXMgY2F0ZWdvcnkgbGFiZWxzLCBvbmUgcGVyIHJvdy4gKi9cbiAgZ2V0IHhMYWJlbHMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLmRhdGEubWFwKChyb3cpID0+IHtcbiAgICAgIGNvbnN0IHJhdyA9IHJvdz8uW3RoaXMueEtleV07XG4gICAgICByZXR1cm4gcmF3ID09IG51bGwgPyAnJyA6IFN0cmluZyhyYXcpO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHJlZ2lzdHJhdGlvblxuXG4gIC8qKlxuICAgKiBSZXBsYWNlcyB0aGUgY2hhcnQncyBjb25maWd1cmF0aW9uIGFuZCByZWNvbXB1dGVzIHRoZSBzY2FsZXMuXG4gICAqIENhbGxlZCBieSB0aGUgY29udGFpbmVyIG9uIGlucHV0IGNoYW5nZXMgYW5kIG9uIHJlc2l6ZS5cbiAgICovXG4gIGNvbmZpZ3VyZShjb25maWc6IFBhcnRpYWw8UGljazxDaGFydFNlcnZpY2UsXG4gICAgJ2RhdGEnIHwgJ3NlcmllcycgfCAneEtleScgfCAnc3RhY2tlZCcgfCAnd2lkdGgnIHwgJ2hlaWdodCcgfCAnbWFyZ2luJyB8ICdiYW5kUGFkZGluZyc+Pik6IHZvaWQge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcywgY29uZmlnKTtcbiAgICBpZiAoY29uZmlnLnNlcmllcykgdGhpcy5zeW5jQ29sb3JTbG90cyhjb25maWcuc2VyaWVzKTtcbiAgICB0aGlzLnJlY29tcHV0ZSgpO1xuICB9XG5cbiAgLyoqIFN3aXRjaGVzIHggdG8gYSBiYW5kIHNjYWxlLiBCYXJzIGNhbGwgdGhpczsgaXQgYWxzbyBmb3JjZXMgemVybyBpbnRvIHRoZSBkb21haW4uICovXG4gIHVzZUJhbmRTY2FsZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zY2FsZU1vZGUgPT09ICdiYW5kJyAmJiB0aGlzLnplcm9SZXF1aXJlZCkgcmV0dXJuO1xuICAgIHRoaXMuc2NhbGVNb2RlID0gJ2JhbmQnO1xuICAgIHRoaXMuemVyb1JlcXVpcmVkID0gdHJ1ZTtcbiAgICB0aGlzLnJlY29tcHV0ZSgpO1xuICB9XG5cbiAgLyoqIEZvcmNlcyB6ZXJvIGludG8gdGhlIHkgZG9tYWluLCBmb3IgbWFya3MgYW5jaG9yZWQgdG8gYSBiYXNlbGluZS4gKi9cbiAgcmVxdWlyZVplcm8oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuemVyb1JlcXVpcmVkKSByZXR1cm47XG4gICAgdGhpcy56ZXJvUmVxdWlyZWQgPSB0cnVlO1xuICAgIHRoaXMucmVjb21wdXRlKCk7XG4gIH1cblxuICAvKiogUmVzZXJ2ZXMgcGFsZXR0ZSBzbG90cyBpbiBzZXJpZXMgb3JkZXIsIGxlYXZpbmcga25vd24ga2V5cyB1bnRvdWNoZWQuICovXG4gIHByaXZhdGUgc3luY0NvbG9yU2xvdHMoc2VyaWVzOiBDaGFydFNlcmllc1tdKTogdm9pZCB7XG4gICAgdGhpcy5jb2xvcnMucmVnaXN0ZXIoc2VyaWVzLm1hcCgoaXRlbSkgPT4gaXRlbS5rZXkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYWludCBmb3IgYSBzZXJpZXMsIGtleWVkIGJ5IGlkZW50aXR5IHJhdGhlciB0aGFuIGJ5IGluZGV4IGluIHRoZSB2aXNpYmxlXG4gICAqIGFycmF5LiBQYXN0IHRoZSBmaWZ0aCBkaXN0aW5jdCBrZXkgdGhpcyByZXR1cm5zIHRoZSBuZXV0cmFsIG92ZXJmbG93IGNvbG91ci5cbiAgICovXG4gIGNvbG9yRm9yKHNlcmllc0tleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5jb2xvcnMuY29sb3JGb3Ioc2VyaWVzS2V5KTtcbiAgfVxuXG4gIC8qKiBUcnVlIHdoZW4gdGhpcyBzZXJpZXMgZmVsbCBwYXN0IHRoZSBwYWxldHRlIGFuZCByZW5kZXJzIG5ldXRyYWwuICovXG4gIGlzT3ZlcmZsb3dTZXJpZXMoc2VyaWVzS2V5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jb2xvcnMuaXNPdmVyZmxvdyhzZXJpZXNLZXkpO1xuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdGhlIHNjYWxlc1xuXG4gIC8qKiBSZWFkcyBhIHNlcmllcyB2YWx1ZSBvZmYgYSByb3csIG9yIG51bGwgd2hlbiBpdCBpcyBtaXNzaW5nL25vbi1udW1lcmljLiAqL1xuICB2YWx1ZUF0KHNlcmllc0tleTogc3RyaW5nLCBpbmRleDogbnVtYmVyKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgY29uc3QgcmF3ID0gdGhpcy5kYXRhW2luZGV4XT8uW3Nlcmllc0tleV07XG4gICAgaWYgKHJhdyA9PSBudWxsIHx8IHJhdyA9PT0gJycpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IG51bSA9IE51bWJlcihyYXcpO1xuICAgIHJldHVybiBOdW1iZXIuaXNGaW5pdGUobnVtKSA/IG51bSA6IG51bGw7XG4gIH1cblxuICAvKiogU3VtIG9mIGV2ZXJ5IHNlcmllcyBiZWxvdyBgc2VyaWVzS2V5YCBhdCBgaW5kZXhgLCBmb3Igc3RhY2tlZCBtYXJrcy4gKi9cbiAgc3RhY2tCYXNlKHNlcmllc0tleTogc3RyaW5nLCBpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoIXRoaXMuc3RhY2tlZCkgcmV0dXJuIDA7XG4gICAgbGV0IGJhc2UgPSAwO1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiB0aGlzLnNlcmllcykge1xuICAgICAgaWYgKGl0ZW0ua2V5ID09PSBzZXJpZXNLZXkpIGJyZWFrO1xuICAgICAgYmFzZSArPSB0aGlzLnZhbHVlQXQoaXRlbS5rZXksIGluZGV4KSA/PyAwO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZTtcbiAgfVxuXG4gIC8qKiBTdW0gb2YgZXZlcnkgc2VyaWVzIGF0IGBpbmRleGAuICovXG4gIHN0YWNrVG90YWwoaW5kZXg6IG51bWJlcik6IG51bWJlciB7XG4gICAgbGV0IHRvdGFsID0gMDtcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgdGhpcy5zZXJpZXMpIHRvdGFsICs9IHRoaXMudmFsdWVBdChpdGVtLmtleSwgaW5kZXgpID8/IDA7XG4gICAgcmV0dXJuIHRvdGFsO1xuICB9XG5cbiAgLyoqXG4gICAqIE1hcHMgYSBkYXRhIHZhbHVlIHRvIGFuIHN2ZyB5LiBTVkcgeSBncm93cyBkb3dud2FyZCwgc28gdGhlIGRvbWFpbiBtYXhpbXVtXG4gICAqIGxhbmRzIG9uIGBwbG90VG9wYCBhbmQgdGhlIG1pbmltdW0gb24gYHBsb3RCb3R0b21gLlxuICAgKi9cbiAgeUZvcih2YWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBzcGFuID0gdGhpcy5kb21haW5NYXggLSB0aGlzLmRvbWFpbk1pbjtcbiAgICBpZiAoc3BhbiA8PSAwKSByZXR1cm4gdGhpcy5wbG90Qm90dG9tO1xuICAgIGNvbnN0IHJhdGlvID0gKHZhbHVlIC0gdGhpcy5kb21haW5NaW4pIC8gc3BhbjtcbiAgICByZXR1cm4gdGhpcy5wbG90Qm90dG9tIC0gcmF0aW8gKiB0aGlzLnBsb3RIZWlnaHQ7XG4gIH1cblxuICAvKiogVGhlIHN2ZyB5IG9mIHRoZSB6ZXJvIGxpbmUsIGNsYW1wZWQgaW50byB0aGUgcGxvdC4gKi9cbiAgZ2V0IGJhc2VsaW5lWSgpOiBudW1iZXIge1xuICAgIGNvbnN0IHplcm8gPSBNYXRoLm1pbihNYXRoLm1heCgwLCB0aGlzLmRvbWFpbk1pbiksIHRoaXMuZG9tYWluTWF4KTtcbiAgICByZXR1cm4gdGhpcy55Rm9yKHplcm8pO1xuICB9XG5cbiAgLyoqIFdpZHRoIG9mIG9uZSBiYW5kLCBleGNsdWRpbmcgaXRzIHBhZGRpbmcuIE1lYW5pbmdmdWwgaW4gYmFuZCBtb2RlLiAqL1xuICBnZXQgYmFuZFdpZHRoKCk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuY291bnQgPT09IDApIHJldHVybiAwO1xuICAgIHJldHVybiB0aGlzLmJhbmRTdGVwICogKDEgLSB0aGlzLmJhbmRQYWRkaW5nKTtcbiAgfVxuXG4gIC8qKiBEaXN0YW5jZSBiZXR3ZWVuIGFkamFjZW50IGJhbmQgc3RhcnRzLiBCYW5kcyB0aWxlIHRoZSBwbG90IGV4YWN0bHkuICovXG4gIGdldCBiYW5kU3RlcCgpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLmNvdW50ID09PSAwKSByZXR1cm4gMDtcbiAgICByZXR1cm4gdGhpcy5wbG90V2lkdGggLyB0aGlzLmNvdW50O1xuICB9XG5cbiAgLyoqIEdlb21ldHJ5IG9mIHRoZSBiYW5kIGF0IGBpbmRleGAuICovXG4gIGJhbmRGb3IoaW5kZXg6IG51bWJlcik6IENoYXJ0QmFuZCB7XG4gICAgY29uc3Qgc3RlcCA9IHRoaXMuYmFuZFN0ZXA7XG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLmJhbmRXaWR0aDtcbiAgICBjb25zdCBzdGFydCA9IHRoaXMucGxvdExlZnQgKyBpbmRleCAqIHN0ZXAgKyAoc3RlcCAtIHdpZHRoKSAvIDI7XG4gICAgcmV0dXJuIHsgc3RhcnQsIGNlbnRyZTogc3RhcnQgKyB3aWR0aCAvIDIsIHdpZHRoIH07XG4gIH1cblxuICAvKiogeCBvZiB0aGUgZGF0YSBwb2ludCBhdCBgaW5kZXhgIG9uIHRoZSBwb2ludCBzY2FsZS4gKi9cbiAgcG9pbnRYKGluZGV4OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLmNvdW50ID09PSAwKSByZXR1cm4gdGhpcy5wbG90TGVmdDtcbiAgICBpZiAodGhpcy5jb3VudCA9PT0gMSkgcmV0dXJuIHRoaXMucGxvdExlZnQgKyB0aGlzLnBsb3RXaWR0aCAvIDI7XG4gICAgcmV0dXJuIHRoaXMucGxvdExlZnQgKyAoaW5kZXggKiB0aGlzLnBsb3RXaWR0aCkgLyAodGhpcy5jb3VudCAtIDEpO1xuICB9XG5cbiAgLyoqIHggb2YgYGluZGV4YCB1bmRlciB3aGljaGV2ZXIgc2NhbGUgdGhlIGNoYXJ0IGlzIGN1cnJlbnRseSB1c2luZy4gKi9cbiAgeEZvcihpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zY2FsZU1vZGUgPT09ICdiYW5kJyA/IHRoaXMuYmFuZEZvcihpbmRleCkuY2VudHJlIDogdGhpcy5wb2ludFgoaW5kZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBwb2ludGVyIGNhdGNobWVudCBhcmVhIGZvciBgaW5kZXhgIOKAlCBkZWxpYmVyYXRlbHkgd2lkZXIgdGhhbiB0aGUgbWFyay5cbiAgICogSW4gYmFuZCBtb2RlIGl0IGlzIHRoZSB3aG9sZSBiYW5kIHN0ZXA7IG9uIHRoZSBwb2ludCBzY2FsZSBpdCBydW5zIHRvIHRoZVxuICAgKiBtaWRwb2ludHMgb2YgdGhlIG5laWdoYm91cmluZyBwb2ludHMsIHNvIHRoZSBwb2ludGVyIG9ubHkgaGFzIHRvIGJlIG5lYXJlc3QuXG4gICAqL1xuICBoaXRCYW5kRm9yKGluZGV4OiBudW1iZXIpOiBDaGFydEJhbmQge1xuICAgIGlmICh0aGlzLnNjYWxlTW9kZSA9PT0gJ2JhbmQnKSB7XG4gICAgICBjb25zdCBzdGVwID0gdGhpcy5iYW5kU3RlcDtcbiAgICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5wbG90TGVmdCArIGluZGV4ICogc3RlcDtcbiAgICAgIHJldHVybiB7IHN0YXJ0LCBjZW50cmU6IHN0YXJ0ICsgc3RlcCAvIDIsIHdpZHRoOiBzdGVwIH07XG4gICAgfVxuICAgIGNvbnN0IHggPSB0aGlzLnBvaW50WChpbmRleCk7XG4gICAgY29uc3QgcHJldiA9IGluZGV4ID4gMCA/IHRoaXMucG9pbnRYKGluZGV4IC0gMSkgOiB0aGlzLnBsb3RMZWZ0IC0gKHRoaXMucGxvdFJpZ2h0IC0gdGhpcy5wbG90TGVmdCk7XG4gICAgY29uc3QgbmV4dCA9XG4gICAgICBpbmRleCA8IHRoaXMuY291bnQgLSAxID8gdGhpcy5wb2ludFgoaW5kZXggKyAxKSA6IHRoaXMucGxvdFJpZ2h0ICsgKHRoaXMucGxvdFJpZ2h0IC0gdGhpcy5wbG90TGVmdCk7XG4gICAgY29uc3Qgc3RhcnQgPSBNYXRoLm1heCh0aGlzLnBsb3RMZWZ0LCAocHJldiArIHgpIC8gMik7XG4gICAgY29uc3QgZW5kID0gTWF0aC5taW4odGhpcy5wbG90UmlnaHQsICh4ICsgbmV4dCkgLyAyKTtcbiAgICByZXR1cm4geyBzdGFydCwgY2VudHJlOiB4LCB3aWR0aDogTWF0aC5tYXgoMCwgZW5kIC0gc3RhcnQpIH07XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gaG92ZXJpbmdcblxuICAvKiogSW5kZXggY3VycmVudGx5IHVuZGVyIHRoZSBwb2ludGVyLCBvciBudWxsLiAqL1xuICBnZXQgYWN0aXZlSW5kZXgoKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlSW5kZXhTdWJqZWN0LnZhbHVlO1xuICB9XG5cbiAgc2V0QWN0aXZlSW5kZXgoaW5kZXg6IG51bWJlciB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hY3RpdmVJbmRleFN1YmplY3QudmFsdWUgPT09IGluZGV4KSByZXR1cm47XG4gICAgdGhpcy5hY3RpdmVJbmRleFN1YmplY3QubmV4dChpbmRleCk7XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBkb21haW5zXG5cbiAgcHJpdmF0ZSByZWNvbXB1dGUoKTogdm9pZCB7XG4gICAgY29uc3QgdmFsdWVzOiBudW1iZXJbXSA9IFtdO1xuXG4gICAgaWYgKHRoaXMuc3RhY2tlZCkge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNvdW50OyBpKyspIHZhbHVlcy5wdXNoKHRoaXMuc3RhY2tUb3RhbChpKSk7XG4gICAgICAvLyBBIHN0YWNrIHN0aWxsIGhhcyB0byBzaG93IGl0cyBvd24gZmxvb3Igd2hlbiBhIHNlcmllcyBnb2VzIG5lZ2F0aXZlLlxuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHRoaXMuc2VyaWVzKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jb3VudDsgaSsrKSB7XG4gICAgICAgICAgY29uc3QgdiA9IHRoaXMudmFsdWVBdChpdGVtLmtleSwgaSk7XG4gICAgICAgICAgaWYgKHYgIT0gbnVsbCAmJiB2IDwgMCkgdmFsdWVzLnB1c2godik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHRoaXMuc2VyaWVzKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jb3VudDsgaSsrKSB7XG4gICAgICAgICAgY29uc3QgdiA9IHRoaXMudmFsdWVBdChpdGVtLmtleSwgaSk7XG4gICAgICAgICAgaWYgKHYgIT0gbnVsbCkgdmFsdWVzLnB1c2godik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy56ZXJvUmVxdWlyZWQpIHZhbHVlcy5wdXNoKDApO1xuXG4gICAgY29uc3QgW21pbiwgbWF4LCBzdGVwLCB0aWNrc10gPSBuaWNlU2NhbGUodmFsdWVzKTtcbiAgICB0aGlzLmRvbWFpbk1pbiA9IG1pbjtcbiAgICB0aGlzLmRvbWFpbk1heCA9IG1heDtcbiAgICB0aGlzLnRpY2tTdGVwID0gc3RlcDtcbiAgICB0aGlzLnRpY2tWYWx1ZXMgPSB0aWNrcztcblxuICAgIC8vIE9ubHkgdGVsbCBzdWJzY3JpYmVycyB3aGVuIHNvbWV0aGluZyB0aGV5IHdvdWxkIGRyYXcgZGlmZmVyZW50bHkgYWN0dWFsbHlcbiAgICAvLyBjaGFuZ2VkLiBgY29uZmlndXJlKClgIGlzIGNhbGxlZCBmcm9tIG5nT25DaGFuZ2VzLCBhbmQgYW4gYXBwIGJpbmRpbmdcbiAgICAvLyBgW2RhdGFdPVwiaXRlbXMuZmlsdGVyKC4uLilcImAgaGFuZHMgdXMgYSBmcmVzaCBhcnJheSByZWZlcmVuY2Ugb24gZXZlcnlcbiAgICAvLyBjaGFuZ2UtZGV0ZWN0aW9uIHBhc3Mg4oCUIGFuIG9yZGluYXJ5IHRoaW5nIHRvIHdyaXRlLiBFbWl0dGluZyBvbiBldmVyeSBjYWxsXG4gICAgLy8gbWFkZSBzdWJzY3JpYmVycyBtYXJrRm9yQ2hlY2ssIHdoaWNoIHNjaGVkdWxlZCBhbm90aGVyIHBhc3MsIHdoaWNoIGNhbGxlZFxuICAgIC8vIGNvbmZpZ3VyZSBhZ2FpbjogdGhlIGN5Y2xlIG5ldmVyIGNsb3NlZCBhbmQgdGhlIHBhZ2UgbG9ja2VkIHVwLlxuICAgIGNvbnN0IHNpZ25hdHVyZSA9IHRoaXMubGF5b3V0U2lnbmF0dXJlKHZhbHVlcyk7XG4gICAgaWYgKHNpZ25hdHVyZSA9PT0gdGhpcy5sYXN0U2lnbmF0dXJlKSByZXR1cm47XG4gICAgdGhpcy5sYXN0U2lnbmF0dXJlID0gc2lnbmF0dXJlO1xuXG4gICAgdGhpcy5zY2hlZHVsZUVtaXQoKTtcbiAgfVxuXG4gIC8qKiBFdmVyeXRoaW5nIGEgc3Vic2NyaWJlciB3b3VsZCByZW5kZXIgZGlmZmVyZW50bHksIGZsYXR0ZW5lZCBmb3IgY29tcGFyaXNvbi4gKi9cbiAgcHJpdmF0ZSBsYXN0U2lnbmF0dXJlID0gJyc7XG5cbiAgcHJpdmF0ZSBsYXlvdXRTaWduYXR1cmUodmFsdWVzOiBudW1iZXJbXSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHRoaXMuY291bnQsXG4gICAgICB0aGlzLnhLZXksXG4gICAgICB0aGlzLnN0YWNrZWQsXG4gICAgICB0aGlzLndpZHRoLFxuICAgICAgdGhpcy5oZWlnaHQsXG4gICAgICB0aGlzLmJhbmRQYWRkaW5nLFxuICAgICAgdGhpcy5zY2FsZU1vZGUsXG4gICAgICB0aGlzLnplcm9SZXF1aXJlZCxcbiAgICAgIHRoaXMubWFyZ2luLnRvcCwgdGhpcy5tYXJnaW4ucmlnaHQsIHRoaXMubWFyZ2luLmJvdHRvbSwgdGhpcy5tYXJnaW4ubGVmdCxcbiAgICAgIHRoaXMuZG9tYWluTWluLCB0aGlzLmRvbWFpbk1heCwgdGhpcy50aWNrU3RlcCxcbiAgICAgIHRoaXMudGlja1ZhbHVlcy5qb2luKCcsJyksXG4gICAgICB0aGlzLnNlcmllcy5tYXAoKHMpID0+IHMua2V5ICsgJzonICsgcy5sYWJlbCkuam9pbignLCcpLFxuICAgICAgdGhpcy54TGFiZWxzLmpvaW4oJ1x1MDAwMScpLFxuICAgICAgdmFsdWVzLmpvaW4oJywnKSxcbiAgICBdLmpvaW4oJ1x1MDAwMCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvYWxlc2NlcyBsYXlvdXQgbm90aWZpY2F0aW9ucyBpbnRvIGEgbWljcm90YXNrLCBzbyBzZXZlcmFsIGNoaWxkcmVuXG4gICAqIHJlZ2lzdGVyaW5nIGluIHRoZSBzYW1lIGNoYW5nZS1kZXRlY3Rpb24gcGFzcyBwcm9kdWNlIG9uZSBlbWlzc2lvbiBhZnRlclxuICAgKiB0aGV5IGhhdmUgYWxsIHNldHRsZWQgcmF0aGVyIHRoYW4gb25lIGVhY2ggbWlkLXBhc3MuXG4gICAqL1xuICBwcml2YXRlIHNjaGVkdWxlRW1pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmxheW91dFZlcnNpb24rKztcbiAgICBpZiAodGhpcy5lbWl0U2NoZWR1bGVkKSByZXR1cm47XG4gICAgdGhpcy5lbWl0U2NoZWR1bGVkID0gdHJ1ZTtcbiAgICBxdWV1ZU1pY3JvdGFzaygoKSA9PiB7XG4gICAgICB0aGlzLmVtaXRTY2hlZHVsZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMubGF5b3V0U3ViamVjdC5uZXh0KHRoaXMubGF5b3V0VmVyc2lvbik7XG4gICAgfSk7XG4gIH1cblxuICAvKiogRm9ybWF0cyBhIHZhbHVlIGZvciBhIHRpY2sgbGFiZWwgYXQgdGhlIGN1cnJlbnQgdGljayBzdGVwJ3MgcHJlY2lzaW9uLiAqL1xuICBmb3JtYXRWYWx1ZSh2YWx1ZTogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBjb25zdCBkZWNpbWFscyA9IGRlY2ltYWxzRm9yKHRoaXMudGlja1N0ZXApO1xuICAgIHJldHVybiB2YWx1ZS50b0xvY2FsZVN0cmluZygnZW4tVVMnLCB7XG4gICAgICBtaW5pbXVtRnJhY3Rpb25EaWdpdHM6IGRlY2ltYWxzLFxuICAgICAgbWF4aW11bUZyYWN0aW9uRGlnaXRzOiBkZWNpbWFscyxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gcGF0aHNcblxuICAvKiogU3RyYWlnaHQtc2VnbWVudCBwYXRoIHRocm91Z2ggdGhlIHNlcmllcycgZGVmaW5lZCBwb2ludHMuICovXG4gIGxpbmVQYXRoKHNlcmllc0tleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYnVpbGRQYXRoKHRoaXMucG9pbnRzRm9yKHNlcmllc0tleSksIGZhbHNlKTtcbiAgfVxuXG4gIC8qKiBNb25vdG9uZS1jdWJpYyBwYXRoIHRocm91Z2ggdGhlIHNlcmllcycgZGVmaW5lZCBwb2ludHMuICovXG4gIHNtb290aFBhdGgoc2VyaWVzS2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBidWlsZFBhdGgodGhpcy5wb2ludHNGb3Ioc2VyaWVzS2V5KSwgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogRmlsbGVkLWFyZWEgcGF0aDogdGhlIHNlcmllcycgbGluZSwgY2xvc2VkIGJhY2sgYWxvbmcgaXRzIGJhc2VsaW5lLiBXaGVuXG4gICAqIHN0YWNrZWQsIHRoZSBmbG9vciBpcyB0aGUgdG9wIG9mIHRoZSBzZXJpZXMgYmVsb3cgcmF0aGVyIHRoYW4gemVyby5cbiAgICovXG4gIGFyZWFQYXRoKHNlcmllc0tleTogc3RyaW5nLCBzbW9vdGg6IGJvb2xlYW4pOiBzdHJpbmcge1xuICAgIGNvbnN0IHBvaW50cyA9IHRoaXMucG9pbnRzRm9yKHNlcmllc0tleSk7XG4gICAgaWYgKHBvaW50cy5sZW5ndGggPT09IDApIHJldHVybiAnJztcblxuICAgIGNvbnN0IHRvcCA9IGJ1aWxkUGF0aChwb2ludHMsIHNtb290aCk7XG4gICAgY29uc3QgZmxvb3IgPSBwb2ludHNcbiAgICAgIC5tYXAoKHApID0+IHtcbiAgICAgICAgY29uc3QgYmFzZSA9IHRoaXMuc3RhY2tlZCA/IHRoaXMuc3RhY2tCYXNlKHNlcmllc0tleSwgcC5pbmRleCkgOiAwO1xuICAgICAgICByZXR1cm4geyB4OiBwLngsIHk6IHRoaXMueUZvcihiYXNlKSwgaW5kZXg6IHAuaW5kZXggfTtcbiAgICAgIH0pXG4gICAgICAucmV2ZXJzZSgpO1xuICAgIGNvbnN0IGJvdHRvbSA9IGJ1aWxkUGF0aChmbG9vciwgc21vb3RoKTtcbiAgICAvLyBSZS1lbnRlciB0aGUgcmV2ZXJzZWQgZmxvb3Igd2l0aCBhIGxpbmUsIHRoZW4gY2xvc2UuXG4gICAgcmV0dXJuIHRvcCArICcgTCAnICsgZmxvb3JbMF0ueCArICcgJyArIGZsb29yWzBdLnkgKyAnICcgKyBib3R0b20ucmVwbGFjZSgvXk0vLCAnTCcpICsgJyBaJztcbiAgfVxuXG4gIC8qKiBSZXNvbHZlZCBzdmcgcG9pbnRzIGZvciBhIHNlcmllcywgc2tpcHBpbmcgcm93cyB3aGVyZSBpdCBoYXMgbm8gdmFsdWUuICovXG4gIHBvaW50c0ZvcihzZXJpZXNLZXk6IHN0cmluZyk6IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IGluZGV4OiBudW1iZXIgfVtdIHtcbiAgICBjb25zdCBwb2ludHM6IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IGluZGV4OiBudW1iZXIgfVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNvdW50OyBpKyspIHtcbiAgICAgIGNvbnN0IHYgPSB0aGlzLnZhbHVlQXQoc2VyaWVzS2V5LCBpKTtcbiAgICAgIGlmICh2ID09IG51bGwpIGNvbnRpbnVlO1xuICAgICAgY29uc3Qgc3RhY2tlZCA9IHRoaXMuc3RhY2tlZCA/IHRoaXMuc3RhY2tCYXNlKHNlcmllc0tleSwgaSkgKyB2IDogdjtcbiAgICAgIHBvaW50cy5wdXNoKHsgeDogdGhpcy54Rm9yKGkpLCB5OiB0aGlzLnlGb3Ioc3RhY2tlZCksIGluZGV4OiBpIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcG9pbnRzO1xuICB9XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gcHVyZSBoZWxwZXJzXG5cbi8qKiBEZWNpbWFsIHBsYWNlcyB3b3J0aCBzaG93aW5nIGZvciBhIGdpdmVuIHRpY2sgc3RlcC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWNpbWFsc0ZvcihzdGVwOiBudW1iZXIpOiBudW1iZXIge1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZShzdGVwKSB8fCBzdGVwIDw9IDApIHJldHVybiAwO1xuICByZXR1cm4gTWF0aC5tYXgoMCwgTWF0aC5taW4oNiwgLU1hdGguZmxvb3IoTWF0aC5sb2cxMChzdGVwKSkpKTtcbn1cblxuLyoqXG4gKiBSb3VuZHMgYSByYXcgc3RlcCB1cCB0byB0aGUgbmV4dCAxLzIvNSB4IDEwXm4uXG4gKlxuICogRGl2aWRpbmcgdGhlIHJhbmdlIGJ5IGEgdGljayBjb3VudCBpbnN0ZWFkIHdvdWxkIHByb2R1Y2Ugc3RlcHMgbGlrZSAxOS40IGFuZFxuICogc28gYXhpcyBsYWJlbHMgbGlrZSAxOS40IC8gMzguOCAvIDU4LjIsIHdoaWNoIG5vYm9keSBjYW4gcmVhZCBhIHZhbHVlIG9mZi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5pY2VTdGVwKHJhd1N0ZXA6IG51bWJlcik6IG51bWJlciB7XG4gIGlmICghTnVtYmVyLmlzRmluaXRlKHJhd1N0ZXApIHx8IHJhd1N0ZXAgPD0gMCkgcmV0dXJuIDE7XG4gIGNvbnN0IG1hZ25pdHVkZSA9IE1hdGgucG93KDEwLCBNYXRoLmZsb29yKE1hdGgubG9nMTAocmF3U3RlcCkpKTtcbiAgY29uc3Qgbm9ybWFsaXNlZCA9IHJhd1N0ZXAgLyBtYWduaXR1ZGU7XG4gIGxldCBtdWx0aXBsaWVyOiBudW1iZXI7XG4gIGlmIChub3JtYWxpc2VkIDw9IDEpIG11bHRpcGxpZXIgPSAxO1xuICBlbHNlIGlmIChub3JtYWxpc2VkIDw9IDIpIG11bHRpcGxpZXIgPSAyO1xuICBlbHNlIGlmIChub3JtYWxpc2VkIDw9IDUpIG11bHRpcGxpZXIgPSA1O1xuICBlbHNlIG11bHRpcGxpZXIgPSAxMDtcbiAgcmV0dXJuIG11bHRpcGxpZXIgKiBtYWduaXR1ZGU7XG59XG5cbi8qKlxuICogQnVpbGRzIGEgcmVhZGFibGUgeSBzY2FsZSBvdmVyIGB2YWx1ZXNgOiByZXR1cm5zIGBbbWluLCBtYXgsIHN0ZXAsIHRpY2tzXWBcbiAqIHdpdGggdGhlIGRvbWFpbiBzbmFwcGVkIG91dHdhcmQgdG8gd2hvbGUgc3RlcHMuXG4gKlxuICogRGVnZW5lcmF0ZSBpbnB1dHMgKGVtcHR5LCBhbGwtaWRlbnRpY2FsKSBzdGlsbCBwcm9kdWNlIGEgdXNhYmxlIG9uZS11bml0XG4gKiBkb21haW4gcmF0aGVyIHRoYW4gYSB6ZXJvLWhlaWdodCBwbG90LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbmljZVNjYWxlKHZhbHVlczogbnVtYmVyW10sIHRhcmdldFRpY2tzID0gNSk6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJbXV0ge1xuICBjb25zdCBmaW5pdGUgPSB2YWx1ZXMuZmlsdGVyKCh2KSA9PiBOdW1iZXIuaXNGaW5pdGUodikpO1xuXG4gIGxldCBtaW4gPSBmaW5pdGUubGVuZ3RoID8gTWF0aC5taW4oLi4uZmluaXRlKSA6IDA7XG4gIGxldCBtYXggPSBmaW5pdGUubGVuZ3RoID8gTWF0aC5tYXgoLi4uZmluaXRlKSA6IDE7XG5cbiAgaWYgKG1pbiA9PT0gbWF4KSB7XG4gICAgLy8gQSBmbGF0IG9yIHNpbmdsZS1wb2ludCBkb21haW4gaGFzIG5vIHNwYW4gdG8gZGl2aWRlOyBvcGVuIGl0IHRvIG9uZSB1bml0XG4gICAgLy8gYXJvdW5kIHRoZSB2YWx1ZSBzbyB0aGUgbWFyayBzaXRzIG9uIGEgcmVhbCBheGlzIGluc3RlYWQgb2Ygb24gdGhlIGZsb29yLlxuICAgIGlmIChtaW4gPT09IDApIHtcbiAgICAgIG1pbiA9IDA7XG4gICAgICBtYXggPSAxO1xuICAgIH0gZWxzZSBpZiAobWluID4gMCkge1xuICAgICAgbWluID0gTWF0aC5taW4oMCwgbWluKTtcbiAgICAgIG1heCA9IG1heCA9PT0gMCA/IDEgOiBtYXg7XG4gICAgICBpZiAobWluID09PSBtYXgpIG1heCA9IG1pbiArIDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1heCA9IE1hdGgubWF4KDAsIG1heCk7XG4gICAgICBpZiAobWluID09PSBtYXgpIG1pbiA9IG1heCAtIDE7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgc3RlcCA9IG5pY2VTdGVwKChtYXggLSBtaW4pIC8gdGFyZ2V0VGlja3MpO1xuICAvLyBOdWRnZSBiZWZvcmUgcm91bmRpbmcgb3V0d2FyZDogMTAwLzIwIGxhbmRzIGEgaGFpciBhYm92ZSA1IGluIGJpbmFyeVxuICAvLyBmbG9hdGluZyBwb2ludCwgd2hpY2ggd291bGQgb3RoZXJ3aXNlIGFkZCBhIHBoYW50b20gdGljayBhdCAxMjAuXG4gIGNvbnN0IGVwc2lsb24gPSAxZS05O1xuICBjb25zdCBuaWNlTWluID0gTWF0aC5mbG9vcihtaW4gLyBzdGVwICsgZXBzaWxvbikgKiBzdGVwO1xuICBjb25zdCBuaWNlTWF4ID0gTWF0aC5jZWlsKG1heCAvIHN0ZXAgLSBlcHNpbG9uKSAqIHN0ZXA7XG4gIGNvbnN0IGRlY2ltYWxzID0gZGVjaW1hbHNGb3Ioc3RlcCk7XG5cbiAgY29uc3QgdGlja3M6IG51bWJlcltdID0gW107XG4gIGNvbnN0IHRvdGFsID0gTWF0aC5yb3VuZCgobmljZU1heCAtIG5pY2VNaW4pIC8gc3RlcCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDw9IHRvdGFsOyBpKyspIHtcbiAgICB0aWNrcy5wdXNoKE51bWJlcigobmljZU1pbiArIGkgKiBzdGVwKS50b0ZpeGVkKGRlY2ltYWxzKSkpO1xuICB9XG5cbiAgcmV0dXJuIFtOdW1iZXIobmljZU1pbi50b0ZpeGVkKGRlY2ltYWxzKSksIE51bWJlcihuaWNlTWF4LnRvRml4ZWQoZGVjaW1hbHMpKSwgc3RlcCwgdGlja3NdO1xufVxuXG4vKipcbiAqIE1vbm90b25lLWN1YmljIHRhbmdlbnRzIChGcml0c2NoLUNhcmxzb24pLiBMaW1pdGluZyBlYWNoIHRhbmdlbnQgdG8gdGhlXG4gKiBuZWlnaGJvdXJpbmcgc2VjYW50cyBpcyB3aGF0IHN0b3BzIHRoZSBjdXJ2ZSBvdmVyc2hvb3Rpbmc6IGEgcGxhaW5cbiAqIENhdG11bGwtUm9tIHNwbGluZSBidWxnZXMgcGFzdCB0aGUgZGF0YSBhbmQgaW52ZW50cyBwZWFrcyB0aGF0IHdlcmUgbmV2ZXJcbiAqIG1lYXN1cmVkLCB3aGljaCBvbiBhIGNoYXJ0IGlzIGEgZmFsc2Ugc3RhdGVtZW50IGFib3V0IHRoZSBudW1iZXJzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbW9ub3RvbmVUYW5nZW50cyh4czogbnVtYmVyW10sIHlzOiBudW1iZXJbXSk6IG51bWJlcltdIHtcbiAgY29uc3QgbiA9IHhzLmxlbmd0aDtcbiAgaWYgKG4gPCAyKSByZXR1cm4gbmV3IEFycmF5KG4pLmZpbGwoMCk7XG5cbiAgY29uc3Qgc2VjYW50czogbnVtYmVyW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuIC0gMTsgaSsrKSB7XG4gICAgY29uc3QgZHggPSB4c1tpICsgMV0gLSB4c1tpXTtcbiAgICBzZWNhbnRzLnB1c2goZHggPT09IDAgPyAwIDogKHlzW2kgKyAxXSAtIHlzW2ldKSAvIGR4KTtcbiAgfVxuXG4gIGNvbnN0IG06IG51bWJlcltdID0gbmV3IEFycmF5KG4pO1xuICBtWzBdID0gc2VjYW50c1swXTtcbiAgbVtuIC0gMV0gPSBzZWNhbnRzW24gLSAyXTtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBuIC0gMTsgaSsrKSBtW2ldID0gKHNlY2FudHNbaSAtIDFdICsgc2VjYW50c1tpXSkgLyAyO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbiAtIDE7IGkrKykge1xuICAgIGlmIChzZWNhbnRzW2ldID09PSAwKSB7XG4gICAgICAvLyBGbGF0IHNlZ21lbnQ6IGJvdGggZW5kcyBtdXN0IGJlIGZsYXQgb3IgdGhlIGN1cnZlIGxlYXZlcyB0aGUgZGF0YSByYW5nZS5cbiAgICAgIG1baV0gPSAwO1xuICAgICAgbVtpICsgMV0gPSAwO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IGEgPSBtW2ldIC8gc2VjYW50c1tpXTtcbiAgICBjb25zdCBiID0gbVtpICsgMV0gLyBzZWNhbnRzW2ldO1xuICAgIC8vIE5lZ2F0aXZlIHJhdGlvcyBtZWFuIHRoZSB0YW5nZW50IHBvaW50cyBhd2F5IGZyb20gdGhlIHNlY2FudC5cbiAgICBpZiAoYSA8IDApIG1baV0gPSAwO1xuICAgIGlmIChiIDwgMCkgbVtpICsgMV0gPSAwO1xuICAgIGNvbnN0IHN1bSA9IGEgKiBhICsgYiAqIGI7XG4gICAgaWYgKHN1bSA+IDkpIHtcbiAgICAgIGNvbnN0IHQgPSAzIC8gTWF0aC5zcXJ0KHN1bSk7XG4gICAgICBtW2ldID0gdCAqIGEgKiBzZWNhbnRzW2ldO1xuICAgICAgbVtpICsgMV0gPSB0ICogYiAqIHNlY2FudHNbaV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG07XG59XG5cbi8qKiBUdXJucyByZXNvbHZlZCBwb2ludHMgaW50byBhbiBzdmcgcGF0aCwgb3B0aW9uYWxseSBtb25vdG9uZS1zbW9vdGhlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFBhdGgocG9pbnRzOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH1bXSwgc21vb3RoOiBib29sZWFuKTogc3RyaW5nIHtcbiAgaWYgKHBvaW50cy5sZW5ndGggPT09IDApIHJldHVybiAnJztcbiAgaWYgKHBvaW50cy5sZW5ndGggPT09IDEpIHJldHVybiAnTSAnICsgcG9pbnRzWzBdLnggKyAnICcgKyBwb2ludHNbMF0ueTtcblxuICBjb25zdCBoZWFkID0gJ00gJyArIHBvaW50c1swXS54ICsgJyAnICsgcG9pbnRzWzBdLnk7XG4gIGlmICghc21vb3RoKSB7XG4gICAgcmV0dXJuIGhlYWQgKyBwb2ludHMuc2xpY2UoMSkubWFwKChwKSA9PiAnIEwgJyArIHAueCArICcgJyArIHAueSkuam9pbignJyk7XG4gIH1cblxuICBjb25zdCB4cyA9IHBvaW50cy5tYXAoKHApID0+IHAueCk7XG4gIGNvbnN0IHlzID0gcG9pbnRzLm1hcCgocCkgPT4gcC55KTtcbiAgY29uc3QgbSA9IG1vbm90b25lVGFuZ2VudHMoeHMsIHlzKTtcblxuICBsZXQgZCA9IGhlYWQ7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgIGNvbnN0IGR4ID0geHNbaSArIDFdIC0geHNbaV07XG4gICAgY29uc3QgYzF4ID0geHNbaV0gKyBkeCAvIDM7XG4gICAgY29uc3QgYzF5ID0geXNbaV0gKyAobVtpXSAqIGR4KSAvIDM7XG4gICAgY29uc3QgYzJ4ID0geHNbaSArIDFdIC0gZHggLyAzO1xuICAgIGNvbnN0IGMyeSA9IHlzW2kgKyAxXSAtIChtW2kgKyAxXSAqIGR4KSAvIDM7XG4gICAgZCArPSAnIEMgJyArIGMxeCArICcgJyArIGMxeSArICcgJyArIGMyeCArICcgJyArIGMyeSArICcgJyArIHhzW2kgKyAxXSArICcgJyArIHlzW2kgKyAxXTtcbiAgfVxuICByZXR1cm4gZDtcbn1cbiJdfQ==