@visuno/angular 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +56 -2
  3. package/account-table/account-table.component.d.ts +72 -0
  4. package/action-log/action-log.component.d.ts +41 -0
  5. package/activity-heatmap/activity-heatmap.component.d.ts +67 -0
  6. package/agent-inbox/agent-inbox.component.d.ts +75 -0
  7. package/agent-lanes/agent-lanes.component.d.ts +152 -0
  8. package/agent-phases/agent-phases.component.d.ts +62 -0
  9. package/agent-run-timeline/agent-run-timeline.component.d.ts +113 -0
  10. package/agent-tree/agent-tree.component.d.ts +80 -0
  11. package/answer-action-bar/answer-action-bar.component.d.ts +110 -0
  12. package/artifact-card/artifact-card.component.d.ts +145 -0
  13. package/attachment-tray/attachment-tray.component.d.ts +84 -0
  14. package/badge/badge.component.d.ts +25 -0
  15. package/bar-chart/bar-chart.component.d.ts +87 -0
  16. package/browser-session/browser-session.component.d.ts +70 -0
  17. package/buttons/buttons.component.d.ts +63 -0
  18. package/card/card.component.d.ts +21 -0
  19. package/change-review/change-review.component.d.ts +97 -0
  20. package/citation-hover-card/citation-hover-card.component.d.ts +95 -0
  21. package/code-viewer/code-viewer.component.d.ts +86 -0
  22. package/composer/composer.component.d.ts +114 -0
  23. package/context-meter/context-meter.component.d.ts +60 -0
  24. package/core/icon.component.d.ts +10 -0
  25. package/core/reduced-motion.service.d.ts +15 -0
  26. package/decision-prompt/decision-prompt.component.d.ts +56 -0
  27. package/design-review/design-review.component.d.ts +108 -0
  28. package/design-tuner/design-tuner.component.d.ts +75 -0
  29. package/details-panel/details-panel.component.d.ts +150 -0
  30. package/donut-chart/donut-chart.component.d.ts +63 -0
  31. package/draft-review/draft-review.component.d.ts +128 -0
  32. package/error-recovery/error-recovery.component.d.ts +59 -0
  33. package/esm2022/account-table/account-table.component.mjs +399 -0
  34. package/esm2022/action-log/action-log.component.mjs +177 -0
  35. package/esm2022/activity-heatmap/activity-heatmap.component.mjs +285 -0
  36. package/esm2022/agent-inbox/agent-inbox.component.mjs +284 -0
  37. package/esm2022/agent-lanes/agent-lanes.component.mjs +600 -0
  38. package/esm2022/agent-phases/agent-phases.component.mjs +300 -0
  39. package/esm2022/agent-run-timeline/agent-run-timeline.component.mjs +412 -0
  40. package/esm2022/agent-tree/agent-tree.component.mjs +393 -0
  41. package/esm2022/answer-action-bar/answer-action-bar.component.mjs +636 -0
  42. package/esm2022/artifact-card/artifact-card.component.mjs +916 -0
  43. package/esm2022/attachment-tray/attachment-tray.component.mjs +402 -0
  44. package/esm2022/badge/badge.component.mjs +97 -0
  45. package/esm2022/bar-chart/bar-chart.component.mjs +300 -0
  46. package/esm2022/browser-session/browser-session.component.mjs +352 -0
  47. package/esm2022/buttons/buttons.component.mjs +215 -0
  48. package/esm2022/card/card.component.mjs +107 -0
  49. package/esm2022/change-review/change-review.component.mjs +398 -0
  50. package/esm2022/citation-hover-card/citation-hover-card.component.mjs +360 -0
  51. package/esm2022/code-viewer/code-viewer.component.mjs +291 -0
  52. package/esm2022/composer/composer.component.mjs +743 -0
  53. package/esm2022/context-meter/context-meter.component.mjs +275 -0
  54. package/esm2022/core/icon.component.mjs +111 -0
  55. package/esm2022/core/reduced-motion.service.mjs +34 -0
  56. package/esm2022/decision-prompt/decision-prompt.component.mjs +259 -0
  57. package/esm2022/design-review/design-review.component.mjs +428 -0
  58. package/esm2022/design-tuner/design-tuner.component.mjs +341 -0
  59. package/esm2022/details-panel/details-panel.component.mjs +537 -0
  60. package/esm2022/donut-chart/donut-chart.component.mjs +240 -0
  61. package/esm2022/draft-review/draft-review.component.mjs +549 -0
  62. package/esm2022/error-recovery/error-recovery.component.mjs +231 -0
  63. package/esm2022/eval-results/eval-results.component.mjs +368 -0
  64. package/esm2022/feedback-sheet/feedback-sheet.component.mjs +411 -0
  65. package/esm2022/field-extraction/field-extraction.component.mjs +368 -0
  66. package/esm2022/funnel-chart/funnel-chart.component.mjs +258 -0
  67. package/esm2022/grid/grid.component.mjs +66 -0
  68. package/esm2022/health-score/health-score.component.mjs +420 -0
  69. package/esm2022/human-handoff/human-handoff.component.mjs +676 -0
  70. package/esm2022/image-generation/image-generation.component.mjs +1028 -0
  71. package/esm2022/inline-text-diff/inline-text-diff.component.mjs +390 -0
  72. package/esm2022/launch-checklist/launch-checklist.component.mjs +229 -0
  73. package/esm2022/line-chart/line-chart.component.mjs +417 -0
  74. package/esm2022/live-answer/live-answer.component.mjs +411 -0
  75. package/esm2022/metric-insight/metric-insight.component.mjs +511 -0
  76. package/esm2022/modal/modal.component.mjs +202 -0
  77. package/esm2022/model-picker/model-picker.component.mjs +491 -0
  78. package/esm2022/permission-gate/permission-gate.component.mjs +498 -0
  79. package/esm2022/plan-review/plan-review.component.mjs +432 -0
  80. package/esm2022/progress/progress.component.mjs +503 -0
  81. package/esm2022/prompt-library/prompt-library.component.mjs +453 -0
  82. package/esm2022/prompt-starters/prompt-starters.component.mjs +272 -0
  83. package/esm2022/proposal-card/proposal-card.component.mjs +402 -0
  84. package/esm2022/public-api.mjs +88 -0
  85. package/esm2022/radar-chart/radar-chart.component.mjs +500 -0
  86. package/esm2022/radial-goals/radial-goals.component.mjs +418 -0
  87. package/esm2022/reasoning-trail/reasoning-trail.component.mjs +284 -0
  88. package/esm2022/response-versions/response-versions.component.mjs +288 -0
  89. package/esm2022/rewrite-toolbar/rewrite-toolbar.component.mjs +397 -0
  90. package/esm2022/rich-text-editor/rich-text-editor.component.mjs +1755 -0
  91. package/esm2022/run-cost/run-cost.component.mjs +215 -0
  92. package/esm2022/run-queue/run-queue.component.mjs +481 -0
  93. package/esm2022/run-summary/run-summary.component.mjs +331 -0
  94. package/esm2022/scatter-chart/scatter-chart.component.mjs +705 -0
  95. package/esm2022/score-breakdown/score-breakdown.component.mjs +460 -0
  96. package/esm2022/segmented-control/segmented-control.component.mjs +180 -0
  97. package/esm2022/source-stack/source-stack.component.mjs +245 -0
  98. package/esm2022/stat-cards/stat-cards.component.mjs +258 -0
  99. package/esm2022/status-pill/status-pill.component.mjs +305 -0
  100. package/esm2022/steering/steering.component.mjs +343 -0
  101. package/esm2022/step-loader/step-loader.component.mjs +209 -0
  102. package/esm2022/task-table/task-table.component.mjs +534 -0
  103. package/esm2022/terminal-stream/terminal-stream.component.mjs +583 -0
  104. package/esm2022/thinking/thinking.component.mjs +276 -0
  105. package/esm2022/thinking-states/thinking-states.component.mjs +333 -0
  106. package/esm2022/thread-panel/thread-panel.component.mjs +271 -0
  107. package/esm2022/toast/toast.component.mjs +195 -0
  108. package/esm2022/toast-stack/toast-stack.component.mjs +301 -0
  109. package/esm2022/tool-call/tool-call.component.mjs +273 -0
  110. package/esm2022/tooltip/tooltip.component.mjs +417 -0
  111. package/esm2022/top-pages/top-pages.component.mjs +240 -0
  112. package/esm2022/trace-view/trace-view.component.mjs +440 -0
  113. package/esm2022/visuno-angular.mjs +5 -0
  114. package/esm2022/voice-capture/voice-capture.component.mjs +650 -0
  115. package/esm2022/voice-orb/voice-orb.component.mjs +538 -0
  116. package/esm2022/web-search/web-search.component.mjs +374 -0
  117. package/eval-results/eval-results.component.d.ts +67 -0
  118. package/feedback-sheet/feedback-sheet.component.d.ts +74 -0
  119. package/fesm2022/visuno-angular.mjs +31992 -0
  120. package/fesm2022/visuno-angular.mjs.map +1 -0
  121. package/field-extraction/field-extraction.component.d.ts +82 -0
  122. package/funnel-chart/funnel-chart.component.d.ts +70 -0
  123. package/grid/grid.component.d.ts +22 -0
  124. package/health-score/health-score.component.d.ts +87 -0
  125. package/human-handoff/human-handoff.component.d.ts +125 -0
  126. package/image-generation/image-generation.component.d.ts +253 -0
  127. package/index.d.ts +5 -0
  128. package/inline-text-diff/inline-text-diff.component.d.ts +76 -0
  129. package/launch-checklist/launch-checklist.component.d.ts +46 -0
  130. package/line-chart/line-chart.component.d.ts +89 -0
  131. package/live-answer/live-answer.component.d.ts +110 -0
  132. package/metric-insight/metric-insight.component.d.ts +110 -0
  133. package/modal/modal.component.d.ts +37 -0
  134. package/model-picker/model-picker.component.d.ts +97 -0
  135. package/package.json +51 -4
  136. package/permission-gate/permission-gate.component.d.ts +100 -0
  137. package/plan-review/plan-review.component.d.ts +86 -0
  138. package/progress/progress.component.d.ts +91 -0
  139. package/prompt-library/prompt-library.component.d.ts +121 -0
  140. package/prompt-starters/prompt-starters.component.d.ts +65 -0
  141. package/proposal-card/proposal-card.component.d.ts +101 -0
  142. package/public-api.d.ts +82 -0
  143. package/radar-chart/radar-chart.component.d.ts +110 -0
  144. package/radial-goals/radial-goals.component.d.ts +90 -0
  145. package/reasoning-trail/reasoning-trail.component.d.ts +73 -0
  146. package/response-versions/response-versions.component.d.ts +54 -0
  147. package/rewrite-toolbar/rewrite-toolbar.component.d.ts +92 -0
  148. package/rich-text-editor/rich-text-editor.component.d.ts +180 -0
  149. package/run-cost/run-cost.component.d.ts +43 -0
  150. package/run-queue/run-queue.component.d.ts +93 -0
  151. package/run-summary/run-summary.component.d.ts +81 -0
  152. package/scatter-chart/scatter-chart.component.d.ts +139 -0
  153. package/score-breakdown/score-breakdown.component.d.ts +107 -0
  154. package/segmented-control/segmented-control.component.d.ts +44 -0
  155. package/source-stack/source-stack.component.d.ts +60 -0
  156. package/stat-cards/stat-cards.component.d.ts +86 -0
  157. package/status-pill/status-pill.component.d.ts +64 -0
  158. package/steering/steering.component.d.ts +75 -0
  159. package/step-loader/step-loader.component.d.ts +40 -0
  160. package/styles.css +424 -0
  161. package/task-table/task-table.component.d.ts +114 -0
  162. package/terminal-stream/terminal-stream.component.d.ts +110 -0
  163. package/thinking/thinking.component.d.ts +63 -0
  164. package/thinking-states/thinking-states.component.d.ts +51 -0
  165. package/thread-panel/thread-panel.component.d.ts +75 -0
  166. package/toast/toast.component.d.ts +56 -0
  167. package/toast-stack/toast-stack.component.d.ts +72 -0
  168. package/tokens.css +424 -0
  169. package/tool-call/tool-call.component.d.ts +61 -0
  170. package/tooltip/tooltip.component.d.ts +89 -0
  171. package/top-pages/top-pages.component.d.ts +75 -0
  172. package/trace-view/trace-view.component.d.ts +95 -0
  173. package/voice-capture/voice-capture.component.d.ts +103 -0
  174. package/voice-orb/voice-orb.component.d.ts +78 -0
  175. package/web-search/web-search.component.d.ts +77 -0
@@ -0,0 +1,417 @@
1
+ // framework/angular/tooltip/tooltip.component.ts
2
+ //
3
+ // Native Angular port of framework/react/tooltip/Tooltip.tsx.
4
+ // A toolbar of icon buttons whose labels wait a moment then follow the pointer
5
+ // instantly between buttons, plus avatar chips that show a richer person card
6
+ // on hover. Inputs mirror the React props; the hover/positioning logic is
7
+ // ported from the Vanilla JS (delay + placement, kept inside the component).
8
+ import { Component, Input, ViewChild, ViewEncapsulation, } from '@angular/core';
9
+ import { VoIconComponent } from '../core/icon.component';
10
+ import * as i0 from "@angular/core";
11
+ const DEFAULT_GROUPS = [
12
+ [
13
+ { key: 'undo', icon: 'undo', label: 'Undo', kbd: '⌘Z' },
14
+ { key: 'comment', icon: 'edit', label: 'Comment', kbd: 'C' },
15
+ { key: 'ask', icon: 'spark', label: 'Ask agent', tip: 'Ask the agent', kbd: '⌘J' },
16
+ ],
17
+ [{ key: 'share', icon: 'users', label: 'Share', tip: 'Share with your team' }],
18
+ ];
19
+ // when the last visible tip closed, shared by every tooltip so moving straight
20
+ // from one button to the next shows the next label at once (as on the site)
21
+ let tipSeen = -Infinity;
22
+ /** The ink for initials on an avatar colour: each of the eight avatar colours has its own ink token. */
23
+ const avatarInk = (color) => /^var\(--vo-av-[a-z]\)$/.test(color) ? color.replace(')', '-ink)') : undefined;
24
+ /** A toolbar whose labels follow the pointer between buttons, with a richer card for people. */
25
+ export class TooltipComponent {
26
+ constructor() {
27
+ /** The toolbar's buttons, in groups with a line between them. */
28
+ this.groups = DEFAULT_GROUPS;
29
+ /** Avatars at the end of the toolbar; hovering one shows a card. */
30
+ this.people = [];
31
+ /** How long the person card waits before it shows. */
32
+ this.cardDelay = 300;
33
+ this.tipAt = null;
34
+ this.tipShow = false;
35
+ this.card = null;
36
+ this.cardShow = false;
37
+ this.tipOverKey = null;
38
+ this.cardOverKey = null;
39
+ this.ready = false;
40
+ }
41
+ /** Shows this tool's tip, by key, as if it were hovered. */
42
+ set openTip(key) {
43
+ this._openTip = key;
44
+ this.applyOpenTip();
45
+ }
46
+ get openTip() {
47
+ return this._openTip;
48
+ }
49
+ /** Shows this person's card, by key, as if they were hovered. */
50
+ set openCard(key) {
51
+ this._openCard = key;
52
+ this.applyOpenCard();
53
+ }
54
+ get openCard() {
55
+ return this._openCard;
56
+ }
57
+ ink(color) {
58
+ return avatarInk(color);
59
+ }
60
+ ngAfterViewInit() {
61
+ this.ready = true;
62
+ this.applyOpenTip();
63
+ this.applyOpenCard();
64
+ }
65
+ /* ---------- toolbar tips ---------- */
66
+ openTipFor(t, e) {
67
+ this.tipOverKey = t.key;
68
+ this.showTip(t, e.currentTarget);
69
+ }
70
+ focusTip(t, e) {
71
+ const el = e.target;
72
+ if (el.matches(':focus-visible'))
73
+ this.showTip(t, el, true);
74
+ }
75
+ leaveTip() {
76
+ this.tipOverKey = null;
77
+ if (this._openTip == null)
78
+ this.hideTip();
79
+ }
80
+ showTip(t, el, now = false) {
81
+ clearTimeout(this.tipTimer);
82
+ const delay = now || performance.now() - tipSeen < 120 ? 0 : 380;
83
+ this.tipTimer = setTimeout(() => this.placeTip(t, el), delay);
84
+ }
85
+ placeTip(t, el) {
86
+ const box = this.root?.nativeElement;
87
+ const node = this.tipEl?.nativeElement;
88
+ if (!box || !node)
89
+ return;
90
+ this.tipAt = { x: 0, y: 0, label: t.tip ?? t.label, kbd: t.kbd };
91
+ this.tipShow = false;
92
+ // measure after the label is in, then centre above the button (within bounds)
93
+ requestAnimationFrame(() => {
94
+ const rr = box.getBoundingClientRect();
95
+ const br = el.getBoundingClientRect();
96
+ const w = node.offsetWidth;
97
+ const h = node.offsetHeight;
98
+ let x = br.left - rr.left + br.width / 2 - w / 2;
99
+ x = Math.max(0, Math.min(x, rr.width - w));
100
+ const y = br.top - rr.top - h - 8;
101
+ this.tipAt = { ...this.tipAt, x, y };
102
+ requestAnimationFrame(() => (this.tipShow = true));
103
+ });
104
+ }
105
+ hideTip() {
106
+ clearTimeout(this.tipTimer);
107
+ if (this.tipAt)
108
+ tipSeen = performance.now();
109
+ this.tipShow = false;
110
+ this.tipAt = null;
111
+ }
112
+ applyOpenTip() {
113
+ if (!this.ready || this._openTip === undefined)
114
+ return;
115
+ const tool = this.groups.flat().find((t) => t.key === this._openTip);
116
+ if (tool) {
117
+ const el = this.buttonFor(tool.key);
118
+ if (el)
119
+ this.showTip(tool, el, true);
120
+ }
121
+ else if (!this.tipOverKey) {
122
+ this.hideTip();
123
+ }
124
+ }
125
+ buttonFor(key) {
126
+ const box = this.root?.nativeElement;
127
+ if (!box)
128
+ return null;
129
+ const idx = this.groups.flat().findIndex((t) => t.key === key);
130
+ const buttons = box.querySelectorAll('.vo-ttp-bar > .vo-ib');
131
+ return buttons[idx] ?? null;
132
+ }
133
+ /* ---------- person card ---------- */
134
+ openCardFor(person, e) {
135
+ this.cardOverKey = person.key;
136
+ this.openCardAt(person, e.currentTarget);
137
+ }
138
+ focusCard(person, e) {
139
+ const el = e.target;
140
+ if (el.matches(':focus-visible'))
141
+ this.openCardAt(person, el, true);
142
+ }
143
+ leaveCard() {
144
+ this.cardOverKey = null;
145
+ this.closeCard();
146
+ }
147
+ openCardAt(person, el, now = false) {
148
+ clearTimeout(this.cardTimer);
149
+ this.cardTimer = setTimeout(() => {
150
+ const box = this.root?.nativeElement;
151
+ if (!box)
152
+ return;
153
+ const rr = box.getBoundingClientRect();
154
+ const br = el.getBoundingClientRect();
155
+ const left = Math.max(0, Math.min(br.left - rr.left + br.width / 2 - 115, rr.width - 230));
156
+ this.card = { person, left, top: br.bottom - rr.top + 10 };
157
+ this.cardShow = true;
158
+ }, now ? 0 : this.cardDelay);
159
+ }
160
+ closeCard() {
161
+ clearTimeout(this.cardTimer);
162
+ this.cardShow = false;
163
+ }
164
+ applyOpenCard() {
165
+ if (!this.ready || this._openCard === undefined)
166
+ return;
167
+ const person = this.people.find((x) => x.key === this._openCard);
168
+ const el = person ? this.avatarFor(person.key) : null;
169
+ if (person && el)
170
+ this.openCardAt(person, el, true);
171
+ else if (!this.cardOverKey)
172
+ this.closeCard();
173
+ }
174
+ avatarFor(key) {
175
+ const box = this.root?.nativeElement;
176
+ if (!box)
177
+ return null;
178
+ const idx = this.people.findIndex((p) => p.key === key);
179
+ const avatars = box.querySelectorAll('.vo-ttp-av');
180
+ return avatars[idx] ?? null;
181
+ }
182
+ ngOnDestroy() {
183
+ clearTimeout(this.tipTimer);
184
+ clearTimeout(this.cardTimer);
185
+ }
186
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
187
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: TooltipComponent, isStandalone: true, selector: "vo-tooltip", inputs: { groups: "groups", people: "people", note: "note", cardDelay: "cardDelay", openTip: "openTip", openCard: "openCard" }, viewQueries: [{ propertyName: "root", first: true, predicate: ["root"], descendants: true }, { propertyName: "tipEl", first: true, predicate: ["tip"], descendants: true }], ngImport: i0, template: `
188
+ <div data-vo="" #root class="vo-ttp">
189
+ <div class="vo-ttp-bar vo-panel">
190
+ @for (g of groups; track $index; let gi = $index) {
191
+ @if (gi > 0) {
192
+ <span class="vo-ttp-sep"></span>
193
+ }
194
+ @for (t of g; track t.key) {
195
+ <button
196
+ type="button"
197
+ class="vo-ib"
198
+ [attr.aria-label]="t.label"
199
+ (click)="t.onClick?.()"
200
+ (pointerenter)="openTipFor(t, $event)"
201
+ (pointerleave)="leaveTip()"
202
+ (focus)="focusTip(t, $event)"
203
+ (blur)="leaveTip()"
204
+ >
205
+ <vo-icon [name]="t.icon" size="sm"></vo-icon>
206
+ </button>
207
+ }
208
+ }
209
+ @if (people.length > 0) {
210
+ <span class="vo-ttp-sep"></span>
211
+ <span class="vo-ttp-avs">
212
+ @for (person of people; track person.key) {
213
+ <button
214
+ type="button"
215
+ class="vo-ttp-av"
216
+ [attr.aria-label]="person.name"
217
+ (mouseenter)="openCardFor(person, $event)"
218
+ (mouseleave)="leaveCard()"
219
+ (focus)="focusCard(person, $event)"
220
+ (blur)="closeCard()"
221
+ >
222
+ <span
223
+ class="vo-av"
224
+ aria-hidden="true"
225
+ [style.background]="person.color"
226
+ [style.color]="ink(person.color)"
227
+ >{{ person.initials }}</span
228
+ >
229
+ </button>
230
+ }
231
+ </span>
232
+ }
233
+ </div>
234
+
235
+ <!-- the toolbar's own dark tip, kept inside the component bounds -->
236
+ <div
237
+ #tip
238
+ class="vo-tip"
239
+ [class.vo-show]="tipShow"
240
+ role="tooltip"
241
+ data-vo=""
242
+ [style.left.px]="tipAt?.x ?? 0"
243
+ [style.top.px]="tipAt?.y ?? 0"
244
+ [style.visibility]="tipAt ? 'visible' : 'hidden'"
245
+ >
246
+ {{ tipAt?.label }}
247
+ @if (tipAt?.kbd) {
248
+ <span class="vo-kbd">{{ tipAt?.kbd }}</span>
249
+ }
250
+ </div>
251
+
252
+ <!-- the richer person card -->
253
+ <div
254
+ class="vo-ttp-card vo-panel"
255
+ [class.vo-show]="cardShow"
256
+ [style.left.px]="card?.left"
257
+ [style.top.px]="card?.top"
258
+ [attr.aria-hidden]="!cardShow"
259
+ >
260
+ <div class="vo-ttp-ci">
261
+ @if (card; as c) {
262
+ <div class="vo-ttp-ch">
263
+ <span
264
+ class="vo-av"
265
+ aria-hidden="true"
266
+ [style.background]="c.person.color"
267
+ [style.color]="ink(c.person.color)"
268
+ >{{ c.person.initials }}</span
269
+ >
270
+ <div><b>{{ c.person.name }}</b><span>{{ c.person.role }}</span></div>
271
+ </div>
272
+ <div class="vo-ttp-cs">
273
+ @if (c.person.working) {
274
+ <span style="display:inline-flex;color:var(--vo-accent)">
275
+ <span class="vo-think vo-on" aria-hidden="true"><i></i><i></i><i></i><i></i></span>
276
+ </span>
277
+ } @else {
278
+ <span class="vo-dot" aria-hidden="true"></span>
279
+ }
280
+ {{ c.person.status }}
281
+ </div>
282
+ }
283
+ </div>
284
+ </div>
285
+
286
+ @if (note) {
287
+ <p class="vo-muted vo-ttp-n">{{ note }}</p>
288
+ }
289
+ </div>
290
+ `, isInline: true, styles: [".vo-ttp{display:flex;flex-direction:column;align-items:center;gap:var(--vo-s-4);position:relative;min-height:200px;justify-content:center}.vo-ttp-bar{display:flex;align-items:center;gap:2px;padding:5px;border-radius:var(--vo-r-pill)}.vo-ttp-sep{width:1px;height:18px;background:var(--vo-line);margin:0 var(--vo-s-1)}.vo-ttp-avs{display:flex;padding-right:3px}.vo-ttp-av{border-radius:50%;margin-left:-4px;transition:transform .3s var(--vo-ease)}.vo-ttp-av:first-child{margin-left:0}@media (hover:hover) and (pointer:fine){.vo-ttp-av:hover{transform:translateY(-2px)}}.vo-ttp-av .vo-av{width:28px;height:28px;font-size:11px;box-shadow:0 0 0 2px var(--vo-surface)}.vo-ttp .vo-tip{position:absolute}.vo-ttp-card{position:absolute;top:0;left:0;width:230px;padding:var(--vo-s-3);box-shadow:var(--vo-shadow-pop);opacity:0;transform:translateY(6px) scale(.97);filter:blur(4px);pointer-events:none;transition:opacity .25s var(--vo-ease),transform .35s var(--vo-ease),filter .25s;z-index:5}.vo-ttp-card.vo-show{opacity:1;transform:none;filter:none}.vo-ttp-ch{display:flex;align-items:center;gap:10px}.vo-ttp-ch .vo-av{width:34px;height:34px;font-size:12px}.vo-ttp-ch div{display:flex;flex-direction:column;font-size:13px}.vo-ttp-ch b{font-weight:500}.vo-ttp-ch div span{font-size:12px;color:var(--vo-muted)}.vo-ttp-cs{display:flex;align-items:center;gap:6px;margin-top:10px;font-size:12px;color:var(--vo-fg2)}.vo-ttp-cs .vo-dot{color:var(--vo-ok)}.vo-ttp-n{font-size:12.5px;text-align:center}\n"], dependencies: [{ kind: "component", type: VoIconComponent, selector: "vo-icon", inputs: ["name", "size"] }], encapsulation: i0.ViewEncapsulation.None }); }
291
+ }
292
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TooltipComponent, decorators: [{
293
+ type: Component,
294
+ args: [{ selector: 'vo-tooltip', standalone: true, encapsulation: ViewEncapsulation.None, imports: [VoIconComponent], template: `
295
+ <div data-vo="" #root class="vo-ttp">
296
+ <div class="vo-ttp-bar vo-panel">
297
+ @for (g of groups; track $index; let gi = $index) {
298
+ @if (gi > 0) {
299
+ <span class="vo-ttp-sep"></span>
300
+ }
301
+ @for (t of g; track t.key) {
302
+ <button
303
+ type="button"
304
+ class="vo-ib"
305
+ [attr.aria-label]="t.label"
306
+ (click)="t.onClick?.()"
307
+ (pointerenter)="openTipFor(t, $event)"
308
+ (pointerleave)="leaveTip()"
309
+ (focus)="focusTip(t, $event)"
310
+ (blur)="leaveTip()"
311
+ >
312
+ <vo-icon [name]="t.icon" size="sm"></vo-icon>
313
+ </button>
314
+ }
315
+ }
316
+ @if (people.length > 0) {
317
+ <span class="vo-ttp-sep"></span>
318
+ <span class="vo-ttp-avs">
319
+ @for (person of people; track person.key) {
320
+ <button
321
+ type="button"
322
+ class="vo-ttp-av"
323
+ [attr.aria-label]="person.name"
324
+ (mouseenter)="openCardFor(person, $event)"
325
+ (mouseleave)="leaveCard()"
326
+ (focus)="focusCard(person, $event)"
327
+ (blur)="closeCard()"
328
+ >
329
+ <span
330
+ class="vo-av"
331
+ aria-hidden="true"
332
+ [style.background]="person.color"
333
+ [style.color]="ink(person.color)"
334
+ >{{ person.initials }}</span
335
+ >
336
+ </button>
337
+ }
338
+ </span>
339
+ }
340
+ </div>
341
+
342
+ <!-- the toolbar's own dark tip, kept inside the component bounds -->
343
+ <div
344
+ #tip
345
+ class="vo-tip"
346
+ [class.vo-show]="tipShow"
347
+ role="tooltip"
348
+ data-vo=""
349
+ [style.left.px]="tipAt?.x ?? 0"
350
+ [style.top.px]="tipAt?.y ?? 0"
351
+ [style.visibility]="tipAt ? 'visible' : 'hidden'"
352
+ >
353
+ {{ tipAt?.label }}
354
+ @if (tipAt?.kbd) {
355
+ <span class="vo-kbd">{{ tipAt?.kbd }}</span>
356
+ }
357
+ </div>
358
+
359
+ <!-- the richer person card -->
360
+ <div
361
+ class="vo-ttp-card vo-panel"
362
+ [class.vo-show]="cardShow"
363
+ [style.left.px]="card?.left"
364
+ [style.top.px]="card?.top"
365
+ [attr.aria-hidden]="!cardShow"
366
+ >
367
+ <div class="vo-ttp-ci">
368
+ @if (card; as c) {
369
+ <div class="vo-ttp-ch">
370
+ <span
371
+ class="vo-av"
372
+ aria-hidden="true"
373
+ [style.background]="c.person.color"
374
+ [style.color]="ink(c.person.color)"
375
+ >{{ c.person.initials }}</span
376
+ >
377
+ <div><b>{{ c.person.name }}</b><span>{{ c.person.role }}</span></div>
378
+ </div>
379
+ <div class="vo-ttp-cs">
380
+ @if (c.person.working) {
381
+ <span style="display:inline-flex;color:var(--vo-accent)">
382
+ <span class="vo-think vo-on" aria-hidden="true"><i></i><i></i><i></i><i></i></span>
383
+ </span>
384
+ } @else {
385
+ <span class="vo-dot" aria-hidden="true"></span>
386
+ }
387
+ {{ c.person.status }}
388
+ </div>
389
+ }
390
+ </div>
391
+ </div>
392
+
393
+ @if (note) {
394
+ <p class="vo-muted vo-ttp-n">{{ note }}</p>
395
+ }
396
+ </div>
397
+ `, styles: [".vo-ttp{display:flex;flex-direction:column;align-items:center;gap:var(--vo-s-4);position:relative;min-height:200px;justify-content:center}.vo-ttp-bar{display:flex;align-items:center;gap:2px;padding:5px;border-radius:var(--vo-r-pill)}.vo-ttp-sep{width:1px;height:18px;background:var(--vo-line);margin:0 var(--vo-s-1)}.vo-ttp-avs{display:flex;padding-right:3px}.vo-ttp-av{border-radius:50%;margin-left:-4px;transition:transform .3s var(--vo-ease)}.vo-ttp-av:first-child{margin-left:0}@media (hover:hover) and (pointer:fine){.vo-ttp-av:hover{transform:translateY(-2px)}}.vo-ttp-av .vo-av{width:28px;height:28px;font-size:11px;box-shadow:0 0 0 2px var(--vo-surface)}.vo-ttp .vo-tip{position:absolute}.vo-ttp-card{position:absolute;top:0;left:0;width:230px;padding:var(--vo-s-3);box-shadow:var(--vo-shadow-pop);opacity:0;transform:translateY(6px) scale(.97);filter:blur(4px);pointer-events:none;transition:opacity .25s var(--vo-ease),transform .35s var(--vo-ease),filter .25s;z-index:5}.vo-ttp-card.vo-show{opacity:1;transform:none;filter:none}.vo-ttp-ch{display:flex;align-items:center;gap:10px}.vo-ttp-ch .vo-av{width:34px;height:34px;font-size:12px}.vo-ttp-ch div{display:flex;flex-direction:column;font-size:13px}.vo-ttp-ch b{font-weight:500}.vo-ttp-ch div span{font-size:12px;color:var(--vo-muted)}.vo-ttp-cs{display:flex;align-items:center;gap:6px;margin-top:10px;font-size:12px;color:var(--vo-fg2)}.vo-ttp-cs .vo-dot{color:var(--vo-ok)}.vo-ttp-n{font-size:12.5px;text-align:center}\n"] }]
398
+ }], propDecorators: { groups: [{
399
+ type: Input
400
+ }], people: [{
401
+ type: Input
402
+ }], note: [{
403
+ type: Input
404
+ }], cardDelay: [{
405
+ type: Input
406
+ }], openTip: [{
407
+ type: Input
408
+ }], openCard: [{
409
+ type: Input
410
+ }], root: [{
411
+ type: ViewChild,
412
+ args: ['root']
413
+ }], tipEl: [{
414
+ type: ViewChild,
415
+ args: ['tip']
416
+ }] } });
417
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbHRpcC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90b29sdGlwL3Rvb2x0aXAuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlEQUFpRDtBQUNqRCxFQUFFO0FBQ0YsOERBQThEO0FBQzlELCtFQUErRTtBQUMvRSw4RUFBOEU7QUFDOUUsMEVBQTBFO0FBQzFFLDZFQUE2RTtBQUU3RSxPQUFPLEVBRUwsU0FBUyxFQUVULEtBQUssRUFFTCxTQUFTLEVBQ1QsaUJBQWlCLEdBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxlQUFlLEVBQW1CLE1BQU0sd0JBQXdCLENBQUM7O0FBNEIxRSxNQUFNLGNBQWMsR0FBb0I7SUFDdEM7UUFDRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUU7UUFDdkQsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFO1FBQzVELEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsR0FBRyxFQUFFLGVBQWUsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFO0tBQ25GO0lBQ0QsQ0FBQyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxzQkFBc0IsRUFBRSxDQUFDO0NBQy9FLENBQUM7QUFFRiwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLElBQUksT0FBTyxHQUFHLENBQUMsUUFBUSxDQUFDO0FBY3hCLHdHQUF3RztBQUN4RyxNQUFNLFNBQVMsR0FBRyxDQUFDLEtBQWEsRUFBc0IsRUFBRSxDQUN0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QUNsQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUN0QyxxQkFBcUIsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNyRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxPQUFPO1FBQ2IsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM1QixJQUFJLElBQUksQ0FBQyxLQUFLO1lBQUUsT0FBTyxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUM1QyxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNyQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztJQUNwQixDQUFDO0lBRU8sWUFBWTtRQUNsQixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVM7WUFBRSxPQUFPO1FBQ3ZELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNyRSxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDcEMsSUFBSSxFQUFFO2dCQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN2QyxDQUFDO2FBQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDakIsQ0FBQztJQUNILENBQUM7SUFFTyxTQUFTLENBQUMsR0FBVztRQUMz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NUIsU0FBUzsrQkFDRSxZQUFZLGNBQ1YsSUFBSSxpQkFDRCxpQkFBaUIsQ0FBQyxJQUFJLFdBQzVCLENBQUMsZUFBZSxDQUFDLFlBQ2hCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdUdUOzhCQUtRLE1BQU07c0JBQWQsS0FBSztnQkFFRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsSUFBSTtzQkFBWixLQUFLO2dCQUVHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBT0YsT0FBTztzQkFEVixLQUFLO2dCQVdGLFFBQVE7c0JBRFgsS0FBSztnQkFTYSxJQUFJO3NCQUF0QixTQUFTO3VCQUFDLE1BQU07Z0JBQ0MsS0FBSztzQkFBdEIsU0FBUzt1QkFBQyxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiLy8gZnJhbWV3b3JrL2FuZ3VsYXIvdG9vbHRpcC90b29sdGlwLmNvbXBvbmVudC50c1xuLy9cbi8vIE5hdGl2ZSBBbmd1bGFyIHBvcnQgb2YgZnJhbWV3b3JrL3JlYWN0L3Rvb2x0aXAvVG9vbHRpcC50c3guXG4vLyBBIHRvb2xiYXIgb2YgaWNvbiBidXR0b25zIHdob3NlIGxhYmVscyB3YWl0IGEgbW9tZW50IHRoZW4gZm9sbG93IHRoZSBwb2ludGVyXG4vLyBpbnN0YW50bHkgYmV0d2VlbiBidXR0b25zLCBwbHVzIGF2YXRhciBjaGlwcyB0aGF0IHNob3cgYSByaWNoZXIgcGVyc29uIGNhcmRcbi8vIG9uIGhvdmVyLiBJbnB1dHMgbWlycm9yIHRoZSBSZWFjdCBwcm9wczsgdGhlIGhvdmVyL3Bvc2l0aW9uaW5nIGxvZ2ljIGlzXG4vLyBwb3J0ZWQgZnJvbSB0aGUgVmFuaWxsYSBKUyAoZGVsYXkgKyBwbGFjZW1lbnQsIGtlcHQgaW5zaWRlIHRoZSBjb21wb25lbnQpLlxuXG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVm9JY29uQ29tcG9uZW50LCB0eXBlIFZvSWNvbk5hbWUgfSBmcm9tICcuLi9jb3JlL2ljb24uY29tcG9uZW50JztcblxuZXhwb3J0IGludGVyZmFjZSBUb29sdGlwVG9vbCB7XG4gIGtleTogc3RyaW5nO1xuICBpY29uOiBWb0ljb25OYW1lO1xuICAvKiogVGhlIGJ1dHRvbidzIG5hbWUsIHJlYWQgb3V0IGJ5IHNjcmVlbiByZWFkZXJzLiAqL1xuICBsYWJlbDogc3RyaW5nO1xuICAvKiogVGhlIHRvb2x0aXAsIHdoZW4gaXQgc2hvdWxkIHNheSBtb3JlIHRoYW4gdGhlIG5hbWUuIERlZmF1bHRzIHRvIHRoZSBsYWJlbC4gKi9cbiAgdGlwPzogc3RyaW5nO1xuICAvKiogQSBzaG9ydGN1dCBzaG93biBhZnRlciB0aGUgdGlwLCBsaWtlIFwi4oyYWlwiLiAqL1xuICBrYmQ/OiBzdHJpbmc7XG4gIG9uQ2xpY2s/OiAoKSA9PiB2b2lkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRvb2x0aXBQZXJzb24ge1xuICBrZXk6IHN0cmluZztcbiAgaW5pdGlhbHM6IHN0cmluZztcbiAgLyoqIFRoZSBhdmF0YXIncyBjb2xvdXIsIGxpa2UgJ3ZhcigtLXZvLWF2LWwpJy4gKi9cbiAgY29sb3I6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICAvKiogVGhlIHF1aWV0IGxpbmUgdW5kZXIgdGhlIG5hbWUsIGxpa2UgXCJEZXNpZ24gbGVhZFwiLiAqL1xuICByb2xlOiBzdHJpbmc7XG4gIC8qKiBXaGF0IHRoZXkgYXJlIGRvaW5nIG5vdywgbGlrZSBcIkVkaXRpbmcgUHJpY2luZywgZnJhbWUgMlwiLiAqL1xuICBzdGF0dXM6IHN0cmluZztcbiAgLyoqIFNob3dzIHRoZSBhZ2VudCdzIHRoaW5raW5nIGRvdHMgaW5zdGVhZCBvZiB0aGUgZ3JlZW4gZG90LiAqL1xuICB3b3JraW5nPzogYm9vbGVhbjtcbn1cblxuY29uc3QgREVGQVVMVF9HUk9VUFM6IFRvb2x0aXBUb29sW11bXSA9IFtcbiAgW1xuICAgIHsga2V5OiAndW5kbycsIGljb246ICd1bmRvJywgbGFiZWw6ICdVbmRvJywga2JkOiAn4oyYWicgfSxcbiAgICB7IGtleTogJ2NvbW1lbnQnLCBpY29uOiAnZWRpdCcsIGxhYmVsOiAnQ29tbWVudCcsIGtiZDogJ0MnIH0sXG4gICAgeyBrZXk6ICdhc2snLCBpY29uOiAnc3BhcmsnLCBsYWJlbDogJ0FzayBhZ2VudCcsIHRpcDogJ0FzayB0aGUgYWdlbnQnLCBrYmQ6ICfijJhKJyB9LFxuICBdLFxuICBbeyBrZXk6ICdzaGFyZScsIGljb246ICd1c2VycycsIGxhYmVsOiAnU2hhcmUnLCB0aXA6ICdTaGFyZSB3aXRoIHlvdXIgdGVhbScgfV0sXG5dO1xuXG4vLyB3aGVuIHRoZSBsYXN0IHZpc2libGUgdGlwIGNsb3NlZCwgc2hhcmVkIGJ5IGV2ZXJ5IHRvb2x0aXAgc28gbW92aW5nIHN0cmFpZ2h0XG4vLyBmcm9tIG9uZSBidXR0b24gdG8gdGhlIG5leHQgc2hvd3MgdGhlIG5leHQgbGFiZWwgYXQgb25jZSAoYXMgb24gdGhlIHNpdGUpXG5sZXQgdGlwU2VlbiA9IC1JbmZpbml0eTtcblxuaW50ZXJmYWNlIFRpcEF0IHtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIGtiZD86IHN0cmluZztcbn1cbmludGVyZmFjZSBDYXJkQXQge1xuICBwZXJzb246IFRvb2x0aXBQZXJzb247XG4gIGxlZnQ6IG51bWJlcjtcbiAgdG9wOiBudW1iZXI7XG59XG5cbi8qKiBUaGUgaW5rIGZvciBpbml0aWFscyBvbiBhbiBhdmF0YXIgY29sb3VyOiBlYWNoIG9mIHRoZSBlaWdodCBhdmF0YXIgY29sb3VycyBoYXMgaXRzIG93biBpbmsgdG9rZW4uICovXG5jb25zdCBhdmF0YXJJbmsgPSAoY29sb3I6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCA9PlxuICAvXnZhclxcKC0tdm8tYXYtW2Etel1cXCkkLy50ZXN0KGNvbG9yKSA/IGNvbG9yLnJlcGxhY2UoJyknLCAnLWluayknKSA6IHVuZGVmaW5lZDtcblxuLyoqIEEgdG9vbGJhciB3aG9zZSBsYWJlbHMgZm9sbG93IHRoZSBwb2ludGVyIGJldHdlZW4gYnV0dG9ucywgd2l0aCBhIHJpY2hlciBjYXJkIGZvciBwZW9wbGUuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd2by10b29sdGlwJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgaW1wb3J0czogW1ZvSWNvbkNvbXBvbmVudF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBkYXRhLXZvPVwiXCIgI3Jvb3QgY2xhc3M9XCJ2by10dHBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJ2by10dHAtYmFyIHZvLXBhbmVsXCI+XG4gICAgICAgIEBmb3IgKGcgb2YgZ3JvdXBzOyB0cmFjayAkaW5kZXg7IGxldCBnaSA9ICRpbmRleCkge1xuICAgICAgICAgIEBpZiAoZ2kgPiAwKSB7XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLXR0cC1zZXBcIj48L3NwYW4+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBmb3IgKHQgb2YgZzsgdHJhY2sgdC5rZXkpIHtcbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzPVwidm8taWJcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cInQubGFiZWxcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwidC5vbkNsaWNrPy4oKVwiXG4gICAgICAgICAgICAgIChwb2ludGVyZW50ZXIpPVwib3BlblRpcEZvcih0LCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgKHBvaW50ZXJsZWF2ZSk9XCJsZWF2ZVRpcCgpXCJcbiAgICAgICAgICAgICAgKGZvY3VzKT1cImZvY3VzVGlwKHQsICRldmVudClcIlxuICAgICAgICAgICAgICAoYmx1cik9XCJsZWF2ZVRpcCgpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHZvLWljb24gW25hbWVdPVwidC5pY29uXCIgc2l6ZT1cInNtXCI+PC92by1pY29uPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIEBpZiAocGVvcGxlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLXR0cC1zZXBcIj48L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by10dHAtYXZzXCI+XG4gICAgICAgICAgICBAZm9yIChwZXJzb24gb2YgcGVvcGxlOyB0cmFjayBwZXJzb24ua2V5KSB7XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInZvLXR0cC1hdlwiXG4gICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJwZXJzb24ubmFtZVwiXG4gICAgICAgICAgICAgICAgKG1vdXNlZW50ZXIpPVwib3BlbkNhcmRGb3IocGVyc29uLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAobW91c2VsZWF2ZSk9XCJsZWF2ZUNhcmQoKVwiXG4gICAgICAgICAgICAgICAgKGZvY3VzKT1cImZvY3VzQ2FyZChwZXJzb24sICRldmVudClcIlxuICAgICAgICAgICAgICAgIChibHVyKT1cImNsb3NlQ2FyZCgpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInZvLWF2XCJcbiAgICAgICAgICAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICBbc3R5bGUuYmFja2dyb3VuZF09XCJwZXJzb24uY29sb3JcIlxuICAgICAgICAgICAgICAgICAgW3N0eWxlLmNvbG9yXT1cImluayhwZXJzb24uY29sb3IpXCJcbiAgICAgICAgICAgICAgICAgID57eyBwZXJzb24uaW5pdGlhbHMgfX08L3NwYW5cbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gdGhlIHRvb2xiYXIncyBvd24gZGFyayB0aXAsIGtlcHQgaW5zaWRlIHRoZSBjb21wb25lbnQgYm91bmRzIC0tPlxuICAgICAgPGRpdlxuICAgICAgICAjdGlwXG4gICAgICAgIGNsYXNzPVwidm8tdGlwXCJcbiAgICAgICAgW2NsYXNzLnZvLXNob3ddPVwidGlwU2hvd1wiXG4gICAgICAgIHJvbGU9XCJ0b29sdGlwXCJcbiAgICAgICAgZGF0YS12bz1cIlwiXG4gICAgICAgIFtzdHlsZS5sZWZ0LnB4XT1cInRpcEF0Py54ID8/IDBcIlxuICAgICAgICBbc3R5bGUudG9wLnB4XT1cInRpcEF0Py55ID8/IDBcIlxuICAgICAgICBbc3R5bGUudmlzaWJpbGl0eV09XCJ0aXBBdCA/ICd2aXNpYmxlJyA6ICdoaWRkZW4nXCJcbiAgICAgID5cbiAgICAgICAge3sgdGlwQXQ/LmxhYmVsIH19XG4gICAgICAgIEBpZiAodGlwQXQ/LmtiZCkge1xuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8ta2JkXCI+e3sgdGlwQXQ/LmtiZCB9fTwvc3Bhbj5cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gdGhlIHJpY2hlciBwZXJzb24gY2FyZCAtLT5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJ2by10dHAtY2FyZCB2by1wYW5lbFwiXG4gICAgICAgIFtjbGFzcy52by1zaG93XT1cImNhcmRTaG93XCJcbiAgICAgICAgW3N0eWxlLmxlZnQucHhdPVwiY2FyZD8ubGVmdFwiXG4gICAgICAgIFtzdHlsZS50b3AucHhdPVwiY2FyZD8udG9wXCJcbiAgICAgICAgW2F0dHIuYXJpYS1oaWRkZW5dPVwiIWNhcmRTaG93XCJcbiAgICAgID5cbiAgICAgICAgPGRpdiBjbGFzcz1cInZvLXR0cC1jaVwiPlxuICAgICAgICAgIEBpZiAoY2FyZDsgYXMgYykge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZvLXR0cC1jaFwiPlxuICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgIGNsYXNzPVwidm8tYXZcIlxuICAgICAgICAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmJhY2tncm91bmRdPVwiYy5wZXJzb24uY29sb3JcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5jb2xvcl09XCJpbmsoYy5wZXJzb24uY29sb3IpXCJcbiAgICAgICAgICAgICAgICA+e3sgYy5wZXJzb24uaW5pdGlhbHMgfX08L3NwYW5cbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8ZGl2PjxiPnt7IGMucGVyc29uLm5hbWUgfX08L2I+PHNwYW4+e3sgYy5wZXJzb24ucm9sZSB9fTwvc3Bhbj48L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZvLXR0cC1jc1wiPlxuICAgICAgICAgICAgICBAaWYgKGMucGVyc29uLndvcmtpbmcpIHtcbiAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImRpc3BsYXk6aW5saW5lLWZsZXg7Y29sb3I6dmFyKC0tdm8tYWNjZW50KVwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by10aGluayB2by1vblwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjxpPjwvaT48aT48L2k+PGk+PC9pPjxpPjwvaT48L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLWRvdFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB7eyBjLnBlcnNvbi5zdGF0dXMgfX1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgQGlmIChub3RlKSB7XG4gICAgICAgIDxwIGNsYXNzPVwidm8tbXV0ZWQgdm8tdHRwLW5cIj57eyBub3RlIH19PC9wPlxuICAgICAgfVxuICAgIDwvZGl2PlxuICBgLFxuICBzdHlsZVVybDogJy4vdG9vbHRpcC5jc3MnLFxufSlcbmV4cG9ydCBjbGFzcyBUb29sdGlwQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgLyoqIFRoZSB0b29sYmFyJ3MgYnV0dG9ucywgaW4gZ3JvdXBzIHdpdGggYSBsaW5lIGJldHdlZW4gdGhlbS4gKi9cbiAgQElucHV0KCkgZ3JvdXBzOiBUb29sdGlwVG9vbFtdW10gPSBERUZBVUxUX0dST1VQUztcbiAgLyoqIEF2YXRhcnMgYXQgdGhlIGVuZCBvZiB0aGUgdG9vbGJhcjsgaG92ZXJpbmcgb25lIHNob3dzIGEgY2FyZC4gKi9cbiAgQElucHV0KCkgcGVvcGxlOiBUb29sdGlwUGVyc29uW10gPSBbXTtcbiAgLyoqIEEgcXVpZXQgbGluZSB1bmRlciB0aGUgdG9vbGJhci4gKi9cbiAgQElucHV0KCkgbm90ZT86IHN0cmluZztcbiAgLyoqIEhvdyBsb25nIHRoZSBwZXJzb24gY2FyZCB3YWl0cyBiZWZvcmUgaXQgc2hvd3MuICovXG4gIEBJbnB1dCgpIGNhcmREZWxheSA9IDMwMDtcblxuICBwcml2YXRlIF9vcGVuVGlwOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIF9vcGVuQ2FyZDogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuICAvKiogU2hvd3MgdGhpcyB0b29sJ3MgdGlwLCBieSBrZXksIGFzIGlmIGl0IHdlcmUgaG92ZXJlZC4gKi9cbiAgQElucHV0KClcbiAgc2V0IG9wZW5UaXAoa2V5OiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5fb3BlblRpcCA9IGtleTtcbiAgICB0aGlzLmFwcGx5T3BlblRpcCgpO1xuICB9XG4gIGdldCBvcGVuVGlwKCk6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9vcGVuVGlwO1xuICB9XG5cbiAgLyoqIFNob3dzIHRoaXMgcGVyc29uJ3MgY2FyZCwgYnkga2V5LCBhcyBpZiB0aGV5IHdlcmUgaG92ZXJlZC4gKi9cbiAgQElucHV0KClcbiAgc2V0IG9wZW5DYXJkKGtleTogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuX29wZW5DYXJkID0ga2V5O1xuICAgIHRoaXMuYXBwbHlPcGVuQ2FyZCgpO1xuICB9XG4gIGdldCBvcGVuQ2FyZCgpOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fb3BlbkNhcmQ7XG4gIH1cblxuICBAVmlld0NoaWxkKCdyb290Jykgcm9vdCE6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuICBAVmlld0NoaWxkKCd0aXAnKSB0aXBFbCE6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuXG4gIHRpcEF0OiBUaXBBdCB8IG51bGwgPSBudWxsO1xuICB0aXBTaG93ID0gZmFsc2U7XG4gIGNhcmQ6IENhcmRBdCB8IG51bGwgPSBudWxsO1xuICBjYXJkU2hvdyA9IGZhbHNlO1xuXG4gIHByaXZhdGUgdGlwVGltZXI/OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PjtcbiAgcHJpdmF0ZSBjYXJkVGltZXI/OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PjtcbiAgcHJpdmF0ZSB0aXBPdmVyS2V5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjYXJkT3ZlcktleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcmVhZHkgPSBmYWxzZTtcblxuICBpbmsoY29sb3I6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGF2YXRhckluayhjb2xvcik7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgdGhpcy5yZWFkeSA9IHRydWU7XG4gICAgdGhpcy5hcHBseU9wZW5UaXAoKTtcbiAgICB0aGlzLmFwcGx5T3BlbkNhcmQoKTtcbiAgfVxuXG4gIC8qIC0tLS0tLS0tLS0gdG9vbGJhciB0aXBzIC0tLS0tLS0tLS0gKi9cblxuICBvcGVuVGlwRm9yKHQ6IFRvb2x0aXBUb29sLCBlOiBFdmVudCk6IHZvaWQge1xuICAgIHRoaXMudGlwT3ZlcktleSA9IHQua2V5O1xuICAgIHRoaXMuc2hvd1RpcCh0LCBlLmN1cnJlbnRUYXJnZXQgYXMgSFRNTEVsZW1lbnQpO1xuICB9XG5cbiAgZm9jdXNUaXAodDogVG9vbHRpcFRvb2wsIGU6IEZvY3VzRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBlbCA9IGUudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgIGlmIChlbC5tYXRjaGVzKCc6Zm9jdXMtdmlzaWJsZScpKSB0aGlzLnNob3dUaXAodCwgZWwsIHRydWUpO1xuICB9XG5cbiAgbGVhdmVUaXAoKTogdm9pZCB7XG4gICAgdGhpcy50aXBPdmVyS2V5ID0gbnVsbDtcbiAgICBpZiAodGhpcy5fb3BlblRpcCA9PSBudWxsKSB0aGlzLmhpZGVUaXAoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2hvd1RpcCh0OiBUb29sdGlwVG9vbCwgZWw6IEhUTUxFbGVtZW50LCBub3cgPSBmYWxzZSk6IHZvaWQge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpcFRpbWVyKTtcbiAgICBjb25zdCBkZWxheSA9IG5vdyB8fCBwZXJmb3JtYW5jZS5ub3coKSAtIHRpcFNlZW4gPCAxMjAgPyAwIDogMzgwO1xuICAgIHRoaXMudGlwVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMucGxhY2VUaXAodCwgZWwpLCBkZWxheSk7XG4gIH1cblxuICBwcml2YXRlIHBsYWNlVGlwKHQ6IFRvb2x0aXBUb29sLCBlbDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcbiAgICBjb25zdCBib3ggPSB0aGlzLnJvb3Q/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMudGlwRWw/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFib3ggfHwgIW5vZGUpIHJldHVybjtcbiAgICB0aGlzLnRpcEF0ID0geyB4OiAwLCB5OiAwLCBsYWJlbDogdC50aXAgPz8gdC5sYWJlbCwga2JkOiB0LmtiZCB9O1xuICAgIHRoaXMudGlwU2hvdyA9IGZhbHNlO1xuICAgIC8vIG1lYXN1cmUgYWZ0ZXIgdGhlIGxhYmVsIGlzIGluLCB0aGVuIGNlbnRyZSBhYm92ZSB0aGUgYnV0dG9uICh3aXRoaW4gYm91bmRzKVxuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICBjb25zdCByciA9IGJveC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGNvbnN0IGJyID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCB3ID0gbm9kZS5vZmZzZXRXaWR0aDtcbiAgICAgIGNvbnN0IGggPSBub2RlLm9mZnNldEhlaWdodDtcbiAgICAgIGxldCB4ID0gYnIubGVmdCAtIHJyLmxlZnQgKyBici53aWR0aCAvIDIgLSB3IC8gMjtcbiAgICAgIHggPSBNYXRoLm1heCgwLCBNYXRoLm1pbih4LCByci53aWR0aCAtIHcpKTtcbiAgICAgIGNvbnN0IHkgPSBici50b3AgLSByci50b3AgLSBoIC0gODtcbiAgICAgIHRoaXMudGlwQXQgPSB7IC4uLnRoaXMudGlwQXQhLCB4LCB5IH07XG4gICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gKHRoaXMudGlwU2hvdyA9IHRydWUpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaGlkZVRpcCgpOiB2b2lkIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy50aXBUaW1lcik7XG4gICAgaWYgKHRoaXMudGlwQXQpIHRpcFNlZW4gPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICB0aGlzLnRpcFNob3cgPSBmYWxzZTtcbiAgICB0aGlzLnRpcEF0ID0gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgYXBwbHlPcGVuVGlwKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5yZWFkeSB8fCB0aGlzLl9vcGVuVGlwID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICBjb25zdCB0b29sID0gdGhpcy5ncm91cHMuZmxhdCgpLmZpbmQoKHQpID0+IHQua2V5ID09PSB0aGlzLl9vcGVuVGlwKTtcbiAgICBpZiAodG9vbCkge1xuICAgICAgY29uc3QgZWwgPSB0aGlzLmJ1dHRvbkZvcih0b29sLmtleSk7XG4gICAgICBpZiAoZWwpIHRoaXMuc2hvd1RpcCh0b29sLCBlbCwgdHJ1ZSk7XG4gICAgfSBlbHNlIGlmICghdGhpcy50aXBPdmVyS2V5KSB7XG4gICAgICB0aGlzLmhpZGVUaXAoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGJ1dHRvbkZvcihrZXk6IHN0cmluZyk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XG4gICAgY29uc3QgYm94ID0gdGhpcy5yb290Py5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghYm94KSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBpZHggPSB0aGlzLmdyb3Vwcy5mbGF0KCkuZmluZEluZGV4KCh0KSA9PiB0LmtleSA9PT0ga2V5KTtcbiAgICBjb25zdCBidXR0b25zID0gYm94LnF1ZXJ5U2VsZWN0b3JBbGw8SFRNTEVsZW1lbnQ+KCcudm8tdHRwLWJhciA+IC52by1pYicpO1xuICAgIHJldHVybiBidXR0b25zW2lkeF0gPz8gbnVsbDtcbiAgfVxuXG4gIC8qIC0tLS0tLS0tLS0gcGVyc29uIGNhcmQgLS0tLS0tLS0tLSAqL1xuXG4gIG9wZW5DYXJkRm9yKHBlcnNvbjogVG9vbHRpcFBlcnNvbiwgZTogRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLmNhcmRPdmVyS2V5ID0gcGVyc29uLmtleTtcbiAgICB0aGlzLm9wZW5DYXJkQXQocGVyc29uLCBlLmN1cnJlbnRUYXJnZXQgYXMgSFRNTEVsZW1lbnQpO1xuICB9XG5cbiAgZm9jdXNDYXJkKHBlcnNvbjogVG9vbHRpcFBlcnNvbiwgZTogRm9jdXNFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IGVsID0gZS50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgaWYgKGVsLm1hdGNoZXMoJzpmb2N1cy12aXNpYmxlJykpIHRoaXMub3BlbkNhcmRBdChwZXJzb24sIGVsLCB0cnVlKTtcbiAgfVxuXG4gIGxlYXZlQ2FyZCgpOiB2b2lkIHtcbiAgICB0aGlzLmNhcmRPdmVyS2V5ID0gbnVsbDtcbiAgICB0aGlzLmNsb3NlQ2FyZCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBvcGVuQ2FyZEF0KHBlcnNvbjogVG9vbHRpcFBlcnNvbiwgZWw6IEhUTUxFbGVtZW50LCBub3cgPSBmYWxzZSk6IHZvaWQge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLmNhcmRUaW1lcik7XG4gICAgdGhpcy5jYXJkVGltZXIgPSBzZXRUaW1lb3V0KFxuICAgICAgKCkgPT4ge1xuICAgICAgICBjb25zdCBib3ggPSB0aGlzLnJvb3Q/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIGlmICghYm94KSByZXR1cm47XG4gICAgICAgIGNvbnN0IHJyID0gYm94LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBjb25zdCBiciA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBjb25zdCBsZWZ0ID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oYnIubGVmdCAtIHJyLmxlZnQgKyBici53aWR0aCAvIDIgLSAxMTUsIHJyLndpZHRoIC0gMjMwKSk7XG4gICAgICAgIHRoaXMuY2FyZCA9IHsgcGVyc29uLCBsZWZ0LCB0b3A6IGJyLmJvdHRvbSAtIHJyLnRvcCArIDEwIH07XG4gICAgICAgIHRoaXMuY2FyZFNob3cgPSB0cnVlO1xuICAgICAgfSxcbiAgICAgIG5vdyA/IDAgOiB0aGlzLmNhcmREZWxheSxcbiAgICApO1xuICB9XG5cbiAgY2xvc2VDYXJkKCk6IHZvaWQge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLmNhcmRUaW1lcik7XG4gICAgdGhpcy5jYXJkU2hvdyA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBseU9wZW5DYXJkKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5yZWFkeSB8fCB0aGlzLl9vcGVuQ2FyZCA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgY29uc3QgcGVyc29uID0gdGhpcy5wZW9wbGUuZmluZCgoeCkgPT4geC5rZXkgPT09IHRoaXMuX29wZW5DYXJkKTtcbiAgICBjb25zdCBlbCA9IHBlcnNvbiA/IHRoaXMuYXZhdGFyRm9yKHBlcnNvbi5rZXkpIDogbnVsbDtcbiAgICBpZiAocGVyc29uICYmIGVsKSB0aGlzLm9wZW5DYXJkQXQocGVyc29uLCBlbCwgdHJ1ZSk7XG4gICAgZWxzZSBpZiAoIXRoaXMuY2FyZE92ZXJLZXkpIHRoaXMuY2xvc2VDYXJkKCk7XG4gIH1cblxuICBwcml2YXRlIGF2YXRhckZvcihrZXk6IHN0cmluZyk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XG4gICAgY29uc3QgYm94ID0gdGhpcy5yb290Py5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghYm94KSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBpZHggPSB0aGlzLnBlb3BsZS5maW5kSW5kZXgoKHApID0+IHAua2V5ID09PSBrZXkpO1xuICAgIGNvbnN0IGF2YXRhcnMgPSBib3gucXVlcnlTZWxlY3RvckFsbDxIVE1MRWxlbWVudD4oJy52by10dHAtYXYnKTtcbiAgICByZXR1cm4gYXZhdGFyc1tpZHhdID8/IG51bGw7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy50aXBUaW1lcik7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuY2FyZFRpbWVyKTtcbiAgfVxufVxuIl19