@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,538 @@
1
+ // framework/angular/voice-orb/voice-orb.component.ts
2
+ //
3
+ // Native Angular port of framework/react/voice-orb/VoiceOrb.tsx.
4
+ // A hands-free voice chat: an orb that swells with whoever is talking, the accent
5
+ // colour for you and violet for the agent, what was said under it, and mute and
6
+ // end below. It draws what you pass; it never opens the microphone itself.
7
+ // Inputs mirror the React props; React callbacks become @Output() EventEmitters.
8
+ import { Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, inject, } from '@angular/core';
9
+ import { VoIconComponent } from '../core/icon.component';
10
+ import { ReducedMotionService } from '../core/reduced-motion.service';
11
+ import * as i0 from "@angular/core";
12
+ const DEFAULTS = {
13
+ ready: 'Ready',
14
+ listening: 'Listening',
15
+ thinking: 'Thinking',
16
+ speaking: 'Speaking',
17
+ muted: 'Muted',
18
+ ended: 'Ended',
19
+ start: 'Start talking',
20
+ end: 'End',
21
+ mute: 'Mute',
22
+ unmute: 'Unmute',
23
+ mutedNotice: "You're muted. Unmute so the agent can hear you.",
24
+ endedTitle: 'Voice chat ended',
25
+ restart: 'Start again',
26
+ };
27
+ const fmt = (s) => `${Math.floor(s / 60)}:${String(Math.floor(s) % 60).padStart(2, '0')}`;
28
+ export class VoiceOrbComponent {
29
+ constructor() {
30
+ /** idle, listening, thinking, speaking or ended. */
31
+ this.state = 'idle';
32
+ /** How loud whoever is talking is, 0 to 1. The orb swells with it. */
33
+ this.level = 0;
34
+ /** Your microphone is off. Listening shows as Muted, the mute button is pressed. */
35
+ this.muted = false;
36
+ /** Shows "You're muted" with an Unmute button, for when someone talks while muted. */
37
+ this.mutedNotice = false;
38
+ /** What was said last and who said it; each word fades in as it arrives. */
39
+ this.caption = null;
40
+ /** Shown before anything is said, like "Talk to the agent about Pricing v4". */
41
+ this.hint = '';
42
+ /** Seconds since the chat started, shown top right. */
43
+ this.elapsed = 0;
44
+ this.labels = {};
45
+ this.className = '';
46
+ this.mutedChange = new EventEmitter();
47
+ this.start = new EventEmitter();
48
+ this.end = new EventEmitter();
49
+ /** Start again, from the row that shows once the chat has ended. */
50
+ this.restart = new EventEmitter();
51
+ this.motion = inject(ReducedMotionService);
52
+ this.L = DEFAULTS;
53
+ this.fmt = fmt;
54
+ // the lit glass sphere, drawn on a canvas in the colours of whoever is talking,
55
+ // faster and brighter as they get louder. With reduced motion it is one still
56
+ // frame, drawn again when the speaker changes; where no canvas can draw the core
57
+ // keeps its plain gradient (set by CSS).
58
+ this.shader = null;
59
+ this.raf = 0;
60
+ this.flow = 0;
61
+ this.last = 0;
62
+ this.cols = null;
63
+ this.colsAt = -1e9;
64
+ this.seen = true;
65
+ this.started = false;
66
+ }
67
+ // muted only changes how listening looks: the agent can still think and speak
68
+ get mode() {
69
+ return this.muted && this.state === 'listening' ? 'muted' : this.state;
70
+ }
71
+ get status() {
72
+ const map = {
73
+ idle: this.L.ready,
74
+ listening: this.L.listening,
75
+ thinking: this.L.thinking,
76
+ speaking: this.L.speaking,
77
+ muted: this.L.muted,
78
+ ended: this.L.ended,
79
+ };
80
+ return map[this.mode] ?? '';
81
+ }
82
+ get on() {
83
+ return this.state !== 'idle' && this.state !== 'ended';
84
+ }
85
+ get noticeOpen() {
86
+ return this.mutedNotice && this.muted && this.on;
87
+ }
88
+ get lv() {
89
+ return Math.max(0, Math.min(1, this.level)).toFixed(3);
90
+ }
91
+ get defaultDetail() {
92
+ return `${fmt(this.elapsed)} · Transcript saved`;
93
+ }
94
+ words(text) {
95
+ return text.split(' ').filter(Boolean);
96
+ }
97
+ emitMuted(next) {
98
+ this.mutedChange.emit(next);
99
+ }
100
+ ngOnChanges(changes) {
101
+ if (changes['labels'])
102
+ this.L = { ...DEFAULTS, ...this.labels };
103
+ // draw once more when the speaker (data-m) changes under reduced motion
104
+ if (this.started && this.motion.reduce() && (changes['state'] || changes['muted'])) {
105
+ this.cols = null;
106
+ queueMicrotask(() => this.draw(this.flow));
107
+ }
108
+ }
109
+ ngAfterViewInit() {
110
+ const cv = this.glRef?.nativeElement;
111
+ if (!cv)
112
+ return;
113
+ this.shader = orbShader(cv);
114
+ if (!this.shader)
115
+ return;
116
+ cv.classList.add('vo-on');
117
+ this.started = true;
118
+ if ('IntersectionObserver' in window) {
119
+ this.io = new IntersectionObserver((e) => (this.seen = e[0].isIntersecting));
120
+ this.io.observe(cv);
121
+ }
122
+ this.draw(0);
123
+ if (!this.motion.reduce()) {
124
+ const tick = (t) => {
125
+ this.flow += Math.min(50, t - (this.last || t)) * (1 + Math.max(0, Math.min(1, this.level)) * 2.5);
126
+ this.last = t;
127
+ if (this.seen)
128
+ this.draw(this.flow);
129
+ this.raf = requestAnimationFrame(tick);
130
+ };
131
+ this.raf = requestAnimationFrame(tick);
132
+ }
133
+ }
134
+ draw(ms) {
135
+ const cv = this.glRef?.nativeElement;
136
+ if (!this.shader || !cv)
137
+ return;
138
+ const now = performance.now();
139
+ if (!this.cols || now - this.colsAt > 250) {
140
+ const box = cv.closest('.vo-vor');
141
+ const dot = box?.querySelector('.vo-vor-dot');
142
+ const pc = box?.querySelector('.vo-vor-pc');
143
+ if (dot && pc) {
144
+ this.cols = [getComputedStyle(dot).backgroundColor, getComputedStyle(pc).backgroundColor];
145
+ this.colsAt = now;
146
+ }
147
+ }
148
+ if (this.cols)
149
+ this.shader.paint(ms, Math.max(0, Math.min(1, this.level)), this.cols[0], this.cols[1]);
150
+ }
151
+ ngOnDestroy() {
152
+ cancelAnimationFrame(this.raf);
153
+ this.io?.disconnect();
154
+ this.shader?.lose();
155
+ }
156
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VoiceOrbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
157
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: VoiceOrbComponent, isStandalone: true, selector: "vo-voice-orb", inputs: { state: "state", level: "level", muted: "muted", mutedNotice: "mutedNotice", caption: "caption", hint: "hint", elapsed: "elapsed", endedDetail: "endedDetail", labels: "labels", className: "className" }, outputs: { mutedChange: "mutedChange", start: "start", end: "end", restart: "restart" }, viewQueries: [{ propertyName: "glRef", first: true, predicate: ["gl"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
158
+ <div data-vo="" [class]="className" style="width:100%">
159
+ <div class="vo-vor vo-panel" [class.vo-on]="on" [attr.data-m]="mode">
160
+ <div class="vo-vor-top">
161
+ <span class="vo-vor-dot"></span>
162
+ <span class="vo-vor-st">{{ status }}</span>
163
+ <span class="vo-vor-t vo-num vo-muted">{{ fmt(elapsed) }}</span>
164
+ </div>
165
+ <div class="vo-vor-orb" aria-hidden="true" [style.--vo-lv]="lv">
166
+ <i class="vo-vor-pc"></i>
167
+ <i class="vo-vor-core"><canvas #gl class="vo-vor-gl"></canvas></i>
168
+ </div>
169
+ <div class="vo-vor-cap" aria-live="polite">
170
+ <span class="vo-vor-who vo-muted">{{ caption?.speaker ?? '' }}</span>
171
+ @if (caption; as cap) {
172
+ <p class="vo-vor-tx">
173
+ @for (w of words(cap.text); track $index) {
174
+ <span class="vo-w">{{ w }} </span>
175
+ }
176
+ </p>
177
+ } @else {
178
+ <p class="vo-vor-tx vo-hint">{{ hint }}</p>
179
+ }
180
+ </div>
181
+ <div class="vo-fold vo-vor-mf" [class.vo-shut]="!noticeOpen" [attr.inert]="noticeOpen ? null : ''">
182
+ <div>
183
+ <div class="vo-vor-mw">
184
+ <p><vo-icon name="alert" size="xs"></vo-icon><span>{{ L.mutedNotice }}</span></p>
185
+ <button type="button" class="vo-pill vo-sm vo-vor-un" (click)="emitMuted(false)">{{ L.unmute }}</button>
186
+ </div>
187
+ </div>
188
+ </div>
189
+ @if (state === 'ended') {
190
+ <div class="vo-vor-done vo-enter">
191
+ <vo-icon name="ok"></vo-icon>
192
+ <span class="vo-t">{{ L.endedTitle }}<span class="vo-muted">{{ endedDetail ?? defaultDetail }}</span></span>
193
+ <button type="button" class="vo-pill vo-sm" (click)="restart.emit()">{{ L.restart }}</button>
194
+ </div>
195
+ } @else {
196
+ <div class="vo-vor-f">
197
+ <button type="button" class="vo-pill vo-primary vo-sm vo-vor-go" (click)="start.emit()">
198
+ <vo-icon name="comment" size="xs"></vo-icon>{{ L.start }}
199
+ </button>
200
+ <button
201
+ type="button"
202
+ class="vo-ib vo-fill vo-vor-mute"
203
+ [attr.aria-label]="L.mute"
204
+ [attr.aria-pressed]="muted"
205
+ [attr.data-tip]="muted ? L.unmute : L.mute"
206
+ (click)="emitMuted(!muted)"
207
+ >
208
+ <vo-icon name="comment"></vo-icon>
209
+ </button>
210
+ <span class="vo-sp"></span>
211
+ <button type="button" class="vo-pill vo-sm vo-vor-end" (click)="end.emit()">{{ L.end }}</button>
212
+ </div>
213
+ }
214
+ </div>
215
+ </div>
216
+ `, isInline: true, styles: [".vo-vor{position:relative;width:100%;max-width:380px;margin:0 auto;padding:var(--vo-s-4);display:flex;flex-direction:column;gap:var(--vo-s-3);--vo-oc:var(--vo-faint);--vo-oc2:var(--vo-accent)}.vo-vor[data-m=listening]{--vo-oc:var(--vo-accent);--vo-oc2:color-mix(in oklch,var(--vo-pl) 45%,var(--vo-accent))}.vo-vor[data-m=speaking]{--vo-oc:var(--vo-pl);--vo-oc2:color-mix(in oklch,var(--vo-accent) 45%,var(--vo-pl))}.vo-vor[data-m=thinking]{--vo-oc:color-mix(in oklch,var(--vo-accent) 50%,var(--vo-pl));--vo-oc2:var(--vo-accent)}.vo-vor[data-m=muted]{--vo-oc:color-mix(in srgb,var(--vo-muted) 55%,var(--vo-faint));--vo-oc2:var(--vo-faint)}.vo-vor-top{display:flex;align-items:center;gap:var(--vo-s-2);font-size:13px}.vo-vor-dot{width:8px;height:8px;border-radius:50%;background:var(--vo-oc);transition:background .4s}.vo-vor[data-m=listening] .vo-vor-dot,.vo-vor[data-m=speaking] .vo-vor-dot{animation:vo-vor-pulse 1.4s var(--vo-ease-io) infinite}@keyframes vo-vor-pulse{0%,to{box-shadow:0 0 color-mix(in srgb,var(--vo-oc) 35%,transparent)}50%{box-shadow:0 0 0 5px transparent}}.vo-vor-t{margin-left:auto;font-size:12.5px}.vo-vor-orb{position:relative;width:112px;height:112px;margin:var(--vo-s-2) auto;--vo-lv:0}.vo-vor-orb i{position:absolute;inset:0;border-radius:50%}.vo-vor .vo-vor-orb i{border-radius:50%!important}.vo-vor-core{overflow:hidden;background-color:color-mix(in srgb,var(--vo-oc) 80%,var(--vo-surface));background-image:radial-gradient(circle at 34% 28%,#fff6,#fff0 60%);box-shadow:inset 0 -10px 20px color-mix(in srgb,var(--vo-oc) 55%,#000 10%);transform:scale(calc(.9 + var(--vo-lv) * .1));transition:background-color .4s}.vo-vor-gl{position:absolute;inset:0;width:100%;height:100%;border-radius:50%;opacity:0;transition:opacity .4s}.vo-vor-gl.vo-on{opacity:1}.vo-vor-core:has(>.vo-vor-gl.vo-on){background:none;box-shadow:none}.vo-vor-pc{visibility:hidden;background:var(--vo-oc2);transition:background .4s}.vo-vor-cap,.vo-vor-mf,.vo-vor-f{position:relative}.vo-vor[data-m=thinking] .vo-vor-core{animation:vo-vor-br 1.6s var(--vo-ease-io) infinite alternate}@keyframes vo-vor-br{0%{transform:scale(.9)}to{transform:scale(.96)}}.vo-vor-cap{min-height:88px;display:flex;flex-direction:column;gap:2px;text-align:center}.vo-vor-who{font-size:12px;min-height:18px}.vo-vor-tx{margin:0;font-size:14px;line-height:1.6;color:var(--vo-fg)}.vo-vor-tx.vo-hint{color:var(--vo-muted);font-size:13px}.vo-vor-tx .vo-w{animation:vo-vor-w .45s var(--vo-ease) both}@keyframes vo-vor-w{0%{opacity:0;filter:blur(3px)}to{opacity:1;filter:none}}.vo-vor-mw{display:flex;align-items:center;gap:10px;padding:var(--vo-s-2) var(--vo-s-2) var(--vo-s-2) var(--vo-s-3);border-radius:var(--vo-r-in);background:var(--vo-warn-bg)}.vo-vor-mw p{margin:0;flex:1;display:flex;gap:var(--vo-s-2);font-size:13px;line-height:1.45;color:var(--vo-fg)}.vo-vor-mw p svg{color:var(--vo-warn);flex:none;margin-top:3px}.vo-vor-mw .vo-pill,.vo-vor-done .vo-pill{background:var(--vo-surface);color:var(--vo-fg);box-shadow:var(--vo-shadow)}.vo-vor-f{display:flex;align-items:center;gap:var(--vo-s-2);min-height:32px}.vo-vor-f .vo-sp{flex:1}.vo-vor:not(.vo-on) .vo-vor-f{justify-content:center}.vo-vor:not(.vo-on) .vo-vor-mute,.vo-vor:not(.vo-on) .vo-vor-end,.vo-vor:not(.vo-on) .vo-vor-f .vo-sp,.vo-vor.vo-on .vo-vor-go{display:none}.vo-vor-mute{position:relative}.vo-vor-mute[aria-pressed=true]{background:var(--vo-bad-bg);color:var(--vo-bad);box-shadow:none}.vo-vor-mute:after{content:\"\";position:absolute;left:50%;top:50%;width:1.5px;height:18px;margin:-9px 0 0 -.75px;border-radius:2px;background:currentColor;transform:rotate(-45deg) scaleY(0);transition:transform .25s var(--vo-ease)}.vo-vor-mute[aria-pressed=true]:after{transform:rotate(-45deg) scaleY(1)}.vo-vor-end{background:var(--vo-bad);color:var(--vo-on-ink)}@media (hover:hover) and (pointer:fine){.vo-vor-end:hover{background:color-mix(in srgb,var(--vo-bad) 86%,#000)}}.vo-vor-done{display:flex;align-items:center;gap:var(--vo-s-3);padding:10px 10px 10px var(--vo-s-3);border-radius:var(--vo-r-in);background:var(--vo-chip);font-size:13.5px}.vo-vor-done>svg{color:var(--vo-fg2);flex:none}.vo-vor-done .vo-t{flex:1;min-width:0;display:flex;flex-direction:column}.vo-vor-done .vo-t span{font-size:13px}.vo-sp{flex:1}.vo-num{font-variant-numeric:tabular-nums}.vo-muted{color:var(--vo-muted)}.vo-panel{background:var(--vo-surface);border-radius:var(--vo-r-card);box-shadow:var(--vo-shadow);position:relative}.vo-ib{width:30px;height:30px;border-radius:50%;display:inline-grid;place-items:center;color:var(--vo-fg2);cursor:pointer;transition:background var(--vo-t-fast),color var(--vo-t-fast),transform .15s}@media (hover:hover) and (pointer:fine){.vo-ib:hover{background:var(--vo-row);color:var(--vo-fg)}}.vo-ib:active{transform:scale(.94)}.vo-ib.vo-fill{background:var(--vo-soft);box-shadow:var(--vo-soft-ring)}@media (hover:hover) and (pointer:fine){.vo-ib.vo-fill:hover{background:var(--vo-soft-h)}}.vo-pill{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:32px;padding:0 14px;border-radius:var(--vo-r-pill);font-size:13px;font-weight:500;white-space:nowrap;cursor:pointer;transition:background var(--vo-t-fast),color var(--vo-t-fast),opacity var(--vo-t-fast),transform .15s}.vo-pill:active{transform:scale(.97)}.vo-pill.vo-primary{background:var(--vo-accent);color:var(--vo-on-accent)}@media (hover:hover) and (pointer:fine){.vo-pill.vo-primary:hover{background:var(--vo-accent-2)}}.vo-pill.vo-sm{height:28px;padding:0 11px;font-size:12.5px}.vo-fold{display:grid;grid-template-rows:1fr;transition:grid-template-rows var(--vo-t) var(--vo-ease),opacity var(--vo-t) var(--vo-ease)}.vo-fold>*{overflow:hidden;min-height:0}.vo-fold.vo-shut{grid-template-rows:0fr;opacity:0;visibility:hidden;transition:grid-template-rows var(--vo-t) var(--vo-ease),opacity var(--vo-t) var(--vo-ease),visibility 0s var(--vo-t)}.vo-enter{animation:vo-enter var(--vo-t-slow) var(--vo-ease) backwards}@keyframes vo-enter{0%{opacity:0;transform:translateY(6px);filter:blur(4px)}to{opacity:1;transform:none;filter:blur(0)}}\n"], dependencies: [{ kind: "component", type: VoIconComponent, selector: "vo-icon", inputs: ["name", "size"] }], encapsulation: i0.ViewEncapsulation.None }); }
217
+ }
218
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VoiceOrbComponent, decorators: [{
219
+ type: Component,
220
+ args: [{ selector: 'vo-voice-orb', standalone: true, encapsulation: ViewEncapsulation.None, imports: [VoIconComponent], template: `
221
+ <div data-vo="" [class]="className" style="width:100%">
222
+ <div class="vo-vor vo-panel" [class.vo-on]="on" [attr.data-m]="mode">
223
+ <div class="vo-vor-top">
224
+ <span class="vo-vor-dot"></span>
225
+ <span class="vo-vor-st">{{ status }}</span>
226
+ <span class="vo-vor-t vo-num vo-muted">{{ fmt(elapsed) }}</span>
227
+ </div>
228
+ <div class="vo-vor-orb" aria-hidden="true" [style.--vo-lv]="lv">
229
+ <i class="vo-vor-pc"></i>
230
+ <i class="vo-vor-core"><canvas #gl class="vo-vor-gl"></canvas></i>
231
+ </div>
232
+ <div class="vo-vor-cap" aria-live="polite">
233
+ <span class="vo-vor-who vo-muted">{{ caption?.speaker ?? '' }}</span>
234
+ @if (caption; as cap) {
235
+ <p class="vo-vor-tx">
236
+ @for (w of words(cap.text); track $index) {
237
+ <span class="vo-w">{{ w }} </span>
238
+ }
239
+ </p>
240
+ } @else {
241
+ <p class="vo-vor-tx vo-hint">{{ hint }}</p>
242
+ }
243
+ </div>
244
+ <div class="vo-fold vo-vor-mf" [class.vo-shut]="!noticeOpen" [attr.inert]="noticeOpen ? null : ''">
245
+ <div>
246
+ <div class="vo-vor-mw">
247
+ <p><vo-icon name="alert" size="xs"></vo-icon><span>{{ L.mutedNotice }}</span></p>
248
+ <button type="button" class="vo-pill vo-sm vo-vor-un" (click)="emitMuted(false)">{{ L.unmute }}</button>
249
+ </div>
250
+ </div>
251
+ </div>
252
+ @if (state === 'ended') {
253
+ <div class="vo-vor-done vo-enter">
254
+ <vo-icon name="ok"></vo-icon>
255
+ <span class="vo-t">{{ L.endedTitle }}<span class="vo-muted">{{ endedDetail ?? defaultDetail }}</span></span>
256
+ <button type="button" class="vo-pill vo-sm" (click)="restart.emit()">{{ L.restart }}</button>
257
+ </div>
258
+ } @else {
259
+ <div class="vo-vor-f">
260
+ <button type="button" class="vo-pill vo-primary vo-sm vo-vor-go" (click)="start.emit()">
261
+ <vo-icon name="comment" size="xs"></vo-icon>{{ L.start }}
262
+ </button>
263
+ <button
264
+ type="button"
265
+ class="vo-ib vo-fill vo-vor-mute"
266
+ [attr.aria-label]="L.mute"
267
+ [attr.aria-pressed]="muted"
268
+ [attr.data-tip]="muted ? L.unmute : L.mute"
269
+ (click)="emitMuted(!muted)"
270
+ >
271
+ <vo-icon name="comment"></vo-icon>
272
+ </button>
273
+ <span class="vo-sp"></span>
274
+ <button type="button" class="vo-pill vo-sm vo-vor-end" (click)="end.emit()">{{ L.end }}</button>
275
+ </div>
276
+ }
277
+ </div>
278
+ </div>
279
+ `, styles: [".vo-vor{position:relative;width:100%;max-width:380px;margin:0 auto;padding:var(--vo-s-4);display:flex;flex-direction:column;gap:var(--vo-s-3);--vo-oc:var(--vo-faint);--vo-oc2:var(--vo-accent)}.vo-vor[data-m=listening]{--vo-oc:var(--vo-accent);--vo-oc2:color-mix(in oklch,var(--vo-pl) 45%,var(--vo-accent))}.vo-vor[data-m=speaking]{--vo-oc:var(--vo-pl);--vo-oc2:color-mix(in oklch,var(--vo-accent) 45%,var(--vo-pl))}.vo-vor[data-m=thinking]{--vo-oc:color-mix(in oklch,var(--vo-accent) 50%,var(--vo-pl));--vo-oc2:var(--vo-accent)}.vo-vor[data-m=muted]{--vo-oc:color-mix(in srgb,var(--vo-muted) 55%,var(--vo-faint));--vo-oc2:var(--vo-faint)}.vo-vor-top{display:flex;align-items:center;gap:var(--vo-s-2);font-size:13px}.vo-vor-dot{width:8px;height:8px;border-radius:50%;background:var(--vo-oc);transition:background .4s}.vo-vor[data-m=listening] .vo-vor-dot,.vo-vor[data-m=speaking] .vo-vor-dot{animation:vo-vor-pulse 1.4s var(--vo-ease-io) infinite}@keyframes vo-vor-pulse{0%,to{box-shadow:0 0 color-mix(in srgb,var(--vo-oc) 35%,transparent)}50%{box-shadow:0 0 0 5px transparent}}.vo-vor-t{margin-left:auto;font-size:12.5px}.vo-vor-orb{position:relative;width:112px;height:112px;margin:var(--vo-s-2) auto;--vo-lv:0}.vo-vor-orb i{position:absolute;inset:0;border-radius:50%}.vo-vor .vo-vor-orb i{border-radius:50%!important}.vo-vor-core{overflow:hidden;background-color:color-mix(in srgb,var(--vo-oc) 80%,var(--vo-surface));background-image:radial-gradient(circle at 34% 28%,#fff6,#fff0 60%);box-shadow:inset 0 -10px 20px color-mix(in srgb,var(--vo-oc) 55%,#000 10%);transform:scale(calc(.9 + var(--vo-lv) * .1));transition:background-color .4s}.vo-vor-gl{position:absolute;inset:0;width:100%;height:100%;border-radius:50%;opacity:0;transition:opacity .4s}.vo-vor-gl.vo-on{opacity:1}.vo-vor-core:has(>.vo-vor-gl.vo-on){background:none;box-shadow:none}.vo-vor-pc{visibility:hidden;background:var(--vo-oc2);transition:background .4s}.vo-vor-cap,.vo-vor-mf,.vo-vor-f{position:relative}.vo-vor[data-m=thinking] .vo-vor-core{animation:vo-vor-br 1.6s var(--vo-ease-io) infinite alternate}@keyframes vo-vor-br{0%{transform:scale(.9)}to{transform:scale(.96)}}.vo-vor-cap{min-height:88px;display:flex;flex-direction:column;gap:2px;text-align:center}.vo-vor-who{font-size:12px;min-height:18px}.vo-vor-tx{margin:0;font-size:14px;line-height:1.6;color:var(--vo-fg)}.vo-vor-tx.vo-hint{color:var(--vo-muted);font-size:13px}.vo-vor-tx .vo-w{animation:vo-vor-w .45s var(--vo-ease) both}@keyframes vo-vor-w{0%{opacity:0;filter:blur(3px)}to{opacity:1;filter:none}}.vo-vor-mw{display:flex;align-items:center;gap:10px;padding:var(--vo-s-2) var(--vo-s-2) var(--vo-s-2) var(--vo-s-3);border-radius:var(--vo-r-in);background:var(--vo-warn-bg)}.vo-vor-mw p{margin:0;flex:1;display:flex;gap:var(--vo-s-2);font-size:13px;line-height:1.45;color:var(--vo-fg)}.vo-vor-mw p svg{color:var(--vo-warn);flex:none;margin-top:3px}.vo-vor-mw .vo-pill,.vo-vor-done .vo-pill{background:var(--vo-surface);color:var(--vo-fg);box-shadow:var(--vo-shadow)}.vo-vor-f{display:flex;align-items:center;gap:var(--vo-s-2);min-height:32px}.vo-vor-f .vo-sp{flex:1}.vo-vor:not(.vo-on) .vo-vor-f{justify-content:center}.vo-vor:not(.vo-on) .vo-vor-mute,.vo-vor:not(.vo-on) .vo-vor-end,.vo-vor:not(.vo-on) .vo-vor-f .vo-sp,.vo-vor.vo-on .vo-vor-go{display:none}.vo-vor-mute{position:relative}.vo-vor-mute[aria-pressed=true]{background:var(--vo-bad-bg);color:var(--vo-bad);box-shadow:none}.vo-vor-mute:after{content:\"\";position:absolute;left:50%;top:50%;width:1.5px;height:18px;margin:-9px 0 0 -.75px;border-radius:2px;background:currentColor;transform:rotate(-45deg) scaleY(0);transition:transform .25s var(--vo-ease)}.vo-vor-mute[aria-pressed=true]:after{transform:rotate(-45deg) scaleY(1)}.vo-vor-end{background:var(--vo-bad);color:var(--vo-on-ink)}@media (hover:hover) and (pointer:fine){.vo-vor-end:hover{background:color-mix(in srgb,var(--vo-bad) 86%,#000)}}.vo-vor-done{display:flex;align-items:center;gap:var(--vo-s-3);padding:10px 10px 10px var(--vo-s-3);border-radius:var(--vo-r-in);background:var(--vo-chip);font-size:13.5px}.vo-vor-done>svg{color:var(--vo-fg2);flex:none}.vo-vor-done .vo-t{flex:1;min-width:0;display:flex;flex-direction:column}.vo-vor-done .vo-t span{font-size:13px}.vo-sp{flex:1}.vo-num{font-variant-numeric:tabular-nums}.vo-muted{color:var(--vo-muted)}.vo-panel{background:var(--vo-surface);border-radius:var(--vo-r-card);box-shadow:var(--vo-shadow);position:relative}.vo-ib{width:30px;height:30px;border-radius:50%;display:inline-grid;place-items:center;color:var(--vo-fg2);cursor:pointer;transition:background var(--vo-t-fast),color var(--vo-t-fast),transform .15s}@media (hover:hover) and (pointer:fine){.vo-ib:hover{background:var(--vo-row);color:var(--vo-fg)}}.vo-ib:active{transform:scale(.94)}.vo-ib.vo-fill{background:var(--vo-soft);box-shadow:var(--vo-soft-ring)}@media (hover:hover) and (pointer:fine){.vo-ib.vo-fill:hover{background:var(--vo-soft-h)}}.vo-pill{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:32px;padding:0 14px;border-radius:var(--vo-r-pill);font-size:13px;font-weight:500;white-space:nowrap;cursor:pointer;transition:background var(--vo-t-fast),color var(--vo-t-fast),opacity var(--vo-t-fast),transform .15s}.vo-pill:active{transform:scale(.97)}.vo-pill.vo-primary{background:var(--vo-accent);color:var(--vo-on-accent)}@media (hover:hover) and (pointer:fine){.vo-pill.vo-primary:hover{background:var(--vo-accent-2)}}.vo-pill.vo-sm{height:28px;padding:0 11px;font-size:12.5px}.vo-fold{display:grid;grid-template-rows:1fr;transition:grid-template-rows var(--vo-t) var(--vo-ease),opacity var(--vo-t) var(--vo-ease)}.vo-fold>*{overflow:hidden;min-height:0}.vo-fold.vo-shut{grid-template-rows:0fr;opacity:0;visibility:hidden;transition:grid-template-rows var(--vo-t) var(--vo-ease),opacity var(--vo-t) var(--vo-ease),visibility 0s var(--vo-t)}.vo-enter{animation:vo-enter var(--vo-t-slow) var(--vo-ease) backwards}@keyframes vo-enter{0%{opacity:0;transform:translateY(6px);filter:blur(4px)}to{opacity:1;transform:none;filter:blur(0)}}\n"] }]
280
+ }], propDecorators: { state: [{
281
+ type: Input
282
+ }], level: [{
283
+ type: Input
284
+ }], muted: [{
285
+ type: Input
286
+ }], mutedNotice: [{
287
+ type: Input
288
+ }], caption: [{
289
+ type: Input
290
+ }], hint: [{
291
+ type: Input
292
+ }], elapsed: [{
293
+ type: Input
294
+ }], endedDetail: [{
295
+ type: Input
296
+ }], labels: [{
297
+ type: Input
298
+ }], className: [{
299
+ type: Input
300
+ }], mutedChange: [{
301
+ type: Output
302
+ }], start: [{
303
+ type: Output
304
+ }], end: [{
305
+ type: Output
306
+ }], restart: [{
307
+ type: Output
308
+ }], glRef: [{
309
+ type: ViewChild,
310
+ args: ['gl']
311
+ }] } });
312
+ // the glass sphere, as a fragment shader (the site's own source, ported from the
313
+ // Vanilla/React originals): a ball lit from the top left, a deeper shifted hue past
314
+ // the terminator, light gathered through the glass on the far side, a fresnel edge,
315
+ // a broad sheen and a sharp highlight. Inside, deep pools of the two colours and a
316
+ // third hue swirl, liquid light flows through the middle and two ribbons turn near
317
+ // the surface. The level speeds the flow, brightens the heart and shimmers the
318
+ // highlight. Where WebGL is missing the same picture is drawn in a few gradients on
319
+ // a 2D canvas. At its widest the sphere still sits inside the canvas.
320
+ const FRAG = `#ifdef GL_FRAGMENT_PRECISION_HIGH
321
+ precision highp float;
322
+ #else
323
+ precision mediump float;
324
+ #endif
325
+ uniform vec2 R;uniform float T,L;uniform vec3 A0,B0;
326
+ float h(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}
327
+ float n(vec2 p){vec2 i=floor(p),f=fract(p);f=f*f*(3.-2.*f);return mix(mix(h(i),h(i+vec2(1,0)),f.x),mix(h(i+vec2(0,1)),h(i+1.),f.x),f.y);}
328
+ float fbm(vec2 p){float v=0.,a=.5;for(int i=0;i<4;i++){v+=a*n(p);p=mat2(1.6,1.2,-1.2,1.6)*p+vec2(1.7,9.2);a*=.5;}return v;}
329
+ mat2 rot(float a){float c=cos(a),s=sin(a);return mat2(c,s,-s,c);}
330
+ vec3 tn(vec3 c){float mx=max(c.r,max(c.g,c.b)),d=mx-min(c.r,min(c.g,c.b));c*=max(1.,.5/max(mx,.01));mx=max(mx,.5);d=mx-min(c.r,min(c.g,c.b));return max(mx-(mx-c)*mix(1.,clamp(.55*mx/max(d,.001),1.,3.),smoothstep(.03,.12,d)),0.);}
331
+ vec3 hue(vec3 c,float a){vec3 k=vec3(.57735);float co=cos(a);return c*co+cross(k,c)*sin(a)+k*dot(k,c)*(1.-co);}
332
+ void main(){
333
+ vec3 A=tn(A0),B=tn(B0),C=hue(A,mix(-.9,1.4,smoothstep(-.1,.1,A.b-A.g)));
334
+ vec2 u=(gl_FragCoord.xy*2.-R)/R.y;
335
+ float t=T*.001,an=atan(u.y,u.x);
336
+ float w=(.002+.008*L)*(sin(3.*an+t*1.9)+.6*sin(5.*an-t*2.7)+.4*sin(2.*an-t*1.1));
337
+ float rad=.955*(1.+.008*sin(t*.9)+w);
338
+ vec2 q=u/rad;float r=length(q),e=3./(R.y*rad);
339
+ float a=1.-smoothstep(1.-e,1.,r);
340
+ if(a<=0.){gl_FragColor=vec4(0.);return;}
341
+ float z=sqrt(max(1.-r*r,0.));
342
+ vec3 N=vec3(q,z);
343
+ N.xy+=(vec2(n(q*5.+t*1.6),n(q*5.-t*1.3+7.))-.5)*(.03+.12*L);N=normalize(N);
344
+ vec3 S=vec3(q,z),D=refract(vec3(0,0,-1),N,.72),P1=S+D*z*.35,P2=S+D*z*.9,P3=S+D*z*1.5;
345
+ float s=t*.22;
346
+ vec3 d1=P3-vec3(.55*sin(s*1.3),.5*cos(s*1.1),.3*sin(s*.7)),d2=P3-vec3(.55*cos(s*.9+2.),.5*sin(s*1.2+1.),.3*cos(s*.8+3.)),d3=P3-vec3(.5*sin(s*1.6+4.),.5*cos(s*1.4+5.),.3*sin(s+1.));
347
+ float g1=exp(-dot(d1,d1)*2.6),g2=exp(-dot(d2,d2)*2.6),g3=exp(-dot(d3,d3)*3.2);
348
+ vec3 col=mix(mix(mix(mix(A,B,.4)*.55,B,g2*.8),C,g3*.7),A,g1*.95);
349
+ vec2 m=rot(t*.09)*P2.xy*1.5,o=vec2(fbm(m+vec2(0.,t*.3)),fbm(m+vec2(5.2,1.3)-t*.25));
350
+ float f=fbm(m+(o-.5)*(2.5+2.*L)+vec2(t*.12,-t*.08));
351
+ col=mix(col,mix(mix(A,B,.5),vec3(1.),.15),smoothstep(.45,.8,f)*.5)*(.8+.35*smoothstep(.2,.6,f));
352
+ vec2 k=rot(-t*.33)*P1.xy;
353
+ float b1=k.y+.32*sin(k.x*2.4+t*1.4)+.12*sin(k.x*5.3-t*2.2)+(o.x-.5)*.5,b2=k.x-.3*sin(k.y*2.1-t*1.1)+.4;
354
+ col+=mix(mix(A,C,.35),vec3(1.),.35)*(exp(-b1*b1*40.)+.6*exp(-b2*b2*55.))*(.25+.35*L)*z;
355
+ col+=mix(A,vec3(1.),.4)*exp(-dot(P2.xy,P2.xy)*3.)*(.08+.3*L);
356
+ vec3 lk=normalize(vec3(-.5,.62,.6)),dk=hue(col,.35);
357
+ col=mix(dk*dk*.6,col*1.06,smoothstep(-.55,.75,dot(N,lk)));
358
+ col+=mix(B,vec3(1.),.5)*pow(1.-z,1.6)*smoothstep(.1,.95,dot(q/max(r,1e-3),-normalize(lk.xy)))*.55;
359
+ col=mix(col,mix(vec3(.06),vec3(1.),smoothstep(-.3,.9,N.y*.7-N.x*.4)),pow(1.-N.z,3.)*.5);
360
+ float nh=max(dot(N,normalize(lk+vec3(0,0,1))),0.);
361
+ col+=pow(nh,700.)*(1.2+.8*L*sin(t*9.+q.x*8.))+pow(nh,60.)*.25+pow(nh,8.)*.1;
362
+ gl_FragColor=vec4(clamp(col,0.,1.)*a,a);
363
+ }`;
364
+ /** Draws the sphere on the orb's canvas: one draw a frame, at most 2 device pixels a
365
+ CSS pixel, nothing made anew each frame. Where WebGL is missing it falls back to a
366
+ few gradients on a 2D canvas. Returns { paint, lose }, or null when neither can draw. */
367
+ function orbShader(cv) {
368
+ // a computed colour to 0..1 channels; mid-transition it can come as oklab() or
369
+ // color(), so a 1px canvas reads it. Only a colour that changed is read.
370
+ const px = document.createElement('canvas').getContext('2d', { willReadFrequently: true });
371
+ if (!px)
372
+ return null;
373
+ px.canvas.width = px.canvas.height = 1;
374
+ const rgb = (s, o) => {
375
+ px.clearRect(0, 0, 1, 1);
376
+ px.fillStyle = '#000';
377
+ px.fillStyle = s;
378
+ px.fillRect(0, 0, 1, 1);
379
+ const d = px.getImageData(0, 0, 1, 1).data;
380
+ o[0] = d[0] / 255;
381
+ o[1] = d[1] / 255;
382
+ o[2] = d[2] / 255;
383
+ };
384
+ const ta = new Float32Array(3), tb = new Float32Array(3), ca = new Float32Array(3), cb = new Float32Array(3);
385
+ let sa = '', sb = '', w = 0, at = -1e9, prev = -1e9;
386
+ const fit = (now) => {
387
+ if (w && now - at < 300)
388
+ return false;
389
+ at = now;
390
+ const n = Math.round(cv.clientWidth * Math.min(2, devicePixelRatio || 1)) || 1;
391
+ if (n === w)
392
+ return false;
393
+ w = cv.width = cv.height = n;
394
+ return true;
395
+ };
396
+ const tint = (a, b, now, snap) => {
397
+ if (a !== sa) {
398
+ sa = a;
399
+ rgb(a, ta);
400
+ }
401
+ if (b !== sb) {
402
+ sb = b;
403
+ rgb(b, tb);
404
+ }
405
+ const k = snap || now - prev > 200 ? 1 : Math.min(1, (now - prev) / 110);
406
+ prev = now;
407
+ for (let i = 0; i < 3; i++) {
408
+ ca[i] += (ta[i] - ca[i]) * k;
409
+ cb[i] += (tb[i] - cb[i]) * k;
410
+ }
411
+ };
412
+ const gl = cv.getContext('webgl', { premultipliedAlpha: true, antialias: false, powerPreference: 'low-power' });
413
+ if (gl) {
414
+ const sh = (type, src) => {
415
+ const s = gl.createShader(type);
416
+ gl.shaderSource(s, src);
417
+ gl.compileShader(s);
418
+ return s;
419
+ };
420
+ const pr = gl.createProgram();
421
+ gl.attachShader(pr, sh(gl.VERTEX_SHADER, 'attribute vec2 p;void main(){gl_Position=vec4(p,0.,1.);}'));
422
+ gl.attachShader(pr, sh(gl.FRAGMENT_SHADER, FRAG));
423
+ gl.linkProgram(pr);
424
+ const lose = () => { gl.getExtension('WEBGL_lose_context')?.loseContext(); };
425
+ if (!gl.getProgramParameter(pr, gl.LINK_STATUS)) {
426
+ lose();
427
+ return null;
428
+ }
429
+ gl.useProgram(pr);
430
+ gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
431
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);
432
+ const p = gl.getAttribLocation(pr, 'p');
433
+ gl.enableVertexAttribArray(p);
434
+ gl.vertexAttribPointer(p, 2, gl.FLOAT, false, 0, 0);
435
+ const U = (k) => gl.getUniformLocation(pr, k);
436
+ const uR = U('R'), uT = U('T'), uL = U('L'), uA = U('A0'), uB = U('B0');
437
+ return {
438
+ paint(ms, lv, a, b) {
439
+ const now = performance.now();
440
+ if (fit(now))
441
+ gl.viewport(0, 0, w, w);
442
+ tint(a, b, now, false);
443
+ gl.uniform2f(uR, w, w);
444
+ gl.uniform1f(uT, ms);
445
+ gl.uniform1f(uL, lv);
446
+ gl.uniform3fv(uA, ca);
447
+ gl.uniform3fv(uB, cb);
448
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
449
+ },
450
+ lose,
451
+ };
452
+ }
453
+ const x = cv.getContext('2d');
454
+ if (!x)
455
+ return null;
456
+ // the shader's colours: dark ones lifted, pale ones given more chroma, a third hue
457
+ // turned round the grey axis toward the warm side
458
+ const tn = (o, d) => {
459
+ const lift = Math.max(1, 0.5 / Math.max(0.01, o[0], o[1], o[2]));
460
+ const mx = Math.max(o[0], o[1], o[2]) * lift;
461
+ const dd = mx - Math.min(o[0], o[1], o[2]) * lift;
462
+ const s = Math.min(1, Math.max(0, (dd - 0.03) / 0.09));
463
+ const k = 1 + (Math.min(3, Math.max(1, 0.55 * mx / Math.max(dd, 0.001))) - 1) * s * s * (3 - 2 * s);
464
+ for (let i = 0; i < 3; i++)
465
+ d[i] = Math.max(0, mx - (mx - o[i] * lift) * k);
466
+ };
467
+ const hue = (o, d, ang) => {
468
+ const co = Math.cos(ang), si = Math.sin(ang) * 0.57735, m = ((o[0] + o[1] + o[2]) / 3) * (1 - co);
469
+ d[0] = o[0] * co + (o[2] - o[1]) * si + m;
470
+ d[1] = o[1] * co + (o[0] - o[2]) * si + m;
471
+ d[2] = o[2] * co + (o[1] - o[0]) * si + m;
472
+ };
473
+ const A = new Float32Array(3), B = new Float32Array(3), C = new Float32Array(3), M = new Float32Array(3);
474
+ const cssCol = (o, al, f = 1) => `rgba(${[0, 1, 2].map((i) => Math.round(Math.min(1, Math.max(0, o[i] * f)) * 255)).join(',')},${al})`;
475
+ const grad = (cx, cy, r, stops) => {
476
+ const g = x.createRadialGradient(cx, cy, 0, cx, cy, r);
477
+ for (let i = 0; i < stops.length; i += 2)
478
+ g.addColorStop(stops[i], stops[i + 1]);
479
+ return g;
480
+ };
481
+ const shade = grad(-0.35, -0.4, 1.6, [0, 'rgba(255,255,255,.16)', 0.45, 'rgba(0,0,0,0)', 1, 'rgba(0,0,0,.5)']);
482
+ const rim = grad(0, 0, 1, [0.78, 'rgba(255,255,255,0)', 1, 'rgba(255,255,255,.28)']);
483
+ const sheen = grad(-0.32, -0.38, 0.6, [0, 'rgba(255,255,255,.22)', 1, 'rgba(255,255,255,0)']);
484
+ const spec = grad(-0.4, -0.46, 0.14, [0, 'rgba(255,255,255,.95)', 1, 'rgba(255,255,255,0)']);
485
+ let g = null;
486
+ let mid = 0, rad = 0;
487
+ const put = (fill, dx, dy, sz) => {
488
+ x.setTransform(rad * sz, 0, 0, rad * sz, mid + rad * dx, mid + rad * dy);
489
+ x.fillStyle = fill;
490
+ x.fillRect(-1, -1, 2, 2);
491
+ };
492
+ return {
493
+ paint(ms, lv, a, b) {
494
+ const now = performance.now();
495
+ fit(now);
496
+ if (!g || a !== sa || b !== sb) {
497
+ tint(a, b, now, true);
498
+ tn(ca, A);
499
+ tn(cb, B);
500
+ hue(A, C, A[2] > A[1] ? 1.4 : -0.9);
501
+ for (let i = 0; i < 3; i++)
502
+ M[i] = (A[i] + B[i]) / 2;
503
+ g = {
504
+ base: cssCol(M, 1, 0.7),
505
+ a: grad(0, 0, 1, [0, cssCol(A, 0.95), 1, cssCol(A, 0)]),
506
+ b: grad(0, 0, 1, [0, cssCol(B, 0.95), 1, cssCol(B, 0)]),
507
+ c: grad(0, 0, 1, [0, cssCol(C, 0.55), 1, cssCol(C, 0)]),
508
+ core: grad(0, 0, 1, [0, cssCol(A, 1, 1.4), 1, cssCol(A, 0)]),
509
+ };
510
+ }
511
+ const t = ms * 0.001, s = t * 0.22;
512
+ mid = w / 2;
513
+ rad = mid * 0.955 * (1 + 0.008 * Math.sin(t * 0.9));
514
+ x.setTransform(1, 0, 0, 1, 0, 0);
515
+ x.clearRect(0, 0, w, w);
516
+ x.save();
517
+ x.beginPath();
518
+ x.arc(mid, mid, rad, 0, Math.PI * 2);
519
+ x.clip();
520
+ x.fillStyle = g.base;
521
+ x.fillRect(0, 0, w, w);
522
+ put(g.a, 0.55 * Math.sin(s * 1.3), -0.5 * Math.cos(s * 1.1), 1.1);
523
+ put(g.b, 0.55 * Math.cos(s * 0.9 + 2), -0.5 * Math.sin(s * 1.2 + 1), 1.1);
524
+ put(g.c, 0.5 * Math.sin(s * 1.6 + 4), -0.5 * Math.cos(s * 1.4 + 5), 0.9);
525
+ x.globalAlpha = 0.15 + 0.45 * lv;
526
+ put(g.core, 0, 0, 0.7);
527
+ x.globalAlpha = 1;
528
+ put(shade, 0, 0, 1);
529
+ put(rim, 0, 0, 1);
530
+ put(sheen, 0, 0, 1);
531
+ x.globalAlpha = 0.85 + 0.15 * lv * Math.sin(t * 9);
532
+ put(spec, 0, 0, 1);
533
+ x.restore();
534
+ },
535
+ lose() { },
536
+ };
537
+ }
538
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2Utb3JiLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3ZvaWNlLW9yYi92b2ljZS1vcmIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHFEQUFxRDtBQUNyRCxFQUFFO0FBQ0YsaUVBQWlFO0FBQ2pFLGtGQUFrRjtBQUNsRixnRkFBZ0Y7QUFDaEYsMkVBQTJFO0FBQzNFLGlGQUFpRjtBQUVqRixPQUFPLEVBRUwsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUVOLFNBQVMsRUFDVCxpQkFBaUIsRUFDakIsTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQzs7QUE2QnRFLE1BQU0sUUFBUSxHQUE2QjtJQUN6QyxLQUFLLEVBQUUsT0FBTztJQUNkLFNBQVMsRUFBRSxXQUFXO0lBQ3RCLFFBQVEsRUFBRSxVQUFVO0lBQ3BCLFFBQVEsRUFBRSxVQUFVO0lBQ3BCLEtBQUssRUFBRSxPQUFPO0lBQ2QsS0FBSyxFQUFFLE9BQU87SUFDZCxLQUFLLEVBQUUsZUFBZTtJQUN0QixHQUFHLEVBQUUsS0FBSztJQUNWLElBQUksRUFBRSxNQUFNO0lBQ1osTUFBTSxFQUFFLFFBQVE7SUFDaEIsV0FBVyxFQUFFLGlEQUFpRDtJQUM5RCxVQUFVLEVBQUUsa0JBQWtCO0lBQzlCLE9BQU8sRUFBRSxhQUFhO0NBQ3ZCLENBQUM7QUFFRixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQVMsRUFBVSxFQUFFLENBQ2hDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFB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QUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN2RCxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNwRyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRTtZQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzlFLENBQUMsQ0FBQztJQUNGLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBZSxFQUFFLENBQWUsRUFBRSxHQUFXLEVBQVEsRUFBRTtRQUNsRSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDbEcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUMxQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDNUMsQ0FBQyxDQUFDO0lBQ0YsTUFBTSxDQUFDLEdBQUcsSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDekcsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFlLEVBQUUsRUFBVSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQVUsRUFBRSxDQUM1RCxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUM7SUFDeEcsTUFBTSxJQUFJLEdBQUcsQ0FBQyxFQUFVLEVBQUUsRUFBVSxFQUFFLENBQVMsRUFBRSxLQUEwQixFQUFrQixFQUFFO1FBQzdGLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3ZELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQUUsQ0FBQyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFXLEVBQUUsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQVcsQ0FBQyxDQUFDO1FBQ3JHLE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBQ0YsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSx1QkFBdUIsRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLENBQUMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7SUFDL0csTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLHFCQUFxQixFQUFFLENBQUMsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDLENBQUM7SUFDckYsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSx1QkFBdUIsRUFBRSxDQUFDLEVBQUUscUJBQXFCLENBQUMsQ0FBQyxDQUFDO0lBQzlGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsdUJBQXVCLEVBQUUsQ0FBQyxFQUFFLHFCQUFxQixDQUFDLENBQUMsQ0FBQztJQUM3RixJQUFJLENBQUMsR0FBMkcsSUFBSSxDQUFDO0lBQ3JILElBQUksR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBQ3JCLE1BQU0sR0FBRyxHQUFHLENBQUMsSUFBNkIsRUFBRSxFQUFVLEVBQUUsRUFBVSxFQUFFLEVBQVUsRUFBUSxFQUFFO1FBQ3RGLENBQUMsQ0FBQyxZQUFZLENBQUMsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUN6RSxDQUFDLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUNuQixDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMzQixDQUFDLENBQUM7SUFDRixPQUFPO1FBQ0wsS0FBSyxDQUFDLEVBQVUsRUFBRSxFQUFVLEVBQUUsQ0FBUyxFQUFFLENBQVM7WUFDaEQsTUFBTSxHQUFHLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQzlCLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNULElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUM7Z0JBQy9CLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDdEIsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDVixFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNWLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDcEMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUU7b0JBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDckQsQ0FBQyxHQUFHO29CQUNGLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUM7b0JBQ3ZCLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUN2RCxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDdkQsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3ZELElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FB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QztRQUNkLENBQUM7UUFDRCxJQUFJLEtBQVUsQ0FBQztLQUNoQixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIGZyYW1ld29yay9hbmd1bGFyL3ZvaWNlLW9yYi92b2ljZS1vcmIuY29tcG9uZW50LnRzXG4vL1xuLy8gTmF0aXZlIEFuZ3VsYXIgcG9ydCBvZiBmcmFtZXdvcmsvcmVhY3Qvdm9pY2Utb3JiL1ZvaWNlT3JiLnRzeC5cbi8vIEEgaGFuZHMtZnJlZSB2b2ljZSBjaGF0OiBhbiBvcmIgdGhhdCBzd2VsbHMgd2l0aCB3aG9ldmVyIGlzIHRhbGtpbmcsIHRoZSBhY2NlbnRcbi8vIGNvbG91ciBmb3IgeW91IGFuZCB2aW9sZXQgZm9yIHRoZSBhZ2VudCwgd2hhdCB3YXMgc2FpZCB1bmRlciBpdCwgYW5kIG11dGUgYW5kXG4vLyBlbmQgYmVsb3cuIEl0IGRyYXdzIHdoYXQgeW91IHBhc3M7IGl0IG5ldmVyIG9wZW5zIHRoZSBtaWNyb3Bob25lIGl0c2VsZi5cbi8vIElucHV0cyBtaXJyb3IgdGhlIFJlYWN0IHByb3BzOyBSZWFjdCBjYWxsYmFja3MgYmVjb21lIEBPdXRwdXQoKSBFdmVudEVtaXR0ZXJzLlxuXG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIGluamVjdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBWb0ljb25Db21wb25lbnQgfSBmcm9tICcuLi9jb3JlL2ljb24uY29tcG9uZW50JztcbmltcG9ydCB7IFJlZHVjZWRNb3Rpb25TZXJ2aWNlIH0gZnJvbSAnLi4vY29yZS9yZWR1Y2VkLW1vdGlvbi5zZXJ2aWNlJztcblxuLyoqIGlkbGUgKG5vdCBzdGFydGVkKSwgbGlzdGVuaW5nLCB0aGlua2luZywgc3BlYWtpbmcgKHRoZSBhZ2VudCkgb3IgZW5kZWQuICovXG5leHBvcnQgdHlwZSBWb2ljZVN0YXRlID0gJ2lkbGUnIHwgJ2xpc3RlbmluZycgfCAndGhpbmtpbmcnIHwgJ3NwZWFraW5nJyB8ICdlbmRlZCc7XG5cbi8qKiBXaGF0IHdhcyBzYWlkIGxhc3QgYW5kIHdobyBzYWlkIGl0LiBBIG5ldyBpZCAob3Igc3BlYWtlcikgc3RhcnRzIGEgbmV3IGxpbmUuICovXG5leHBvcnQgaW50ZXJmYWNlIFZvaWNlQ2FwdGlvbiB7XG4gIHNwZWFrZXI6IHN0cmluZztcbiAgdGV4dDogc3RyaW5nO1xuICBpZD86IHN0cmluZztcbn1cblxuLyoqIExhYmVscywgc28gZXZlcnkgYml0IG9mIHRleHQgY2FuIGJlIGxvY2FsaXNlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVm9pY2VPcmJMYWJlbHMge1xuICByZWFkeT86IHN0cmluZztcbiAgbGlzdGVuaW5nPzogc3RyaW5nO1xuICB0aGlua2luZz86IHN0cmluZztcbiAgc3BlYWtpbmc/OiBzdHJpbmc7XG4gIG11dGVkPzogc3RyaW5nO1xuICBlbmRlZD86IHN0cmluZztcbiAgc3RhcnQ/OiBzdHJpbmc7XG4gIGVuZD86IHN0cmluZztcbiAgbXV0ZT86IHN0cmluZztcbiAgdW5tdXRlPzogc3RyaW5nO1xuICBtdXRlZE5vdGljZT86IHN0cmluZztcbiAgZW5kZWRUaXRsZT86IHN0cmluZztcbiAgcmVzdGFydD86IHN0cmluZztcbn1cblxuY29uc3QgREVGQVVMVFM6IFJlcXVpcmVkPFZvaWNlT3JiTGFiZWxzPiA9IHtcbiAgcmVhZHk6ICdSZWFkeScsXG4gIGxpc3RlbmluZzogJ0xpc3RlbmluZycsXG4gIHRoaW5raW5nOiAnVGhpbmtpbmcnLFxuICBzcGVha2luZzogJ1NwZWFraW5nJyxcbiAgbXV0ZWQ6ICdNdXRlZCcsXG4gIGVuZGVkOiAnRW5kZWQnLFxuICBzdGFydDogJ1N0YXJ0IHRhbGtpbmcnLFxuICBlbmQ6ICdFbmQnLFxuICBtdXRlOiAnTXV0ZScsXG4gIHVubXV0ZTogJ1VubXV0ZScsXG4gIG11dGVkTm90aWNlOiBcIllvdSdyZSBtdXRlZC4gVW5tdXRlIHNvIHRoZSBhZ2VudCBjYW4gaGVhciB5b3UuXCIsXG4gIGVuZGVkVGl0bGU6ICdWb2ljZSBjaGF0IGVuZGVkJyxcbiAgcmVzdGFydDogJ1N0YXJ0IGFnYWluJyxcbn07XG5cbmNvbnN0IGZtdCA9IChzOiBudW1iZXIpOiBzdHJpbmcgPT5cbiAgYCR7TWF0aC5mbG9vcihzIC8gNjApfToke1N0cmluZyhNYXRoLmZsb29yKHMpICUgNjApLnBhZFN0YXJ0KDIsICcwJyl9YDtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndm8tdm9pY2Utb3JiJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgaW1wb3J0czogW1ZvSWNvbkNvbXBvbmVudF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBkYXRhLXZvPVwiXCIgW2NsYXNzXT1cImNsYXNzTmFtZVwiIHN0eWxlPVwid2lkdGg6MTAwJVwiPlxuICAgICAgPGRpdiBjbGFzcz1cInZvLXZvciB2by1wYW5lbFwiIFtjbGFzcy52by1vbl09XCJvblwiIFthdHRyLmRhdGEtbV09XCJtb2RlXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ2by12b3ItdG9wXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by12b3ItZG90XCI+PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tdm9yLXN0XCI+e3sgc3RhdHVzIH19PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tdm9yLXQgdm8tbnVtIHZvLW11dGVkXCI+e3sgZm10KGVsYXBzZWQpIH19PC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInZvLXZvci1vcmJcIiBhcmlhLWhpZGRlbj1cInRydWVcIiBbc3R5bGUuLS12by1sdl09XCJsdlwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwidm8tdm9yLXBjXCI+PC9pPlxuICAgICAgICAgIDxpIGNsYXNzPVwidm8tdm9yLWNvcmVcIj48Y2FudmFzICNnbCBjbGFzcz1cInZvLXZvci1nbFwiPjwvY2FudmFzPjwvaT5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ2by12b3ItY2FwXCIgYXJpYS1saXZlPVwicG9saXRlXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by12b3Itd2hvIHZvLW11dGVkXCI+e3sgY2FwdGlvbj8uc3BlYWtlciA/PyAnJyB9fTwvc3Bhbj5cbiAgICAgICAgICBAaWYgKGNhcHRpb247IGFzIGNhcCkge1xuICAgICAgICAgICAgPHAgY2xhc3M9XCJ2by12b3ItdHhcIj5cbiAgICAgICAgICAgICAgQGZvciAodyBvZiB3b3JkcyhjYXAudGV4dCk7IHRyYWNrICRpbmRleCkge1xuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8td1wiPnt7IHcgfX0gPC9zcGFuPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICA8cCBjbGFzcz1cInZvLXZvci10eCB2by1oaW50XCI+e3sgaGludCB9fTwvcD5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwidm8tZm9sZCB2by12b3ItbWZcIiBbY2xhc3Mudm8tc2h1dF09XCIhbm90aWNlT3BlblwiIFthdHRyLmluZXJ0XT1cIm5vdGljZU9wZW4gPyBudWxsIDogJydcIj5cbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZvLXZvci1td1wiPlxuICAgICAgICAgICAgICA8cD48dm8taWNvbiBuYW1lPVwiYWxlcnRcIiBzaXplPVwieHNcIj48L3ZvLWljb24+PHNwYW4+e3sgTC5tdXRlZE5vdGljZSB9fTwvc3Bhbj48L3A+XG4gICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidm8tcGlsbCB2by1zbSB2by12b3ItdW5cIiAoY2xpY2spPVwiZW1pdE11dGVkKGZhbHNlKVwiPnt7IEwudW5tdXRlIH19PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIEBpZiAoc3RhdGUgPT09ICdlbmRlZCcpIHtcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidm8tdm9yLWRvbmUgdm8tZW50ZXJcIj5cbiAgICAgICAgICAgIDx2by1pY29uIG5hbWU9XCJva1wiPjwvdm8taWNvbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tdFwiPnt7IEwuZW5kZWRUaXRsZSB9fTxzcGFuIGNsYXNzPVwidm8tbXV0ZWRcIj57eyBlbmRlZERldGFpbCA/PyBkZWZhdWx0RGV0YWlsIH19PC9zcGFuPjwvc3Bhbj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidm8tcGlsbCB2by1zbVwiIChjbGljayk9XCJyZXN0YXJ0LmVtaXQoKVwiPnt7IEwucmVzdGFydCB9fTwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidm8tdm9yLWZcIj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidm8tcGlsbCB2by1wcmltYXJ5IHZvLXNtIHZvLXZvci1nb1wiIChjbGljayk9XCJzdGFydC5lbWl0KClcIj5cbiAgICAgICAgICAgICAgPHZvLWljb24gbmFtZT1cImNvbW1lbnRcIiBzaXplPVwieHNcIj48L3ZvLWljb24+e3sgTC5zdGFydCB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cInZvLWliIHZvLWZpbGwgdm8tdm9yLW11dGVcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIkwubXV0ZVwiXG4gICAgICAgICAgICAgIFthdHRyLmFyaWEtcHJlc3NlZF09XCJtdXRlZFwiXG4gICAgICAgICAgICAgIFthdHRyLmRhdGEtdGlwXT1cIm11dGVkID8gTC51bm11dGUgOiBMLm11dGVcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiZW1pdE11dGVkKCFtdXRlZClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8dm8taWNvbiBuYW1lPVwiY29tbWVudFwiPjwvdm8taWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by1zcFwiPjwvc3Bhbj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidm8tcGlsbCB2by1zbSB2by12b3ItZW5kXCIgKGNsaWNrKT1cImVuZC5lbWl0KClcIj57eyBMLmVuZCB9fTwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVVcmw6ICcuL3ZvaWNlLW9yYi5jc3MnLFxufSlcbmV4cG9ydCBjbGFzcyBWb2ljZU9yYkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgLyoqIGlkbGUsIGxpc3RlbmluZywgdGhpbmtpbmcsIHNwZWFraW5nIG9yIGVuZGVkLiAqL1xuICBASW5wdXQoKSBzdGF0ZTogVm9pY2VTdGF0ZSA9ICdpZGxlJztcbiAgLyoqIEhvdyBsb3VkIHdob2V2ZXIgaXMgdGFsa2luZyBpcywgMCB0byAxLiBUaGUgb3JiIHN3ZWxscyB3aXRoIGl0LiAqL1xuICBASW5wdXQoKSBsZXZlbCA9IDA7XG4gIC8qKiBZb3VyIG1pY3JvcGhvbmUgaXMgb2ZmLiBMaXN0ZW5pbmcgc2hvd3MgYXMgTXV0ZWQsIHRoZSBtdXRlIGJ1dHRvbiBpcyBwcmVzc2VkLiAqL1xuICBASW5wdXQoKSBtdXRlZCA9IGZhbHNlO1xuICAvKiogU2hvd3MgXCJZb3UncmUgbXV0ZWRcIiB3aXRoIGFuIFVubXV0ZSBidXR0b24sIGZvciB3aGVuIHNvbWVvbmUgdGFsa3Mgd2hpbGUgbXV0ZWQuICovXG4gIEBJbnB1dCgpIG11dGVkTm90aWNlID0gZmFsc2U7XG4gIC8qKiBXaGF0IHdhcyBzYWlkIGxhc3QgYW5kIHdobyBzYWlkIGl0OyBlYWNoIHdvcmQgZmFkZXMgaW4gYXMgaXQgYXJyaXZlcy4gKi9cbiAgQElucHV0KCkgY2FwdGlvbjogVm9pY2VDYXB0aW9uIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBTaG93biBiZWZvcmUgYW55dGhpbmcgaXMgc2FpZCwgbGlrZSBcIlRhbGsgdG8gdGhlIGFnZW50IGFib3V0IFByaWNpbmcgdjRcIi4gKi9cbiAgQElucHV0KCkgaGludCA9ICcnO1xuICAvKiogU2Vjb25kcyBzaW5jZSB0aGUgY2hhdCBzdGFydGVkLCBzaG93biB0b3AgcmlnaHQuICovXG4gIEBJbnB1dCgpIGVsYXBzZWQgPSAwO1xuICAvKiogVGhlIHF1aWV0IGxpbmUgdW5kZXIgXCJWb2ljZSBjaGF0IGVuZGVkXCIuIERlZmF1bHRzIHRvIHRoZSBsZW5ndGggYW5kIFwiVHJhbnNjcmlwdCBzYXZlZFwiLiAqL1xuICBASW5wdXQoKSBlbmRlZERldGFpbD86IHN0cmluZztcbiAgQElucHV0KCkgbGFiZWxzOiBWb2ljZU9yYkxhYmVscyA9IHt9O1xuICBASW5wdXQoKSBjbGFzc05hbWUgPSAnJztcblxuICBAT3V0cHV0KCkgbXV0ZWRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG4gIEBPdXRwdXQoKSBzdGFydCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQE91dHB1dCgpIGVuZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFN0YXJ0IGFnYWluLCBmcm9tIHRoZSByb3cgdGhhdCBzaG93cyBvbmNlIHRoZSBjaGF0IGhhcyBlbmRlZC4gKi9cbiAgQE91dHB1dCgpIHJlc3RhcnQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgQFZpZXdDaGlsZCgnZ2wnKSBwcml2YXRlIGdsUmVmPzogRWxlbWVudFJlZjxIVE1MQ2FudmFzRWxlbWVudD47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBtb3Rpb24gPSBpbmplY3QoUmVkdWNlZE1vdGlvblNlcnZpY2UpO1xuXG4gIEw6IFJlcXVpcmVkPFZvaWNlT3JiTGFiZWxzPiA9IERFRkFVTFRTO1xuXG4gIC8vIG11dGVkIG9ubHkgY2hhbmdlcyBob3cgbGlzdGVuaW5nIGxvb2tzOiB0aGUgYWdlbnQgY2FuIHN0aWxsIHRoaW5rIGFuZCBzcGVha1xuICBnZXQgbW9kZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLm11dGVkICYmIHRoaXMuc3RhdGUgPT09ICdsaXN0ZW5pbmcnID8gJ211dGVkJyA6IHRoaXMuc3RhdGU7XG4gIH1cbiAgZ2V0IHN0YXR1cygpOiBzdHJpbmcge1xuICAgIGNvbnN0IG1hcDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgIGlkbGU6IHRoaXMuTC5yZWFkeSxcbiAgICAgIGxpc3RlbmluZzogdGhpcy5MLmxpc3RlbmluZyxcbiAgICAgIHRoaW5raW5nOiB0aGlzLkwudGhpbmtpbmcsXG4gICAgICBzcGVha2luZzogdGhpcy5MLnNwZWFraW5nLFxuICAgICAgbXV0ZWQ6IHRoaXMuTC5tdXRlZCxcbiAgICAgIGVuZGVkOiB0aGlzLkwuZW5kZWQsXG4gICAgfTtcbiAgICByZXR1cm4gbWFwW3RoaXMubW9kZV0gPz8gJyc7XG4gIH1cbiAgZ2V0IG9uKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YXRlICE9PSAnaWRsZScgJiYgdGhpcy5zdGF0ZSAhPT0gJ2VuZGVkJztcbiAgfVxuICBnZXQgbm90aWNlT3BlbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5tdXRlZE5vdGljZSAmJiB0aGlzLm11dGVkICYmIHRoaXMub247XG4gIH1cbiAgZ2V0IGx2KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIE1hdGgubWF4KDAsIE1hdGgubWluKDEsIHRoaXMubGV2ZWwpKS50b0ZpeGVkKDMpO1xuICB9XG4gIGdldCBkZWZhdWx0RGV0YWlsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke2ZtdCh0aGlzLmVsYXBzZWQpfSDCtyBUcmFuc2NyaXB0IHNhdmVkYDtcbiAgfVxuXG4gIHJlYWRvbmx5IGZtdCA9IGZtdDtcbiAgd29yZHModGV4dDogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0ZXh0LnNwbGl0KCcgJykuZmlsdGVyKEJvb2xlYW4pO1xuICB9XG5cbiAgZW1pdE11dGVkKG5leHQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLm11dGVkQ2hhbmdlLmVtaXQobmV4dCk7XG4gIH1cblxuICAvLyB0aGUgbGl0IGdsYXNzIHNwaGVyZSwgZHJhd24gb24gYSBjYW52YXMgaW4gdGhlIGNvbG91cnMgb2Ygd2hvZXZlciBpcyB0YWxraW5nLFxuICAvLyBmYXN0ZXIgYW5kIGJyaWdodGVyIGFzIHRoZXkgZ2V0IGxvdWRlci4gV2l0aCByZWR1Y2VkIG1vdGlvbiBpdCBpcyBvbmUgc3RpbGxcbiAgLy8gZnJhbWUsIGRyYXduIGFnYWluIHdoZW4gdGhlIHNwZWFrZXIgY2hhbmdlczsgd2hlcmUgbm8gY2FudmFzIGNhbiBkcmF3IHRoZSBjb3JlXG4gIC8vIGtlZXBzIGl0cyBwbGFpbiBncmFkaWVudCAoc2V0IGJ5IENTUykuXG4gIHByaXZhdGUgc2hhZGVyOiBPcmJTaGFkZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByYWYgPSAwO1xuICBwcml2YXRlIGZsb3cgPSAwO1xuICBwcml2YXRlIGxhc3QgPSAwO1xuICBwcml2YXRlIGNvbHM6IFtzdHJpbmcsIHN0cmluZ10gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjb2xzQXQgPSAtMWU5O1xuICBwcml2YXRlIGlvPzogSW50ZXJzZWN0aW9uT2JzZXJ2ZXI7XG4gIHByaXZhdGUgc2VlbiA9IHRydWU7XG4gIHByaXZhdGUgc3RhcnRlZCA9IGZhbHNlO1xuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snbGFiZWxzJ10pIHRoaXMuTCA9IHsgLi4uREVGQVVMVFMsIC4uLnRoaXMubGFiZWxzIH07XG4gICAgLy8gZHJhdyBvbmNlIG1vcmUgd2hlbiB0aGUgc3BlYWtlciAoZGF0YS1tKSBjaGFuZ2VzIHVuZGVyIHJlZHVjZWQgbW90aW9uXG4gICAgaWYgKHRoaXMuc3RhcnRlZCAmJiB0aGlzLm1vdGlvbi5yZWR1Y2UoKSAmJiAoY2hhbmdlc1snc3RhdGUnXSB8fCBjaGFuZ2VzWydtdXRlZCddKSkge1xuICAgICAgdGhpcy5jb2xzID0gbnVsbDtcbiAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHRoaXMuZHJhdyh0aGlzLmZsb3cpKTtcbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgY29uc3QgY3YgPSB0aGlzLmdsUmVmPy5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghY3YpIHJldHVybjtcbiAgICB0aGlzLnNoYWRlciA9IG9yYlNoYWRlcihjdik7XG4gICAgaWYgKCF0aGlzLnNoYWRlcikgcmV0dXJuO1xuICAgIGN2LmNsYXNzTGlzdC5hZGQoJ3ZvLW9uJyk7XG4gICAgdGhpcy5zdGFydGVkID0gdHJ1ZTtcbiAgICBpZiAoJ0ludGVyc2VjdGlvbk9ic2VydmVyJyBpbiB3aW5kb3cpIHtcbiAgICAgIHRoaXMuaW8gPSBuZXcgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIoKGUpID0+ICh0aGlzLnNlZW4gPSBlWzBdLmlzSW50ZXJzZWN0aW5nKSk7XG4gICAgICB0aGlzLmlvLm9ic2VydmUoY3YpO1xuICAgIH1cbiAgICB0aGlzLmRyYXcoMCk7XG4gICAgaWYgKCF0aGlzLm1vdGlvbi5yZWR1Y2UoKSkge1xuICAgICAgY29uc3QgdGljayA9ICh0OiBudW1iZXIpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5mbG93ICs9IE1hdGgubWluKDUwLCB0IC0gKHRoaXMubGFzdCB8fCB0KSkgKiAoMSArIE1hdGgubWF4KDAsIE1hdGgubWluKDEsIHRoaXMubGV2ZWwpKSAqIDIuNSk7XG4gICAgICAgIHRoaXMubGFzdCA9IHQ7XG4gICAgICAgIGlmICh0aGlzLnNlZW4pIHRoaXMuZHJhdyh0aGlzLmZsb3cpO1xuICAgICAgICB0aGlzLnJhZiA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aWNrKTtcbiAgICAgIH07XG4gICAgICB0aGlzLnJhZiA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aWNrKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRyYXcobXM6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGN2ID0gdGhpcy5nbFJlZj8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIXRoaXMuc2hhZGVyIHx8ICFjdikgcmV0dXJuO1xuICAgIGNvbnN0IG5vdyA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgIGlmICghdGhpcy5jb2xzIHx8IG5vdyAtIHRoaXMuY29sc0F0ID4gMjUwKSB7XG4gICAgICBjb25zdCBib3ggPSBjdi5jbG9zZXN0PEhUTUxFbGVtZW50PignLnZvLXZvcicpO1xuICAgICAgY29uc3QgZG90ID0gYm94Py5xdWVyeVNlbGVjdG9yKCcudm8tdm9yLWRvdCcpO1xuICAgICAgY29uc3QgcGMgPSBib3g/LnF1ZXJ5U2VsZWN0b3IoJy52by12b3ItcGMnKTtcbiAgICAgIGlmIChkb3QgJiYgcGMpIHtcbiAgICAgICAgdGhpcy5jb2xzID0gW2dldENvbXB1dGVkU3R5bGUoZG90KS5iYWNrZ3JvdW5kQ29sb3IsIGdldENvbXB1dGVkU3R5bGUocGMpLmJhY2tncm91bmRDb2xvcl07XG4gICAgICAgIHRoaXMuY29sc0F0ID0gbm93O1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGhpcy5jb2xzKSB0aGlzLnNoYWRlci5wYWludChtcywgTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgdGhpcy5sZXZlbCkpLCB0aGlzLmNvbHNbMF0sIHRoaXMuY29sc1sxXSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLnJhZik7XG4gICAgdGhpcy5pbz8uZGlzY29ubmVjdCgpO1xuICAgIHRoaXMuc2hhZGVyPy5sb3NlKCk7XG4gIH1cbn1cblxuaW50ZXJmYWNlIE9yYlNoYWRlciB7XG4gIHBhaW50KG1zOiBudW1iZXIsIGx2OiBudW1iZXIsIGE6IHN0cmluZywgYjogc3RyaW5nKTogdm9pZDtcbiAgbG9zZSgpOiB2b2lkO1xufVxuXG4vLyB0aGUgZ2xhc3Mgc3BoZXJlLCBhcyBhIGZyYWdtZW50IHNoYWRlciAodGhlIHNpdGUncyBvd24gc291cmNlLCBwb3J0ZWQgZnJvbSB0aGVcbi8vIFZhbmlsbGEvUmVhY3Qgb3JpZ2luYWxzKTogYSBiYWxsIGxpdCBmcm9tIHRoZSB0b3AgbGVmdCwgYSBkZWVwZXIgc2hpZnRlZCBodWUgcGFzdFxuLy8gdGhlIHRlcm1pbmF0b3IsIGxpZ2h0IGdhdGhlcmVkIHRocm91Z2ggdGhlIGdsYXNzIG9uIHRoZSBmYXIgc2lkZSwgYSBmcmVzbmVsIGVkZ2UsXG4vLyBhIGJyb2FkIHNoZWVuIGFuZCBhIHNoYXJwIGhpZ2hsaWdodC4gSW5zaWRlLCBkZWVwIHBvb2xzIG9mIHRoZSB0d28gY29sb3VycyBhbmQgYVxuLy8gdGhpcmQgaHVlIHN3aXJsLCBsaXF1aWQgbGlnaHQgZmxvd3MgdGhyb3VnaCB0aGUgbWlkZGxlIGFuZCB0d28gcmliYm9ucyB0dXJuIG5lYXJcbi8vIHRoZSBzdXJmYWNlLiBUaGUgbGV2ZWwgc3BlZWRzIHRoZSBmbG93LCBicmlnaHRlbnMgdGhlIGhlYXJ0IGFuZCBzaGltbWVycyB0aGVcbi8vIGhpZ2hsaWdodC4gV2hlcmUgV2ViR0wgaXMgbWlzc2luZyB0aGUgc2FtZSBwaWN0dXJlIGlzIGRyYXduIGluIGEgZmV3IGdyYWRpZW50cyBvblxuLy8gYSAyRCBjYW52YXMuIEF0IGl0cyB3aWRlc3QgdGhlIHNwaGVyZSBzdGlsbCBzaXRzIGluc2lkZSB0aGUgY2FudmFzLlxuY29uc3QgRlJBRyA9IGAjaWZkZWYgR0xfRlJBR01FTlRfUFJFQ0lTSU9OX0hJR0hcbnByZWNpc2lvbiBoaWdocCBmbG9hdDtcbiNlbHNlXG5wcmVjaXNpb24gbWVkaXVtcCBmbG9hdDtcbiNlbmRpZlxudW5pZm9ybSB2ZWMyIFI7dW5pZm9ybSBmbG9hdCBULEw7dW5pZm9ybSB2ZWMzIEEwLEIwO1xuZmxvYXQgaCh2ZWMyIHApe3JldHVybiBmcmFjdChzaW4oZG90KHAsdmVjMigxMjcuMSwzMTEuNykpKSo0Mzc1OC41NDUzKTt9XG5mbG9hdCBuKHZlYzIgcCl7dmVjMiBpPWZsb29yKHApLGY9ZnJhY3QocCk7Zj1mKmYqKDMuLTIuKmYpO3JldHVybiBtaXgobWl4KGgoaSksaChpK3ZlYzIoMSwwKSksZi54KSxtaXgoaChpK3ZlYzIoMCwxKSksaChpKzEuKSxmLngpLGYueSk7fVxuZmxvYXQgZmJtKHZlYzIgcCl7ZmxvYXQgdj0wLixhPS41O2ZvcihpbnQgaT0wO2k8NDtpKyspe3YrPWEqbihwKTtwPW1hdDIoMS42LDEuMiwtMS4yLDEuNikqcCt2ZWMyKDEuNyw5LjIpO2EqPS41O31yZXR1cm4gdjt9XG5tYXQyIHJvdChmbG9hdCBhKXtmbG9hdCBjPWNvcyhhKSxzPXNpbihhKTtyZXR1cm4gbWF0MihjLHMsLXMsYyk7fVxudmVjMyB0bih2ZWMzIGMpe2Zsb2F0IG14PW1heChjLnIsbWF4KGMuZyxjLmIpKSxkPW14LW1pbihjLnIsbWluKGMuZyxjLmIpKTtjKj1tYXgoMS4sLjUvbWF4KG14LC4wMSkpO214PW1heChteCwuNSk7ZD1teC1taW4oYy5yLG1pbihjLmcsYy5iKSk7cmV0dXJuIG1heChteC0obXgtYykqbWl4KDEuLGNsYW1wKC41NSpteC9tYXgoZCwuMDAxKSwxLiwzLiksc21vb3Roc3RlcCguMDMsLjEyLGQpKSwwLik7fVxudmVjMyBodWUodmVjMyBjLGZsb2F0IGEpe3ZlYzMgaz12ZWMzKC41NzczNSk7ZmxvYXQgY289Y29zKGEpO3JldHVybiBjKmNvK2Nyb3NzKGssYykqc2luKGEpK2sqZG90KGssYykqKDEuLWNvKTt9XG52b2lkIG1haW4oKXtcbiAgdmVjMyBBPXRuKEEwKSxCPXRuKEIwKSxDPWh1ZShBLG1peCgtLjksMS40LHNtb290aHN0ZXAoLS4xLC4xLEEuYi1BLmcpKSk7XG4gIHZlYzIgdT0oZ2xfRnJhZ0Nvb3JkLnh5KjIuLVIpL1IueTtcbiAgZmxvYXQgdD1UKi4wMDEsYW49YXRhbih1LnksdS54KTtcbiAgZmxvYXQgdz0oLjAwMisuMDA4KkwpKihzaW4oMy4qYW4rdCoxLjkpKy42KnNpbig1Liphbi10KjIuNykrLjQqc2luKDIuKmFuLXQqMS4xKSk7XG4gIGZsb2F0IHJhZD0uOTU1KigxLisuMDA4KnNpbih0Ki45KSt3KTtcbiAgdmVjMiBxPXUvcmFkO2Zsb2F0IHI9bGVuZ3RoKHEpLGU9My4vKFIueSpyYWQpO1xuICBmbG9hdCBhPTEuLXNtb290aHN0ZXAoMS4tZSwxLixyKTtcbiAgaWYoYTw9MC4pe2dsX0ZyYWdDb2xvcj12ZWM0KDAuKTtyZXR1cm47fVxuICBmbG9hdCB6PXNxcnQobWF4KDEuLXIqciwwLikpO1xuICB2ZWMzIE49dmVjMyhxLHopO1xuICBOLnh5Kz0odmVjMihuKHEqNS4rdCoxLjYpLG4ocSo1Li10KjEuMys3LikpLS41KSooLjAzKy4xMipMKTtOPW5vcm1hbGl6ZShOKTtcbiAgdmVjMyBTPXZlYzMocSx6KSxEPXJlZnJhY3QodmVjMygwLDAsLTEpLE4sLjcyKSxQMT1TK0QqeiouMzUsUDI9UytEKnoqLjksUDM9UytEKnoqMS41O1xuICBmbG9hdCBzPXQqLjIyO1xuICB2ZWMzIGQxPVAzLXZlYzMoLjU1KnNpbihzKjEuMyksLjUqY29zKHMqMS4xKSwuMypzaW4ocyouNykpLGQyPVAzLXZlYzMoLjU1KmNvcyhzKi45KzIuKSwuNSpzaW4ocyoxLjIrMS4pLC4zKmNvcyhzKi44KzMuKSksZDM9UDMtdmVjMyguNSpzaW4ocyoxLjYrNC4pLC41KmNvcyhzKjEuNCs1LiksLjMqc2luKHMrMS4pKTtcbiAgZmxvYXQgZzE9ZXhwKC1kb3QoZDEsZDEpKjIuNiksZzI9ZXhwKC1kb3QoZDIsZDIpKjIuNiksZzM9ZXhwKC1kb3QoZDMsZDMpKjMuMik7XG4gIHZlYzMgY29sPW1peChtaXgobWl4KG1peChBLEIsLjQpKi41NSxCLGcyKi44KSxDLGczKi43KSxBLGcxKi45NSk7XG4gIHZlYzIgbT1yb3QodCouMDkpKlAyLnh5KjEuNSxvPXZlYzIoZmJtKG0rdmVjMigwLix0Ki4zKSksZmJtKG0rdmVjMig1LjIsMS4zKS10Ki4yNSkpO1xuICBmbG9hdCBmPWZibShtKyhvLS41KSooMi41KzIuKkwpK3ZlYzIodCouMTIsLXQqLjA4KSk7XG4gIGNvbD1taXgoY29sLG1peChtaXgoQSxCLC41KSx2ZWMzKDEuKSwuMTUpLHNtb290aHN0ZXAoLjQ1LC44LGYpKi41KSooLjgrLjM1KnNtb290aHN0ZXAoLjIsLjYsZikpO1xuICB2ZWMyIGs9cm90KC10Ki4zMykqUDEueHk7XG4gIGZsb2F0IGIxPWsueSsuMzIqc2luKGsueCoyLjQrdCoxLjQpKy4xMipzaW4oay54KjUuMy10KjIuMikrKG8ueC0uNSkqLjUsYjI9ay54LS4zKnNpbihrLnkqMi4xLXQqMS4xKSsuNDtcbiAgY29sKz1taXgobWl4KEEsQywuMzUpLHZlYzMoMS4pLC4zNSkqKGV4cCgtYjEqYjEqNDAuKSsuNipleHAoLWIyKmIyKjU1LikpKiguMjUrLjM1KkwpKno7XG4gIGNvbCs9bWl4KEEsdmVjMygxLiksLjQpKmV4cCgtZG90KFAyLnh5LFAyLnh5KSozLikqKC4wOCsuMypMKTtcbiAgdmVjMyBsaz1ub3JtYWxpemUodmVjMygtLjUsLjYyLC42KSksZGs9aHVlKGNvbCwuMzUpO1xuICBjb2w9bWl4KGRrKmRrKi42LGNvbCoxLjA2LHNtb290aHN0ZXAoLS41NSwuNzUsZG90KE4sbGspKSk7XG4gIGNvbCs9bWl4KEIsdmVjMygxLiksLjUpKnBvdygxLi16LDEuNikqc21vb3Roc3RlcCguMSwuOTUsZG90KHEvbWF4KHIsMWUtMyksLW5vcm1hbGl6ZShsay54eSkpKSouNTU7XG4gIGNvbD1taXgoY29sLG1peCh2ZWMzKC4wNiksdmVjMygxLiksc21vb3Roc3RlcCgtLjMsLjksTi55Ki43LU4ueCouNCkpLHBvdygxLi1OLnosMy4pKi41KTtcbiAgZmxvYXQgbmg9bWF4KGRvdChOLG5vcm1hbGl6ZShsayt2ZWMzKDAsMCwxKSkpLDAuKTtcbiAgY29sKz1wb3cobmgsNzAwLikqKDEuMisuOCpMKnNpbih0KjkuK3EueCo4LikpK3BvdyhuaCw2MC4pKi4yNStwb3cobmgsOC4pKi4xO1xuICBnbF9GcmFnQ29sb3I9dmVjNChjbGFtcChjb2wsMC4sMS4pKmEsYSk7XG59YDtcblxuLyoqIERyYXdzIHRoZSBzcGhlcmUgb24gdGhlIG9yYidzIGNhbnZhczogb25lIGRyYXcgYSBmcmFtZSwgYXQgbW9zdCAyIGRldmljZSBwaXhlbHMgYVxuICAgIENTUyBwaXhlbCwgbm90aGluZyBtYWRlIGFuZXcgZWFjaCBmcmFtZS4gV2hlcmUgV2ViR0wgaXMgbWlzc2luZyBpdCBmYWxscyBiYWNrIHRvIGFcbiAgICBmZXcgZ3JhZGllbnRzIG9uIGEgMkQgY2FudmFzLiBSZXR1cm5zIHsgcGFpbnQsIGxvc2UgfSwgb3IgbnVsbCB3aGVuIG5laXRoZXIgY2FuIGRyYXcuICovXG5mdW5jdGlvbiBvcmJTaGFkZXIoY3Y6IEhUTUxDYW52YXNFbGVtZW50KTogT3JiU2hhZGVyIHwgbnVsbCB7XG4gIC8vIGEgY29tcHV0ZWQgY29sb3VyIHRvIDAuLjEgY2hhbm5lbHM7IG1pZC10cmFuc2l0aW9uIGl0IGNhbiBjb21lIGFzIG9rbGFiKCkgb3JcbiAgLy8gY29sb3IoKSwgc28gYSAxcHggY2FudmFzIHJlYWRzIGl0LiBPbmx5IGEgY29sb3VyIHRoYXQgY2hhbmdlZCBpcyByZWFkLlxuICBjb25zdCBweCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpLmdldENvbnRleHQoJzJkJywgeyB3aWxsUmVhZEZyZXF1ZW50bHk6IHRydWUgfSk7XG4gIGlmICghcHgpIHJldHVybiBudWxsO1xuICBweC5jYW52YXMud2lkdGggPSBweC5jYW52YXMuaGVpZ2h0ID0gMTtcbiAgY29uc3QgcmdiID0gKHM6IHN0cmluZywgbzogRmxvYXQzMkFycmF5KTogdm9pZCA9PiB7XG4gICAgcHguY2xlYXJSZWN0KDAsIDAsIDEsIDEpO1xuICAgIHB4LmZpbGxTdHlsZSA9ICcjMDAwJztcbiAgICBweC5maWxsU3R5bGUgPSBzO1xuICAgIHB4LmZpbGxSZWN0KDAsIDAsIDEsIDEpO1xuICAgIGNvbnN0IGQgPSBweC5nZXRJbWFnZURhdGEoMCwgMCwgMSwgMSkuZGF0YTtcbiAgICBvWzBdID0gZFswXSAvIDI1NTtcbiAgICBvWzFdID0gZFsxXSAvIDI1NTtcbiAgICBvWzJdID0gZFsyXSAvIDI1NTtcbiAgfTtcbiAgY29uc3QgdGEgPSBuZXcgRmxvYXQzMkFycmF5KDMpLCB0YiA9IG5ldyBGbG9hdDMyQXJyYXkoMyksIGNhID0gbmV3IEZsb2F0MzJBcnJheSgzKSwgY2IgPSBuZXcgRmxvYXQzMkFycmF5KDMpO1xuICBsZXQgc2EgPSAnJywgc2IgPSAnJywgdyA9IDAsIGF0ID0gLTFlOSwgcHJldiA9IC0xZTk7XG4gIGNvbnN0IGZpdCA9IChub3c6IG51bWJlcik6IGJvb2xlYW4gPT4ge1xuICAgIGlmICh3ICYmIG5vdyAtIGF0IDwgMzAwKSByZXR1cm4gZmFsc2U7XG4gICAgYXQgPSBub3c7XG4gICAgY29uc3QgbiA9IE1hdGgucm91bmQoY3YuY2xpZW50V2lkdGggKiBNYXRoLm1pbigyLCBkZXZpY2VQaXhlbFJhdGlvIHx8IDEpKSB8fCAxO1xuICAgIGlmIChuID09PSB3KSByZXR1cm4gZmFsc2U7XG4gICAgdyA9IGN2LndpZHRoID0gY3YuaGVpZ2h0ID0gbjtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcbiAgY29uc3QgdGludCA9IChhOiBzdHJpbmcsIGI6IHN0cmluZywgbm93OiBudW1iZXIsIHNuYXA6IGJvb2xlYW4pOiB2b2lkID0+IHtcbiAgICBpZiAoYSAhPT0gc2EpIHsgc2EgPSBhOyByZ2IoYSwgdGEpOyB9XG4gICAgaWYgKGIgIT09IHNiKSB7IHNiID0gYjsgcmdiKGIsIHRiKTsgfVxuICAgIGNvbnN0IGsgPSBzbmFwIHx8IG5vdyAtIHByZXYgPiAyMDAgPyAxIDogTWF0aC5taW4oMSwgKG5vdyAtIHByZXYpIC8gMTEwKTtcbiAgICBwcmV2ID0gbm93O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMzsgaSsrKSB7IGNhW2ldICs9ICh0YVtpXSAtIGNhW2ldKSAqIGs7IGNiW2ldICs9ICh0YltpXSAtIGNiW2ldKSAqIGs7IH1cbiAgfTtcbiAgY29uc3QgZ2wgPSBjdi5nZXRDb250ZXh0KCd3ZWJnbCcsIHsgcHJlbXVsdGlwbGllZEFscGhhOiB0cnVlLCBhbnRpYWxpYXM6IGZhbHNlLCBwb3dlclByZWZlcmVuY2U6ICdsb3ctcG93ZXInIH0pO1xuICBpZiAoZ2wpIHtcbiAgICBjb25zdCBzaCA9ICh0eXBlOiBudW1iZXIsIHNyYzogc3RyaW5nKTogV2ViR0xTaGFkZXIgPT4ge1xuICAgICAgY29uc3QgcyA9IGdsLmNyZWF0ZVNoYWRlcih0eXBlKSE7XG4gICAgICBnbC5zaGFkZXJTb3VyY2Uocywgc3JjKTtcbiAgICAgIGdsLmNvbXBpbGVTaGFkZXIocyk7XG4gICAgICByZXR1cm4gcztcbiAgICB9O1xuICAgIGNvbnN0IHByID0gZ2wuY3JlYXRlUHJvZ3JhbSgpITtcbiAgICBnbC5hdHRhY2hTaGFkZXIocHIsIHNoKGdsLlZFUlRFWF9TSEFERVIsICdhdHRyaWJ1dGUgdmVjMiBwO3ZvaWQgbWFpbigpe2dsX1Bvc2l0aW9uPXZlYzQocCwwLiwxLik7fScpKTtcbiAgICBnbC5hdHRhY2hTaGFkZXIocHIsIHNoKGdsLkZSQUdNRU5UX1NIQURFUiwgRlJBRykpO1xuICAgIGdsLmxpbmtQcm9ncmFtKHByKTtcbiAgICBjb25zdCBsb3NlID0gKCk6IHZvaWQgPT4geyBnbC5nZXRFeHRlbnNpb24oJ1dFQkdMX2xvc2VfY29udGV4dCcpPy5sb3NlQ29udGV4dCgpOyB9O1xuICAgIGlmICghZ2wuZ2V0UHJvZ3JhbVBhcmFtZXRlcihwciwgZ2wuTElOS19TVEFUVVMpKSB7IGxvc2UoKTsgcmV0dXJuIG51bGw7IH1cbiAgICBnbC51c2VQcm9ncmFtKHByKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgZ2wuY3JlYXRlQnVmZmVyKCkpO1xuICAgIGdsLmJ1ZmZlckRhdGEoZ2wuQVJSQVlfQlVGRkVSLCBuZXcgRmxvYXQzMkFycmF5KFstMSwgLTEsIDEsIC0xLCAtMSwgMSwgMSwgMV0pLCBnbC5TVEFUSUNfRFJBVyk7XG4gICAgY29uc3QgcCA9IGdsLmdldEF0dHJpYkxvY2F0aW9uKHByLCAncCcpO1xuICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHApO1xuICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIocCwgMiwgZ2wuRkxPQVQsIGZhbHNlLCAwLCAwKTtcbiAgICBjb25zdCBVID0gKGs6IHN0cmluZyk6IFdlYkdMVW5pZm9ybUxvY2F0aW9uIHwgbnVsbCA9PiBnbC5nZXRVbmlmb3JtTG9jYXRpb24ocHIsIGspO1xuICAgIGNvbnN0IHVSID0gVSgnUicpLCB1VCA9IFUoJ1QnKSwgdUwgPSBVKCdMJyksIHVBID0gVSgnQTAnKSwgdUIgPSBVKCdCMCcpO1xuICAgIHJldHVybiB7XG4gICAgICBwYWludChtczogbnVtYmVyLCBsdjogbnVtYmVyLCBhOiBzdHJpbmcsIGI6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zdCBub3cgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICAgICAgaWYgKGZpdChub3cpKSBnbC52aWV3cG9ydCgwLCAwLCB3LCB3KTtcbiAgICAgICAgdGludChhLCBiLCBub3csIGZhbHNlKTtcbiAgICAgICAgZ2wudW5pZm9ybTJmKHVSLCB3LCB3KTtcbiAgICAgICAgZ2wudW5pZm9ybTFmKHVULCBtcyk7XG4gICAgICAgIGdsLnVuaWZvcm0xZih1TCwgbHYpO1xuICAgICAgICBnbC51bmlmb3JtM2Z2KHVBLCBjYSk7XG4gICAgICAgIGdsLnVuaWZvcm0zZnYodUIsIGNiKTtcbiAgICAgICAgZ2wuZHJhd0FycmF5cyhnbC5UUklBTkdMRV9TVFJJUCwgMCwgNCk7XG4gICAgICB9LFxuICAgICAgbG9zZSxcbiAgICB9O1xuICB9XG4gIGNvbnN0IHggPSBjdi5nZXRDb250ZXh0KCcyZCcpO1xuICBpZiAoIXgpIHJldHVybiBudWxsO1xuICAvLyB0aGUgc2hhZGVyJ3MgY29sb3VyczogZGFyayBvbmVzIGxpZnRlZCwgcGFsZSBvbmVzIGdpdmVuIG1vcmUgY2hyb21hLCBhIHRoaXJkIGh1ZVxuICAvLyB0dXJuZWQgcm91bmQgdGhlIGdyZXkgYXhpcyB0b3dhcmQgdGhlIHdhcm0gc2lkZVxuICBjb25zdCB0biA9IChvOiBGbG9hdDMyQXJyYXksIGQ6IEZsb2F0MzJBcnJheSk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGxpZnQgPSBNYXRoLm1heCgxLCAwLjUgLyBNYXRoLm1heCgwLjAxLCBvWzBdLCBvWzFdLCBvWzJdKSk7XG4gICAgY29uc3QgbXggPSBNYXRoLm1heChvWzBdLCBvWzFdLCBvWzJdKSAqIGxpZnQ7XG4gICAgY29uc3QgZGQgPSBteCAtIE1hdGgubWluKG9bMF0sIG9bMV0sIG9bMl0pICogbGlmdDtcbiAgICBjb25zdCBzID0gTWF0aC5taW4oMSwgTWF0aC5tYXgoMCwgKGRkIC0gMC4wMykgLyAwLjA5KSk7XG4gICAgY29uc3QgayA9IDEgKyAoTWF0aC5taW4oMywgTWF0aC5tYXgoMSwgMC41NSAqIG14IC8gTWF0aC5tYXgoZGQsIDAuMDAxKSkpIC0gMSkgKiBzICogcyAqICgzIC0gMiAqIHMpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMzsgaSsrKSBkW2ldID0gTWF0aC5tYXgoMCwgbXggLSAobXggLSBvW2ldICogbGlmdCkgKiBrKTtcbiAgfTtcbiAgY29uc3QgaHVlID0gKG86IEZsb2F0MzJBcnJheSwgZDogRmxvYXQzMkFycmF5LCBhbmc6IG51bWJlcik6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGNvID0gTWF0aC5jb3MoYW5nKSwgc2kgPSBNYXRoLnNpbihhbmcpICogMC41NzczNSwgbSA9ICgob1swXSArIG9bMV0gKyBvWzJdKSAvIDMpICogKDEgLSBjbyk7XG4gICAgZFswXSA9IG9bMF0gKiBjbyArIChvWzJdIC0gb1sxXSkgKiBzaSArIG07XG4gICAgZFsxXSA9IG9bMV0gKiBjbyArIChvWzBdIC0gb1syXSkgKiBzaSArIG07XG4gICAgZFsyXSA9IG9bMl0gKiBjbyArIChvWzFdIC0gb1swXSkgKiBzaSArIG07XG4gIH07XG4gIGNvbnN0IEEgPSBuZXcgRmxvYXQzMkFycmF5KDMpLCBCID0gbmV3IEZsb2F0MzJBcnJheSgzKSwgQyA9IG5ldyBGbG9hdDMyQXJyYXkoMyksIE0gPSBuZXcgRmxvYXQzMkFycmF5KDMpO1xuICBjb25zdCBjc3NDb2wgPSAobzogRmxvYXQzMkFycmF5LCBhbDogbnVtYmVyLCBmID0gMSk6IHN0cmluZyA9PlxuICAgIGByZ2JhKCR7WzAsIDEsIDJdLm1hcCgoaSkgPT4gTWF0aC5yb3VuZChNYXRoLm1pbigxLCBNYXRoLm1heCgwLCBvW2ldICogZikpICogMjU1KSkuam9pbignLCcpfSwke2FsfSlgO1xuICBjb25zdCBncmFkID0gKGN4OiBudW1iZXIsIGN5OiBudW1iZXIsIHI6IG51bWJlciwgc3RvcHM6IChudW1iZXIgfCBzdHJpbmcpW10pOiBDYW52YXNHcmFkaWVudCA9PiB7XG4gICAgY29uc3QgZyA9IHguY3JlYXRlUmFkaWFsR3JhZGllbnQoY3gsIGN5LCAwLCBjeCwgY3ksIHIpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RvcHMubGVuZ3RoOyBpICs9IDIpIGcuYWRkQ29sb3JTdG9wKHN0b3BzW2ldIGFzIG51bWJlciwgc3RvcHNbaSArIDFdIGFzIHN0cmluZyk7XG4gICAgcmV0dXJuIGc7XG4gIH07XG4gIGNvbnN0IHNoYWRlID0gZ3JhZCgtMC4zNSwgLTAuNCwgMS42LCBbMCwgJ3JnYmEoMjU1LDI1NSwyNTUsLjE2KScsIDAuNDUsICdyZ2JhKDAsMCwwLDApJywgMSwgJ3JnYmEoMCwwLDAsLjUpJ10pO1xuICBjb25zdCByaW0gPSBncmFkKDAsIDAsIDEsIFswLjc4LCAncmdiYSgyNTUsMjU1LDI1NSwwKScsIDEsICdyZ2JhKDI1NSwyNTUsMjU1LC4yOCknXSk7XG4gIGNvbnN0IHNoZWVuID0gZ3JhZCgtMC4zMiwgLTAuMzgsIDAuNiwgWzAsICdyZ2JhKDI1NSwyNTUsMjU1LC4yMiknLCAxLCAncmdiYSgyNTUsMjU1LDI1NSwwKSddKTtcbiAgY29uc3Qgc3BlYyA9IGdyYWQoLTAuNCwgLTAuNDYsIDAuMTQsIFswLCAncmdiYSgyNTUsMjU1LDI1NSwuOTUpJywgMSwgJ3JnYmEoMjU1LDI1NSwyNTUsMCknXSk7XG4gIGxldCBnOiB7IGJhc2U6IHN0cmluZzsgYTogQ2FudmFzR3JhZGllbnQ7IGI6IENhbnZhc0dyYWRpZW50OyBjOiBDYW52YXNHcmFkaWVudDsgY29yZTogQ2FudmFzR3JhZGllbnQgfSB8IG51bGwgPSBudWxsO1xuICBsZXQgbWlkID0gMCwgcmFkID0gMDtcbiAgY29uc3QgcHV0ID0gKGZpbGw6IHN0cmluZyB8IENhbnZhc0dyYWRpZW50LCBkeDogbnVtYmVyLCBkeTogbnVtYmVyLCBzejogbnVtYmVyKTogdm9pZCA9PiB7XG4gICAgeC5zZXRUcmFuc2Zvcm0ocmFkICogc3osIDAsIDAsIHJhZCAqIHN6LCBtaWQgKyByYWQgKiBkeCwgbWlkICsgcmFkICogZHkpO1xuICAgIHguZmlsbFN0eWxlID0gZmlsbDtcbiAgICB4LmZpbGxSZWN0KC0xLCAtMSwgMiwgMik7XG4gIH07XG4gIHJldHVybiB7XG4gICAgcGFpbnQobXM6IG51bWJlciwgbHY6IG51bWJlciwgYTogc3RyaW5nLCBiOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgIGNvbnN0IG5vdyA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgZml0KG5vdyk7XG4gICAgICBpZiAoIWcgfHwgYSAhPT0gc2EgfHwgYiAhPT0gc2IpIHtcbiAgICAgICAgdGludChhLCBiLCBub3csIHRydWUpO1xuICAgICAgICB0bihjYSwgQSk7XG4gICAgICAgIHRuKGNiLCBCKTtcbiAgICAgICAgaHVlKEEsIEMsIEFbMl0gPiBBWzFdID8gMS40IDogLTAuOSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMzsgaSsrKSBNW2ldID0gKEFbaV0gKyBCW2ldKSAvIDI7XG4gICAgICAgIGcgPSB7XG4gICAgICAgICAgYmFzZTogY3NzQ29sKE0sIDEsIDAuNyksXG4gICAgICAgICAgYTogZ3JhZCgwLCAwLCAxLCBbMCwgY3NzQ29sKEEsIDAuOTUpLCAxLCBjc3NDb2woQSwgMCldKSxcbiAgICAgICAgICBiOiBncmFkKDAsIDAsIDEsIFswLCBjc3NDb2woQiwgMC45NSksIDEsIGNzc0NvbChCLCAwKV0pLFxuICAgICAgICAgIGM6IGdyYWQoMCwgMCwgMSwgWzAsIGNzc0NvbChDLCAwLjU1KSwgMSwgY3NzQ29sKEMsIDApXSksXG4gICAgICAgICAgY29yZTogZ3JhZCgwLCAwLCAxLCBbMCwgY3NzQ29sKEEsIDEsIDEuNCksIDEsIGNzc0NvbChBLCAwKV0pLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgY29uc3QgdCA9IG1zICogMC4wMDEsIHMgPSB0ICogMC4yMjtcbiAgICAgIG1pZCA9IHcgLyAyO1xuICAgICAgcmFkID0gbWlkICogMC45NTUgKiAoMSArIDAuMDA4ICogTWF0aC5zaW4odCAqIDAuOSkpO1xuICAgICAgeC5zZXRUcmFuc2Zvcm0oMSwgMCwgMCwgMSwgMCwgMCk7XG4gICAgICB4LmNsZWFyUmVjdCgwLCAwLCB3LCB3KTtcbiAgICAgIHguc2F2ZSgpO1xuICAgICAgeC5iZWdpblBhdGgoKTtcbiAgICAgIHguYXJjKG1pZCwgbWlkLCByYWQsIDAsIE1hdGguUEkgKiAyKTtcbiAgICAgIHguY2xpcCgpO1xuICAgICAgeC5maWxsU3R5bGUgPSBnLmJhc2U7XG4gICAgICB4LmZpbGxSZWN0KDAsIDAsIHcsIHcpO1xuICAgICAgcHV0KGcuYSwgMC41NSAqIE1hdGguc2luKHMgKiAxLjMpLCAtMC41ICogTWF0aC5jb3MocyAqIDEuMSksIDEuMSk7XG4gICAgICBwdXQoZy5iLCAwLjU1ICogTWF0aC5jb3MocyAqIDAuOSArIDIpLCAtMC41ICogTWF0aC5zaW4ocyAqIDEuMiArIDEpLCAxLjEpO1xuICAgICAgcHV0KGcuYywgMC41ICogTWF0aC5zaW4ocyAqIDEuNiArIDQpLCAtMC41ICogTWF0aC5jb3MocyAqIDEuNCArIDUpLCAwLjkpO1xuICAgICAgeC5nbG9iYWxBbHBoYSA9IDAuMTUgKyAwLjQ1ICogbHY7XG4gICAgICBwdXQoZy5jb3JlLCAwLCAwLCAwLjcpO1xuICAgICAgeC5nbG9iYWxBbHBoYSA9IDE7XG4gICAgICBwdXQoc2hhZGUsIDAsIDAsIDEpO1xuICAgICAgcHV0KHJpbSwgMCwgMCwgMSk7XG4gICAgICBwdXQoc2hlZW4sIDAsIDAsIDEpO1xuICAgICAgeC5nbG9iYWxBbHBoYSA9IDAuODUgKyAwLjE1ICogbHYgKiBNYXRoLnNpbih0ICogOSk7XG4gICAgICBwdXQoc3BlYywgMCwgMCwgMSk7XG4gICAgICB4LnJlc3RvcmUoKTtcbiAgICB9LFxuICAgIGxvc2UoKTogdm9pZCB7fSxcbiAgfTtcbn1cbiJdfQ==