@tolle_/tolle-ui 18.2.29 → 18.2.30

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 (279) 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 +5 -10
  4. package/esm2022/lib/alert-dialog.component.mjs +44 -59
  5. package/esm2022/lib/alert.component.mjs +5 -11
  6. package/esm2022/lib/aspect-ratio.component.mjs +119 -0
  7. package/esm2022/lib/attachment.component.mjs +334 -0
  8. package/esm2022/lib/avatar-fallback.component.mjs +3 -3
  9. package/esm2022/lib/avatar.component.mjs +4 -9
  10. package/esm2022/lib/badge.component.mjs +4 -9
  11. package/esm2022/lib/breadcrumb-item.component.mjs +3 -3
  12. package/esm2022/lib/breadcrumb-link.component.mjs +3 -3
  13. package/esm2022/lib/breadcrumb-separator.component.mjs +3 -3
  14. package/esm2022/lib/breadcrumb.component.mjs +3 -3
  15. package/esm2022/lib/bubble.component.mjs +301 -0
  16. package/esm2022/lib/button.component.mjs +5 -11
  17. package/esm2022/lib/calendar.component.mjs +5 -11
  18. package/esm2022/lib/card.component.mjs +14 -43
  19. package/esm2022/lib/carousel/carousel.component.mjs +5 -12
  20. package/esm2022/lib/chain-of-thought.component.mjs +380 -0
  21. package/esm2022/lib/chart-pie.component.mjs +386 -0
  22. package/esm2022/lib/chart.component.mjs +1146 -0
  23. package/esm2022/lib/chart.service.mjs +555 -0
  24. package/esm2022/lib/checkbox.component.mjs +5 -11
  25. package/esm2022/lib/checkpoint.component.mjs +134 -0
  26. package/esm2022/lib/collapsible.component.mjs +4 -11
  27. package/esm2022/lib/combobox.component.mjs +372 -0
  28. package/esm2022/lib/command-dialog.component.mjs +164 -0
  29. package/esm2022/lib/command.component.mjs +514 -0
  30. package/esm2022/lib/command.service.mjs +130 -0
  31. package/esm2022/lib/confirmation.component.mjs +219 -0
  32. package/esm2022/lib/context-menu-trigger.directive.mjs +36 -0
  33. package/esm2022/lib/context-menu.component.mjs +460 -0
  34. package/esm2022/lib/context-menu.service.mjs +121 -0
  35. package/esm2022/lib/context.component.mjs +377 -0
  36. package/esm2022/lib/conversation.component.mjs +442 -0
  37. package/esm2022/lib/country-selector.component.mjs +5 -11
  38. package/esm2022/lib/data-table.component.mjs +59 -12
  39. package/esm2022/lib/date-picker.component.mjs +251 -198
  40. package/esm2022/lib/date-range-picker.component.mjs +224 -116
  41. package/esm2022/lib/date-time-picker.component.mjs +506 -0
  42. package/esm2022/lib/direction.component.mjs +79 -0
  43. package/esm2022/lib/dropdown-item.component.mjs +3 -3
  44. package/esm2022/lib/dropdown-label.component.mjs +3 -3
  45. package/esm2022/lib/dropdown-menu.component.mjs +3 -3
  46. package/esm2022/lib/dropdown-separator.component.mjs +3 -3
  47. package/esm2022/lib/dropdown-trigger.directive.mjs +6 -4
  48. package/esm2022/lib/empty-state.component.mjs +4 -9
  49. package/esm2022/lib/field.component.mjs +394 -0
  50. package/esm2022/lib/hover-card.component.mjs +6 -16
  51. package/esm2022/lib/inline-citation.component.mjs +263 -0
  52. package/esm2022/lib/input-group.component.mjs +418 -0
  53. package/esm2022/lib/input.component.mjs +5 -11
  54. package/esm2022/lib/item.component.mjs +243 -0
  55. package/esm2022/lib/kbd.component.mjs +82 -0
  56. package/esm2022/lib/label.component.mjs +4 -9
  57. package/esm2022/lib/marker.component.mjs +135 -0
  58. package/esm2022/lib/masked-input.component.mjs +5 -11
  59. package/esm2022/lib/menubar.component.mjs +683 -0
  60. package/esm2022/lib/message-scroller.component.mjs +353 -0
  61. package/esm2022/lib/message-scroller.service.mjs +157 -0
  62. package/esm2022/lib/message.component.mjs +228 -0
  63. package/esm2022/lib/model-selector.component.mjs +310 -0
  64. package/esm2022/lib/multi-select.component.mjs +155 -72
  65. package/esm2022/lib/native-select.component.mjs +201 -0
  66. package/esm2022/lib/navigation-menu.component.mjs +642 -0
  67. package/esm2022/lib/otp-group.component.mjs +3 -3
  68. package/esm2022/lib/otp-slot.component.mjs +4 -9
  69. package/esm2022/lib/otp.component.mjs +5 -11
  70. package/esm2022/lib/pagination.component.mjs +7 -10
  71. package/esm2022/lib/plan.component.mjs +335 -0
  72. package/esm2022/lib/popover-content.component.mjs +4 -9
  73. package/esm2022/lib/popover.component.mjs +15 -13
  74. package/esm2022/lib/progress.component.mjs +4 -9
  75. package/esm2022/lib/prompt-input.component.mjs +526 -0
  76. package/esm2022/lib/queue.component.mjs +280 -0
  77. package/esm2022/lib/radio-group.component.mjs +6 -13
  78. package/esm2022/lib/radio-item.component.mjs +4 -9
  79. package/esm2022/lib/range-calendar.component.mjs +5 -11
  80. package/esm2022/lib/reasoning.component.mjs +335 -0
  81. package/esm2022/lib/resizable.component.mjs +219 -0
  82. package/esm2022/lib/segment.component.mjs +17 -7
  83. package/esm2022/lib/select-group.component.mjs +4 -8
  84. package/esm2022/lib/select-item.component.mjs +4 -9
  85. package/esm2022/lib/select-separator.component.mjs +4 -8
  86. package/esm2022/lib/select.component.mjs +133 -49
  87. package/esm2022/lib/separator.component.mjs +4 -9
  88. package/esm2022/lib/sheet.component.mjs +38 -56
  89. package/esm2022/lib/shimmer.component.mjs +84 -0
  90. package/esm2022/lib/sidebar.component.mjs +11 -1
  91. package/esm2022/lib/skeleton.component.mjs +4 -9
  92. package/esm2022/lib/sources.component.mjs +452 -0
  93. package/esm2022/lib/spinner.component.mjs +68 -0
  94. package/esm2022/lib/suggestion.component.mjs +207 -0
  95. package/esm2022/lib/switch.component.mjs +5 -11
  96. package/esm2022/lib/table.component.mjs +213 -0
  97. package/esm2022/lib/tabs.component.mjs +4 -11
  98. package/esm2022/lib/tag-input.component.mjs +5 -11
  99. package/esm2022/lib/task.component.mjs +359 -0
  100. package/esm2022/lib/textarea.component.mjs +5 -11
  101. package/esm2022/lib/theme.service.mjs +17 -6
  102. package/esm2022/lib/time-picker.component.mjs +923 -0
  103. package/esm2022/lib/toast.service.mjs +3 -2
  104. package/esm2022/lib/toaster.component.mjs +76 -39
  105. package/esm2022/lib/toggle-group.component.mjs +4 -9
  106. package/esm2022/lib/toggle.component.mjs +5 -11
  107. package/esm2022/lib/tool.component.mjs +462 -0
  108. package/esm2022/lib/typography.component.mjs +83 -0
  109. package/esm2022/lib/utils/color.mjs +140 -19
  110. package/esm2022/public-api.mjs +61 -1
  111. package/fesm2022/tolle-ui.mjs +16453 -1024
  112. package/fesm2022/tolle-ui.mjs.map +1 -1
  113. package/lib/alert-dialog.component.d.ts +10 -2
  114. package/lib/aspect-ratio.component.d.ts +20 -0
  115. package/lib/attachment.component.d.ts +101 -0
  116. package/lib/bubble.component.d.ts +112 -0
  117. package/lib/chain-of-thought.component.d.ts +166 -0
  118. package/lib/chart-pie.component.d.ts +108 -0
  119. package/lib/chart.component.d.ts +369 -0
  120. package/lib/chart.service.d.ts +222 -0
  121. package/lib/checkpoint.component.d.ts +51 -0
  122. package/lib/combobox.component.d.ts +90 -0
  123. package/lib/command-dialog.component.d.ts +53 -0
  124. package/lib/command.component.d.ts +189 -0
  125. package/lib/command.service.d.ts +67 -0
  126. package/lib/confirmation.component.d.ts +70 -0
  127. package/lib/context-menu-trigger.directive.d.ts +12 -0
  128. package/lib/context-menu.component.d.ts +41 -0
  129. package/lib/context-menu.service.d.ts +38 -0
  130. package/lib/context.component.d.ts +134 -0
  131. package/lib/conversation.component.d.ts +165 -0
  132. package/lib/data-table.component.d.ts +26 -1
  133. package/lib/date-picker.component.d.ts +72 -11
  134. package/lib/date-range-picker.component.d.ts +63 -6
  135. package/lib/date-time-picker.component.d.ts +119 -0
  136. package/lib/direction.component.d.ts +45 -0
  137. package/lib/field.component.d.ts +201 -0
  138. package/lib/inline-citation.component.d.ts +103 -0
  139. package/lib/input-group.component.d.ts +150 -0
  140. package/lib/item.component.d.ts +154 -0
  141. package/lib/kbd.component.d.ts +50 -0
  142. package/lib/marker.component.d.ts +58 -0
  143. package/lib/menubar.component.d.ts +247 -0
  144. package/lib/message-scroller.component.d.ts +159 -0
  145. package/lib/message-scroller.service.d.ts +73 -0
  146. package/lib/message.component.d.ts +128 -0
  147. package/lib/model-selector.component.d.ts +103 -0
  148. package/lib/multi-select.component.d.ts +66 -14
  149. package/lib/native-select.component.d.ts +57 -0
  150. package/lib/navigation-menu.component.d.ts +230 -0
  151. package/lib/plan.component.d.ts +120 -0
  152. package/lib/popover.component.d.ts +1 -0
  153. package/lib/prompt-input.component.d.ts +194 -0
  154. package/lib/queue.component.d.ts +106 -0
  155. package/lib/reasoning.component.d.ts +127 -0
  156. package/lib/resizable.component.d.ts +43 -0
  157. package/lib/segment.component.d.ts +13 -3
  158. package/lib/select.component.d.ts +37 -5
  159. package/lib/sheet.component.d.ts +3 -0
  160. package/lib/shimmer.component.d.ts +38 -0
  161. package/lib/sidebar.component.d.ts +2 -0
  162. package/lib/sources.component.d.ts +156 -0
  163. package/lib/spinner.component.d.ts +29 -0
  164. package/lib/suggestion.component.d.ts +96 -0
  165. package/lib/table.component.d.ts +106 -0
  166. package/lib/task.component.d.ts +151 -0
  167. package/lib/theme.service.d.ts +9 -0
  168. package/lib/time-picker.component.d.ts +243 -0
  169. package/lib/toast.service.d.ts +3 -1
  170. package/lib/toaster.component.d.ts +26 -9
  171. package/lib/tool.component.d.ts +158 -0
  172. package/lib/typography.component.d.ts +32 -0
  173. package/lib/utils/color.d.ts +19 -5
  174. package/package.json +1 -1
  175. package/public-api.d.ts +50 -0
  176. package/registry/docs-content.json +8480 -1542
  177. package/registry/llms-full.txt +2679 -319
  178. package/registry/llms.txt +43 -4
  179. package/registry/manifest.json +9090 -1742
  180. package/registry/r/accordion-item.json +1 -1
  181. package/registry/r/accordion.json +1 -1
  182. package/registry/r/alert-dialog-dynamic.json +1 -1
  183. package/registry/r/alert-dialog.json +1 -1
  184. package/registry/r/alert.json +1 -1
  185. package/registry/r/attachment.json +23 -0
  186. package/registry/r/avatar-fallback.json +1 -1
  187. package/registry/r/avatar.json +1 -1
  188. package/registry/r/badge.json +1 -1
  189. package/registry/r/breadcrumb-item.json +1 -1
  190. package/registry/r/breadcrumb-link.json +1 -1
  191. package/registry/r/breadcrumb-separator.json +1 -1
  192. package/registry/r/breadcrumb.json +1 -1
  193. package/registry/r/bubble.json +23 -0
  194. package/registry/r/button.json +1 -1
  195. package/registry/r/calendar.json +1 -1
  196. package/registry/r/card.json +1 -1
  197. package/registry/r/carousel.json +1 -1
  198. package/registry/r/chain-of-thought.json +23 -0
  199. package/registry/r/chart-pie.json +30 -0
  200. package/registry/r/chart.json +28 -0
  201. package/registry/r/checkbox.json +1 -1
  202. package/registry/r/checkpoint.json +23 -0
  203. package/registry/r/collapsible.json +1 -1
  204. package/registry/r/combobox.json +31 -0
  205. package/registry/r/command-dialog.json +21 -0
  206. package/registry/r/command.json +26 -0
  207. package/registry/r/confirmation.json +23 -0
  208. package/registry/r/context.json +26 -0
  209. package/registry/r/conversation.json +23 -0
  210. package/registry/r/country-selector.json +1 -1
  211. package/registry/r/data-table.json +1 -1
  212. package/registry/r/date-picker.json +4 -4
  213. package/registry/r/date-range-picker.json +3 -3
  214. package/registry/r/date-time-picker.json +28 -0
  215. package/registry/r/direction.json +16 -0
  216. package/registry/r/dropdown-item.json +1 -1
  217. package/registry/r/dropdown-label.json +1 -1
  218. package/registry/r/dropdown-menu.json +1 -1
  219. package/registry/r/dropdown-separator.json +1 -1
  220. package/registry/r/dropdown-trigger.json +1 -1
  221. package/registry/r/empty-state.json +1 -1
  222. package/registry/r/field.json +23 -0
  223. package/registry/r/hover-card.json +1 -1
  224. package/registry/r/inline-citation.json +26 -0
  225. package/registry/r/input-group.json +23 -0
  226. package/registry/r/input.json +1 -1
  227. package/registry/r/item.json +23 -0
  228. package/registry/r/kbd.json +23 -0
  229. package/registry/r/label.json +1 -1
  230. package/registry/r/marker.json +23 -0
  231. package/registry/r/masked-input.json +1 -1
  232. package/registry/r/menubar.json +24 -0
  233. package/registry/r/message-scroller.json +26 -0
  234. package/registry/r/message.json +23 -0
  235. package/registry/r/model-selector.json +32 -0
  236. package/registry/r/multi-select.json +2 -2
  237. package/registry/r/native-select.json +23 -0
  238. package/registry/r/navigation-menu.json +24 -0
  239. package/registry/r/otp-group.json +1 -1
  240. package/registry/r/otp-slot.json +1 -1
  241. package/registry/r/otp.json +1 -1
  242. package/registry/r/pagination.json +3 -2
  243. package/registry/r/plan.json +23 -0
  244. package/registry/r/popover-content.json +1 -1
  245. package/registry/r/popover.json +1 -1
  246. package/registry/r/progress.json +1 -1
  247. package/registry/r/prompt-input.json +23 -0
  248. package/registry/r/queue.json +23 -0
  249. package/registry/r/radio-group.json +1 -1
  250. package/registry/r/radio-item.json +1 -1
  251. package/registry/r/range-calendar.json +1 -1
  252. package/registry/r/reasoning.json +23 -0
  253. package/registry/r/segment.json +1 -1
  254. package/registry/r/select-group.json +1 -1
  255. package/registry/r/select-item.json +1 -1
  256. package/registry/r/select-separator.json +1 -1
  257. package/registry/r/select.json +4 -3
  258. package/registry/r/separator.json +1 -1
  259. package/registry/r/sheet.json +1 -1
  260. package/registry/r/shimmer.json +23 -0
  261. package/registry/r/sidebar.json +1 -1
  262. package/registry/r/skeleton.json +1 -1
  263. package/registry/r/sources.json +23 -0
  264. package/registry/r/spinner.json +23 -0
  265. package/registry/r/suggestion.json +23 -0
  266. package/registry/r/switch.json +1 -1
  267. package/registry/r/table.json +21 -0
  268. package/registry/r/tabs.json +1 -1
  269. package/registry/r/tag-input.json +1 -1
  270. package/registry/r/task.json +23 -0
  271. package/registry/r/textarea.json +1 -1
  272. package/registry/r/time-picker.json +24 -0
  273. package/registry/r/toaster.json +2 -2
  274. package/registry/r/toggle-group.json +1 -1
  275. package/registry/r/toggle.json +1 -1
  276. package/registry/r/tool.json +23 -0
  277. package/registry/r/typography.json +23 -0
  278. package/registry/registry.json +915 -22
  279. package/theme.css +109 -8
@@ -0,0 +1,514 @@
1
+ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef, inject } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { Subscription } from 'rxjs';
4
+ import { cn } from './utils/cn';
5
+ import { CommandService } from './command.service';
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "@angular/common";
8
+ let commandItemId = 0;
9
+ /**
10
+ * A filterable command menu — the list half of a command palette (⌘K),
11
+ * a searchable dropdown, or an inline action list.
12
+ *
13
+ * Compose it from `tolle-command-input`, `tolle-command-list`,
14
+ * `tolle-command-group`, `tolle-command-item` and `tolle-command-empty`.
15
+ * Filtering, keyboard navigation and `aria-activedescendant` are handled for
16
+ * you by the `CommandService` this component provides.
17
+ *
18
+ * For the ⌘K modal version use `tolle-command-dialog`; for a form control use
19
+ * `tolle-combobox`.
20
+ * @new
21
+ */
22
+ export class CommandComponent {
23
+ /**
24
+ * Set false to keep every item visible and filter the list yourself —
25
+ * for server-side or fuzzy search. @default true
26
+ */
27
+ shouldFilter = true;
28
+ /** Accessible name for the command menu. @default '' */
29
+ ariaLabel = '';
30
+ /** Extra Tailwind classes merged onto the menu via `cn()` (last-wins). */
31
+ class = '';
32
+ /** Emitted with the chosen item's `value` when the user selects one. */
33
+ selected = new EventEmitter();
34
+ /** Emitted with the query text whenever the search input changes. */
35
+ queryChange = new EventEmitter();
36
+ service = inject(CommandService);
37
+ subscriptions = new Subscription();
38
+ ngOnInit() {
39
+ this.service.shouldFilter = this.shouldFilter;
40
+ this.subscriptions.add(this.service.selected$.subscribe((value) => this.selected.emit(value)));
41
+ this.subscriptions.add(this.service.query$.subscribe((query) => this.queryChange.emit(query)));
42
+ }
43
+ ngOnChanges() {
44
+ this.service.shouldFilter = this.shouldFilter;
45
+ }
46
+ ngOnDestroy() {
47
+ this.subscriptions.unsubscribe();
48
+ }
49
+ get computedClass() {
50
+ return cn('flex w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground', this.class);
51
+ }
52
+ /**
53
+ * Menu-level keyboard handling, so the arrows work whether focus is in the
54
+ * search input or on the menu itself.
55
+ */
56
+ onKeyDown(event) {
57
+ switch (event.key) {
58
+ case 'ArrowDown':
59
+ event.preventDefault();
60
+ this.service.move(1);
61
+ break;
62
+ case 'ArrowUp':
63
+ event.preventDefault();
64
+ this.service.move(-1);
65
+ break;
66
+ case 'Home':
67
+ event.preventDefault();
68
+ this.service.setActive(this.service.visibleIds[0] ?? null);
69
+ break;
70
+ case 'End':
71
+ event.preventDefault();
72
+ this.service.setActive(this.service.visibleIds[this.service.visibleIds.length - 1] ?? null);
73
+ break;
74
+ case 'Enter':
75
+ event.preventDefault();
76
+ this.service.selectActive();
77
+ break;
78
+ }
79
+ }
80
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
81
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: CommandComponent, isStandalone: true, selector: "tolle-command", inputs: { shouldFilter: "shouldFilter", ariaLabel: "ariaLabel", class: "class" }, outputs: { selected: "selected", queryChange: "queryChange" }, providers: [CommandService], usesOnChanges: true, ngImport: i0, template: `
82
+ <div
83
+ role="combobox"
84
+ aria-haspopup="listbox"
85
+ aria-expanded="true"
86
+ [attr.aria-label]="ariaLabel || null"
87
+ [class]="computedClass"
88
+ (keydown)="onKeyDown($event)"
89
+ >
90
+ <ng-content></ng-content>
91
+ </div>
92
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
93
+ }
94
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandComponent, decorators: [{
95
+ type: Component,
96
+ args: [{ selector: 'tolle-command', standalone: true, imports: [CommonModule], providers: [CommandService], template: `
97
+ <div
98
+ role="combobox"
99
+ aria-haspopup="listbox"
100
+ aria-expanded="true"
101
+ [attr.aria-label]="ariaLabel || null"
102
+ [class]="computedClass"
103
+ (keydown)="onKeyDown($event)"
104
+ >
105
+ <ng-content></ng-content>
106
+ </div>
107
+ `, styles: [":host{display:block}\n"] }]
108
+ }], propDecorators: { shouldFilter: [{
109
+ type: Input
110
+ }], ariaLabel: [{
111
+ type: Input
112
+ }], class: [{
113
+ type: Input
114
+ }], selected: [{
115
+ type: Output
116
+ }], queryChange: [{
117
+ type: Output
118
+ }] } });
119
+ /** Search box for a `tolle-command`. Typing here drives the filtering. */
120
+ export class CommandInputComponent {
121
+ /** Placeholder shown when the query is empty. @default 'Type a command or search…' */
122
+ placeholder = 'Type a command or search…';
123
+ /** Accessible name for the search box. @default '' */
124
+ ariaLabel = '';
125
+ /** Extra Tailwind classes merged onto the search row via `cn()` (last-wins). */
126
+ class = '';
127
+ /** Extra Tailwind classes merged onto the `<input>` itself via `cn()` (last-wins). */
128
+ inputClass = '';
129
+ service = inject(CommandService);
130
+ subscriptions = new Subscription();
131
+ cdr = inject(ChangeDetectorRef);
132
+ value = '';
133
+ activeId = null;
134
+ cn = cn;
135
+ ngOnInit() {
136
+ this.subscriptions.add(this.service.activeId$.subscribe((id) => {
137
+ this.activeId = id;
138
+ this.cdr.markForCheck();
139
+ }));
140
+ // The dialog clears the query when it reopens; mirror that back into the box.
141
+ this.subscriptions.add(this.service.query$.subscribe((query) => {
142
+ if (query !== this.value) {
143
+ this.value = query;
144
+ this.cdr.markForCheck();
145
+ }
146
+ }));
147
+ }
148
+ ngOnDestroy() {
149
+ this.subscriptions.unsubscribe();
150
+ }
151
+ onInput(event) {
152
+ const next = event.target.value;
153
+ this.value = next;
154
+ this.service.setQuery(next);
155
+ }
156
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
157
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: CommandInputComponent, isStandalone: true, selector: "tolle-command-input", inputs: { placeholder: "placeholder", ariaLabel: "ariaLabel", class: "class", inputClass: "inputClass" }, ngImport: i0, template: `
158
+ <div [class]="cn('flex items-center gap-2 border-b border-border px-3', class)">
159
+ <i class="ri-search-line shrink-0 text-muted-foreground" aria-hidden="true"></i>
160
+ <input
161
+ [attr.placeholder]="placeholder"
162
+ [attr.aria-activedescendant]="activeId"
163
+ [attr.aria-label]="ariaLabel || placeholder || 'Search'"
164
+ aria-autocomplete="list"
165
+ autocomplete="off"
166
+ spellcheck="false"
167
+ [value]="value"
168
+ [class]="cn(
169
+ 'h-11 w-full bg-transparent py-3 text-sm text-foreground outline-none',
170
+ 'placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50',
171
+ inputClass
172
+ )"
173
+ (input)="onInput($event)"
174
+ />
175
+ </div>
176
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
177
+ }
178
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandInputComponent, decorators: [{
179
+ type: Component,
180
+ args: [{ selector: 'tolle-command-input', standalone: true, imports: [CommonModule], template: `
181
+ <div [class]="cn('flex items-center gap-2 border-b border-border px-3', class)">
182
+ <i class="ri-search-line shrink-0 text-muted-foreground" aria-hidden="true"></i>
183
+ <input
184
+ [attr.placeholder]="placeholder"
185
+ [attr.aria-activedescendant]="activeId"
186
+ [attr.aria-label]="ariaLabel || placeholder || 'Search'"
187
+ aria-autocomplete="list"
188
+ autocomplete="off"
189
+ spellcheck="false"
190
+ [value]="value"
191
+ [class]="cn(
192
+ 'h-11 w-full bg-transparent py-3 text-sm text-foreground outline-none',
193
+ 'placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50',
194
+ inputClass
195
+ )"
196
+ (input)="onInput($event)"
197
+ />
198
+ </div>
199
+ `, styles: [":host{display:block}\n"] }]
200
+ }], propDecorators: { placeholder: [{
201
+ type: Input
202
+ }], ariaLabel: [{
203
+ type: Input
204
+ }], class: [{
205
+ type: Input
206
+ }], inputClass: [{
207
+ type: Input
208
+ }] } });
209
+ /** Scrolling container for the command items. */
210
+ export class CommandListComponent {
211
+ cdr = inject(ChangeDetectorRef);
212
+ /**
213
+ * Angular writes a bound `class` input through its styling path, which does
214
+ * not mark an OnPush component dirty — without this hook the component keeps
215
+ * rendering the class it was born with.
216
+ */
217
+ ngOnChanges() {
218
+ this.cdr.markForCheck();
219
+ }
220
+ /** Accessible name for the list. @default '' */
221
+ ariaLabel = '';
222
+ /** Extra Tailwind classes merged onto the list via `cn()` (last-wins). */
223
+ class = '';
224
+ cn = cn;
225
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
226
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: CommandListComponent, isStandalone: true, selector: "tolle-command-list", inputs: { ariaLabel: "ariaLabel", class: "class" }, usesOnChanges: true, ngImport: i0, template: `
227
+ <div role="listbox" [attr.aria-label]="ariaLabel || null" [class]="cn('max-h-80 overflow-y-auto overflow-x-hidden p-1', class)">
228
+ <ng-content></ng-content>
229
+ </div>
230
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
231
+ }
232
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandListComponent, decorators: [{
233
+ type: Component,
234
+ args: [{ selector: 'tolle-command-list', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
235
+ <div role="listbox" [attr.aria-label]="ariaLabel || null" [class]="cn('max-h-80 overflow-y-auto overflow-x-hidden p-1', class)">
236
+ <ng-content></ng-content>
237
+ </div>
238
+ `, styles: [":host{display:block}\n"] }]
239
+ }], propDecorators: { ariaLabel: [{
240
+ type: Input
241
+ }], class: [{
242
+ type: Input
243
+ }] } });
244
+ /**
245
+ * Shown only when the query matches nothing. Renders nothing otherwise, so it
246
+ * can live in the template permanently.
247
+ */
248
+ export class CommandEmptyComponent {
249
+ /** Extra Tailwind classes merged onto the empty state via `cn()` (last-wins). */
250
+ class = '';
251
+ service = inject(CommandService);
252
+ subscriptions = new Subscription();
253
+ cdr = inject(ChangeDetectorRef);
254
+ isEmpty = false;
255
+ cn = cn;
256
+ ngOnInit() {
257
+ this.subscriptions.add(this.service.visible$.subscribe(() => {
258
+ this.isEmpty = this.service.isEmpty;
259
+ this.cdr.markForCheck();
260
+ }));
261
+ }
262
+ ngOnDestroy() {
263
+ this.subscriptions.unsubscribe();
264
+ }
265
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandEmptyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
266
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: CommandEmptyComponent, isStandalone: true, selector: "tolle-command-empty", inputs: { class: "class" }, ngImport: i0, template: `
267
+ <div *ngIf="isEmpty" role="status" [class]="cn('py-6 text-center text-sm text-muted-foreground', class)">
268
+ <ng-content></ng-content>
269
+ </div>
270
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
271
+ }
272
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandEmptyComponent, decorators: [{
273
+ type: Component,
274
+ args: [{ selector: 'tolle-command-empty', standalone: true, imports: [CommonModule], template: `
275
+ <div *ngIf="isEmpty" role="status" [class]="cn('py-6 text-center text-sm text-muted-foreground', class)">
276
+ <ng-content></ng-content>
277
+ </div>
278
+ `, styles: [":host{display:block}\n"] }]
279
+ }], propDecorators: { class: [{
280
+ type: Input
281
+ }] } });
282
+ /**
283
+ * A labelled section of items. The heading hides itself when filtering removes
284
+ * every item in the group, so you never get a stranded header.
285
+ */
286
+ export class CommandGroupComponent {
287
+ /** Section heading. @default '' */
288
+ heading = '';
289
+ /** Extra Tailwind classes merged onto the group via `cn()` (last-wins). */
290
+ class = '';
291
+ service = inject(CommandService);
292
+ subscriptions = new Subscription();
293
+ cdr = inject(ChangeDetectorRef);
294
+ memberIds = new Set();
295
+ hidden = false;
296
+ cn = cn;
297
+ ngOnInit() {
298
+ this.subscriptions.add(this.service.visible$.subscribe((visible) => {
299
+ // Hide the heading once none of this group's items survive the filter.
300
+ this.hidden = this.memberIds.size > 0 && !visible.some((id) => this.memberIds.has(id));
301
+ this.cdr.markForCheck();
302
+ }));
303
+ }
304
+ ngOnDestroy() {
305
+ this.subscriptions.unsubscribe();
306
+ }
307
+ /** Called by child items so the group knows which ids belong to it. */
308
+ addMember(id) {
309
+ this.memberIds.add(id);
310
+ }
311
+ removeMember(id) {
312
+ this.memberIds.delete(id);
313
+ }
314
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
315
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: CommandGroupComponent, isStandalone: true, selector: "tolle-command-group", inputs: { heading: "heading", class: "class" }, ngImport: i0, template: `
316
+ <div role="group" [attr.aria-label]="heading || null" [class]="cn('overflow-hidden p-1 text-foreground', class)">
317
+ <div
318
+ *ngIf="heading"
319
+ [class]="cn('px-2 py-1.5 text-xs font-medium text-muted-foreground', hidden && 'hidden')"
320
+ >
321
+ {{ heading }}
322
+ </div>
323
+ <ng-content></ng-content>
324
+ </div>
325
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
326
+ }
327
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandGroupComponent, decorators: [{
328
+ type: Component,
329
+ args: [{ selector: 'tolle-command-group', standalone: true, imports: [CommonModule], template: `
330
+ <div role="group" [attr.aria-label]="heading || null" [class]="cn('overflow-hidden p-1 text-foreground', class)">
331
+ <div
332
+ *ngIf="heading"
333
+ [class]="cn('px-2 py-1.5 text-xs font-medium text-muted-foreground', hidden && 'hidden')"
334
+ >
335
+ {{ heading }}
336
+ </div>
337
+ <ng-content></ng-content>
338
+ </div>
339
+ `, styles: [":host{display:block}\n"] }]
340
+ }], propDecorators: { heading: [{
341
+ type: Input
342
+ }], class: [{
343
+ type: Input
344
+ }] } });
345
+ /** A selectable row in a command menu. */
346
+ export class CommandItemComponent {
347
+ /** Value emitted from the menu's `selected` output when this row is chosen. */
348
+ value = null;
349
+ /**
350
+ * Text matched against the query. Defaults to `value` when omitted — set it
351
+ * explicitly whenever the row's visible text differs from its value.
352
+ * @default ''
353
+ */
354
+ label = '';
355
+ /** Extra terms that should also match this row, e.g. synonyms. @default [] */
356
+ keywords = [];
357
+ /** Makes the row unselectable and skipped by the arrow keys. @default false */
358
+ disabled = false;
359
+ /** Extra Tailwind classes merged onto the row via `cn()` (last-wins). */
360
+ class = '';
361
+ /** Emitted when this specific row is chosen. */
362
+ selected = new EventEmitter();
363
+ service = inject(CommandService);
364
+ group = inject(CommandGroupComponent, { optional: true });
365
+ subscriptions = new Subscription();
366
+ cdr = inject(ChangeDetectorRef);
367
+ id = `command-item-${commandItemId++}`;
368
+ visible = true;
369
+ active = false;
370
+ ngOnInit() {
371
+ this.service.register({
372
+ id: this.id,
373
+ searchText: this.searchText,
374
+ value: this.value,
375
+ disabled: this.disabled,
376
+ });
377
+ this.group?.addMember(this.id);
378
+ this.subscriptions.add(this.service.visible$.subscribe((ids) => {
379
+ this.visible = ids.includes(this.id);
380
+ this.cdr.markForCheck();
381
+ }));
382
+ this.subscriptions.add(this.service.activeId$.subscribe((activeId) => {
383
+ this.active = activeId === this.id;
384
+ this.cdr.markForCheck();
385
+ }));
386
+ this.subscriptions.add(this.service.selected$.subscribe((value) => {
387
+ if (value === this.value)
388
+ this.selected.emit(value);
389
+ }));
390
+ }
391
+ ngOnChanges() {
392
+ this.service.update(this.id, {
393
+ searchText: this.searchText,
394
+ value: this.value,
395
+ disabled: this.disabled,
396
+ });
397
+ }
398
+ ngOnDestroy() {
399
+ this.group?.removeMember(this.id);
400
+ this.service.unregister(this.id);
401
+ this.subscriptions.unsubscribe();
402
+ }
403
+ /** Label plus keywords, so synonyms match without being displayed. */
404
+ get searchText() {
405
+ const base = this.label || (this.value != null ? String(this.value) : '');
406
+ return [base, ...this.keywords].join(' ');
407
+ }
408
+ get computedClass() {
409
+ return cn('relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors', this.active && !this.disabled && 'bg-accent text-accent-foreground', this.disabled && 'pointer-events-none opacity-50', this.class);
410
+ }
411
+ onClick() {
412
+ if (this.disabled)
413
+ return;
414
+ this.service.selectById(this.id);
415
+ }
416
+ onMouseEnter() {
417
+ if (this.disabled)
418
+ return;
419
+ this.service.setActive(this.id);
420
+ }
421
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
422
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: CommandItemComponent, isStandalone: true, selector: "tolle-command-item", inputs: { value: "value", label: "label", keywords: "keywords", disabled: "disabled", class: "class" }, outputs: { selected: "selected" }, usesOnChanges: true, ngImport: i0, template: `
423
+ <div
424
+ *ngIf="visible"
425
+ [id]="id"
426
+ role="option"
427
+ [attr.aria-selected]="active"
428
+ [attr.aria-disabled]="disabled || null"
429
+ [attr.data-active]="active ? '' : null"
430
+ [class]="computedClass"
431
+ (click)="onClick()"
432
+ (mouseenter)="onMouseEnter()"
433
+ >
434
+ <ng-content></ng-content>
435
+ </div>
436
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
437
+ }
438
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandItemComponent, decorators: [{
439
+ type: Component,
440
+ args: [{ selector: 'tolle-command-item', standalone: true, imports: [CommonModule], template: `
441
+ <div
442
+ *ngIf="visible"
443
+ [id]="id"
444
+ role="option"
445
+ [attr.aria-selected]="active"
446
+ [attr.aria-disabled]="disabled || null"
447
+ [attr.data-active]="active ? '' : null"
448
+ [class]="computedClass"
449
+ (click)="onClick()"
450
+ (mouseenter)="onMouseEnter()"
451
+ >
452
+ <ng-content></ng-content>
453
+ </div>
454
+ `, styles: [":host{display:block}\n"] }]
455
+ }], propDecorators: { value: [{
456
+ type: Input
457
+ }], label: [{
458
+ type: Input
459
+ }], keywords: [{
460
+ type: Input
461
+ }], disabled: [{
462
+ type: Input
463
+ }], class: [{
464
+ type: Input
465
+ }], selected: [{
466
+ type: Output
467
+ }] } });
468
+ /** Divider between command groups. */
469
+ export class CommandSeparatorComponent {
470
+ cdr = inject(ChangeDetectorRef);
471
+ /**
472
+ * Angular writes a bound `class` input through its styling path, which does
473
+ * not mark an OnPush component dirty — without this hook the component keeps
474
+ * rendering the class it was born with.
475
+ */
476
+ ngOnChanges() {
477
+ this.cdr.markForCheck();
478
+ }
479
+ /** Extra Tailwind classes merged onto the separator via `cn()` (last-wins). */
480
+ class = '';
481
+ cn = cn;
482
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandSeparatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
483
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: CommandSeparatorComponent, isStandalone: true, selector: "tolle-command-separator", inputs: { class: "class" }, usesOnChanges: true, ngImport: i0, template: `<div role="separator" [class]="cn('-mx-1 h-px bg-border', class)"></div>`, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
484
+ }
485
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandSeparatorComponent, decorators: [{
486
+ type: Component,
487
+ args: [{ selector: 'tolle-command-separator', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `<div role="separator" [class]="cn('-mx-1 h-px bg-border', class)"></div>`, styles: [":host{display:block}\n"] }]
488
+ }], propDecorators: { class: [{
489
+ type: Input
490
+ }] } });
491
+ /** Right-aligned shortcut hint inside a command item. Pairs with `tolle-kbd`. */
492
+ export class CommandShortcutComponent {
493
+ cdr = inject(ChangeDetectorRef);
494
+ /**
495
+ * Angular writes a bound `class` input through its styling path, which does
496
+ * not mark an OnPush component dirty — without this hook the component keeps
497
+ * rendering the class it was born with.
498
+ */
499
+ ngOnChanges() {
500
+ this.cdr.markForCheck();
501
+ }
502
+ /** Extra Tailwind classes merged onto the shortcut via `cn()` (last-wins). */
503
+ class = '';
504
+ cn = cn;
505
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandShortcutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
506
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: CommandShortcutComponent, isStandalone: true, selector: "tolle-command-shortcut", inputs: { class: "class" }, usesOnChanges: true, ngImport: i0, template: `<span [class]="cn('ml-auto flex items-center gap-1 text-xs tracking-widest text-muted-foreground', class)"><ng-content></ng-content></span>`, isInline: true, styles: [":host{display:inline-flex}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
507
+ }
508
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommandShortcutComponent, decorators: [{
509
+ type: Component,
510
+ args: [{ selector: 'tolle-command-shortcut', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `<span [class]="cn('ml-auto flex items-center gap-1 text-xs tracking-widest text-muted-foreground', class)"><ng-content></ng-content></span>`, styles: [":host{display:inline-flex}\n"] }]
511
+ }], propDecorators: { class: [{
512
+ type: Input
513
+ }] } });
514
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWFuZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy90b2xsZS9zcmMvbGliL2NvbW1hbmQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQWdDLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6SixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNwQyxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ2hDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQzs7O0FBRW5ELElBQUksYUFBYSxHQUFHLENBQUMsQ0FBQztBQUV0Qjs7Ozs7Ozs7Ozs7O0dBWUc7QUFvQkgsTUFBTSxPQUFPLGdCQUFnQjtJQUMzQjs7O09BR0c7SUFDTSxZQUFZLEdBQUcsSUFBSSxDQUFDO0lBQzdCLHdEQUF3RDtJQUMvQyxTQUFTLEdBQUcsRUFBRSxDQUFDO0lBQ3hCLDBFQUEwRTtJQUNqRSxLQUFLLEdBQUcsRUFBRSxDQUFDO0lBRXBCLHdFQUF3RTtJQUM5RCxRQUFRLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztJQUM3QyxxRUFBcUU7SUFDM0QsV0FBVyxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7SUFFbEMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUNqQyxhQUFhLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUVwRCxRQUFRO1FBQ04sSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUM5QyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJ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QUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUVqRDs7OztPQUlHO0lBQ0gsV0FBVztRQUNULElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVELCtFQUErRTtJQUN0RSxLQUFLLEdBQUcsRUFBRSxDQUFDO0lBQ1YsRUFBRSxHQUFHLEVBQUUsQ0FBQzt3R0FkUCx5QkFBeUI7NEZBQXpCLHlCQUF5QixvSUFGMUIsMEVBQTBFLCtGQUYxRSxZQUFZOzs0RkFJWCx5QkFBeUI7a0JBUnJDLFNBQVM7K0JBQ0UseUJBQXlCLGNBRXZCLElBQUksV0FDUCxDQUFDLFlBQVksQ0FBQyxtQkFDTix1QkFBdUIsQ0FBQyxNQUFNLFlBQ3JDLDBFQUEwRTs4QkFlM0UsS0FBSztzQkFBYixLQUFLOztBQUlSLGlGQUFpRjtBQVNqRixNQUFNLE9BQU8sd0JBQXdCO0lBQ2xCLEdBQUcsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUVqRDs7OztPQUlHO0lBQ0gsV0FBVztRQUNULElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVELDhFQUE4RTtJQUNyRSxLQUFLLEdBQUcsRUFBRSxDQUFDO0lBQ1YsRUFBRSxHQUFHLEVBQUUsQ0FBQzt3R0FkUCx3QkFBd0I7NEZBQXhCLHdCQUF3QixtSUFGekIsNklBQTZJLHFHQUY3SSxZQUFZOzs0RkFJWCx3QkFBd0I7a0JBUnBDLFNBQVM7K0JBQ0Usd0JBQXdCLGNBRXRCLElBQUksV0FDUCxDQUFDLFlBQVksQ0FBQyxtQkFDTix1QkFBdUIsQ0FBQyxNQUFNLFlBQ3JDLDZJQUE2STs4QkFlOUksS0FBSztzQkFBYixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjbiB9IGZyb20gJy4vdXRpbHMvY24nO1xuaW1wb3J0IHsgQ29tbWFuZFNlcnZpY2UgfSBmcm9tICcuL2NvbW1hbmQuc2VydmljZSc7XG5cbmxldCBjb21tYW5kSXRlbUlkID0gMDtcblxuLyoqXG4gKiBBIGZpbHRlcmFibGUgY29tbWFuZCBtZW51IOKAlCB0aGUgbGlzdCBoYWxmIG9mIGEgY29tbWFuZCBwYWxldHRlICjijJhLKSxcbiAqIGEgc2VhcmNoYWJsZSBkcm9wZG93biwgb3IgYW4gaW5saW5lIGFjdGlvbiBsaXN0LlxuICpcbiAqIENvbXBvc2UgaXQgZnJvbSBgdG9sbGUtY29tbWFuZC1pbnB1dGAsIGB0b2xsZS1jb21tYW5kLWxpc3RgLFxuICogYHRvbGxlLWNvbW1hbmQtZ3JvdXBgLCBgdG9sbGUtY29tbWFuZC1pdGVtYCBhbmQgYHRvbGxlLWNvbW1hbmQtZW1wdHlgLlxuICogRmlsdGVyaW5nLCBrZXlib2FyZCBuYXZpZ2F0aW9uIGFuZCBgYXJpYS1hY3RpdmVkZXNjZW5kYW50YCBhcmUgaGFuZGxlZCBmb3JcbiAqIHlvdSBieSB0aGUgYENvbW1hbmRTZXJ2aWNlYCB0aGlzIGNvbXBvbmVudCBwcm92aWRlcy5cbiAqXG4gKiBGb3IgdGhlIOKMmEsgbW9kYWwgdmVyc2lvbiB1c2UgYHRvbGxlLWNvbW1hbmQtZGlhbG9nYDsgZm9yIGEgZm9ybSBjb250cm9sIHVzZVxuICogYHRvbGxlLWNvbWJvYm94YC5cbiAqIEBuZXdcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtY29tbWFuZCcsXG4gIHN0eWxlczogWyc6aG9zdCB7IGRpc3BsYXk6IGJsb2NrOyB9J10sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICBwcm92aWRlcnM6IFtDb21tYW5kU2VydmljZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdlxuICAgICAgcm9sZT1cImNvbWJvYm94XCJcbiAgICAgIGFyaWEtaGFzcG9wdXA9XCJsaXN0Ym94XCJcbiAgICAgIGFyaWEtZXhwYW5kZWQ9XCJ0cnVlXCJcbiAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiYXJpYUxhYmVsIHx8IG51bGxcIlxuICAgICAgW2NsYXNzXT1cImNvbXB1dGVkQ2xhc3NcIlxuICAgICAgKGtleWRvd24pPVwib25LZXlEb3duKCRldmVudClcIlxuICAgID5cbiAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICA8L2Rpdj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgQ29tbWFuZENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICAvKipcbiAgICogU2V0IGZhbHNlIHRvIGtlZXAgZXZlcnkgaXRlbSB2aXNpYmxlIGFuZCBmaWx0ZXIgdGhlIGxpc3QgeW91cnNlbGYg4oCUXG4gICAqIGZvciBzZXJ2ZXItc2lkZSBvciBmdXp6eSBzZWFyY2guIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIEBJbnB1dCgpIHNob3VsZEZpbHRlciA9IHRydWU7XG4gIC8qKiBBY2Nlc3NpYmxlIG5hbWUgZm9yIHRoZSBjb21tYW5kIG1lbnUuIEBkZWZhdWx0ICcnICovXG4gIEBJbnB1dCgpIGFyaWFMYWJlbCA9ICcnO1xuICAvKiogRXh0cmEgVGFpbHdpbmQgY2xhc3NlcyBtZXJnZWQgb250byB0aGUgbWVudSB2aWEgYGNuKClgIChsYXN0LXdpbnMpLiAqL1xuICBASW5wdXQoKSBjbGFzcyA9ICcnO1xuXG4gIC8qKiBFbWl0dGVkIHdpdGggdGhlIGNob3NlbiBpdGVtJ3MgYHZhbHVlYCB3aGVuIHRoZSB1c2VyIHNlbGVjdHMgb25lLiAqL1xuICBAT3V0cHV0KCkgc2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgLyoqIEVtaXR0ZWQgd2l0aCB0aGUgcXVlcnkgdGV4dCB3aGVuZXZlciB0aGUgc2VhcmNoIGlucHV0IGNoYW5nZXMuICovXG4gIEBPdXRwdXQoKSBxdWVyeUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgc2VydmljZSA9IGluamVjdChDb21tYW5kU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3Vic2NyaXB0aW9ucyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnNlcnZpY2Uuc2hvdWxkRmlsdGVyID0gdGhpcy5zaG91bGRGaWx0ZXI7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZCh0aGlzLnNlcnZpY2Uuc2VsZWN0ZWQkLnN1YnNjcmliZSgodmFsdWUpID0+IHRoaXMuc2VsZWN0ZWQuZW1pdCh2YWx1ZSkpKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKHRoaXMuc2VydmljZS5xdWVyeSQuc3Vic2NyaWJlKChxdWVyeSkgPT4gdGhpcy5xdWVyeUNoYW5nZS5lbWl0KHF1ZXJ5KSkpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5zZXJ2aWNlLnNob3VsZEZpbHRlciA9IHRoaXMuc2hvdWxkRmlsdGVyO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBnZXQgY29tcHV0ZWRDbGFzcygpIHtcbiAgICByZXR1cm4gY24oJ2ZsZXggdy1mdWxsIGZsZXgtY29sIG92ZXJmbG93LWhpZGRlbiByb3VuZGVkLW1kIGJnLXBvcG92ZXIgdGV4dC1wb3BvdmVyLWZvcmVncm91bmQnLCB0aGlzLmNsYXNzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZW51LWxldmVsIGtleWJvYXJkIGhhbmRsaW5nLCBzbyB0aGUgYXJyb3dzIHdvcmsgd2hldGhlciBmb2N1cyBpcyBpbiB0aGVcbiAgICogc2VhcmNoIGlucHV0IG9yIG9uIHRoZSBtZW51IGl0c2VsZi5cbiAgICovXG4gIG9uS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIHN3aXRjaCAoZXZlbnQua2V5KSB7XG4gICAgICBjYXNlICdBcnJvd0Rvd24nOlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnNlcnZpY2UubW92ZSgxKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdBcnJvd1VwJzpcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5zZXJ2aWNlLm1vdmUoLTEpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0hvbWUnOlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnNlcnZpY2Uuc2V0QWN0aXZlKHRoaXMuc2VydmljZS52aXNpYmxlSWRzWzBdID8/IG51bGwpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0VuZCc6XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuc2VydmljZS5zZXRBY3RpdmUodGhpcy5zZXJ2aWNlLnZpc2libGVJZHNbdGhpcy5zZXJ2aWNlLnZpc2libGVJZHMubGVuZ3RoIC0gMV0gPz8gbnVsbCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnRW50ZXInOlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnNlcnZpY2Uuc2VsZWN0QWN0aXZlKCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufVxuXG4vKiogU2VhcmNoIGJveCBmb3IgYSBgdG9sbGUtY29tbWFuZGAuIFR5cGluZyBoZXJlIGRyaXZlcyB0aGUgZmlsdGVyaW5nLiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtY29tbWFuZC1pbnB1dCcsXG4gIHN0eWxlczogWyc6aG9zdCB7IGRpc3BsYXk6IGJsb2NrOyB9J10sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgW2NsYXNzXT1cImNuKCdmbGV4IGl0ZW1zLWNlbnRlciBnYXAtMiBib3JkZXItYiBib3JkZXItYm9yZGVyIHB4LTMnLCBjbGFzcylcIj5cbiAgICAgIDxpIGNsYXNzPVwicmktc2VhcmNoLWxpbmUgc2hyaW5rLTAgdGV4dC1tdXRlZC1mb3JlZ3JvdW5kXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgPGlucHV0XG4gICAgICAgIFthdHRyLnBsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAgICAgW2F0dHIuYXJpYS1hY3RpdmVkZXNjZW5kYW50XT1cImFjdGl2ZUlkXCJcbiAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJhcmlhTGFiZWwgfHwgcGxhY2Vob2xkZXIgfHwgJ1NlYXJjaCdcIlxuICAgICAgICBhcmlhLWF1dG9jb21wbGV0ZT1cImxpc3RcIlxuICAgICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICBzcGVsbGNoZWNrPVwiZmFsc2VcIlxuICAgICAgICBbdmFsdWVdPVwidmFsdWVcIlxuICAgICAgICBbY2xhc3NdPVwiY24oXG4gICAgICAgICAgJ2gtMTEgdy1mdWxsIGJnLXRyYW5zcGFyZW50IHB5LTMgdGV4dC1zbSB0ZXh0LWZvcmVncm91bmQgb3V0bGluZS1ub25lJyxcbiAgICAgICAgICAncGxhY2Vob2xkZXI6dGV4dC1tdXRlZC1mb3JlZ3JvdW5kIGRpc2FibGVkOmN1cnNvci1ub3QtYWxsb3dlZCBkaXNhYmxlZDpvcGFjaXR5LTUwJyxcbiAgICAgICAgICBpbnB1dENsYXNzXG4gICAgICAgIClcIlxuICAgICAgICAoaW5wdXQpPVwib25JbnB1dCgkZXZlbnQpXCJcbiAgICAgIC8+XG4gICAgPC9kaXY+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIENvbW1hbmRJbnB1dENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgLyoqIFBsYWNlaG9sZGVyIHNob3duIHdoZW4gdGhlIHF1ZXJ5IGlzIGVtcHR5LiBAZGVmYXVsdCAnVHlwZSBhIGNvbW1hbmQgb3Igc2VhcmNo4oCmJyAqL1xuICBASW5wdXQoKSBwbGFjZWhvbGRlciA9ICdUeXBlIGEgY29tbWFuZCBvciBzZWFyY2jigKYnO1xuICAvKiogQWNjZXNzaWJsZSBuYW1lIGZvciB0aGUgc2VhcmNoIGJveC4gQGRlZmF1bHQgJycgKi9cbiAgQElucHV0KCkgYXJpYUxhYmVsID0gJyc7XG4gIC8qKiBFeHRyYSBUYWlsd2luZCBjbGFzc2VzIG1lcmdlZCBvbnRvIHRoZSBzZWFyY2ggcm93IHZpYSBgY24oKWAgKGxhc3Qtd2lucykuICovXG4gIEBJbnB1dCgpIGNsYXNzID0gJyc7XG4gIC8qKiBFeHRyYSBUYWlsd2luZCBjbGFzc2VzIG1lcmdlZCBvbnRvIHRoZSBgPGlucHV0PmAgaXRzZWxmIHZpYSBgY24oKWAgKGxhc3Qtd2lucykuICovXG4gIEBJbnB1dCgpIGlucHV0Q2xhc3MgPSAnJztcblxuICBwcml2YXRlIHJlYWRvbmx5IHNlcnZpY2UgPSBpbmplY3QoQ29tbWFuZFNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IHN1YnNjcmlwdGlvbnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblxuICB2YWx1ZSA9ICcnO1xuICBhY3RpdmVJZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHByb3RlY3RlZCBjbiA9IGNuO1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICB0aGlzLnNlcnZpY2UuYWN0aXZlSWQkLnN1YnNjcmliZSgoaWQpID0+IHtcbiAgICAgICAgdGhpcy5hY3RpdmVJZCA9IGlkO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICAvLyBUaGUgZGlhbG9nIGNsZWFycyB0aGUgcXVlcnkgd2hlbiBpdCByZW9wZW5zOyBtaXJyb3IgdGhhdCBiYWNrIGludG8gdGhlIGJveC5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgdGhpcy5zZXJ2aWNlLnF1ZXJ5JC5zdWJzY3JpYmUoKHF1ZXJ5KSA9PiB7XG4gICAgICAgIGlmIChxdWVyeSAhPT0gdGhpcy52YWx1ZSkge1xuICAgICAgICAgIHRoaXMudmFsdWUgPSBxdWVyeTtcbiAgICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBvbklucHV0KGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IG5leHQgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpLnZhbHVlO1xuICAgIHRoaXMudmFsdWUgPSBuZXh0O1xuICAgIHRoaXMuc2VydmljZS5zZXRRdWVyeShuZXh0KTtcbiAgfVxufVxuXG4vKiogU2Nyb2xsaW5nIGNvbnRhaW5lciBmb3IgdGhlIGNvbW1hbmQgaXRlbXMuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0b2xsZS1jb21tYW5kLWxpc3QnLFxuICBzdHlsZXM6IFsnOmhvc3QgeyBkaXNwbGF5OiBibG9jazsgfSddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiByb2xlPVwibGlzdGJveFwiIFthdHRyLmFyaWEtbGFiZWxdPVwiYXJpYUxhYmVsIHx8IG51bGxcIiBbY2xhc3NdPVwiY24oJ21heC1oLTgwIG92ZXJmbG93LXktYXV0byBvdmVyZmxvdy14LWhpZGRlbiBwLTEnLCBjbGFzcylcIj5cbiAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICA8L2Rpdj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgQ29tbWFuZExpc3RDb21wb25lbnQgIGltcGxlbWVudHMgT25DaGFuZ2Vze1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgLyoqXG4gICAqIEFuZ3VsYXIgd3JpdGVzIGEgYm91bmQgYGNsYXNzYCBpbnB1dCB0aHJvdWdoIGl0cyBzdHlsaW5nIHBhdGgsIHdoaWNoIGRvZXNcbiAgICogbm90IG1hcmsgYW4gT25QdXNoIGNvbXBvbmVudCBkaXJ0eSDigJQgd2l0aG91dCB0aGlzIGhvb2sgdGhlIGNvbXBvbmVudCBrZWVwc1xuICAgKiByZW5kZXJpbmcgdGhlIGNsYXNzIGl0IHdhcyBib3JuIHdpdGguXG4gICAqL1xuICBuZ09uQ2hhbmdlcygpOiB2b2lkIHtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKiBBY2Nlc3NpYmxlIG5hbWUgZm9yIHRoZSBsaXN0LiBAZGVmYXVsdCAnJyAqL1xuICBASW5wdXQoKSBhcmlhTGFiZWwgPSAnJztcbiAgLyoqIEV4dHJhIFRhaWx3aW5kIGNsYXNzZXMgbWVyZ2VkIG9udG8gdGhlIGxpc3QgdmlhIGBjbigpYCAobGFzdC13aW5zKS4gKi9cbiAgQElucHV0KCkgY2xhc3MgPSAnJztcbiAgcHJvdGVjdGVkIGNuID0gY247XG59XG5cbi8qKlxuICogU2hvd24gb25seSB3aGVuIHRoZSBxdWVyeSBtYXRjaGVzIG5vdGhpbmcuIFJlbmRlcnMgbm90aGluZyBvdGhlcndpc2UsIHNvIGl0XG4gKiBjYW4gbGl2ZSBpbiB0aGUgdGVtcGxhdGUgcGVybWFuZW50bHkuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3RvbGxlLWNvbW1hbmQtZW1wdHknLFxuICBzdHlsZXM6IFsnOmhvc3QgeyBkaXNwbGF5OiBibG9jazsgfSddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2ICpuZ0lmPVwiaXNFbXB0eVwiIHJvbGU9XCJzdGF0dXNcIiBbY2xhc3NdPVwiY24oJ3B5LTYgdGV4dC1jZW50ZXIgdGV4dC1zbSB0ZXh0LW11dGVkLWZvcmVncm91bmQnLCBjbGFzcylcIj5cbiAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICA8L2Rpdj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgQ29tbWFuZEVtcHR5Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICAvKiogRXh0cmEgVGFpbHdpbmQgY2xhc3NlcyBtZXJnZWQgb250byB0aGUgZW1wdHkgc3RhdGUgdmlhIGBjbigpYCAobGFzdC13aW5zKS4gKi9cbiAgQElucHV0KCkgY2xhc3MgPSAnJztcblxuICBwcml2YXRlIHJlYWRvbmx5IHNlcnZpY2UgPSBpbmplY3QoQ29tbWFuZFNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IHN1YnNjcmlwdGlvbnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblxuICBpc0VtcHR5ID0gZmFsc2U7XG4gIHByb3RlY3RlZCBjbiA9IGNuO1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICB0aGlzLnNlcnZpY2UudmlzaWJsZSQuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5pc0VtcHR5ID0gdGhpcy5zZXJ2aWNlLmlzRW1wdHk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBIGxhYmVsbGVkIHNlY3Rpb24gb2YgaXRlbXMuIFRoZSBoZWFkaW5nIGhpZGVzIGl0c2VsZiB3aGVuIGZpbHRlcmluZyByZW1vdmVzXG4gKiBldmVyeSBpdGVtIGluIHRoZSBncm91cCwgc28geW91IG5ldmVyIGdldCBhIHN0cmFuZGVkIGhlYWRlci5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtY29tbWFuZC1ncm91cCcsXG4gIHN0eWxlczogWyc6aG9zdCB7IGRpc3BsYXk6IGJsb2NrOyB9J10sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgcm9sZT1cImdyb3VwXCIgW2F0dHIuYXJpYS1sYWJlbF09XCJoZWFkaW5nIHx8IG51bGxcIiBbY2xhc3NdPVwiY24oJ292ZXJmbG93LWhpZGRlbiBwLTEgdGV4dC1mb3JlZ3JvdW5kJywgY2xhc3MpXCI+XG4gICAgICA8ZGl2XG4gICAgICAgICpuZ0lmPVwiaGVhZGluZ1wiXG4gICAgICAgIFtjbGFzc109XCJjbigncHgtMiBweS0xLjUgdGV4dC14cyBmb250LW1lZGl1bSB0ZXh0LW11dGVkLWZvcmVncm91bmQnLCBoaWRkZW4gJiYgJ2hpZGRlbicpXCJcbiAgICAgID5cbiAgICAgICAge3sgaGVhZGluZyB9fVxuICAgICAgPC9kaXY+XG4gICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgPC9kaXY+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIENvbW1hbmRHcm91cENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgLyoqIFNlY3Rpb24gaGVhZGluZy4gQGRlZmF1bHQgJycgKi9cbiAgQElucHV0KCkgaGVhZGluZyA9ICcnO1xuICAvKiogRXh0cmEgVGFpbHdpbmQgY2xhc3NlcyBtZXJnZWQgb250byB0aGUgZ3JvdXAgdmlhIGBjbigpYCAobGFzdC13aW5zKS4gKi9cbiAgQElucHV0KCkgY2xhc3MgPSAnJztcblxuICBwcml2YXRlIHJlYWRvbmx5IHNlcnZpY2UgPSBpbmplY3QoQ29tbWFuZFNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IHN1YnNjcmlwdGlvbnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcbiAgcHJpdmF0ZSByZWFkb25seSBtZW1iZXJJZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICBoaWRkZW4gPSBmYWxzZTtcbiAgcHJvdGVjdGVkIGNuID0gY247XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgIHRoaXMuc2VydmljZS52aXNpYmxlJC5zdWJzY3JpYmUoKHZpc2libGUpID0+IHtcbiAgICAgICAgLy8gSGlkZSB0aGUgaGVhZGluZyBvbmNlIG5vbmUgb2YgdGhpcyBncm91cCdzIGl0ZW1zIHN1cnZpdmUgdGhlIGZpbHRlci5cbiAgICAgICAgdGhpcy5oaWRkZW4gPSB0aGlzLm1lbWJlcklkcy5zaXplID4gMCAmJiAhdmlzaWJsZS5zb21lKChpZCkgPT4gdGhpcy5tZW1iZXJJZHMuaGFzKGlkKSk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICAvKiogQ2FsbGVkIGJ5IGNoaWxkIGl0ZW1zIHNvIHRoZSBncm91cCBrbm93cyB3aGljaCBpZHMgYmVsb25nIHRvIGl0LiAqL1xuICBhZGRNZW1iZXIoaWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMubWVtYmVySWRzLmFkZChpZCk7XG4gIH1cblxuICByZW1vdmVNZW1iZXIoaWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMubWVtYmVySWRzLmRlbGV0ZShpZCk7XG4gIH1cbn1cblxuLyoqIEEgc2VsZWN0YWJsZSByb3cgaW4gYSBjb21tYW5kIG1lbnUuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0b2xsZS1jb21tYW5kLWl0ZW0nLFxuICBzdHlsZXM6IFsnOmhvc3QgeyBkaXNwbGF5OiBibG9jazsgfSddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2XG4gICAgICAqbmdJZj1cInZpc2libGVcIlxuICAgICAgW2lkXT1cImlkXCJcbiAgICAgIHJvbGU9XCJvcHRpb25cIlxuICAgICAgW2F0dHIuYXJpYS1zZWxlY3RlZF09XCJhY3RpdmVcIlxuICAgICAgW2F0dHIuYXJpYS1kaXNhYmxlZF09XCJkaXNhYmxlZCB8fCBudWxsXCJcbiAgICAgIFthdHRyLmRhdGEtYWN0aXZlXT1cImFjdGl2ZSA/ICcnIDogbnVsbFwiXG4gICAgICBbY2xhc3NdPVwiY29tcHV0ZWRDbGFzc1wiXG4gICAgICAoY2xpY2spPVwib25DbGljaygpXCJcbiAgICAgIChtb3VzZWVudGVyKT1cIm9uTW91c2VFbnRlcigpXCJcbiAgICA+XG4gICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgPC9kaXY+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIENvbW1hbmRJdGVtQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIC8qKiBWYWx1ZSBlbWl0dGVkIGZyb20gdGhlIG1lbnUncyBgc2VsZWN0ZWRgIG91dHB1dCB3aGVuIHRoaXMgcm93IGlzIGNob3Nlbi4gKi9cbiAgQElucHV0KCkgdmFsdWU6IGFueSA9IG51bGw7XG4gIC8qKlxuICAgKiBUZXh0IG1hdGNoZWQgYWdhaW5zdCB0aGUgcXVlcnkuIERlZmF1bHRzIHRvIGB2YWx1ZWAgd2hlbiBvbWl0dGVkIOKAlCBzZXQgaXRcbiAgICogZXhwbGljaXRseSB3aGVuZXZlciB0aGUgcm93J3MgdmlzaWJsZSB0ZXh0IGRpZmZlcnMgZnJvbSBpdHMgdmFsdWUuXG4gICAqIEBkZWZhdWx0ICcnXG4gICAqL1xuICBASW5wdXQoKSBsYWJlbCA9ICcnO1xuICAvKiogRXh0cmEgdGVybXMgdGhhdCBzaG91bGQgYWxzbyBtYXRjaCB0aGlzIHJvdywgZS5nLiBzeW5vbnltcy4gQGRlZmF1bHQgW10gKi9cbiAgQElucHV0KCkga2V5d29yZHM6IHN0cmluZ1tdID0gW107XG4gIC8qKiBNYWtlcyB0aGUgcm93IHVuc2VsZWN0YWJsZSBhbmQgc2tpcHBlZCBieSB0aGUgYXJyb3cga2V5cy4gQGRlZmF1bHQgZmFsc2UgKi9cbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcbiAgLyoqIEV4dHJhIFRhaWx3aW5kIGNsYXNzZXMgbWVyZ2VkIG9udG8gdGhlIHJvdyB2aWEgYGNuKClgIChsYXN0LXdpbnMpLiAqL1xuICBASW5wdXQoKSBjbGFzcyA9ICcnO1xuXG4gIC8qKiBFbWl0dGVkIHdoZW4gdGhpcyBzcGVjaWZpYyByb3cgaXMgY2hvc2VuLiAqL1xuICBAT3V0cHV0KCkgc2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IHNlcnZpY2UgPSBpbmplY3QoQ29tbWFuZFNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IGdyb3VwID0gaW5qZWN0KENvbW1hbmRHcm91cENvbXBvbmVudCwgeyBvcHRpb25hbDogdHJ1ZSB9KTtcbiAgcHJpdmF0ZSByZWFkb25seSBzdWJzY3JpcHRpb25zID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgcmVhZG9ubHkgaWQgPSBgY29tbWFuZC1pdGVtLSR7Y29tbWFuZEl0ZW1JZCsrfWA7XG4gIHZpc2libGUgPSB0cnVlO1xuICBhY3RpdmUgPSBmYWxzZTtcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnNlcnZpY2UucmVnaXN0ZXIoe1xuICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgICBzZWFyY2hUZXh0OiB0aGlzLnNlYXJjaFRleHQsXG4gICAgICB2YWx1ZTogdGhpcy52YWx1ZSxcbiAgICAgIGRpc2FibGVkOiB0aGlzLmRpc2FibGVkLFxuICAgIH0pO1xuICAgIHRoaXMuZ3JvdXA/LmFkZE1lbWJlcih0aGlzLmlkKTtcblxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICB0aGlzLnNlcnZpY2UudmlzaWJsZSQuc3Vic2NyaWJlKChpZHMpID0+IHtcbiAgICAgICAgdGhpcy52aXNpYmxlID0gaWRzLmluY2x1ZGVzKHRoaXMuaWQpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgdGhpcy5zZXJ2aWNlLmFjdGl2ZUlkJC5zdWJzY3JpYmUoKGFjdGl2ZUlkKSA9PiB7XG4gICAgICAgIHRoaXMuYWN0aXZlID0gYWN0aXZlSWQgPT09IHRoaXMuaWQ7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSlcbiAgICApO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICB0aGlzLnNlcnZpY2Uuc2VsZWN0ZWQkLnN1YnNjcmliZSgodmFsdWUpID0+IHtcbiAgICAgICAgaWYgKHZhbHVlID09PSB0aGlzLnZhbHVlKSB0aGlzLnNlbGVjdGVkLmVtaXQodmFsdWUpO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5zZXJ2aWNlLnVwZGF0ZSh0aGlzLmlkLCB7XG4gICAgICBzZWFyY2hUZXh0OiB0aGlzLnNlYXJjaFRleHQsXG4gICAgICB2YWx1ZTogdGhpcy52YWx1ZSxcbiAgICAgIGRpc2FibGVkOiB0aGlzLmRpc2FibGVkLFxuICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5ncm91cD8ucmVtb3ZlTWVtYmVyKHRoaXMuaWQpO1xuICAgIHRoaXMuc2VydmljZS51bnJlZ2lzdGVyKHRoaXMuaWQpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLyoqIExhYmVsIHBsdXMga2V5d29yZHMsIHNvIHN5bm9ueW1zIG1hdGNoIHdpdGhvdXQgYmVpbmcgZGlzcGxheWVkLiAqL1xuICBwcml2YXRlIGdldCBzZWFyY2hUZXh0KCk6IHN0cmluZyB7XG4gICAgY29uc3QgYmFzZSA9IHRoaXMubGFiZWwgfHwgKHRoaXMudmFsdWUgIT0gbnVsbCA/IFN0cmluZyh0aGlzLnZhbHVlKSA6ICcnKTtcbiAgICByZXR1cm4gW2Jhc2UsIC4uLnRoaXMua2V5d29yZHNdLmpvaW4oJyAnKTtcbiAgfVxuXG4gIGdldCBjb21wdXRlZENsYXNzKCkge1xuICAgIHJldHVybiBjbihcbiAgICAgICdyZWxhdGl2ZSBmbGV4IGN1cnNvci1wb2ludGVyIHNlbGVjdC1ub25lIGl0ZW1zLWNlbnRlciBnYXAtMiByb3VuZGVkLXNtIHB4LTIgcHktMS41IHRleHQtc20gb3V0bGluZS1ub25lIHRyYW5zaXRpb24tY29sb3JzJyxcbiAgICAgIHRoaXMuYWN0aXZlICYmICF0aGlzLmRpc2FibGVkICYmICdiZy1hY2NlbnQgdGV4dC1hY2NlbnQtZm9yZWdyb3VuZCcsXG4gICAgICB0aGlzLmRpc2FibGVkICYmICdwb2ludGVyLWV2ZW50cy1ub25lIG9wYWNpdHktNTAnLFxuICAgICAgdGhpcy5jbGFzc1xuICAgICk7XG4gIH1cblxuICBvbkNsaWNrKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSByZXR1cm47XG4gICAgdGhpcy5zZXJ2aWNlLnNlbGVjdEJ5SWQodGhpcy5pZCk7XG4gIH1cblxuICBvbk1vdXNlRW50ZXIoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHJldHVybjtcbiAgICB0aGlzLnNlcnZpY2Uuc2V0QWN0aXZlKHRoaXMuaWQpO1xuICB9XG59XG5cbi8qKiBEaXZpZGVyIGJldHdlZW4gY29tbWFuZCBncm91cHMuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0b2xsZS1jb21tYW5kLXNlcGFyYXRvcicsXG4gIHN0eWxlczogWyc6aG9zdCB7IGRpc3BsYXk6IGJsb2NrOyB9J10sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgdGVtcGxhdGU6IGA8ZGl2IHJvbGU9XCJzZXBhcmF0b3JcIiBbY2xhc3NdPVwiY24oJy1teC0xIGgtcHggYmctYm9yZGVyJywgY2xhc3MpXCI+PC9kaXY+YCxcbn0pXG5leHBvcnQgY2xhc3MgQ29tbWFuZFNlcGFyYXRvckNvbXBvbmVudCAgaW1wbGVtZW50cyBPbkNoYW5nZXN7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblxuICAvKipcbiAgICogQW5ndWxhciB3cml0ZXMgYSBib3VuZCBgY2xhc3NgIGlucHV0IHRocm91Z2ggaXRzIHN0eWxpbmcgcGF0aCwgd2hpY2ggZG9lc1xuICAgKiBub3QgbWFyayBhbiBPblB1c2ggY29tcG9uZW50IGRpcnR5IOKAlCB3aXRob3V0IHRoaXMgaG9vayB0aGUgY29tcG9uZW50IGtlZXBzXG4gICAqIHJlbmRlcmluZyB0aGUgY2xhc3MgaXQgd2FzIGJvcm4gd2l0aC5cbiAgICovXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqIEV4dHJhIFRhaWx3aW5kIGNsYXNzZXMgbWVyZ2VkIG9udG8gdGhlIHNlcGFyYXRvciB2aWEgYGNuKClgIChsYXN0LXdpbnMpLiAqL1xuICBASW5wdXQoKSBjbGFzcyA9ICcnO1xuICBwcm90ZWN0ZWQgY24gPSBjbjtcbn1cblxuLyoqIFJpZ2h0LWFsaWduZWQgc2hvcnRjdXQgaGludCBpbnNpZGUgYSBjb21tYW5kIGl0ZW0uIFBhaXJzIHdpdGggYHRvbGxlLWtiZGAuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0b2xsZS1jb21tYW5kLXNob3J0Y3V0JyxcbiAgc3R5bGVzOiBbJzpob3N0IHsgZGlzcGxheTogaW5saW5lLWZsZXg7IH0nXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYDxzcGFuIFtjbGFzc109XCJjbignbWwtYXV0byBmbGV4IGl0ZW1zLWNlbnRlciBnYXAtMSB0ZXh0LXhzIHRyYWNraW5nLXdpZGVzdCB0ZXh0LW11dGVkLWZvcmVncm91bmQnLCBjbGFzcylcIj48bmctY29udGVudD48L25nLWNvbnRlbnQ+PC9zcGFuPmAsXG59KVxuZXhwb3J0IGNsYXNzIENvbW1hbmRTaG9ydGN1dENvbXBvbmVudCAgaW1wbGVtZW50cyBPbkNoYW5nZXN7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblxuICAvKipcbiAgICogQW5ndWxhciB3cml0ZXMgYSBib3VuZCBgY2xhc3NgIGlucHV0IHRocm91Z2ggaXRzIHN0eWxpbmcgcGF0aCwgd2hpY2ggZG9lc1xuICAgKiBub3QgbWFyayBhbiBPblB1c2ggY29tcG9uZW50IGRpcnR5IOKAlCB3aXRob3V0IHRoaXMgaG9vayB0aGUgY29tcG9uZW50IGtlZXBzXG4gICAqIHJlbmRlcmluZyB0aGUgY2xhc3MgaXQgd2FzIGJvcm4gd2l0aC5cbiAgICovXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqIEV4dHJhIFRhaWx3aW5kIGNsYXNzZXMgbWVyZ2VkIG9udG8gdGhlIHNob3J0Y3V0IHZpYSBgY24oKWAgKGxhc3Qtd2lucykuICovXG4gIEBJbnB1dCgpIGNsYXNzID0gJyc7XG4gIHByb3RlY3RlZCBjbiA9IGNuO1xufVxuIl19