@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,452 @@
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Injectable, Input, Output, inject } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { BehaviorSubject, Subscription } from 'rxjs';
4
+ import { skip } from 'rxjs/operators';
5
+ import { cva } from 'class-variance-authority';
6
+ import { cn } from './utils/cn';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "@angular/common";
9
+ let sourceId = 0;
10
+ /**
11
+ * Coordinates a `tolle-sources` with its trigger, content and sources.
12
+ *
13
+ * The trigger has to report how many sources were projected into a sibling
14
+ * component, so every `tolle-source` registers here and the trigger renders
15
+ * from the resulting count.
16
+ *
17
+ * Provided on `SourcesComponent`, so each citation list gets its own instance.
18
+ */
19
+ export class SourcesService {
20
+ openSource = new BehaviorSubject(false);
21
+ /** Emits whether the citation list is expanded. */
22
+ open$ = this.openSource.asObservable();
23
+ idsSource = new BehaviorSubject([]);
24
+ /** Emits the ids of the registered sources, in registration (DOM) order. */
25
+ ids$ = this.idsSource.asObservable();
26
+ /** True while the citation list is expanded. */
27
+ get open() {
28
+ return this.openSource.value;
29
+ }
30
+ /** How many sources are currently registered. */
31
+ get count() {
32
+ return this.idsSource.value.length;
33
+ }
34
+ setOpen(value) {
35
+ if (this.openSource.value !== value)
36
+ this.openSource.next(value);
37
+ }
38
+ toggle() {
39
+ this.setOpen(!this.openSource.value);
40
+ }
41
+ register(id) {
42
+ if (this.idsSource.value.includes(id))
43
+ return;
44
+ this.idsSource.next([...this.idsSource.value, id]);
45
+ }
46
+ unregister(id) {
47
+ this.idsSource.next(this.idsSource.value.filter((existing) => existing !== id));
48
+ }
49
+ /** Zero-based position of a source, or -1 when it is not registered. */
50
+ indexOf(id) {
51
+ return this.idsSource.value.indexOf(id);
52
+ }
53
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SourcesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
54
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SourcesService });
55
+ }
56
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SourcesService, decorators: [{
57
+ type: Injectable
58
+ }] });
59
+ const sourcesVariants = cva('flex w-full flex-col gap-2 text-sm', {
60
+ variants: {
61
+ variant: {
62
+ default: '',
63
+ card: 'rounded-md border border-border bg-card p-3 text-card-foreground',
64
+ muted: 'rounded-md bg-muted p-3',
65
+ },
66
+ },
67
+ defaultVariants: {
68
+ variant: 'default',
69
+ },
70
+ });
71
+ /**
72
+ * A collapsible list of the citations behind a response.
73
+ *
74
+ * Compose it from `tolle-sources-trigger`, `tolle-sources-content` and one
75
+ * `tolle-source` per citation — the trigger counts the sources for you.
76
+ * @new
77
+ */
78
+ export class SourcesComponent {
79
+ /** Whether the citation list is expanded. @default false */
80
+ open = false;
81
+ /** Visual treatment of the list container. @default 'default' */
82
+ variant = 'default';
83
+ /** Extra Tailwind classes merged onto the list via `cn()` (last-wins). */
84
+ class = '';
85
+ /** Emitted with the new state whenever the list is expanded or collapsed. */
86
+ openChange = new EventEmitter();
87
+ service = inject(SourcesService);
88
+ cdr = inject(ChangeDetectorRef);
89
+ subscriptions = new Subscription();
90
+ /** True while an `open` input is being pushed into the service. */
91
+ applyingInput = false;
92
+ ngOnInit() {
93
+ this.service.setOpen(this.open);
94
+ // `skip(1)` drops the BehaviorSubject's current value so mounting never
95
+ // emits a spurious `openChange`.
96
+ this.subscriptions.add(this.service.open$.pipe(skip(1)).subscribe((open) => {
97
+ this.open = open;
98
+ this.cdr.markForCheck();
99
+ // Only user-driven toggles are worth reporting; echoing a change the
100
+ // parent just made would fight a `[(open)]` binding.
101
+ if (!this.applyingInput)
102
+ this.openChange.emit(open);
103
+ }));
104
+ }
105
+ ngOnChanges(changes) {
106
+ if (changes['open'])
107
+ this.applyInput(this.open);
108
+ // A bound `class` input is written through Angular's styling path,
109
+ // which does not mark an OnPush view dirty on its own.
110
+ this.cdr.markForCheck();
111
+ }
112
+ applyInput(open) {
113
+ this.applyingInput = true;
114
+ try {
115
+ this.service.setOpen(open);
116
+ }
117
+ finally {
118
+ this.applyingInput = false;
119
+ }
120
+ }
121
+ ngOnDestroy() {
122
+ this.subscriptions.unsubscribe();
123
+ }
124
+ get computedClass() {
125
+ return cn(sourcesVariants({ variant: this.variant }), this.class);
126
+ }
127
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SourcesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
128
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SourcesComponent, isStandalone: true, selector: "tolle-sources", inputs: { open: "open", variant: "variant", class: "class" }, outputs: { openChange: "openChange" }, providers: [SourcesService], usesOnChanges: true, ngImport: i0, template: `
129
+ <div [class]="computedClass" [attr.data-state]="open ? 'open' : 'closed'">
130
+ <ng-content></ng-content>
131
+ </div>
132
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
133
+ }
134
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SourcesComponent, decorators: [{
135
+ type: Component,
136
+ args: [{ selector: 'tolle-sources', standalone: true, imports: [CommonModule], providers: [SourcesService], changeDetection: ChangeDetectionStrategy.OnPush, template: `
137
+ <div [class]="computedClass" [attr.data-state]="open ? 'open' : 'closed'">
138
+ <ng-content></ng-content>
139
+ </div>
140
+ `, styles: [":host{display:block}\n"] }]
141
+ }], propDecorators: { open: [{
142
+ type: Input
143
+ }], variant: [{
144
+ type: Input
145
+ }], class: [{
146
+ type: Input
147
+ }], openChange: [{
148
+ type: Output
149
+ }] } });
150
+ /** Toggle for a `tolle-sources`, labelled with how many sources there are. */
151
+ export class SourcesTriggerComponent {
152
+ /**
153
+ * Angular writes a bound `class` input through its styling path, which does
154
+ * not mark an OnPush component dirty — without this hook the component keeps
155
+ * rendering the class it was born with.
156
+ */
157
+ ngOnChanges() {
158
+ this.cdr.markForCheck();
159
+ }
160
+ /** Overrides the counted number of sources. @default null */
161
+ count = null;
162
+ /** Extra Tailwind classes merged onto the trigger via `cn()` (last-wins). */
163
+ class = '';
164
+ service = inject(SourcesService);
165
+ cdr = inject(ChangeDetectorRef);
166
+ subscriptions = new Subscription();
167
+ open = false;
168
+ registered = 0;
169
+ ngOnInit() {
170
+ this.subscriptions.add(this.service.open$.subscribe((open) => {
171
+ this.open = open;
172
+ this.cdr.markForCheck();
173
+ }));
174
+ this.subscriptions.add(this.service.ids$.subscribe((ids) => {
175
+ this.registered = ids.length;
176
+ this.cdr.markForCheck();
177
+ }));
178
+ }
179
+ ngOnDestroy() {
180
+ this.subscriptions.unsubscribe();
181
+ }
182
+ /** How many sources the trigger reports. */
183
+ get total() {
184
+ return this.count ?? this.registered;
185
+ }
186
+ get label() {
187
+ return 'Used ' + this.total + (this.total === 1 ? ' source' : ' sources');
188
+ }
189
+ get computedClass() {
190
+ return cn('flex w-fit items-center gap-1.5 rounded-md px-1.5 py-1 text-sm text-muted-foreground transition-colors', 'hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring', this.class);
191
+ }
192
+ onToggle() {
193
+ this.service.toggle();
194
+ }
195
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SourcesTriggerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
196
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SourcesTriggerComponent, isStandalone: true, selector: "tolle-sources-trigger", inputs: { count: "count", class: "class" }, usesOnChanges: true, ngImport: i0, template: `
197
+ <button
198
+ type="button"
199
+ data-sources-trigger
200
+ [attr.aria-expanded]="open"
201
+ [attr.data-state]="open ? 'open' : 'closed'"
202
+ [class]="computedClass"
203
+ (click)="onToggle()"
204
+ >
205
+ <i class="ri-links-line" aria-hidden="true"></i>
206
+
207
+ <span data-sources-label>{{ label }}</span>
208
+
209
+ <i
210
+ class="ri-arrow-down-s-line transition-transform duration-200"
211
+ [class.rotate-180]="open"
212
+ aria-hidden="true"
213
+ ></i>
214
+
215
+ <ng-content></ng-content>
216
+ </button>
217
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
218
+ }
219
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SourcesTriggerComponent, decorators: [{
220
+ type: Component,
221
+ args: [{ selector: 'tolle-sources-trigger', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
222
+ <button
223
+ type="button"
224
+ data-sources-trigger
225
+ [attr.aria-expanded]="open"
226
+ [attr.data-state]="open ? 'open' : 'closed'"
227
+ [class]="computedClass"
228
+ (click)="onToggle()"
229
+ >
230
+ <i class="ri-links-line" aria-hidden="true"></i>
231
+
232
+ <span data-sources-label>{{ label }}</span>
233
+
234
+ <i
235
+ class="ri-arrow-down-s-line transition-transform duration-200"
236
+ [class.rotate-180]="open"
237
+ aria-hidden="true"
238
+ ></i>
239
+
240
+ <ng-content></ng-content>
241
+ </button>
242
+ `, styles: [":host{display:block}\n"] }]
243
+ }], propDecorators: { count: [{
244
+ type: Input
245
+ }], class: [{
246
+ type: Input
247
+ }] } });
248
+ /**
249
+ * Holds the `tolle-source` entries of a `tolle-sources`.
250
+ *
251
+ * Stays in the DOM while collapsed — hidden and `inert` rather than removed —
252
+ * so the sources inside it stay registered and the trigger's count is right
253
+ * before the list has ever been opened.
254
+ */
255
+ export class SourcesContentComponent {
256
+ /**
257
+ * Angular writes a bound `class` input through its styling path, which does
258
+ * not mark an OnPush component dirty — without this hook the component keeps
259
+ * rendering the class it was born with.
260
+ */
261
+ ngOnChanges() {
262
+ this.cdr.markForCheck();
263
+ }
264
+ /** Extra Tailwind classes merged onto the content via `cn()` (last-wins). */
265
+ class = '';
266
+ service = inject(SourcesService);
267
+ cdr = inject(ChangeDetectorRef);
268
+ subscriptions = new Subscription();
269
+ open = false;
270
+ ngOnInit() {
271
+ this.subscriptions.add(this.service.open$.subscribe((open) => {
272
+ this.open = open;
273
+ this.cdr.markForCheck();
274
+ }));
275
+ }
276
+ ngOnDestroy() {
277
+ this.subscriptions.unsubscribe();
278
+ }
279
+ get computedClass() {
280
+ return cn('flex flex-col gap-1.5', !this.open && 'hidden', this.class);
281
+ }
282
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SourcesContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
283
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SourcesContentComponent, isStandalone: true, selector: "tolle-sources-content", inputs: { class: "class" }, usesOnChanges: true, ngImport: i0, template: `
284
+ <div
285
+ data-sources-content
286
+ [attr.data-state]="open ? 'open' : 'closed'"
287
+ [attr.inert]="open ? null : ''"
288
+ [attr.aria-hidden]="open ? null : 'true'"
289
+ [class]="computedClass"
290
+ >
291
+ <ng-content></ng-content>
292
+ </div>
293
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
294
+ }
295
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SourcesContentComponent, decorators: [{
296
+ type: Component,
297
+ args: [{ selector: 'tolle-sources-content', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
298
+ <div
299
+ data-sources-content
300
+ [attr.data-state]="open ? 'open' : 'closed'"
301
+ [attr.inert]="open ? null : ''"
302
+ [attr.aria-hidden]="open ? null : 'true'"
303
+ [class]="computedClass"
304
+ >
305
+ <ng-content></ng-content>
306
+ </div>
307
+ `, styles: [":host{display:block}\n"] }]
308
+ }], propDecorators: { class: [{
309
+ type: Input
310
+ }] } });
311
+ const sourceVariants = cva('group flex items-center gap-2 rounded-md px-2 py-1.5 transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring', {
312
+ variants: {
313
+ size: {
314
+ sm: 'text-xs',
315
+ default: 'text-sm',
316
+ },
317
+ },
318
+ defaultVariants: {
319
+ size: 'default',
320
+ },
321
+ });
322
+ /** A single citation inside a `tolle-sources-content`. */
323
+ export class SourceComponent {
324
+ /**
325
+ * Angular writes a bound `class` input through its styling path, which does
326
+ * not mark an OnPush component dirty — without this hook the component keeps
327
+ * rendering the class it was born with.
328
+ */
329
+ ngOnChanges() {
330
+ this.cdr.markForCheck();
331
+ }
332
+ /** URL the citation points at. @default '' */
333
+ href = '';
334
+ /** Human-readable title; falls back to the href when empty. @default '' */
335
+ title = '';
336
+ /** URL of a favicon shown instead of the numbered chip. @default '' */
337
+ favicon = '';
338
+ /** Overrides the auto-numbered position chip. @default null */
339
+ index = null;
340
+ /** Text scale of the citation. @default 'default' */
341
+ size = 'default';
342
+ /** Extra Tailwind classes merged onto the citation via `cn()` (last-wins). */
343
+ class = '';
344
+ service = inject(SourcesService);
345
+ cdr = inject(ChangeDetectorRef);
346
+ subscriptions = new Subscription();
347
+ id = 'source-' + sourceId++;
348
+ order = 0;
349
+ ngOnInit() {
350
+ this.service.register(this.id);
351
+ this.subscriptions.add(this.service.ids$.subscribe(() => {
352
+ this.order = this.service.indexOf(this.id);
353
+ this.cdr.markForCheck();
354
+ }));
355
+ }
356
+ ngOnDestroy() {
357
+ this.service.unregister(this.id);
358
+ this.subscriptions.unsubscribe();
359
+ }
360
+ /** One-based number shown in the chip. */
361
+ get position() {
362
+ return this.index ?? this.order + 1;
363
+ }
364
+ get computedClass() {
365
+ return cn(sourceVariants({ size: this.size }), this.class);
366
+ }
367
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SourceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
368
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SourceComponent, isStandalone: true, selector: "tolle-source", inputs: { href: "href", title: "title", favicon: "favicon", index: "index", size: "size", class: "class" }, usesOnChanges: true, ngImport: i0, template: `
369
+ <a
370
+ data-source
371
+ [attr.href]="href || null"
372
+ target="_blank"
373
+ rel="noreferrer noopener"
374
+ [class]="computedClass"
375
+ >
376
+ <img
377
+ *ngIf="favicon; else chip"
378
+ [attr.src]="favicon"
379
+ alt=""
380
+ aria-hidden="true"
381
+ class="size-4 shrink-0 rounded-sm"
382
+ />
383
+
384
+ <ng-template #chip>
385
+ <span
386
+ class="flex size-4 shrink-0 items-center justify-center rounded-sm bg-muted text-[10px] font-medium text-muted-foreground"
387
+ aria-hidden="true"
388
+ >{{ position }}</span
389
+ >
390
+ </ng-template>
391
+
392
+ <span class="truncate text-foreground" data-source-title>{{ title || href }}</span>
393
+
394
+ <i
395
+ class="ri-external-link-line ml-auto shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100"
396
+ aria-hidden="true"
397
+ ></i>
398
+
399
+ <ng-content></ng-content>
400
+ </a>
401
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
402
+ }
403
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SourceComponent, decorators: [{
404
+ type: Component,
405
+ args: [{ selector: 'tolle-source', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
406
+ <a
407
+ data-source
408
+ [attr.href]="href || null"
409
+ target="_blank"
410
+ rel="noreferrer noopener"
411
+ [class]="computedClass"
412
+ >
413
+ <img
414
+ *ngIf="favicon; else chip"
415
+ [attr.src]="favicon"
416
+ alt=""
417
+ aria-hidden="true"
418
+ class="size-4 shrink-0 rounded-sm"
419
+ />
420
+
421
+ <ng-template #chip>
422
+ <span
423
+ class="flex size-4 shrink-0 items-center justify-center rounded-sm bg-muted text-[10px] font-medium text-muted-foreground"
424
+ aria-hidden="true"
425
+ >{{ position }}</span
426
+ >
427
+ </ng-template>
428
+
429
+ <span class="truncate text-foreground" data-source-title>{{ title || href }}</span>
430
+
431
+ <i
432
+ class="ri-external-link-line ml-auto shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100"
433
+ aria-hidden="true"
434
+ ></i>
435
+
436
+ <ng-content></ng-content>
437
+ </a>
438
+ `, styles: [":host{display:block}\n"] }]
439
+ }], propDecorators: { href: [{
440
+ type: Input
441
+ }], title: [{
442
+ type: Input
443
+ }], favicon: [{
444
+ type: Input
445
+ }], index: [{
446
+ type: Input
447
+ }], size: [{
448
+ type: Input
449
+ }], class: [{
450
+ type: Input
451
+ }] } });
452
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic291cmNlcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy90b2xsZS9zcmMvbGliL3NvdXJjZXMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQWdDLE1BQU0sRUFBaUIsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3BMLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEMsT0FBTyxFQUFFLEdBQUcsRUFBcUIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sWUFBWSxDQUFDOzs7QUFFaEMsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBRWpCOzs7Ozs7OztHQVFHO0FBRUgsTUFBTSxPQUFPLGNBQWM7SUFDUixVQUFVLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDbEUsbURBQW1EO0lBQzFDLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRS9CLFNBQVMsR0FBRyxJQUFJLGVBQWUsQ0FBVyxFQUFFLENBQUMsQ0FBQztJQUMvRCw0RUFBNEU7SUFDbkUsSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFOUMsZ0RBQWdEO0lBQ2hELElBQUksSUFBSTtRQUNOLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUM7SUFDL0IsQ0FBQztJQUVELGlEQUFpRDtJQUNqRCxJQUFJLEtBQUs7UUFDUCxPQUFPLElB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QWE7UUFDZixPQUFPLEVBQUUsQ0FBQyxjQUFjLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdELENBQUM7d0dBdERVLGVBQWU7NEZBQWYsZUFBZSx5TUFuQ2hCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQ1QsK0ZBbkNTLFlBQVk7OzRGQXFDWCxlQUFlO2tCQXpDM0IsU0FBUzsrQkFDRSxjQUFjLGNBRVosSUFBSSxXQUNQLENBQUMsWUFBWSxDQUFDLG1CQUNOLHVCQUF1QixDQUFDLE1BQU0sWUFDckM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWlDVDs4QkFjUSxJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsS0FBSztzQkFBYixLQUFLO2dCQUVHLE9BQU87c0JBQWYsS0FBSztnQkFFRyxLQUFLO3NCQUFiLEtBQUs7Z0JBRUcsSUFBSTtzQkFBWixLQUFLO2dCQUVHLEtBQUs7c0JBQWIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIEluamVjdGFibGUsIElucHV0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgT25Jbml0LCBPdXRwdXQsIFNpbXBsZUNoYW5nZXMsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBza2lwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgY3ZhLCB0eXBlIFZhcmlhbnRQcm9wcyB9IGZyb20gJ2NsYXNzLXZhcmlhbmNlLWF1dGhvcml0eSc7XG5pbXBvcnQgeyBjbiB9IGZyb20gJy4vdXRpbHMvY24nO1xuXG5sZXQgc291cmNlSWQgPSAwO1xuXG4vKipcbiAqIENvb3JkaW5hdGVzIGEgYHRvbGxlLXNvdXJjZXNgIHdpdGggaXRzIHRyaWdnZXIsIGNvbnRlbnQgYW5kIHNvdXJjZXMuXG4gKlxuICogVGhlIHRyaWdnZXIgaGFzIHRvIHJlcG9ydCBob3cgbWFueSBzb3VyY2VzIHdlcmUgcHJvamVjdGVkIGludG8gYSBzaWJsaW5nXG4gKiBjb21wb25lbnQsIHNvIGV2ZXJ5IGB0b2xsZS1zb3VyY2VgIHJlZ2lzdGVycyBoZXJlIGFuZCB0aGUgdHJpZ2dlciByZW5kZXJzXG4gKiBmcm9tIHRoZSByZXN1bHRpbmcgY291bnQuXG4gKlxuICogUHJvdmlkZWQgb24gYFNvdXJjZXNDb21wb25lbnRgLCBzbyBlYWNoIGNpdGF0aW9uIGxpc3QgZ2V0cyBpdHMgb3duIGluc3RhbmNlLlxuICovXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgU291cmNlc1NlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IG9wZW5Tb3VyY2UgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgLyoqIEVtaXRzIHdoZXRoZXIgdGhlIGNpdGF0aW9uIGxpc3QgaXMgZXhwYW5kZWQuICovXG4gIHJlYWRvbmx5IG9wZW4kID0gdGhpcy5vcGVuU291cmNlLmFzT2JzZXJ2YWJsZSgpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgaWRzU291cmNlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmdbXT4oW10pO1xuICAvKiogRW1pdHMgdGhlIGlkcyBvZiB0aGUgcmVnaXN0ZXJlZCBzb3VyY2VzLCBpbiByZWdpc3RyYXRpb24gKERPTSkgb3JkZXIuICovXG4gIHJlYWRvbmx5IGlkcyQgPSB0aGlzLmlkc1NvdXJjZS5hc09ic2VydmFibGUoKTtcblxuICAvKiogVHJ1ZSB3aGlsZSB0aGUgY2l0YXRpb24gbGlzdCBpcyBleHBhbmRlZC4gKi9cbiAgZ2V0IG9wZW4oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMub3BlblNvdXJjZS52YWx1ZTtcbiAgfVxuXG4gIC8qKiBIb3cgbWFueSBzb3VyY2VzIGFyZSBjdXJyZW50bHkgcmVnaXN0ZXJlZC4gKi9cbiAgZ2V0IGNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuaWRzU291cmNlLnZhbHVlLmxlbmd0aDtcbiAgfVxuXG4gIHNldE9wZW4odmFsdWU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5vcGVuU291cmNlLnZhbHVlICE9PSB2YWx1ZSkgdGhpcy5vcGVuU291cmNlLm5leHQodmFsdWUpO1xuICB9XG5cbiAgdG9nZ2xlKCk6IHZvaWQge1xuICAgIHRoaXMuc2V0T3BlbighdGhpcy5vcGVuU291cmNlLnZhbHVlKTtcbiAgfVxuXG4gIHJlZ2lzdGVyKGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pZHNTb3VyY2UudmFsdWUuaW5jbHVkZXMoaWQpKSByZXR1cm47XG4gICAgdGhpcy5pZHNTb3VyY2UubmV4dChbLi4udGhpcy5pZHNTb3VyY2UudmFsdWUsIGlkXSk7XG4gIH1cblxuICB1bnJlZ2lzdGVyKGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmlkc1NvdXJjZS5uZXh0KHRoaXMuaWRzU291cmNlLnZhbHVlLmZpbHRlcigoZXhpc3RpbmcpID0+IGV4aXN0aW5nICE9PSBpZCkpO1xuICB9XG5cbiAgLyoqIFplcm8tYmFzZWQgcG9zaXRpb24gb2YgYSBzb3VyY2UsIG9yIC0xIHdoZW4gaXQgaXMgbm90IHJlZ2lzdGVyZWQuICovXG4gIGluZGV4T2YoaWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuaWRzU291cmNlLnZhbHVlLmluZGV4T2YoaWQpO1xuICB9XG59XG5cbmNvbnN0IHNvdXJjZXNWYXJpYW50cyA9IGN2YSgnZmxleCB3LWZ1bGwgZmxleC1jb2wgZ2FwLTIgdGV4dC1zbScsIHtcbiAgdmFyaWFudHM6IHtcbiAgICB2YXJpYW50OiB7XG4gICAgICBkZWZhdWx0OiAnJyxcbiAgICAgIGNhcmQ6ICdyb3VuZGVkLW1kIGJvcmRlciBib3JkZXItYm9yZGVyIGJnLWNhcmQgcC0zIHRleHQtY2FyZC1mb3JlZ3JvdW5kJyxcbiAgICAgIG11dGVkOiAncm91bmRlZC1tZCBiZy1tdXRlZCBwLTMnLFxuICAgIH0sXG4gIH0sXG4gIGRlZmF1bHRWYXJpYW50czoge1xuICAgIHZhcmlhbnQ6ICdkZWZhdWx0JyxcbiAgfSxcbn0pO1xuXG5leHBvcnQgdHlwZSBTb3VyY2VzUHJvcHMgPSBWYXJpYW50UHJvcHM8dHlwZW9mIHNvdXJjZXNWYXJpYW50cz47XG5cbi8qKlxuICogQSBjb2xsYXBzaWJsZSBsaXN0IG9mIHRoZSBjaXRhdGlvbnMgYmVoaW5kIGEgcmVzcG9uc2UuXG4gKlxuICogQ29tcG9zZSBpdCBmcm9tIGB0b2xsZS1zb3VyY2VzLXRyaWdnZXJgLCBgdG9sbGUtc291cmNlcy1jb250ZW50YCBhbmQgb25lXG4gKiBgdG9sbGUtc291cmNlYCBwZXIgY2l0YXRpb24g4oCUIHRoZSB0cmlnZ2VyIGNvdW50cyB0aGUgc291cmNlcyBmb3IgeW91LlxuICogQG5ld1xuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0b2xsZS1zb3VyY2VzJyxcbiAgc3R5bGVzOiBbJzpob3N0IHsgZGlzcGxheTogYmxvY2s7IH0nXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG4gIHByb3ZpZGVyczogW1NvdXJjZXNTZXJ2aWNlXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBbY2xhc3NdPVwiY29tcHV0ZWRDbGFzc1wiIFthdHRyLmRhdGEtc3RhdGVdPVwib3BlbiA/ICdvcGVuJyA6ICdjbG9zZWQnXCI+XG4gICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgPC9kaXY+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIFNvdXJjZXNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcbiAgLyoqIFdoZXRoZXIgdGhlIGNpdGF0aW9uIGxpc3QgaXMgZXhwYW5kZWQuIEBkZWZhdWx0IGZhbHNlICovXG4gIEBJbnB1dCgpIG9wZW4gPSBmYWxzZTtcbiAgLyoqIFZpc3VhbCB0cmVhdG1lbnQgb2YgdGhlIGxpc3QgY29udGFpbmVyLiBAZGVmYXVsdCAnZGVmYXVsdCcgKi9cbiAgQElucHV0KCkgdmFyaWFudDogU291cmNlc1Byb3BzWyd2YXJpYW50J10gPSAnZGVmYXVsdCc7XG4gIC8qKiBFeHRyYSBUYWlsd2luZCBjbGFzc2VzIG1lcmdlZCBvbnRvIHRoZSBsaXN0IHZpYSBgY24oKWAgKGxhc3Qtd2lucykuICovXG4gIEBJbnB1dCgpIGNsYXNzID0gJyc7XG5cbiAgLyoqIEVtaXR0ZWQgd2l0aCB0aGUgbmV3IHN0YXRlIHdoZW5ldmVyIHRoZSBsaXN0IGlzIGV4cGFuZGVkIG9yIGNvbGxhcHNlZC4gKi9cbiAgQE91dHB1dCgpIG9wZW5DaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBzZXJ2aWNlID0gaW5qZWN0KFNvdXJjZXNTZXJ2aWNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBjZHIgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IHN1YnNjcmlwdGlvbnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIC8qKiBUcnVlIHdoaWxlIGFuIGBvcGVuYCBpbnB1dCBpcyBiZWluZyBwdXNoZWQgaW50byB0aGUgc2VydmljZS4gKi9cbiAgcHJpdmF0ZSBhcHBseWluZ0lucHV0ID0gZmFsc2U7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5zZXJ2aWNlLnNldE9wZW4odGhpcy5vcGVuKTtcbiAgICAvLyBgc2tpcCgxKWAgZHJvcHMgdGhlIEJlaGF2aW9yU3ViamVjdCdzIGN1cnJlbnQgdmFsdWUgc28gbW91bnRpbmcgbmV2ZXJcbiAgICAvLyBlbWl0cyBhIHNwdXJpb3VzIGBvcGVuQ2hhbmdlYC5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgdGhpcy5zZXJ2aWNlLm9wZW4kLnBpcGUoc2tpcCgxKSkuc3Vic2NyaWJlKChvcGVuKSA9PiB7XG4gICAgICAgIHRoaXMub3BlbiA9IG9wZW47XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAvLyBPbmx5IHVzZXItZHJpdmVuIHRvZ2dsZXMgYXJlIHdvcnRoIHJlcG9ydGluZzsgZWNob2luZyBhIGNoYW5nZSB0aGVcbiAgICAgICAgLy8gcGFyZW50IGp1c3QgbWFkZSB3b3VsZCBmaWdodCBhIGBbKG9wZW4pXWAgYmluZGluZy5cbiAgICAgICAgaWYgKCF0aGlzLmFwcGx5aW5nSW5wdXQpIHRoaXMub3BlbkNoYW5nZS5lbWl0KG9wZW4pO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWydvcGVuJ10pIHRoaXMuYXBwbHlJbnB1dCh0aGlzLm9wZW4pO1xuICBcbiAgICAvLyBBIGJvdW5kIGBjbGFzc2AgaW5wdXQgaXMgd3JpdHRlbiB0aHJvdWdoIEFuZ3VsYXIncyBzdHlsaW5nIHBhdGgsXG4gICAgLy8gd2hpY2ggZG9lcyBub3QgbWFyayBhbiBPblB1c2ggdmlldyBkaXJ0eSBvbiBpdHMgb3duLlxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBseUlucHV0KG9wZW46IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmFwcGx5aW5nSW5wdXQgPSB0cnVlO1xuICAgIHRyeSB7XG4gICAgICB0aGlzLnNlcnZpY2Uuc2V0T3BlbihvcGVuKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5hcHBseWluZ0lucHV0ID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBnZXQgY29tcHV0ZWRDbGFzcygpIHtcbiAgICByZXR1cm4gY24oc291cmNlc1ZhcmlhbnRzKHsgdmFyaWFudDogdGhpcy52YXJpYW50IH0pLCB0aGlzLmNsYXNzKTtcbiAgfVxufVxuXG4vKiogVG9nZ2xlIGZvciBhIGB0b2xsZS1zb3VyY2VzYCwgbGFiZWxsZWQgd2l0aCBob3cgbWFueSBzb3VyY2VzIHRoZXJlIGFyZS4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3RvbGxlLXNvdXJjZXMtdHJpZ2dlcicsXG4gIHN0eWxlczogWyc6aG9zdCB7IGRpc3BsYXk6IGJsb2NrOyB9J10sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgdGVtcGxhdGU6IGBcbiAgICA8YnV0dG9uXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIGRhdGEtc291cmNlcy10cmlnZ2VyXG4gICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cIm9wZW5cIlxuICAgICAgW2F0dHIuZGF0YS1zdGF0ZV09XCJvcGVuID8gJ29wZW4nIDogJ2Nsb3NlZCdcIlxuICAgICAgW2NsYXNzXT1cImNvbXB1dGVkQ2xhc3NcIlxuICAgICAgKGNsaWNrKT1cIm9uVG9nZ2xlKClcIlxuICAgID5cbiAgICAgIDxpIGNsYXNzPVwicmktbGlua3MtbGluZVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cblxuICAgICAgPHNwYW4gZGF0YS1zb3VyY2VzLWxhYmVsPnt7IGxhYmVsIH19PC9zcGFuPlxuXG4gICAgICA8aVxuICAgICAgICBjbGFzcz1cInJpLWFycm93LWRvd24tcy1saW5lIHRyYW5zaXRpb24tdHJhbnNmb3JtIGR1cmF0aW9uLTIwMFwiXG4gICAgICAgIFtjbGFzcy5yb3RhdGUtMTgwXT1cIm9wZW5cIlxuICAgICAgICBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgPjwvaT5cblxuICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgIDwvYnV0dG9uPlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBTb3VyY2VzVHJpZ2dlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0LCBPbkRlc3Ryb3kge1xuXG4gIC8qKlxuICAgKiBBbmd1bGFyIHdyaXRlcyBhIGJvdW5kIGBjbGFzc2AgaW5wdXQgdGhyb3VnaCBpdHMgc3R5bGluZyBwYXRoLCB3aGljaCBkb2VzXG4gICAqIG5vdCBtYXJrIGFuIE9uUHVzaCBjb21wb25lbnQgZGlydHkg4oCUIHdpdGhvdXQgdGhpcyBob29rIHRoZSBjb21wb25lbnQga2VlcHNcbiAgICogcmVuZGVyaW5nIHRoZSBjbGFzcyBpdCB3YXMgYm9ybiB3aXRoLlxuICAgKi9cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKiogT3ZlcnJpZGVzIHRoZSBjb3VudGVkIG51bWJlciBvZiBzb3VyY2VzLiBAZGVmYXVsdCBudWxsICovXG4gIEBJbnB1dCgpIGNvdW50OiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIEV4dHJhIFRhaWx3aW5kIGNsYXNzZXMgbWVyZ2VkIG9udG8gdGhlIHRyaWdnZXIgdmlhIGBjbigpYCAobGFzdC13aW5zKS4gKi9cbiAgQElucHV0KCkgY2xhc3MgPSAnJztcblxuICBwcml2YXRlIHJlYWRvbmx5IHNlcnZpY2UgPSBpbmplY3QoU291cmNlc1NlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3Vic2NyaXB0aW9ucyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICBvcGVuID0gZmFsc2U7XG4gIHJlZ2lzdGVyZWQgPSAwO1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICB0aGlzLnNlcnZpY2Uub3BlbiQuc3Vic2NyaWJlKChvcGVuKSA9PiB7XG4gICAgICAgIHRoaXMub3BlbiA9IG9wZW47XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSlcbiAgICApO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICB0aGlzLnNlcnZpY2UuaWRzJC5zdWJzY3JpYmUoKGlkcykgPT4ge1xuICAgICAgICB0aGlzLnJlZ2lzdGVyZWQgPSBpZHMubGVuZ3RoO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLyoqIEhvdyBtYW55IHNvdXJjZXMgdGhlIHRyaWdnZXIgcmVwb3J0cy4gKi9cbiAgZ2V0IHRvdGFsKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuY291bnQgPz8gdGhpcy5yZWdpc3RlcmVkO1xuICB9XG5cbiAgZ2V0IGxhYmVsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdVc2VkICcgKyB0aGlzLnRvdGFsICsgKHRoaXMudG90YWwgPT09IDEgPyAnIHNvdXJjZScgOiAnIHNvdXJjZXMnKTtcbiAgfVxuXG4gIGdldCBjb21wdXRlZENsYXNzKCkge1xuICAgIHJldHVybiBjbihcbiAgICAgICdmbGV4IHctZml0IGl0ZW1zLWNlbnRlciBnYXAtMS41IHJvdW5kZWQtbWQgcHgtMS41IHB5LTEgdGV4dC1zbSB0ZXh0LW11dGVkLWZvcmVncm91bmQgdHJhbnNpdGlvbi1jb2xvcnMnLFxuICAgICAgJ2hvdmVyOnRleHQtZm9yZWdyb3VuZCBmb2N1cy12aXNpYmxlOm91dGxpbmUtbm9uZSBmb2N1cy12aXNpYmxlOnJpbmctMiBmb2N1cy12aXNpYmxlOnJpbmctcmluZycsXG4gICAgICB0aGlzLmNsYXNzXG4gICAgKTtcbiAgfVxuXG4gIG9uVG9nZ2xlKCk6IHZvaWQge1xuICAgIHRoaXMuc2VydmljZS50b2dnbGUoKTtcbiAgfVxufVxuXG4vKipcbiAqIEhvbGRzIHRoZSBgdG9sbGUtc291cmNlYCBlbnRyaWVzIG9mIGEgYHRvbGxlLXNvdXJjZXNgLlxuICpcbiAqIFN0YXlzIGluIHRoZSBET00gd2hpbGUgY29sbGFwc2VkIOKAlCBoaWRkZW4gYW5kIGBpbmVydGAgcmF0aGVyIHRoYW4gcmVtb3ZlZCDigJRcbiAqIHNvIHRoZSBzb3VyY2VzIGluc2lkZSBpdCBzdGF5IHJlZ2lzdGVyZWQgYW5kIHRoZSB0cmlnZ2VyJ3MgY291bnQgaXMgcmlnaHRcbiAqIGJlZm9yZSB0aGUgbGlzdCBoYXMgZXZlciBiZWVuIG9wZW5lZC5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtc291cmNlcy1jb250ZW50JyxcbiAgc3R5bGVzOiBbJzpob3N0IHsgZGlzcGxheTogYmxvY2s7IH0nXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXZcbiAgICAgIGRhdGEtc291cmNlcy1jb250ZW50XG4gICAgICBbYXR0ci5kYXRhLXN0YXRlXT1cIm9wZW4gPyAnb3BlbicgOiAnY2xvc2VkJ1wiXG4gICAgICBbYXR0ci5pbmVydF09XCJvcGVuID8gbnVsbCA6ICcnXCJcbiAgICAgIFthdHRyLmFyaWEtaGlkZGVuXT1cIm9wZW4gPyBudWxsIDogJ3RydWUnXCJcbiAgICAgIFtjbGFzc109XCJjb21wdXRlZENsYXNzXCJcbiAgICA+XG4gICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgPC9kaXY+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIFNvdXJjZXNDb250ZW50Q29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkluaXQsIE9uRGVzdHJveSB7XG5cbiAgLyoqXG4gICAqIEFuZ3VsYXIgd3JpdGVzIGEgYm91bmQgYGNsYXNzYCBpbnB1dCB0aHJvdWdoIGl0cyBzdHlsaW5nIHBhdGgsIHdoaWNoIGRvZXNcbiAgICogbm90IG1hcmsgYW4gT25QdXNoIGNvbXBvbmVudCBkaXJ0eSDigJQgd2l0aG91dCB0aGlzIGhvb2sgdGhlIGNvbXBvbmVudCBrZWVwc1xuICAgKiByZW5kZXJpbmcgdGhlIGNsYXNzIGl0IHdhcyBib3JuIHdpdGguXG4gICAqL1xuICBuZ09uQ2hhbmdlcygpOiB2b2lkIHtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKiBFeHRyYSBUYWlsd2luZCBjbGFzc2VzIG1lcmdlZCBvbnRvIHRoZSBjb250ZW50IHZpYSBgY24oKWAgKGxhc3Qtd2lucykuICovXG4gIEBJbnB1dCgpIGNsYXNzID0gJyc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBzZXJ2aWNlID0gaW5qZWN0KFNvdXJjZXNTZXJ2aWNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBjZHIgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IHN1YnNjcmlwdGlvbnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cbiAgb3BlbiA9IGZhbHNlO1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICB0aGlzLnNlcnZpY2Uub3BlbiQuc3Vic2NyaWJlKChvcGVuKSA9PiB7XG4gICAgICAgIHRoaXMub3BlbiA9IG9wZW47XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBnZXQgY29tcHV0ZWRDbGFzcygpIHtcbiAgICByZXR1cm4gY24oJ2ZsZXggZmxleC1jb2wgZ2FwLTEuNScsICF0aGlzLm9wZW4gJiYgJ2hpZGRlbicsIHRoaXMuY2xhc3MpO1xuICB9XG59XG5cbmNvbnN0IHNvdXJjZVZhcmlhbnRzID0gY3ZhKFxuICAnZ3JvdXAgZmxleCBpdGVtcy1jZW50ZXIgZ2FwLTIgcm91bmRlZC1tZCBweC0yIHB5LTEuNSB0cmFuc2l0aW9uLWNvbG9ycyBob3ZlcjpiZy1hY2NlbnQgaG92ZXI6dGV4dC1hY2NlbnQtZm9yZWdyb3VuZCBmb2N1cy12aXNpYmxlOm91dGxpbmUtbm9uZSBmb2N1cy12aXNpYmxlOnJpbmctMiBmb2N1cy12aXNpYmxlOnJpbmctcmluZycsXG4gIHtcbiAgICB2YXJpYW50czoge1xuICAgICAgc2l6ZToge1xuICAgICAgICBzbTogJ3RleHQteHMnLFxuICAgICAgICBkZWZhdWx0OiAndGV4dC1zbScsXG4gICAgICB9LFxuICAgIH0sXG4gICAgZGVmYXVsdFZhcmlhbnRzOiB7XG4gICAgICBzaXplOiAnZGVmYXVsdCcsXG4gICAgfSxcbiAgfVxuKTtcblxuZXhwb3J0IHR5cGUgU291cmNlUHJvcHMgPSBWYXJpYW50UHJvcHM8dHlwZW9mIHNvdXJjZVZhcmlhbnRzPjtcblxuLyoqIEEgc2luZ2xlIGNpdGF0aW9uIGluc2lkZSBhIGB0b2xsZS1zb3VyY2VzLWNvbnRlbnRgLiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtc291cmNlJyxcbiAgc3R5bGVzOiBbJzpob3N0IHsgZGlzcGxheTogYmxvY2s7IH0nXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxhXG4gICAgICBkYXRhLXNvdXJjZVxuICAgICAgW2F0dHIuaHJlZl09XCJocmVmIHx8IG51bGxcIlxuICAgICAgdGFyZ2V0PVwiX2JsYW5rXCJcbiAgICAgIHJlbD1cIm5vcmVmZXJyZXIgbm9vcGVuZXJcIlxuICAgICAgW2NsYXNzXT1cImNvbXB1dGVkQ2xhc3NcIlxuICAgID5cbiAgICAgIDxpbWdcbiAgICAgICAgKm5nSWY9XCJmYXZpY29uOyBlbHNlIGNoaXBcIlxuICAgICAgICBbYXR0ci5zcmNdPVwiZmF2aWNvblwiXG4gICAgICAgIGFsdD1cIlwiXG4gICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICAgIGNsYXNzPVwic2l6ZS00IHNocmluay0wIHJvdW5kZWQtc21cIlxuICAgICAgLz5cblxuICAgICAgPG5nLXRlbXBsYXRlICNjaGlwPlxuICAgICAgICA8c3BhblxuICAgICAgICAgIGNsYXNzPVwiZmxleCBzaXplLTQgc2hyaW5rLTAgaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHJvdW5kZWQtc20gYmctbXV0ZWQgdGV4dC1bMTBweF0gZm9udC1tZWRpdW0gdGV4dC1tdXRlZC1mb3JlZ3JvdW5kXCJcbiAgICAgICAgICBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgICAgID57eyBwb3NpdGlvbiB9fTwvc3BhblxuICAgICAgICA+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICA8c3BhbiBjbGFzcz1cInRydW5jYXRlIHRleHQtZm9yZWdyb3VuZFwiIGRhdGEtc291cmNlLXRpdGxlPnt7IHRpdGxlIHx8IGhyZWYgfX08L3NwYW4+XG5cbiAgICAgIDxpXG4gICAgICAgIGNsYXNzPVwicmktZXh0ZXJuYWwtbGluay1saW5lIG1sLWF1dG8gc2hyaW5rLTAgdGV4dC1tdXRlZC1mb3JlZ3JvdW5kIG9wYWNpdHktMCB0cmFuc2l0aW9uLW9wYWNpdHkgZ3JvdXAtaG92ZXI6b3BhY2l0eS0xMDBcIlxuICAgICAgICBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgPjwvaT5cblxuICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgIDwvYT5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgU291cmNlQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkluaXQsIE9uRGVzdHJveSB7XG5cbiAgLyoqXG4gICAqIEFuZ3VsYXIgd3JpdGVzIGEgYm91bmQgYGNsYXNzYCBpbnB1dCB0aHJvdWdoIGl0cyBzdHlsaW5nIHBhdGgsIHdoaWNoIGRvZXNcbiAgICogbm90IG1hcmsgYW4gT25QdXNoIGNvbXBvbmVudCBkaXJ0eSDigJQgd2l0aG91dCB0aGlzIGhvb2sgdGhlIGNvbXBvbmVudCBrZWVwc1xuICAgKiByZW5kZXJpbmcgdGhlIGNsYXNzIGl0IHdhcyBib3JuIHdpdGguXG4gICAqL1xuICBuZ09uQ2hhbmdlcygpOiB2b2lkIHtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKiBVUkwgdGhlIGNpdGF0aW9uIHBvaW50cyBhdC4gQGRlZmF1bHQgJycgKi9cbiAgQElucHV0KCkgaHJlZiA9ICcnO1xuICAvKiogSHVtYW4tcmVhZGFibGUgdGl0bGU7IGZhbGxzIGJhY2sgdG8gdGhlIGhyZWYgd2hlbiBlbXB0eS4gQGRlZmF1bHQgJycgKi9cbiAgQElucHV0KCkgdGl0bGUgPSAnJztcbiAgLyoqIFVSTCBvZiBhIGZhdmljb24gc2hvd24gaW5zdGVhZCBvZiB0aGUgbnVtYmVyZWQgY2hpcC4gQGRlZmF1bHQgJycgKi9cbiAgQElucHV0KCkgZmF2aWNvbiA9ICcnO1xuICAvKiogT3ZlcnJpZGVzIHRoZSBhdXRvLW51bWJlcmVkIHBvc2l0aW9uIGNoaXAuIEBkZWZhdWx0IG51bGwgKi9cbiAgQElucHV0KCkgaW5kZXg6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICAvKiogVGV4dCBzY2FsZSBvZiB0aGUgY2l0YXRpb24uIEBkZWZhdWx0ICdkZWZhdWx0JyAqL1xuICBASW5wdXQoKSBzaXplOiBTb3VyY2VQcm9wc1snc2l6ZSddID0gJ2RlZmF1bHQnO1xuICAvKiogRXh0cmEgVGFpbHdpbmQgY2xhc3NlcyBtZXJnZWQgb250byB0aGUgY2l0YXRpb24gdmlhIGBjbigpYCAobGFzdC13aW5zKS4gKi9cbiAgQElucHV0KCkgY2xhc3MgPSAnJztcblxuICBwcml2YXRlIHJlYWRvbmx5IHNlcnZpY2UgPSBpbmplY3QoU291cmNlc1NlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3Vic2NyaXB0aW9ucyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGlkID0gJ3NvdXJjZS0nICsgc291cmNlSWQrKztcblxuICBvcmRlciA9IDA7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5zZXJ2aWNlLnJlZ2lzdGVyKHRoaXMuaWQpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICB0aGlzLnNlcnZpY2UuaWRzJC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLm9yZGVyID0gdGhpcy5zZXJ2aWNlLmluZGV4T2YodGhpcy5pZCk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zZXJ2aWNlLnVucmVnaXN0ZXIodGhpcy5pZCk7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICAvKiogT25lLWJhc2VkIG51bWJlciBzaG93biBpbiB0aGUgY2hpcC4gKi9cbiAgZ2V0IHBvc2l0aW9uKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuaW5kZXggPz8gdGhpcy5vcmRlciArIDE7XG4gIH1cblxuICBnZXQgY29tcHV0ZWRDbGFzcygpIHtcbiAgICByZXR1cm4gY24oc291cmNlVmFyaWFudHMoeyBzaXplOiB0aGlzLnNpemUgfSksIHRoaXMuY2xhc3MpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,68 @@
1
+ import { Component, Input, ChangeDetectionStrategy, ChangeDetectorRef, inject } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { cva } from 'class-variance-authority';
4
+ import { cn } from './utils/cn';
5
+ import * as i0 from "@angular/core";
6
+ const spinnerVariants = cva('inline-block animate-spin rounded-full border-solid border-current border-r-transparent align-[-0.125em]', {
7
+ variants: {
8
+ size: {
9
+ xs: 'h-3 w-3 border-[1.5px]',
10
+ sm: 'h-4 w-4 border-2',
11
+ default: 'h-5 w-5 border-2',
12
+ lg: 'h-8 w-8 border-[3px]',
13
+ xl: 'h-12 w-12 border-4',
14
+ },
15
+ variant: {
16
+ default: 'text-foreground',
17
+ primary: 'text-primary',
18
+ muted: 'text-muted-foreground',
19
+ destructive: 'text-destructive',
20
+ },
21
+ },
22
+ defaultVariants: { size: 'default', variant: 'default' },
23
+ });
24
+ /**
25
+ * An indeterminate loading indicator. Renders as `role="status"` with a
26
+ * visually-hidden label so screen readers announce the loading state.
27
+ * @new
28
+ */
29
+ export class SpinnerComponent {
30
+ cdr = inject(ChangeDetectorRef);
31
+ ngOnChanges() {
32
+ this.cdr.markForCheck();
33
+ }
34
+ /** Diameter of the spinner. @default 'default' */
35
+ size = 'default';
36
+ /** Colour of the spinner, inherited from the theme tokens. @default 'default' */
37
+ variant = 'default';
38
+ /** Accessible label announced while the spinner is visible. @default 'Loading' */
39
+ label = 'Loading';
40
+ /** Extra Tailwind classes merged onto the spinner via `cn()` (last-wins). */
41
+ class = '';
42
+ get computedClass() {
43
+ return cn(spinnerVariants({ size: this.size, variant: this.variant }), this.class);
44
+ }
45
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
46
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SpinnerComponent, isStandalone: true, selector: "tolle-spinner", inputs: { size: "size", variant: "variant", label: "label", class: "class" }, usesOnChanges: true, ngImport: i0, template: `
47
+ <span role="status" [attr.aria-label]="label" [class]="computedClass">
48
+ <span class="sr-only">{{ label }}</span>
49
+ </span>
50
+ `, isInline: true, styles: [":host{display:inline-flex}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
51
+ }
52
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SpinnerComponent, decorators: [{
53
+ type: Component,
54
+ args: [{ selector: 'tolle-spinner', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
55
+ <span role="status" [attr.aria-label]="label" [class]="computedClass">
56
+ <span class="sr-only">{{ label }}</span>
57
+ </span>
58
+ `, styles: [":host{display:inline-flex}\n"] }]
59
+ }], propDecorators: { size: [{
60
+ type: Input
61
+ }], variant: [{
62
+ type: Input
63
+ }], label: [{
64
+ type: Input
65
+ }], class: [{
66
+ type: Input
67
+ }] } });
68
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Bpbm5lci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy90b2xsZS9zcmMvbGliL3NwaW5uZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLHVCQUF1QixFQUFFLGlCQUFpQixFQUFhLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoSCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLEdBQUcsRUFBcUIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sWUFBWSxDQUFDOztBQUVoQyxNQUFNLGVBQWUsR0FBRyxHQUFHLENBQUMsMEdBQTBHLEVBQUU7SUFDdEksUUFBUSxFQUFFO1FBQ1IsSUFBSSxFQUFFO1lBQ0osRUFBRSxFQUFFLHdCQUF3QjtZQUM1QixFQUFFLEVBQUUsa0JBQWtCO1lBQ3RCLE9BQU8sRUFBRSxrQkFBa0I7WUFDM0IsRUFBRSxFQUFFLHNCQUFzQjtZQUMxQixFQUFFLEVBQUUsb0JBQW9CO1NBQ3pCO1FBQ0QsT0FBTyxFQUFFO1lBQ1AsT0FBTyxFQUFFLGlCQUFpQjtZQUMxQixPQUFPLEVBQUUsY0FBYztZQUN2QixLQUFLLEVBQUUsdUJBQXVCO1lBQzlCLFdBQVcsRUFBRSxrQkFBa0I7U0FDaEM7S0FDRjtJQUNELGVBQWUsRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRTtDQUN6RCxDQUFDLENBQUM7QUFJSDs7OztHQUlHO0FBYUgsTUFBTSxPQUFPLGdCQUFnQjtJQUNWLEdBQUcsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUVqRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQsa0RBQWtEO0lBQ3pDLElBQUksR0FBeUIsU0FBUyxDQUFDO0lBQ2hELGlGQUFpRjtJQUN4RSxPQUFPLEdBQTRCLFNBQVMsQ0FBQztJQUN0RCxrRkFBa0Y7SUFDekUsS0FBSyxHQUFHLFNBQVMsQ0FBQztJQUMzQiw2RUFBNkU7SUFDcEUsS0FBSyxHQUFHLEVBQUUsQ0FBQztJQUVwQixJQUFJLGFBQWE7UUFDZixPQUFPLEVBQUUsQ0FBQyxlQUFlLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3JGLENBQUM7d0dBbEJVLGdCQUFnQjs0RkFBaEIsZ0JBQWdCLDRLQU5qQjs7OztHQUlULHFHQU5TLFlBQVk7OzRGQVFYLGdCQUFnQjtrQkFaNUIsU0FBUzsrQkFDRSxlQUFlLGNBRWIsSUFBSSxXQUNQLENBQUMsWUFBWSxDQUFDLG1CQUNOLHVCQUF1QixDQUFDLE1BQU0sWUFDckM7Ozs7R0FJVDs4QkFVUSxJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsT0FBTztzQkFBZixLQUFLO2dCQUVHLEtBQUs7c0JBQWIsS0FBSztnQkFFRyxLQUFLO3NCQUFiLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIE9uQ2hhbmdlcywgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgY3ZhLCB0eXBlIFZhcmlhbnRQcm9wcyB9IGZyb20gJ2NsYXNzLXZhcmlhbmNlLWF1dGhvcml0eSc7XG5pbXBvcnQgeyBjbiB9IGZyb20gJy4vdXRpbHMvY24nO1xuXG5jb25zdCBzcGlubmVyVmFyaWFudHMgPSBjdmEoJ2lubGluZS1ibG9jayBhbmltYXRlLXNwaW4gcm91bmRlZC1mdWxsIGJvcmRlci1zb2xpZCBib3JkZXItY3VycmVudCBib3JkZXItci10cmFuc3BhcmVudCBhbGlnbi1bLTAuMTI1ZW1dJywge1xuICB2YXJpYW50czoge1xuICAgIHNpemU6IHtcbiAgICAgIHhzOiAnaC0zIHctMyBib3JkZXItWzEuNXB4XScsXG4gICAgICBzbTogJ2gtNCB3LTQgYm9yZGVyLTInLFxuICAgICAgZGVmYXVsdDogJ2gtNSB3LTUgYm9yZGVyLTInLFxuICAgICAgbGc6ICdoLTggdy04IGJvcmRlci1bM3B4XScsXG4gICAgICB4bDogJ2gtMTIgdy0xMiBib3JkZXItNCcsXG4gICAgfSxcbiAgICB2YXJpYW50OiB7XG4gICAgICBkZWZhdWx0OiAndGV4dC1mb3JlZ3JvdW5kJyxcbiAgICAgIHByaW1hcnk6ICd0ZXh0LXByaW1hcnknLFxuICAgICAgbXV0ZWQ6ICd0ZXh0LW11dGVkLWZvcmVncm91bmQnLFxuICAgICAgZGVzdHJ1Y3RpdmU6ICd0ZXh0LWRlc3RydWN0aXZlJyxcbiAgICB9LFxuICB9LFxuICBkZWZhdWx0VmFyaWFudHM6IHsgc2l6ZTogJ2RlZmF1bHQnLCB2YXJpYW50OiAnZGVmYXVsdCcgfSxcbn0pO1xuXG5leHBvcnQgdHlwZSBTcGlubmVyUHJvcHMgPSBWYXJpYW50UHJvcHM8dHlwZW9mIHNwaW5uZXJWYXJpYW50cz47XG5cbi8qKlxuICogQW4gaW5kZXRlcm1pbmF0ZSBsb2FkaW5nIGluZGljYXRvci4gUmVuZGVycyBhcyBgcm9sZT1cInN0YXR1c1wiYCB3aXRoIGFcbiAqIHZpc3VhbGx5LWhpZGRlbiBsYWJlbCBzbyBzY3JlZW4gcmVhZGVycyBhbm5vdW5jZSB0aGUgbG9hZGluZyBzdGF0ZS5cbiAqIEBuZXdcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtc3Bpbm5lcicsXG4gIHN0eWxlczogWyc6aG9zdCB7IGRpc3BsYXk6IGlubGluZS1mbGV4OyB9J10sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgdGVtcGxhdGU6IGBcbiAgICA8c3BhbiByb2xlPVwic3RhdHVzXCIgW2F0dHIuYXJpYS1sYWJlbF09XCJsYWJlbFwiIFtjbGFzc109XCJjb21wdXRlZENsYXNzXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cInNyLW9ubHlcIj57eyBsYWJlbCB9fTwvc3Bhbj5cbiAgICA8L3NwYW4+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIFNwaW5uZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKiogRGlhbWV0ZXIgb2YgdGhlIHNwaW5uZXIuIEBkZWZhdWx0ICdkZWZhdWx0JyAqL1xuICBASW5wdXQoKSBzaXplOiBTcGlubmVyUHJvcHNbJ3NpemUnXSA9ICdkZWZhdWx0JztcbiAgLyoqIENvbG91ciBvZiB0aGUgc3Bpbm5lciwgaW5oZXJpdGVkIGZyb20gdGhlIHRoZW1lIHRva2Vucy4gQGRlZmF1bHQgJ2RlZmF1bHQnICovXG4gIEBJbnB1dCgpIHZhcmlhbnQ6IFNwaW5uZXJQcm9wc1sndmFyaWFudCddID0gJ2RlZmF1bHQnO1xuICAvKiogQWNjZXNzaWJsZSBsYWJlbCBhbm5vdW5jZWQgd2hpbGUgdGhlIHNwaW5uZXIgaXMgdmlzaWJsZS4gQGRlZmF1bHQgJ0xvYWRpbmcnICovXG4gIEBJbnB1dCgpIGxhYmVsID0gJ0xvYWRpbmcnO1xuICAvKiogRXh0cmEgVGFpbHdpbmQgY2xhc3NlcyBtZXJnZWQgb250byB0aGUgc3Bpbm5lciB2aWEgYGNuKClgIChsYXN0LXdpbnMpLiAqL1xuICBASW5wdXQoKSBjbGFzcyA9ICcnO1xuXG4gIGdldCBjb21wdXRlZENsYXNzKCkge1xuICAgIHJldHVybiBjbihzcGlubmVyVmFyaWFudHMoeyBzaXplOiB0aGlzLnNpemUsIHZhcmlhbnQ6IHRoaXMudmFyaWFudCB9KSwgdGhpcy5jbGFzcyk7XG4gIH1cbn1cbiJdfQ==