@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.
- package/LICENSE +24 -0
- package/README.md +56 -2
- package/account-table/account-table.component.d.ts +72 -0
- package/action-log/action-log.component.d.ts +41 -0
- package/activity-heatmap/activity-heatmap.component.d.ts +67 -0
- package/agent-inbox/agent-inbox.component.d.ts +75 -0
- package/agent-lanes/agent-lanes.component.d.ts +152 -0
- package/agent-phases/agent-phases.component.d.ts +62 -0
- package/agent-run-timeline/agent-run-timeline.component.d.ts +113 -0
- package/agent-tree/agent-tree.component.d.ts +80 -0
- package/answer-action-bar/answer-action-bar.component.d.ts +110 -0
- package/artifact-card/artifact-card.component.d.ts +145 -0
- package/attachment-tray/attachment-tray.component.d.ts +84 -0
- package/badge/badge.component.d.ts +25 -0
- package/bar-chart/bar-chart.component.d.ts +87 -0
- package/browser-session/browser-session.component.d.ts +70 -0
- package/buttons/buttons.component.d.ts +63 -0
- package/card/card.component.d.ts +21 -0
- package/change-review/change-review.component.d.ts +97 -0
- package/citation-hover-card/citation-hover-card.component.d.ts +95 -0
- package/code-viewer/code-viewer.component.d.ts +86 -0
- package/composer/composer.component.d.ts +114 -0
- package/context-meter/context-meter.component.d.ts +60 -0
- package/core/icon.component.d.ts +10 -0
- package/core/reduced-motion.service.d.ts +15 -0
- package/decision-prompt/decision-prompt.component.d.ts +56 -0
- package/design-review/design-review.component.d.ts +108 -0
- package/design-tuner/design-tuner.component.d.ts +75 -0
- package/details-panel/details-panel.component.d.ts +150 -0
- package/donut-chart/donut-chart.component.d.ts +63 -0
- package/draft-review/draft-review.component.d.ts +128 -0
- package/error-recovery/error-recovery.component.d.ts +59 -0
- package/esm2022/account-table/account-table.component.mjs +399 -0
- package/esm2022/action-log/action-log.component.mjs +177 -0
- package/esm2022/activity-heatmap/activity-heatmap.component.mjs +285 -0
- package/esm2022/agent-inbox/agent-inbox.component.mjs +284 -0
- package/esm2022/agent-lanes/agent-lanes.component.mjs +600 -0
- package/esm2022/agent-phases/agent-phases.component.mjs +300 -0
- package/esm2022/agent-run-timeline/agent-run-timeline.component.mjs +412 -0
- package/esm2022/agent-tree/agent-tree.component.mjs +393 -0
- package/esm2022/answer-action-bar/answer-action-bar.component.mjs +636 -0
- package/esm2022/artifact-card/artifact-card.component.mjs +916 -0
- package/esm2022/attachment-tray/attachment-tray.component.mjs +402 -0
- package/esm2022/badge/badge.component.mjs +97 -0
- package/esm2022/bar-chart/bar-chart.component.mjs +300 -0
- package/esm2022/browser-session/browser-session.component.mjs +352 -0
- package/esm2022/buttons/buttons.component.mjs +215 -0
- package/esm2022/card/card.component.mjs +107 -0
- package/esm2022/change-review/change-review.component.mjs +398 -0
- package/esm2022/citation-hover-card/citation-hover-card.component.mjs +360 -0
- package/esm2022/code-viewer/code-viewer.component.mjs +291 -0
- package/esm2022/composer/composer.component.mjs +743 -0
- package/esm2022/context-meter/context-meter.component.mjs +275 -0
- package/esm2022/core/icon.component.mjs +111 -0
- package/esm2022/core/reduced-motion.service.mjs +34 -0
- package/esm2022/decision-prompt/decision-prompt.component.mjs +259 -0
- package/esm2022/design-review/design-review.component.mjs +428 -0
- package/esm2022/design-tuner/design-tuner.component.mjs +341 -0
- package/esm2022/details-panel/details-panel.component.mjs +537 -0
- package/esm2022/donut-chart/donut-chart.component.mjs +240 -0
- package/esm2022/draft-review/draft-review.component.mjs +549 -0
- package/esm2022/error-recovery/error-recovery.component.mjs +231 -0
- package/esm2022/eval-results/eval-results.component.mjs +368 -0
- package/esm2022/feedback-sheet/feedback-sheet.component.mjs +411 -0
- package/esm2022/field-extraction/field-extraction.component.mjs +368 -0
- package/esm2022/funnel-chart/funnel-chart.component.mjs +258 -0
- package/esm2022/grid/grid.component.mjs +66 -0
- package/esm2022/health-score/health-score.component.mjs +420 -0
- package/esm2022/human-handoff/human-handoff.component.mjs +676 -0
- package/esm2022/image-generation/image-generation.component.mjs +1028 -0
- package/esm2022/inline-text-diff/inline-text-diff.component.mjs +390 -0
- package/esm2022/launch-checklist/launch-checklist.component.mjs +229 -0
- package/esm2022/line-chart/line-chart.component.mjs +417 -0
- package/esm2022/live-answer/live-answer.component.mjs +411 -0
- package/esm2022/metric-insight/metric-insight.component.mjs +511 -0
- package/esm2022/modal/modal.component.mjs +202 -0
- package/esm2022/model-picker/model-picker.component.mjs +491 -0
- package/esm2022/permission-gate/permission-gate.component.mjs +498 -0
- package/esm2022/plan-review/plan-review.component.mjs +432 -0
- package/esm2022/progress/progress.component.mjs +503 -0
- package/esm2022/prompt-library/prompt-library.component.mjs +453 -0
- package/esm2022/prompt-starters/prompt-starters.component.mjs +272 -0
- package/esm2022/proposal-card/proposal-card.component.mjs +402 -0
- package/esm2022/public-api.mjs +88 -0
- package/esm2022/radar-chart/radar-chart.component.mjs +500 -0
- package/esm2022/radial-goals/radial-goals.component.mjs +418 -0
- package/esm2022/reasoning-trail/reasoning-trail.component.mjs +284 -0
- package/esm2022/response-versions/response-versions.component.mjs +288 -0
- package/esm2022/rewrite-toolbar/rewrite-toolbar.component.mjs +397 -0
- package/esm2022/rich-text-editor/rich-text-editor.component.mjs +1755 -0
- package/esm2022/run-cost/run-cost.component.mjs +215 -0
- package/esm2022/run-queue/run-queue.component.mjs +481 -0
- package/esm2022/run-summary/run-summary.component.mjs +331 -0
- package/esm2022/scatter-chart/scatter-chart.component.mjs +705 -0
- package/esm2022/score-breakdown/score-breakdown.component.mjs +460 -0
- package/esm2022/segmented-control/segmented-control.component.mjs +180 -0
- package/esm2022/source-stack/source-stack.component.mjs +245 -0
- package/esm2022/stat-cards/stat-cards.component.mjs +258 -0
- package/esm2022/status-pill/status-pill.component.mjs +305 -0
- package/esm2022/steering/steering.component.mjs +343 -0
- package/esm2022/step-loader/step-loader.component.mjs +209 -0
- package/esm2022/task-table/task-table.component.mjs +534 -0
- package/esm2022/terminal-stream/terminal-stream.component.mjs +583 -0
- package/esm2022/thinking/thinking.component.mjs +276 -0
- package/esm2022/thinking-states/thinking-states.component.mjs +333 -0
- package/esm2022/thread-panel/thread-panel.component.mjs +271 -0
- package/esm2022/toast/toast.component.mjs +195 -0
- package/esm2022/toast-stack/toast-stack.component.mjs +301 -0
- package/esm2022/tool-call/tool-call.component.mjs +273 -0
- package/esm2022/tooltip/tooltip.component.mjs +417 -0
- package/esm2022/top-pages/top-pages.component.mjs +240 -0
- package/esm2022/trace-view/trace-view.component.mjs +440 -0
- package/esm2022/visuno-angular.mjs +5 -0
- package/esm2022/voice-capture/voice-capture.component.mjs +650 -0
- package/esm2022/voice-orb/voice-orb.component.mjs +538 -0
- package/esm2022/web-search/web-search.component.mjs +374 -0
- package/eval-results/eval-results.component.d.ts +67 -0
- package/feedback-sheet/feedback-sheet.component.d.ts +74 -0
- package/fesm2022/visuno-angular.mjs +31992 -0
- package/fesm2022/visuno-angular.mjs.map +1 -0
- package/field-extraction/field-extraction.component.d.ts +82 -0
- package/funnel-chart/funnel-chart.component.d.ts +70 -0
- package/grid/grid.component.d.ts +22 -0
- package/health-score/health-score.component.d.ts +87 -0
- package/human-handoff/human-handoff.component.d.ts +125 -0
- package/image-generation/image-generation.component.d.ts +253 -0
- package/index.d.ts +5 -0
- package/inline-text-diff/inline-text-diff.component.d.ts +76 -0
- package/launch-checklist/launch-checklist.component.d.ts +46 -0
- package/line-chart/line-chart.component.d.ts +89 -0
- package/live-answer/live-answer.component.d.ts +110 -0
- package/metric-insight/metric-insight.component.d.ts +110 -0
- package/modal/modal.component.d.ts +37 -0
- package/model-picker/model-picker.component.d.ts +97 -0
- package/package.json +51 -4
- package/permission-gate/permission-gate.component.d.ts +100 -0
- package/plan-review/plan-review.component.d.ts +86 -0
- package/progress/progress.component.d.ts +91 -0
- package/prompt-library/prompt-library.component.d.ts +121 -0
- package/prompt-starters/prompt-starters.component.d.ts +65 -0
- package/proposal-card/proposal-card.component.d.ts +101 -0
- package/public-api.d.ts +82 -0
- package/radar-chart/radar-chart.component.d.ts +110 -0
- package/radial-goals/radial-goals.component.d.ts +90 -0
- package/reasoning-trail/reasoning-trail.component.d.ts +73 -0
- package/response-versions/response-versions.component.d.ts +54 -0
- package/rewrite-toolbar/rewrite-toolbar.component.d.ts +92 -0
- package/rich-text-editor/rich-text-editor.component.d.ts +180 -0
- package/run-cost/run-cost.component.d.ts +43 -0
- package/run-queue/run-queue.component.d.ts +93 -0
- package/run-summary/run-summary.component.d.ts +81 -0
- package/scatter-chart/scatter-chart.component.d.ts +139 -0
- package/score-breakdown/score-breakdown.component.d.ts +107 -0
- package/segmented-control/segmented-control.component.d.ts +44 -0
- package/source-stack/source-stack.component.d.ts +60 -0
- package/stat-cards/stat-cards.component.d.ts +86 -0
- package/status-pill/status-pill.component.d.ts +64 -0
- package/steering/steering.component.d.ts +75 -0
- package/step-loader/step-loader.component.d.ts +40 -0
- package/styles.css +424 -0
- package/task-table/task-table.component.d.ts +114 -0
- package/terminal-stream/terminal-stream.component.d.ts +110 -0
- package/thinking/thinking.component.d.ts +63 -0
- package/thinking-states/thinking-states.component.d.ts +51 -0
- package/thread-panel/thread-panel.component.d.ts +75 -0
- package/toast/toast.component.d.ts +56 -0
- package/toast-stack/toast-stack.component.d.ts +72 -0
- package/tokens.css +424 -0
- package/tool-call/tool-call.component.d.ts +61 -0
- package/tooltip/tooltip.component.d.ts +89 -0
- package/top-pages/top-pages.component.d.ts +75 -0
- package/trace-view/trace-view.component.d.ts +95 -0
- package/voice-capture/voice-capture.component.d.ts +103 -0
- package/voice-orb/voice-orb.component.d.ts +78 -0
- package/web-search/web-search.component.d.ts +77 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
// framework/angular/funnel-chart/funnel-chart.component.ts
|
|
2
|
+
//
|
|
3
|
+
// Native Angular port of framework/react/funnel-chart/FunnelChart.tsx.
|
|
4
|
+
// How many people reach each stage, with the biggest drop marked and a note
|
|
5
|
+
// from the agent. The bars draw a moment after the funnel appears, then redraw
|
|
6
|
+
// top to bottom on every view switch; the note crossfades on a switch. Inputs
|
|
7
|
+
// mirror the React props. Behaviour ported from the vanilla JS (funnel-chart.js):
|
|
8
|
+
// a staggered glide of each bar's width (and its count's position), the worst
|
|
9
|
+
// drop marked, and a blur-swap note.
|
|
10
|
+
//
|
|
11
|
+
// Icon: uses `spark` (the only available match for the React `spark` glyph).
|
|
12
|
+
import { Component, EventEmitter, Input, Output, ViewEncapsulation, } from '@angular/core';
|
|
13
|
+
import { VoIconComponent } from '../core/icon.component';
|
|
14
|
+
import * as i0 from "@angular/core";
|
|
15
|
+
import * as i1 from "../core/reduced-motion.service";
|
|
16
|
+
export class FunnelChartComponent {
|
|
17
|
+
/** Key of the view shown. Leave it out to let the switch change it. */
|
|
18
|
+
set view(value) {
|
|
19
|
+
this.controlled = value !== undefined;
|
|
20
|
+
if (value !== undefined && value !== this.cur) {
|
|
21
|
+
this.cur = value;
|
|
22
|
+
if (this.ready) {
|
|
23
|
+
this.placeKnob();
|
|
24
|
+
this.draw(this.cur);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
constructor(reduced, cdr, host) {
|
|
29
|
+
this.reduced = reduced;
|
|
30
|
+
this.cdr = cdr;
|
|
31
|
+
this.host = host;
|
|
32
|
+
/** Like "Signup to paid". */
|
|
33
|
+
this.title = '';
|
|
34
|
+
/** The stages in order, like "Signed up" then "Opened a file". */
|
|
35
|
+
this.stages = [];
|
|
36
|
+
/** One set of numbers per view. With more than one, a switch picks between them. */
|
|
37
|
+
this.views = [];
|
|
38
|
+
/** Ends a stage's tip, like "of signups" in "51.8% of signups". */
|
|
39
|
+
this.shareLabel = 'of the first stage';
|
|
40
|
+
/** The first stage's tip. */
|
|
41
|
+
this.startLabel = 'Starting point';
|
|
42
|
+
/** Writes a count. Defaults to whole numbers like 12,400. */
|
|
43
|
+
this.format = (n) => Math.round(n).toLocaleString('en-US');
|
|
44
|
+
this.viewChange = new EventEmitter();
|
|
45
|
+
this.cur = '';
|
|
46
|
+
this.rows = [];
|
|
47
|
+
this.knobLeft = 0;
|
|
48
|
+
this.knobWidth = 0;
|
|
49
|
+
this.note = '';
|
|
50
|
+
this.noteOut = false;
|
|
51
|
+
this.hasInsight = false;
|
|
52
|
+
this.controlled = false;
|
|
53
|
+
this.ready = false;
|
|
54
|
+
this.noteId = 0;
|
|
55
|
+
this.timers = [];
|
|
56
|
+
}
|
|
57
|
+
ngAfterViewInit() {
|
|
58
|
+
if (!this.controlled)
|
|
59
|
+
this.cur = this.defaultView ?? this.views[0]?.key ?? '';
|
|
60
|
+
this.hasInsight = this.views.some((v) => v.insight !== undefined);
|
|
61
|
+
const last = Math.max(1, this.stages.length - 1);
|
|
62
|
+
this.rows = this.stages.map((stage, index) => ({
|
|
63
|
+
stage,
|
|
64
|
+
index,
|
|
65
|
+
fc: `color-mix(in oklab,var(--vo-c1) ${Math.round(100 - (index * 100) / last)}%,var(--vo-c2))`,
|
|
66
|
+
width: 0,
|
|
67
|
+
count: '',
|
|
68
|
+
out: false,
|
|
69
|
+
drop: false,
|
|
70
|
+
change: '',
|
|
71
|
+
tip: '',
|
|
72
|
+
}));
|
|
73
|
+
this.ready = true;
|
|
74
|
+
this.cdr.detectChanges();
|
|
75
|
+
this.placeKnob();
|
|
76
|
+
// the first draw starts a moment after the funnel appears, and its note fades in after it
|
|
77
|
+
this.later(() => this.draw(this.cur), 280);
|
|
78
|
+
this.note = this.byKey(this.cur)?.insight ?? '';
|
|
79
|
+
}
|
|
80
|
+
select(key) {
|
|
81
|
+
if (!this.controlled) {
|
|
82
|
+
this.cur = key;
|
|
83
|
+
this.placeKnob();
|
|
84
|
+
this.draw(key);
|
|
85
|
+
}
|
|
86
|
+
this.viewChange.emit(key);
|
|
87
|
+
}
|
|
88
|
+
byKey(key) {
|
|
89
|
+
return this.views.find((v) => v.key === key);
|
|
90
|
+
}
|
|
91
|
+
draw(key) {
|
|
92
|
+
const shown = this.byKey(key);
|
|
93
|
+
const d = shown?.values ?? [];
|
|
94
|
+
// the stage that loses the largest share of the one before it
|
|
95
|
+
let worst = -1;
|
|
96
|
+
let ratio = 1;
|
|
97
|
+
d.forEach((n, i) => {
|
|
98
|
+
if (i && n / d[i - 1] < ratio) {
|
|
99
|
+
ratio = n / d[i - 1];
|
|
100
|
+
worst = i;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
this.rows.forEach((row, i) => {
|
|
104
|
+
const w = d.length ? Math.max(6, (d[i] / d[0]) * 100) : 0;
|
|
105
|
+
row.width = w;
|
|
106
|
+
row.out = w < 24;
|
|
107
|
+
row.count = shown ? this.format(d[i]) : '';
|
|
108
|
+
row.change = shown ? (i ? '−' + Math.round((1 - d[i] / d[i - 1]) * 100) + '%' : '100%') : '';
|
|
109
|
+
row.drop = i === worst;
|
|
110
|
+
row.tip = shown
|
|
111
|
+
? i
|
|
112
|
+
? `${Math.round((d[i] / d[0]) * 1000) / 10}% ${this.shareLabel}`
|
|
113
|
+
: this.startLabel
|
|
114
|
+
: '';
|
|
115
|
+
});
|
|
116
|
+
this.say(shown?.insight ?? '');
|
|
117
|
+
this.cdr.markForCheck();
|
|
118
|
+
}
|
|
119
|
+
// the note crossfades on a switch; the newest note is the one that lands
|
|
120
|
+
say(text) {
|
|
121
|
+
const id = ++this.noteId;
|
|
122
|
+
if (this.note === text && !this.noteOut)
|
|
123
|
+
return;
|
|
124
|
+
this.noteOut = true;
|
|
125
|
+
this.later(() => {
|
|
126
|
+
if (id !== this.noteId)
|
|
127
|
+
return;
|
|
128
|
+
this.note = text;
|
|
129
|
+
this.noteOut = false;
|
|
130
|
+
this.cdr.markForCheck();
|
|
131
|
+
}, this.reduced.reduce() ? 0 : 170);
|
|
132
|
+
}
|
|
133
|
+
placeKnob() {
|
|
134
|
+
const btns = this.host.nativeElement.querySelectorAll('.vo-fnx-sg button');
|
|
135
|
+
const idx = this.views.findIndex((v) => v.key === this.cur);
|
|
136
|
+
const b = btns[idx];
|
|
137
|
+
if (b) {
|
|
138
|
+
this.knobLeft = b.offsetLeft;
|
|
139
|
+
this.knobWidth = b.offsetWidth;
|
|
140
|
+
this.cdr.markForCheck();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
later(fn, ms) {
|
|
144
|
+
this.timers.push(setTimeout(fn, ms));
|
|
145
|
+
}
|
|
146
|
+
ngOnDestroy() {
|
|
147
|
+
this.timers.forEach(clearTimeout);
|
|
148
|
+
this.timers = [];
|
|
149
|
+
}
|
|
150
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FunnelChartComponent, deps: [{ token: i1.ReducedMotionService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
151
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: FunnelChartComponent, isStandalone: true, selector: "vo-funnel-chart", inputs: { title: "title", stages: "stages", views: "views", view: "view", defaultView: "defaultView", shareLabel: "shareLabel", startLabel: "startLabel", format: "format" }, outputs: { viewChange: "viewChange" }, ngImport: i0, template: `
|
|
152
|
+
<div data-vo="" class="vo-fnx vo-panel">
|
|
153
|
+
<div class="vo-fnx-h">
|
|
154
|
+
<b>{{ title }}</b>
|
|
155
|
+
@if (views.length > 1) {
|
|
156
|
+
<div class="vo-seg2 vo-fnx-sg" role="group" aria-label="Segment">
|
|
157
|
+
<span class="vo-knob" [style.left.px]="knobLeft" [style.width.px]="knobWidth"></span>
|
|
158
|
+
@for (v of views; track v.key) {
|
|
159
|
+
<button
|
|
160
|
+
type="button"
|
|
161
|
+
[attr.aria-pressed]="v.key === cur"
|
|
162
|
+
(click)="select(v.key)"
|
|
163
|
+
>{{ v.label }}</button>
|
|
164
|
+
}
|
|
165
|
+
</div>
|
|
166
|
+
}
|
|
167
|
+
</div>
|
|
168
|
+
<div class="vo-fnx-rows">
|
|
169
|
+
@for (r of rows; track r.index) {
|
|
170
|
+
<div class="vo-fnx-r" [class.vo-drop]="r.drop" [style.--vo-fc]="r.fc" [attr.title]="r.tip">
|
|
171
|
+
<span class="vo-k">{{ r.stage }}</span>
|
|
172
|
+
<div class="vo-tr">
|
|
173
|
+
<div class="vo-bar" [style.width.%]="r.width"></div>
|
|
174
|
+
<span
|
|
175
|
+
class="vo-n vo-num"
|
|
176
|
+
[class.vo-out]="r.out"
|
|
177
|
+
[style.left]="r.out ? 'calc(' + r.width + '% + 8px)' : '10px'"
|
|
178
|
+
>{{ r.count }}</span>
|
|
179
|
+
</div>
|
|
180
|
+
<span class="vo-v vo-num">{{ r.change }}</span>
|
|
181
|
+
</div>
|
|
182
|
+
}
|
|
183
|
+
</div>
|
|
184
|
+
@if (hasInsight) {
|
|
185
|
+
<div class="vo-fnx-ins">
|
|
186
|
+
<span class="vo-fnx-ic"><vo-icon name="spark" size="xs"></vo-icon></span>
|
|
187
|
+
<span class="vo-sw vo-fnx-t" [class.vo-out]="noteOut">{{ note }}</span>
|
|
188
|
+
</div>
|
|
189
|
+
}
|
|
190
|
+
</div>
|
|
191
|
+
`, isInline: true, styles: [".vo-fnx{padding:var(--vo-s-4);display:flex;flex-direction:column;gap:var(--vo-s-3)}.vo-fnx-h{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:13.5px;flex-wrap:wrap}.vo-fnx-h b{font-weight:500}.vo-fnx-sg button{font-size:12px;height:26px;padding:0 9px}.vo-fnx-rows{display:flex;flex-direction:column;gap:6px}.vo-fnx-r{display:grid;grid-template-columns:118px 1fr 48px;align-items:center;gap:10px;font-size:12.5px;padding:2px 0;border-radius:var(--vo-r-sm)}.vo-fnx-r .vo-k{color:var(--vo-fg2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.vo-fnx-r .vo-tr{height:26px;border-radius:var(--vo-r-sm);background:var(--vo-chip);position:relative;overflow:hidden}.vo-fnx-r .vo-bar{position:absolute;inset:0 auto 0 0;border-radius:var(--vo-r-sm);background:var(--vo-accent);box-shadow:inset 0 0 0 1px var(--vo-accent-mark,var(--vo-accent));transition:width .9s var(--vo-ease),opacity .3s}.vo-fnx-r .vo-n{position:absolute;left:10px;top:0;bottom:0;display:flex;align-items:center;color:var(--vo-on-accent);font-size:11.5px;font-weight:500;transition:left .9s var(--vo-ease),color .3s}.vo-fnx-r .vo-n.vo-out{color:var(--vo-fg2)}.vo-fnx-r .vo-bar{background:var(--vo-fc,var(--vo-accent));box-shadow:none}:root:not([data-style=soft]) .vo-fnx-r .vo-bar:not(:where([data-style=soft],[data-style=soft] *)){background:var(--vo-accent);box-shadow:inset 0 0 0 1px var(--vo-accent-mark,var(--vo-accent))}.vo-fnx-r .vo-v{text-align:right;color:var(--vo-muted);font-size:12px}.vo-fnx-r.vo-drop .vo-v{color:var(--vo-bad);font-weight:500}@media (hover:hover) and (pointer:fine){.vo-fnx-rows:hover .vo-fnx-r:not(:hover) .vo-bar{opacity:.35}}.vo-fnx-ins{display:flex;gap:var(--vo-s-2);font-size:12.5px;line-height:1.5;color:var(--vo-fg2);padding:10px var(--vo-s-3);border-radius:var(--vo-r-in);background:var(--vo-accent-bg)}.vo-fnx-ic{color:var(--vo-accent-fg,var(--vo-accent));display:grid;margin-top:2px}.vo-panel{background:var(--vo-surface);border-radius:var(--vo-r-card);box-shadow:var(--vo-shadow);position:relative}.vo-num{font-variant-numeric:tabular-nums;font-feature-settings:\"tnum\" 1}.vo-sw{display:inline-block;transition:opacity .17s var(--vo-ease),filter .17s var(--vo-ease),transform .17s var(--vo-ease)}.vo-sw.vo-out{opacity:0;filter:blur(3px);transform:translateY(3px)}@media (prefers-reduced-motion:reduce){.vo-sw{transition:none}}.vo-seg2{display:inline-flex;padding:2px;background:var(--vo-chip);border-radius:var(--vo-r-pill);position:relative}.vo-seg2 button{position:relative;z-index:1;height:26px;padding:0 11px;border-radius:var(--vo-r-pill);font-size:12.5px;color:var(--vo-fg2);cursor:pointer;transition:color var(--vo-t-fast)}.vo-seg2 button[aria-pressed=true]{color:var(--vo-fg)}.vo-seg2 .vo-knob{position:absolute;top:2px;bottom:2px;border-radius:var(--vo-r-pill);background:var(--vo-surface);box-shadow:0 1px 2px #00000014;transition:left var(--vo-t) var(--vo-ease),width var(--vo-t) var(--vo-ease)}.vo-seg2 button:focus-visible{outline-offset:-2px;border-radius:var(--vo-r-pill)}:root:not([data-style=soft]) .vo-seg2 .vo-knob:not(:where([data-style=soft],[data-style=soft] *)){box-shadow:0 0 0 1px color-mix(in srgb,var(--vo-rail) 50%,transparent)}\n"], dependencies: [{ kind: "component", type: VoIconComponent, selector: "vo-icon", inputs: ["name", "size"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
192
|
+
}
|
|
193
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FunnelChartComponent, decorators: [{
|
|
194
|
+
type: Component,
|
|
195
|
+
args: [{ selector: 'vo-funnel-chart', standalone: true, encapsulation: ViewEncapsulation.None, imports: [VoIconComponent], template: `
|
|
196
|
+
<div data-vo="" class="vo-fnx vo-panel">
|
|
197
|
+
<div class="vo-fnx-h">
|
|
198
|
+
<b>{{ title }}</b>
|
|
199
|
+
@if (views.length > 1) {
|
|
200
|
+
<div class="vo-seg2 vo-fnx-sg" role="group" aria-label="Segment">
|
|
201
|
+
<span class="vo-knob" [style.left.px]="knobLeft" [style.width.px]="knobWidth"></span>
|
|
202
|
+
@for (v of views; track v.key) {
|
|
203
|
+
<button
|
|
204
|
+
type="button"
|
|
205
|
+
[attr.aria-pressed]="v.key === cur"
|
|
206
|
+
(click)="select(v.key)"
|
|
207
|
+
>{{ v.label }}</button>
|
|
208
|
+
}
|
|
209
|
+
</div>
|
|
210
|
+
}
|
|
211
|
+
</div>
|
|
212
|
+
<div class="vo-fnx-rows">
|
|
213
|
+
@for (r of rows; track r.index) {
|
|
214
|
+
<div class="vo-fnx-r" [class.vo-drop]="r.drop" [style.--vo-fc]="r.fc" [attr.title]="r.tip">
|
|
215
|
+
<span class="vo-k">{{ r.stage }}</span>
|
|
216
|
+
<div class="vo-tr">
|
|
217
|
+
<div class="vo-bar" [style.width.%]="r.width"></div>
|
|
218
|
+
<span
|
|
219
|
+
class="vo-n vo-num"
|
|
220
|
+
[class.vo-out]="r.out"
|
|
221
|
+
[style.left]="r.out ? 'calc(' + r.width + '% + 8px)' : '10px'"
|
|
222
|
+
>{{ r.count }}</span>
|
|
223
|
+
</div>
|
|
224
|
+
<span class="vo-v vo-num">{{ r.change }}</span>
|
|
225
|
+
</div>
|
|
226
|
+
}
|
|
227
|
+
</div>
|
|
228
|
+
@if (hasInsight) {
|
|
229
|
+
<div class="vo-fnx-ins">
|
|
230
|
+
<span class="vo-fnx-ic"><vo-icon name="spark" size="xs"></vo-icon></span>
|
|
231
|
+
<span class="vo-sw vo-fnx-t" [class.vo-out]="noteOut">{{ note }}</span>
|
|
232
|
+
</div>
|
|
233
|
+
}
|
|
234
|
+
</div>
|
|
235
|
+
`, styles: [".vo-fnx{padding:var(--vo-s-4);display:flex;flex-direction:column;gap:var(--vo-s-3)}.vo-fnx-h{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:13.5px;flex-wrap:wrap}.vo-fnx-h b{font-weight:500}.vo-fnx-sg button{font-size:12px;height:26px;padding:0 9px}.vo-fnx-rows{display:flex;flex-direction:column;gap:6px}.vo-fnx-r{display:grid;grid-template-columns:118px 1fr 48px;align-items:center;gap:10px;font-size:12.5px;padding:2px 0;border-radius:var(--vo-r-sm)}.vo-fnx-r .vo-k{color:var(--vo-fg2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.vo-fnx-r .vo-tr{height:26px;border-radius:var(--vo-r-sm);background:var(--vo-chip);position:relative;overflow:hidden}.vo-fnx-r .vo-bar{position:absolute;inset:0 auto 0 0;border-radius:var(--vo-r-sm);background:var(--vo-accent);box-shadow:inset 0 0 0 1px var(--vo-accent-mark,var(--vo-accent));transition:width .9s var(--vo-ease),opacity .3s}.vo-fnx-r .vo-n{position:absolute;left:10px;top:0;bottom:0;display:flex;align-items:center;color:var(--vo-on-accent);font-size:11.5px;font-weight:500;transition:left .9s var(--vo-ease),color .3s}.vo-fnx-r .vo-n.vo-out{color:var(--vo-fg2)}.vo-fnx-r .vo-bar{background:var(--vo-fc,var(--vo-accent));box-shadow:none}:root:not([data-style=soft]) .vo-fnx-r .vo-bar:not(:where([data-style=soft],[data-style=soft] *)){background:var(--vo-accent);box-shadow:inset 0 0 0 1px var(--vo-accent-mark,var(--vo-accent))}.vo-fnx-r .vo-v{text-align:right;color:var(--vo-muted);font-size:12px}.vo-fnx-r.vo-drop .vo-v{color:var(--vo-bad);font-weight:500}@media (hover:hover) and (pointer:fine){.vo-fnx-rows:hover .vo-fnx-r:not(:hover) .vo-bar{opacity:.35}}.vo-fnx-ins{display:flex;gap:var(--vo-s-2);font-size:12.5px;line-height:1.5;color:var(--vo-fg2);padding:10px var(--vo-s-3);border-radius:var(--vo-r-in);background:var(--vo-accent-bg)}.vo-fnx-ic{color:var(--vo-accent-fg,var(--vo-accent));display:grid;margin-top:2px}.vo-panel{background:var(--vo-surface);border-radius:var(--vo-r-card);box-shadow:var(--vo-shadow);position:relative}.vo-num{font-variant-numeric:tabular-nums;font-feature-settings:\"tnum\" 1}.vo-sw{display:inline-block;transition:opacity .17s var(--vo-ease),filter .17s var(--vo-ease),transform .17s var(--vo-ease)}.vo-sw.vo-out{opacity:0;filter:blur(3px);transform:translateY(3px)}@media (prefers-reduced-motion:reduce){.vo-sw{transition:none}}.vo-seg2{display:inline-flex;padding:2px;background:var(--vo-chip);border-radius:var(--vo-r-pill);position:relative}.vo-seg2 button{position:relative;z-index:1;height:26px;padding:0 11px;border-radius:var(--vo-r-pill);font-size:12.5px;color:var(--vo-fg2);cursor:pointer;transition:color var(--vo-t-fast)}.vo-seg2 button[aria-pressed=true]{color:var(--vo-fg)}.vo-seg2 .vo-knob{position:absolute;top:2px;bottom:2px;border-radius:var(--vo-r-pill);background:var(--vo-surface);box-shadow:0 1px 2px #00000014;transition:left var(--vo-t) var(--vo-ease),width var(--vo-t) var(--vo-ease)}.vo-seg2 button:focus-visible{outline-offset:-2px;border-radius:var(--vo-r-pill)}:root:not([data-style=soft]) .vo-seg2 .vo-knob:not(:where([data-style=soft],[data-style=soft] *)){box-shadow:0 0 0 1px color-mix(in srgb,var(--vo-rail) 50%,transparent)}\n"] }]
|
|
236
|
+
}], ctorParameters: () => [{ type: i1.ReducedMotionService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { title: [{
|
|
237
|
+
type: Input,
|
|
238
|
+
args: [{ required: true }]
|
|
239
|
+
}], stages: [{
|
|
240
|
+
type: Input,
|
|
241
|
+
args: [{ required: true }]
|
|
242
|
+
}], views: [{
|
|
243
|
+
type: Input,
|
|
244
|
+
args: [{ required: true }]
|
|
245
|
+
}], view: [{
|
|
246
|
+
type: Input
|
|
247
|
+
}], defaultView: [{
|
|
248
|
+
type: Input
|
|
249
|
+
}], shareLabel: [{
|
|
250
|
+
type: Input
|
|
251
|
+
}], startLabel: [{
|
|
252
|
+
type: Input
|
|
253
|
+
}], format: [{
|
|
254
|
+
type: Input
|
|
255
|
+
}], viewChange: [{
|
|
256
|
+
type: Output
|
|
257
|
+
}] } });
|
|
258
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnVubmVsLWNoYXJ0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2Z1bm5lbC1jaGFydC9mdW5uZWwtY2hhcnQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDJEQUEyRDtBQUMzRCxFQUFFO0FBQ0YsdUVBQXVFO0FBQ3ZFLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLGtGQUFrRjtBQUNsRiw4RUFBOEU7QUFDOUUscUNBQXFDO0FBQ3JDLEVBQUU7QUFDRiw2RUFBNkU7QUFFN0UsT0FBTyxFQUdMLFNBQVMsRUFFVCxZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sRUFDTixpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFDOzs7QUEyRXpELE1BQU0sT0FBTyxvQkFBb0I7SUFPL0IsdUVBQXVFO0lBQ3ZFLElBQWEsSUFBSSxDQUFDLEtBQXlCO1FBQ3pDLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxLQUFLLFNBQVMsQ0FBQztRQUN0QyxJQUFJLEtBQUssS0FBSyxTQUFTLElBQUksS0FBSyxLQUFLLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUM5QyxJQUFJLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQztZQUNqQixJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDZixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ2pCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3RCLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQXlCRCxZQUNtQixPQUE2QixFQUM3QixHQUFzQixFQUN0QixJQUE2QjtRQUY3QixZQUFPLEdBQVAsT0FBTyxDQUFzQjtRQUM3QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUN0QixTQUFJLEdBQUosSUFBSSxDQUF5QjtRQTVDaEQsNkJBQTZCO1FBQ0YsVUFBSyxHQUFHLEVBQUUsQ0FBQztRQUN0QyxrRUFBa0U7UUFDdkMsV0FBTSxHQUFhLEVBQUUsQ0FBQztRQUNqRCxvRkFBb0Y7UUFDekQsVUFBSyxHQUFzQixFQUFFLENBQUM7UUFjekQsbUVBQW1FO1FBQzFELGVBQVUsR0FBRyxvQkFBb0IsQ0FBQztRQUMzQyw2QkFBNkI7UUFDcEIsZUFBVSxHQUFHLGdCQUFnQixDQUFDO1FBQ3ZDLDZEQUE2RDtRQUNwRCxXQUFNLEdBQTBCLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUU1RSxlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUVsRCxRQUFHLEdBQUcsRUFBRSxDQUFDO1FBQ1QsU0FBSSxHQUFjLEVBQUUsQ0FBQztRQUNyQixhQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsY0FBUyxHQUFHLENBQUMsQ0FBQztRQUNkLFNBQUksR0FBRyxFQUFFLENBQUM7UUFDVixZQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ2hCLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFFWCxlQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ25CLFVBQUssR0FBRyxLQUFLLENBQUM7UUFDZCxXQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ1gsV0FBTSxHQUFvQyxFQUFFLENBQUM7SUFNbEQsQ0FBQztJQUVKLGVBQWU7UUFDYixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVU7WUFBRSxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDO1FBQzlFLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssU0FBUyxDQUFDLENBQUM7UUFDbEUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDN0MsS0FBSztZQUNMLEtBQUs7WUFDTCxFQUFFLEVBQUUsbUNBQW1DLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxpQkFBaUI7WUFDOUYsS0FBSyxFQUFFLENBQUM7WUFDUixLQUFLLEVBQUUsRUFBRTtZQUNULEdBQUcsRUFBRSxLQUFLO1lBQ1YsSUFBSSxFQUFFLEtBQUs7WUFDWCxNQUFNLEVBQUUsRUFBRTtZQUNWLEdBQUcsRUFBRSxFQUFFO1NBQ1IsQ0FBQyxDQUFDLENBQUM7UUFDSixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztRQUNsQixJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNqQiwwRkFBMEY7UUFDMUYsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUMzQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLE9BQU8sSUFBSSxFQUFFLENBQUM7SUFDbEQsQ0FBQztJQUVELE1BQU0sQ0FBQyxHQUFXO1FBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7WUFDZixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNqQixDQUFDO1FBQ0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVPLEtBQUssQ0FBQyxHQUFXO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDL0MsQ0FBQztJQUVPLElBQUksQ0FBQyxHQUFXO1FBQ3RCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUIsTUFBTSxDQUFDLEdBQUcsS0FBSyxFQUFFLE1BQU0sSUFBSSxFQUFFLENBQUM7UUFDOUIsOERBQThEO1FBQzlELElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2YsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ2QsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNqQixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQztnQkFDOUIsS0FBSyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUNyQixLQUFLLEdBQUcsQ0FBQyxDQUFDO1lBQ1osQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDM0IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMxRCxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztZQUNkLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNqQixHQUFHLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzNDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDN0YsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLEtBQUssS0FBSyxDQUFDO1lBQ3ZCLEdBQUcsQ0FBQyxHQUFHLEdBQUcsS0FBSztnQkFDYixDQUFDLENBQUMsQ0FBQztvQkFDRCxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxJQUFJLENBQUMsVUFBVSxFQUFFO29CQUNoRSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVU7Z0JBQ25CLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDVCxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLE9BQU8sSUFBSSxFQUFFLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFRCx5RUFBeUU7SUFDakUsR0FBRyxDQUFDLElBQVk7UUFDdEIsTUFBTSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3pCLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU87UUFDaEQsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFDcEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLEVBQUUsS0FBSyxJQUFJLENBQUMsTUFBTTtnQkFBRSxPQUFPO1lBQy9CLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1lBQ2pCLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1lBQ3JCLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDMUIsQ0FBQyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVPLFNBQVM7UUFDZixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBYyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3hGLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM1RCxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDcEIsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNOLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQztZQUM3QixJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxXQUFXLENBQUM7WUFDL0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQyxFQUFjLEVBQUUsRUFBVTtRQUN0QyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNsQyxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztJQUNuQixDQUFDOytHQWhKVSxvQkFBb0I7bUdBQXBCLG9CQUFvQixnU0EzQ3JCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0NULDRzR0F6Q1MsZUFBZTs7NEZBNENkLG9CQUFvQjtrQkFoRGhDLFNBQVM7K0JBQ0UsaUJBQWlCLGNBQ2YsSUFBSSxpQkFDRCxpQkFBaUIsQ0FBQyxJQUFJLFdBQzVCLENBQUMsZUFBZSxDQUFDLFlBQ2hCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0NUO2tKQUswQixLQUFLO3NCQUEvQixLQUFLO3VCQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRTtnQkFFRSxNQUFNO3NCQUFoQyxLQUFLO3VCQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRTtnQkFFRSxLQUFLO3NCQUEvQixLQUFLO3VCQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRTtnQkFFWixJQUFJO3NCQUFoQixLQUFLO2dCQVdHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUcsVUFBVTtzQkFBbEIsS0FBSztnQkFFRyxVQUFVO3NCQUFsQixLQUFLO2dCQUVHLE1BQU07c0JBQWQsS0FBSztnQkFFSSxVQUFVO3NCQUFuQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiLy8gZnJhbWV3b3JrL2FuZ3VsYXIvZnVubmVsLWNoYXJ0L2Z1bm5lbC1jaGFydC5jb21wb25lbnQudHNcbi8vXG4vLyBOYXRpdmUgQW5ndWxhciBwb3J0IG9mIGZyYW1ld29yay9yZWFjdC9mdW5uZWwtY2hhcnQvRnVubmVsQ2hhcnQudHN4LlxuLy8gSG93IG1hbnkgcGVvcGxlIHJlYWNoIGVhY2ggc3RhZ2UsIHdpdGggdGhlIGJpZ2dlc3QgZHJvcCBtYXJrZWQgYW5kIGEgbm90ZVxuLy8gZnJvbSB0aGUgYWdlbnQuIFRoZSBiYXJzIGRyYXcgYSBtb21lbnQgYWZ0ZXIgdGhlIGZ1bm5lbCBhcHBlYXJzLCB0aGVuIHJlZHJhd1xuLy8gdG9wIHRvIGJvdHRvbSBvbiBldmVyeSB2aWV3IHN3aXRjaDsgdGhlIG5vdGUgY3Jvc3NmYWRlcyBvbiBhIHN3aXRjaC4gSW5wdXRzXG4vLyBtaXJyb3IgdGhlIFJlYWN0IHByb3BzLiBCZWhhdmlvdXIgcG9ydGVkIGZyb20gdGhlIHZhbmlsbGEgSlMgKGZ1bm5lbC1jaGFydC5qcyk6XG4vLyBhIHN0YWdnZXJlZCBnbGlkZSBvZiBlYWNoIGJhcidzIHdpZHRoIChhbmQgaXRzIGNvdW50J3MgcG9zaXRpb24pLCB0aGUgd29yc3Rcbi8vIGRyb3AgbWFya2VkLCBhbmQgYSBibHVyLXN3YXAgbm90ZS5cbi8vXG4vLyBJY29uOiB1c2VzIGBzcGFya2AgKHRoZSBvbmx5IGF2YWlsYWJsZSBtYXRjaCBmb3IgdGhlIFJlYWN0IGBzcGFya2AgZ2x5cGgpLlxuXG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVm9JY29uQ29tcG9uZW50IH0gZnJvbSAnLi4vY29yZS9pY29uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBSZWR1Y2VkTW90aW9uU2VydmljZSB9IGZyb20gJy4uL2NvcmUvcmVkdWNlZC1tb3Rpb24uc2VydmljZSc7XG5cbi8qKiBPbmUgc2V0IG9mIG51bWJlcnMsIHBpY2tlZCBieSB0aGUgc3dpdGNoLiAqL1xuZXhwb3J0IGludGVyZmFjZSBGdW5uZWxDaGFydFZpZXcge1xuICBrZXk6IHN0cmluZztcbiAgLyoqIE9uIHRoZSBzd2l0Y2gsIGxpa2UgXCJUZWFtc1wiLiAqL1xuICBsYWJlbDogc3RyaW5nO1xuICAvKiogSG93IG1hbnkgcmVhY2hlZCBlYWNoIHN0YWdlLCBpbiBvcmRlci4gKi9cbiAgdmFsdWVzOiBudW1iZXJbXTtcbiAgLyoqIFRoZSBhZ2VudCdzIG5vdGUgdW5kZXIgdGhlIGZ1bm5lbCBmb3IgdGhpcyB2aWV3LiAqL1xuICBpbnNpZ2h0Pzogc3RyaW5nO1xufVxuXG4vKiogSW50ZXJuYWwgcGVyLXN0YWdlIHJlbmRlciBzdGF0ZS4gKi9cbmludGVyZmFjZSBSb3dWaWV3IHtcbiAgc3RhZ2U6IHN0cmluZztcbiAgaW5kZXg6IG51bWJlcjtcbiAgZmM6IHN0cmluZztcbiAgd2lkdGg6IG51bWJlcjtcbiAgY291bnQ6IHN0cmluZztcbiAgb3V0OiBib29sZWFuO1xuICBkcm9wOiBib29sZWFuO1xuICBjaGFuZ2U6IHN0cmluZztcbiAgdGlwOiBzdHJpbmc7XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3ZvLWZ1bm5lbC1jaGFydCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGltcG9ydHM6IFtWb0ljb25Db21wb25lbnRdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgZGF0YS12bz1cIlwiIGNsYXNzPVwidm8tZm54IHZvLXBhbmVsXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwidm8tZm54LWhcIj5cbiAgICAgICAgPGI+e3sgdGl0bGUgfX08L2I+XG4gICAgICAgIEBpZiAodmlld3MubGVuZ3RoID4gMSkge1xuICAgICAgICAgIDxkaXYgY2xhc3M9XCJ2by1zZWcyIHZvLWZueC1zZ1wiIHJvbGU9XCJncm91cFwiIGFyaWEtbGFiZWw9XCJTZWdtZW50XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLWtub2JcIiBbc3R5bGUubGVmdC5weF09XCJrbm9iTGVmdFwiIFtzdHlsZS53aWR0aC5weF09XCJrbm9iV2lkdGhcIj48L3NwYW4+XG4gICAgICAgICAgICBAZm9yICh2IG9mIHZpZXdzOyB0cmFjayB2LmtleSkge1xuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1wcmVzc2VkXT1cInYua2V5ID09PSBjdXJcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3Qodi5rZXkpXCJcbiAgICAgICAgICAgICAgPnt7IHYubGFiZWwgfX08L2J1dHRvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwidm8tZm54LXJvd3NcIj5cbiAgICAgICAgQGZvciAociBvZiByb3dzOyB0cmFjayByLmluZGV4KSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInZvLWZueC1yXCIgW2NsYXNzLnZvLWRyb3BdPVwici5kcm9wXCIgW3N0eWxlLi0tdm8tZmNdPVwici5mY1wiIFthdHRyLnRpdGxlXT1cInIudGlwXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLWtcIj57eyByLnN0YWdlIH19PC9zcGFuPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZvLXRyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ2by1iYXJcIiBbc3R5bGUud2lkdGguJV09XCJyLndpZHRoXCI+PC9kaXY+XG4gICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJ2by1uIHZvLW51bVwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLnZvLW91dF09XCJyLm91dFwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmxlZnRdPVwici5vdXQgPyAnY2FsYygnICsgci53aWR0aCArICclICsgOHB4KScgOiAnMTBweCdcIlxuICAgICAgICAgICAgICA+e3sgci5jb3VudCB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by12IHZvLW51bVwiPnt7IHIuY2hhbmdlIH19PC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICAgIEBpZiAoaGFzSW5zaWdodCkge1xuICAgICAgICA8ZGl2IGNsYXNzPVwidm8tZm54LWluc1wiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tZm54LWljXCI+PHZvLWljb24gbmFtZT1cInNwYXJrXCIgc2l6ZT1cInhzXCI+PC92by1pY29uPjwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLXN3IHZvLWZueC10XCIgW2NsYXNzLnZvLW91dF09XCJub3RlT3V0XCI+e3sgbm90ZSB9fTwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG4gICAgPC9kaXY+XG4gIGAsXG4gIHN0eWxlVXJsOiAnLi9mdW5uZWwtY2hhcnQuY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgRnVubmVsQ2hhcnRDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICAvKiogTGlrZSBcIlNpZ251cCB0byBwYWlkXCIuICovXG4gIEBJbnB1dCh7IHJlcXVpcmVkOiB0cnVlIH0pIHRpdGxlID0gJyc7XG4gIC8qKiBUaGUgc3RhZ2VzIGluIG9yZGVyLCBsaWtlIFwiU2lnbmVkIHVwXCIgdGhlbiBcIk9wZW5lZCBhIGZpbGVcIi4gKi9cbiAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSkgc3RhZ2VzOiBzdHJpbmdbXSA9IFtdO1xuICAvKiogT25lIHNldCBvZiBudW1iZXJzIHBlciB2aWV3LiBXaXRoIG1vcmUgdGhhbiBvbmUsIGEgc3dpdGNoIHBpY2tzIGJldHdlZW4gdGhlbS4gKi9cbiAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSkgdmlld3M6IEZ1bm5lbENoYXJ0Vmlld1tdID0gW107XG4gIC8qKiBLZXkgb2YgdGhlIHZpZXcgc2hvd24uIExlYXZlIGl0IG91dCB0byBsZXQgdGhlIHN3aXRjaCBjaGFuZ2UgaXQuICovXG4gIEBJbnB1dCgpIHNldCB2aWV3KHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLmNvbnRyb2xsZWQgPSB2YWx1ZSAhPT0gdW5kZWZpbmVkO1xuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSB0aGlzLmN1cikge1xuICAgICAgdGhpcy5jdXIgPSB2YWx1ZTtcbiAgICAgIGlmICh0aGlzLnJlYWR5KSB7XG4gICAgICAgIHRoaXMucGxhY2VLbm9iKCk7XG4gICAgICAgIHRoaXMuZHJhdyh0aGlzLmN1cik7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8qKiBEZWZhdWx0cyB0byB0aGUgZmlyc3Qgdmlldy4gKi9cbiAgQElucHV0KCkgZGVmYXVsdFZpZXc/OiBzdHJpbmc7XG4gIC8qKiBFbmRzIGEgc3RhZ2UncyB0aXAsIGxpa2UgXCJvZiBzaWdudXBzXCIgaW4gXCI1MS44JSBvZiBzaWdudXBzXCIuICovXG4gIEBJbnB1dCgpIHNoYXJlTGFiZWwgPSAnb2YgdGhlIGZpcnN0IHN0YWdlJztcbiAgLyoqIFRoZSBmaXJzdCBzdGFnZSdzIHRpcC4gKi9cbiAgQElucHV0KCkgc3RhcnRMYWJlbCA9ICdTdGFydGluZyBwb2ludCc7XG4gIC8qKiBXcml0ZXMgYSBjb3VudC4gRGVmYXVsdHMgdG8gd2hvbGUgbnVtYmVycyBsaWtlIDEyLDQwMC4gKi9cbiAgQElucHV0KCkgZm9ybWF0OiAobjogbnVtYmVyKSA9PiBzdHJpbmcgPSAobikgPT4gTWF0aC5yb3VuZChuKS50b0xvY2FsZVN0cmluZygnZW4tVVMnKTtcblxuICBAT3V0cHV0KCkgdmlld0NoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIGN1ciA9ICcnO1xuICByb3dzOiBSb3dWaWV3W10gPSBbXTtcbiAga25vYkxlZnQgPSAwO1xuICBrbm9iV2lkdGggPSAwO1xuICBub3RlID0gJyc7XG4gIG5vdGVPdXQgPSBmYWxzZTtcbiAgaGFzSW5zaWdodCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgY29udHJvbGxlZCA9IGZhbHNlO1xuICBwcml2YXRlIHJlYWR5ID0gZmFsc2U7XG4gIHByaXZhdGUgbm90ZUlkID0gMDtcbiAgcHJpdmF0ZSB0aW1lcnM6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+W10gPSBbXTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlZHVjZWQ6IFJlZHVjZWRNb3Rpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGhvc3Q6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICApIHt9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jb250cm9sbGVkKSB0aGlzLmN1ciA9IHRoaXMuZGVmYXVsdFZpZXcgPz8gdGhpcy52aWV3c1swXT8ua2V5ID8/ICcnO1xuICAgIHRoaXMuaGFzSW5zaWdodCA9IHRoaXMudmlld3Muc29tZSgodikgPT4gdi5pbnNpZ2h0ICE9PSB1bmRlZmluZWQpO1xuICAgIGNvbnN0IGxhc3QgPSBNYXRoLm1heCgxLCB0aGlzLnN0YWdlcy5sZW5ndGggLSAxKTtcbiAgICB0aGlzLnJvd3MgPSB0aGlzLnN0YWdlcy5tYXAoKHN0YWdlLCBpbmRleCkgPT4gKHtcbiAgICAgIHN0YWdlLFxuICAgICAgaW5kZXgsXG4gICAgICBmYzogYGNvbG9yLW1peChpbiBva2xhYix2YXIoLS12by1jMSkgJHtNYXRoLnJvdW5kKDEwMCAtIChpbmRleCAqIDEwMCkgLyBsYXN0KX0lLHZhcigtLXZvLWMyKSlgLFxuICAgICAgd2lkdGg6IDAsXG4gICAgICBjb3VudDogJycsXG4gICAgICBvdXQ6IGZhbHNlLFxuICAgICAgZHJvcDogZmFsc2UsXG4gICAgICBjaGFuZ2U6ICcnLFxuICAgICAgdGlwOiAnJyxcbiAgICB9KSk7XG4gICAgdGhpcy5yZWFkeSA9IHRydWU7XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIHRoaXMucGxhY2VLbm9iKCk7XG4gICAgLy8gdGhlIGZpcnN0IGRyYXcgc3RhcnRzIGEgbW9tZW50IGFmdGVyIHRoZSBmdW5uZWwgYXBwZWFycywgYW5kIGl0cyBub3RlIGZhZGVzIGluIGFmdGVyIGl0XG4gICAgdGhpcy5sYXRlcigoKSA9PiB0aGlzLmRyYXcodGhpcy5jdXIpLCAyODApO1xuICAgIHRoaXMubm90ZSA9IHRoaXMuYnlLZXkodGhpcy5jdXIpPy5pbnNpZ2h0ID8/ICcnO1xuICB9XG5cbiAgc2VsZWN0KGtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2xsZWQpIHtcbiAgICAgIHRoaXMuY3VyID0ga2V5O1xuICAgICAgdGhpcy5wbGFjZUtub2IoKTtcbiAgICAgIHRoaXMuZHJhdyhrZXkpO1xuICAgIH1cbiAgICB0aGlzLnZpZXdDaGFuZ2UuZW1pdChrZXkpO1xuICB9XG5cbiAgcHJpdmF0ZSBieUtleShrZXk6IHN0cmluZyk6IEZ1bm5lbENoYXJ0VmlldyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMudmlld3MuZmluZCgodikgPT4gdi5rZXkgPT09IGtleSk7XG4gIH1cblxuICBwcml2YXRlIGRyYXcoa2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzaG93biA9IHRoaXMuYnlLZXkoa2V5KTtcbiAgICBjb25zdCBkID0gc2hvd24/LnZhbHVlcyA/PyBbXTtcbiAgICAvLyB0aGUgc3RhZ2UgdGhhdCBsb3NlcyB0aGUgbGFyZ2VzdCBzaGFyZSBvZiB0aGUgb25lIGJlZm9yZSBpdFxuICAgIGxldCB3b3JzdCA9IC0xO1xuICAgIGxldCByYXRpbyA9IDE7XG4gICAgZC5mb3JFYWNoKChuLCBpKSA9PiB7XG4gICAgICBpZiAoaSAmJiBuIC8gZFtpIC0gMV0gPCByYXRpbykge1xuICAgICAgICByYXRpbyA9IG4gLyBkW2kgLSAxXTtcbiAgICAgICAgd29yc3QgPSBpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMucm93cy5mb3JFYWNoKChyb3csIGkpID0+IHtcbiAgICAgIGNvbnN0IHcgPSBkLmxlbmd0aCA/IE1hdGgubWF4KDYsIChkW2ldIC8gZFswXSkgKiAxMDApIDogMDtcbiAgICAgIHJvdy53aWR0aCA9IHc7XG4gICAgICByb3cub3V0ID0gdyA8IDI0O1xuICAgICAgcm93LmNvdW50ID0gc2hvd24gPyB0aGlzLmZvcm1hdChkW2ldKSA6ICcnO1xuICAgICAgcm93LmNoYW5nZSA9IHNob3duID8gKGkgPyAn4oiSJyArIE1hdGgucm91bmQoKDEgLSBkW2ldIC8gZFtpIC0gMV0pICogMTAwKSArICclJyA6ICcxMDAlJykgOiAnJztcbiAgICAgIHJvdy5kcm9wID0gaSA9PT0gd29yc3Q7XG4gICAgICByb3cudGlwID0gc2hvd25cbiAgICAgICAgPyBpXG4gICAgICAgICAgPyBgJHtNYXRoLnJvdW5kKChkW2ldIC8gZFswXSkgKiAxMDAwKSAvIDEwfSUgJHt0aGlzLnNoYXJlTGFiZWx9YFxuICAgICAgICAgIDogdGhpcy5zdGFydExhYmVsXG4gICAgICAgIDogJyc7XG4gICAgfSk7XG4gICAgdGhpcy5zYXkoc2hvd24/Lmluc2lnaHQgPz8gJycpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLy8gdGhlIG5vdGUgY3Jvc3NmYWRlcyBvbiBhIHN3aXRjaDsgdGhlIG5ld2VzdCBub3RlIGlzIHRoZSBvbmUgdGhhdCBsYW5kc1xuICBwcml2YXRlIHNheSh0ZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBpZCA9ICsrdGhpcy5ub3RlSWQ7XG4gICAgaWYgKHRoaXMubm90ZSA9PT0gdGV4dCAmJiAhdGhpcy5ub3RlT3V0KSByZXR1cm47XG4gICAgdGhpcy5ub3RlT3V0ID0gdHJ1ZTtcbiAgICB0aGlzLmxhdGVyKCgpID0+IHtcbiAgICAgIGlmIChpZCAhPT0gdGhpcy5ub3RlSWQpIHJldHVybjtcbiAgICAgIHRoaXMubm90ZSA9IHRleHQ7XG4gICAgICB0aGlzLm5vdGVPdXQgPSBmYWxzZTtcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH0sIHRoaXMucmVkdWNlZC5yZWR1Y2UoKSA/IDAgOiAxNzApO1xuICB9XG5cbiAgcHJpdmF0ZSBwbGFjZUtub2IoKTogdm9pZCB7XG4gICAgY29uc3QgYnRucyA9IHRoaXMuaG9zdC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGw8SFRNTEVsZW1lbnQ+KCcudm8tZm54LXNnIGJ1dHRvbicpO1xuICAgIGNvbnN0IGlkeCA9IHRoaXMudmlld3MuZmluZEluZGV4KCh2KSA9PiB2LmtleSA9PT0gdGhpcy5jdXIpO1xuICAgIGNvbnN0IGIgPSBidG5zW2lkeF07XG4gICAgaWYgKGIpIHtcbiAgICAgIHRoaXMua25vYkxlZnQgPSBiLm9mZnNldExlZnQ7XG4gICAgICB0aGlzLmtub2JXaWR0aCA9IGIub2Zmc2V0V2lkdGg7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGxhdGVyKGZuOiAoKSA9PiB2b2lkLCBtczogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy50aW1lcnMucHVzaChzZXRUaW1lb3V0KGZuLCBtcykpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy50aW1lcnMuZm9yRWFjaChjbGVhclRpbWVvdXQpO1xuICAgIHRoaXMudGltZXJzID0gW107XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// framework/angular/grid/grid.component.ts
|
|
2
|
+
//
|
|
3
|
+
// Native Angular port of framework/react/grid/Grid.tsx.
|
|
4
|
+
// A responsive grid you drop cards or any other components into. Inputs mirror
|
|
5
|
+
// the React props. Use the `voGridItem` directive on a child to span columns.
|
|
6
|
+
//
|
|
7
|
+
// The grid class and CSS vars live on the host element itself (not a wrapper),
|
|
8
|
+
// so projected children are direct children of `.vo-grd` and the `>` span
|
|
9
|
+
// selectors apply.
|
|
10
|
+
import { Component, Directive, Input, ViewEncapsulation } from '@angular/core';
|
|
11
|
+
import * as i0 from "@angular/core";
|
|
12
|
+
export class GridComponent {
|
|
13
|
+
constructor() {
|
|
14
|
+
/** A fixed column count. Ignored when `fit` is set. 3 by default. */
|
|
15
|
+
this.cols = 3;
|
|
16
|
+
/** Pack as many columns as fit at `min` width, reflowing with no column count. */
|
|
17
|
+
this.fit = false;
|
|
18
|
+
/** Minimum column width when `fit` is set. '200px' by default. */
|
|
19
|
+
this.min = '200px';
|
|
20
|
+
/** The gutter: a core spacing step (1–8) or a raw CSS length. 4 by default. */
|
|
21
|
+
this.gap = 4;
|
|
22
|
+
}
|
|
23
|
+
get gapVar() {
|
|
24
|
+
return typeof this.gap === 'number' ? `var(--vo-s-${this.gap})` : this.gap;
|
|
25
|
+
}
|
|
26
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
27
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: GridComponent, isStandalone: true, selector: "vo-grid", inputs: { cols: "cols", fit: "fit", min: "min", gap: "gap" }, host: { properties: { "attr.data-fit": "fit ? 'true' : null", "style.--grd-cols": "cols", "style.--grd-gap": "gapVar", "style.--grd-min": "min" }, classAttribute: "vo-grd" }, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, styles: [".vo-grd{--grd-cols:3;--grd-gap:var(--vo-s-4);--grd-min:200px;display:grid;gap:var(--grd-gap);grid-template-columns:repeat(var(--grd-cols),minmax(0,1fr));min-width:0;container:grd/inline-size}.vo-grd[data-fit=true]{grid-template-columns:repeat(auto-fit,minmax(min(var(--grd-min),100%),1fr))}.vo-grd>[data-span=\"2\"]{grid-column:span 2}.vo-grd>[data-span=\"3\"]{grid-column:span 3}.vo-grd>[data-span=\"4\"]{grid-column:span 4}.vo-grd>[data-span=full]{grid-column:1 / -1}@container grd (max-width:420px){.vo-grd:not([data-fit=true]){grid-template-columns:minmax(0,1fr)}.vo-grd>[data-span]{grid-column:auto}}\n"], encapsulation: i0.ViewEncapsulation.None }); }
|
|
28
|
+
}
|
|
29
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GridComponent, decorators: [{
|
|
30
|
+
type: Component,
|
|
31
|
+
args: [{ selector: 'vo-grid', standalone: true, encapsulation: ViewEncapsulation.None, host: {
|
|
32
|
+
class: 'vo-grd',
|
|
33
|
+
'[attr.data-fit]': "fit ? 'true' : null",
|
|
34
|
+
'[style.--grd-cols]': 'cols',
|
|
35
|
+
'[style.--grd-gap]': 'gapVar',
|
|
36
|
+
'[style.--grd-min]': 'min',
|
|
37
|
+
}, template: `<ng-content></ng-content>`, styles: [".vo-grd{--grd-cols:3;--grd-gap:var(--vo-s-4);--grd-min:200px;display:grid;gap:var(--grd-gap);grid-template-columns:repeat(var(--grd-cols),minmax(0,1fr));min-width:0;container:grd/inline-size}.vo-grd[data-fit=true]{grid-template-columns:repeat(auto-fit,minmax(min(var(--grd-min),100%),1fr))}.vo-grd>[data-span=\"2\"]{grid-column:span 2}.vo-grd>[data-span=\"3\"]{grid-column:span 3}.vo-grd>[data-span=\"4\"]{grid-column:span 4}.vo-grd>[data-span=full]{grid-column:1 / -1}@container grd (max-width:420px){.vo-grd:not([data-fit=true]){grid-template-columns:minmax(0,1fr)}.vo-grd>[data-span]{grid-column:auto}}\n"] }]
|
|
38
|
+
}], propDecorators: { cols: [{
|
|
39
|
+
type: Input
|
|
40
|
+
}], fit: [{
|
|
41
|
+
type: Input
|
|
42
|
+
}], min: [{
|
|
43
|
+
type: Input
|
|
44
|
+
}], gap: [{
|
|
45
|
+
type: Input
|
|
46
|
+
}] } });
|
|
47
|
+
/** A grid child that spans more than one column (2, 3, 4) or the full row ('full'). */
|
|
48
|
+
export class GridItemDirective {
|
|
49
|
+
constructor() {
|
|
50
|
+
this.span = '';
|
|
51
|
+
}
|
|
52
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GridItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
53
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: GridItemDirective, isStandalone: true, selector: "[voGridItem]", inputs: { span: ["voGridItem", "span"] }, host: { properties: { "attr.data-span": "span || null" } }, ngImport: i0 }); }
|
|
54
|
+
}
|
|
55
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GridItemDirective, decorators: [{
|
|
56
|
+
type: Directive,
|
|
57
|
+
args: [{
|
|
58
|
+
selector: '[voGridItem]',
|
|
59
|
+
standalone: true,
|
|
60
|
+
host: { '[attr.data-span]': 'span || null' },
|
|
61
|
+
}]
|
|
62
|
+
}], propDecorators: { span: [{
|
|
63
|
+
type: Input,
|
|
64
|
+
args: ['voGridItem']
|
|
65
|
+
}] } });
|
|
66
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9ncmlkL2dyaWQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDJDQUEyQztBQUMzQyxFQUFFO0FBQ0Ysd0RBQXdEO0FBQ3hELCtFQUErRTtBQUMvRSw4RUFBOEU7QUFDOUUsRUFBRTtBQUNGLCtFQUErRTtBQUMvRSwwRUFBMEU7QUFDMUUsbUJBQW1CO0FBRW5CLE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7QUFtQi9FLE1BQU0sT0FBTyxhQUFhO0lBZDFCO1FBZUUscUVBQXFFO1FBQzVELFNBQUksR0FBRyxDQUFDLENBQUM7UUFDbEIsa0ZBQWtGO1FBQ3pFLFFBQUcsR0FBRyxLQUFLLENBQUM7UUFDckIsa0VBQWtFO1FBQ3pELFFBQUcsR0FBRyxPQUFPLENBQUM7UUFDdkIsK0VBQStFO1FBQ3RFLFFBQUcsR0FBWSxDQUFDLENBQUM7S0FLM0I7SUFIQyxJQUFJLE1BQU07UUFDUixPQUFPLE9BQU8sSUFBSSxDQUFDLEdBQUcsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLGNBQWMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQzdFLENBQUM7K0dBWlUsYUFBYTttR0FBYixhQUFhLGdUQUhkLDJCQUEyQjs7NEZBRzFCLGFBQWE7a0JBZHpCLFNBQVM7K0JBQ0UsU0FBUyxjQUNQLElBQUksaUJBQ0QsaUJBQWlCLENBQUMsSUFBSSxRQUMvQjt3QkFDSixLQUFLLEVBQUUsUUFBUTt3QkFDZixpQkFBaUIsRUFBRSxxQkFBcUI7d0JBQ3hDLG9CQUFvQixFQUFFLE1BQU07d0JBQzVCLG1CQUFtQixFQUFFLFFBQVE7d0JBQzdCLG1CQUFtQixFQUFFLEtBQUs7cUJBQzNCLFlBQ1MsMkJBQTJCOzhCQUs1QixJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsR0FBRztzQkFBWCxLQUFLO2dCQUVHLEdBQUc7c0JBQVgsS0FBSztnQkFFRyxHQUFHO3NCQUFYLEtBQUs7O0FBT1IsdUZBQXVGO0FBTXZGLE1BQU0sT0FBTyxpQkFBaUI7SUFMOUI7UUFNdUIsU0FBSSxHQUE0QixFQUFFLENBQUM7S0FDekQ7K0dBRlksaUJBQWlCO21HQUFqQixpQkFBaUI7OzRGQUFqQixpQkFBaUI7a0JBTDdCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGNBQWM7b0JBQ3hCLFVBQVUsRUFBRSxJQUFJO29CQUNoQixJQUFJLEVBQUUsRUFBRSxrQkFBa0IsRUFBRSxjQUFjLEVBQUU7aUJBQzdDOzhCQUVzQixJQUFJO3NCQUF4QixLQUFLO3VCQUFDLFlBQVkiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBmcmFtZXdvcmsvYW5ndWxhci9ncmlkL2dyaWQuY29tcG9uZW50LnRzXG4vL1xuLy8gTmF0aXZlIEFuZ3VsYXIgcG9ydCBvZiBmcmFtZXdvcmsvcmVhY3QvZ3JpZC9HcmlkLnRzeC5cbi8vIEEgcmVzcG9uc2l2ZSBncmlkIHlvdSBkcm9wIGNhcmRzIG9yIGFueSBvdGhlciBjb21wb25lbnRzIGludG8uIElucHV0cyBtaXJyb3Jcbi8vIHRoZSBSZWFjdCBwcm9wcy4gVXNlIHRoZSBgdm9HcmlkSXRlbWAgZGlyZWN0aXZlIG9uIGEgY2hpbGQgdG8gc3BhbiBjb2x1bW5zLlxuLy9cbi8vIFRoZSBncmlkIGNsYXNzIGFuZCBDU1MgdmFycyBsaXZlIG9uIHRoZSBob3N0IGVsZW1lbnQgaXRzZWxmIChub3QgYSB3cmFwcGVyKSxcbi8vIHNvIHByb2plY3RlZCBjaGlsZHJlbiBhcmUgZGlyZWN0IGNoaWxkcmVuIG9mIGAudm8tZ3JkYCBhbmQgdGhlIGA+YCBzcGFuXG4vLyBzZWxlY3RvcnMgYXBwbHkuXG5cbmltcG9ydCB7IENvbXBvbmVudCwgRGlyZWN0aXZlLCBJbnB1dCwgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuLyoqIEEgY29yZSBzcGFjaW5nIHRva2VuICgx4oCTOCkgZm9yIHRoZSBndXR0ZXIsIG9yIGEgcmF3IENTUyBsZW5ndGguICovXG5leHBvcnQgdHlwZSBHcmlkR2FwID0gMSB8IDIgfCAzIHwgNCB8IDUgfCA2IHwgOCB8IHN0cmluZztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndm8tZ3JpZCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGhvc3Q6IHtcbiAgICBjbGFzczogJ3ZvLWdyZCcsXG4gICAgJ1thdHRyLmRhdGEtZml0XSc6IFwiZml0ID8gJ3RydWUnIDogbnVsbFwiLFxuICAgICdbc3R5bGUuLS1ncmQtY29sc10nOiAnY29scycsXG4gICAgJ1tzdHlsZS4tLWdyZC1nYXBdJzogJ2dhcFZhcicsXG4gICAgJ1tzdHlsZS4tLWdyZC1taW5dJzogJ21pbicsXG4gIH0sXG4gIHRlbXBsYXRlOiBgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PmAsXG4gIHN0eWxlVXJsOiAnLi9ncmlkLmNzcycsXG59KVxuZXhwb3J0IGNsYXNzIEdyaWRDb21wb25lbnQge1xuICAvKiogQSBmaXhlZCBjb2x1bW4gY291bnQuIElnbm9yZWQgd2hlbiBgZml0YCBpcyBzZXQuIDMgYnkgZGVmYXVsdC4gKi9cbiAgQElucHV0KCkgY29scyA9IDM7XG4gIC8qKiBQYWNrIGFzIG1hbnkgY29sdW1ucyBhcyBmaXQgYXQgYG1pbmAgd2lkdGgsIHJlZmxvd2luZyB3aXRoIG5vIGNvbHVtbiBjb3VudC4gKi9cbiAgQElucHV0KCkgZml0ID0gZmFsc2U7XG4gIC8qKiBNaW5pbXVtIGNvbHVtbiB3aWR0aCB3aGVuIGBmaXRgIGlzIHNldC4gJzIwMHB4JyBieSBkZWZhdWx0LiAqL1xuICBASW5wdXQoKSBtaW4gPSAnMjAwcHgnO1xuICAvKiogVGhlIGd1dHRlcjogYSBjb3JlIHNwYWNpbmcgc3RlcCAoMeKAkzgpIG9yIGEgcmF3IENTUyBsZW5ndGguIDQgYnkgZGVmYXVsdC4gKi9cbiAgQElucHV0KCkgZ2FwOiBHcmlkR2FwID0gNDtcblxuICBnZXQgZ2FwVmFyKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHR5cGVvZiB0aGlzLmdhcCA9PT0gJ251bWJlcicgPyBgdmFyKC0tdm8tcy0ke3RoaXMuZ2FwfSlgIDogdGhpcy5nYXA7XG4gIH1cbn1cblxuLyoqIEEgZ3JpZCBjaGlsZCB0aGF0IHNwYW5zIG1vcmUgdGhhbiBvbmUgY29sdW1uICgyLCAzLCA0KSBvciB0aGUgZnVsbCByb3cgKCdmdWxsJykuICovXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbdm9HcmlkSXRlbV0nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBob3N0OiB7ICdbYXR0ci5kYXRhLXNwYW5dJzogJ3NwYW4gfHwgbnVsbCcgfSxcbn0pXG5leHBvcnQgY2xhc3MgR3JpZEl0ZW1EaXJlY3RpdmUge1xuICBASW5wdXQoJ3ZvR3JpZEl0ZW0nKSBzcGFuOiAyIHwgMyB8IDQgfCAnZnVsbCcgfCAnJyA9ICcnO1xufVxuIl19
|