@firestitch/report 18.9.0 → 18.10.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/app/reports/anchor-at-point.d.ts +14 -0
- package/app/reports/canvas-landing-page.d.ts +2 -0
- package/app/reports/components/component-chart/component-chart.component.d.ts +18 -2
- package/app/reports/components/component-kpi/component-kpi.component.d.ts +4 -1
- package/app/reports/components/report-canvas/report-canvas.component.d.ts +3 -0
- package/app/reports/components/report-component/report-component.component.d.ts +35 -1
- package/app/reports/components/report-view-picker/report-view-picker.component.d.ts +21 -0
- package/app/reports/data/report.data.d.ts +17 -2
- package/app/reports/dialogs/component-settings/component-settings.component.d.ts +18 -3
- package/app/reports/dialogs/report-settings/report-settings.component.d.ts +15 -6
- package/app/reports/dialogs/report-view/report-view-dialog.component.d.ts +13 -0
- package/app/reports/drill-crumbs.d.ts +12 -0
- package/app/reports/export/report-export-collector.service.d.ts +13 -4
- package/app/reports/export/report-filter-lines.d.ts +18 -0
- package/app/reports/filter-settings-rules.d.ts +33 -0
- package/app/reports/format.d.ts +0 -1
- package/app/reports/interfaces/canvas-landing-input.interface.d.ts +8 -0
- package/app/reports/interfaces/component-data-applied.interface.d.ts +13 -0
- package/app/reports/interfaces/component-data-drill.interface.d.ts +22 -0
- package/app/reports/interfaces/filter-bar-placement.type.d.ts +1 -0
- package/app/reports/interfaces/filter-component-toggle-state.interface.d.ts +4 -0
- package/app/reports/interfaces/filter-settings-option.interface.d.ts +4 -0
- package/app/reports/interfaces/filter-type-select-state.interface.d.ts +5 -0
- package/app/reports/interfaces/report-chart-hit.interface.d.ts +5 -0
- package/app/reports/interfaces/report-chat-viewer-cross-filter-field.interface.d.ts +4 -0
- package/app/reports/interfaces/report-chat-viewer-cross-filter.interface.d.ts +7 -0
- package/app/reports/interfaces/report-chat-viewer-detail.interface.d.ts +4 -0
- package/app/reports/interfaces/report-chat-viewer-drill-step.interface.d.ts +5 -0
- package/app/reports/interfaces/report-chat-viewer-drill.interface.d.ts +5 -0
- package/app/reports/interfaces/report-chat-viewer-filter.interface.d.ts +3 -0
- package/app/reports/interfaces/report-chat-viewer-selection.interface.d.ts +5 -0
- package/app/reports/interfaces/report-chat-viewer-state.interface.d.ts +12 -0
- package/app/reports/interfaces/report-drill-crumb.interface.d.ts +6 -0
- package/app/reports/interfaces/report-drill-refusal.type.d.ts +1 -0
- package/app/reports/interfaces/report-drill-step.interface.d.ts +5 -0
- package/app/reports/interfaces/report-export-line-kind.type.d.ts +1 -0
- package/app/reports/interfaces/report-export-line.interface.d.ts +8 -0
- package/app/reports/interfaces/report-export-lines-input.interface.d.ts +9 -0
- package/app/reports/interfaces/report-export-snapshot.interface.d.ts +15 -0
- package/app/reports/interfaces/report-filter-line-context.interface.d.ts +8 -0
- package/app/reports/interfaces/report-filter-line-form.type.d.ts +1 -0
- package/app/reports/interfaces/report-filter-match.type.d.ts +1 -0
- package/app/reports/interfaces/report-filter-option-pair.interface.d.ts +4 -0
- package/app/reports/interfaces/report-filter-options-ask.interface.d.ts +6 -0
- package/app/reports/interfaces/report-filter-options-list.interface.d.ts +7 -0
- package/app/reports/interfaces/report-filter-options-request.interface.d.ts +6 -0
- package/app/reports/interfaces/report-filter-options-stream.interface.d.ts +11 -0
- package/app/reports/interfaces/report-filter-options.interface.d.ts +7 -0
- package/app/reports/interfaces/report-filter-skip.type.d.ts +1 -0
- package/app/reports/interfaces/report-mark-action.type.d.ts +1 -0
- package/app/reports/interfaces/report-mark-click.interface.d.ts +13 -0
- package/app/reports/interfaces/report-mark-context.interface.d.ts +6 -0
- package/app/reports/interfaces/report-mark-decision.interface.d.ts +6 -0
- package/app/reports/interfaces/report-mark-event.interface.d.ts +11 -0
- package/app/reports/interfaces/report-mark-point.interface.d.ts +8 -0
- package/app/reports/interfaces/report-temporary-state.interface.d.ts +4 -0
- package/app/reports/interfaces/report-tile-state.interface.d.ts +8 -0
- package/app/reports/interfaces/report-url-link.interface.d.ts +4 -0
- package/app/reports/interfaces/report-url-value-name.type.d.ts +1 -0
- package/app/reports/interfaces/report-url-write.interface.d.ts +4 -0
- package/app/reports/interfaces/report-view-config.interface.d.ts +11 -0
- package/app/reports/interfaces/report-view-create.interface.d.ts +7 -0
- package/app/reports/interfaces/report-view-deleted.interface.d.ts +4 -0
- package/app/reports/interfaces/report-view-dialog-data.interface.d.ts +7 -0
- package/app/reports/interfaces/report-view-dropped.interface.d.ts +5 -0
- package/app/reports/interfaces/report-view-menu-item.interface.d.ts +10 -0
- package/app/reports/interfaces/report-view-summary.interface.d.ts +11 -0
- package/app/reports/interfaces/report-view.interface.d.ts +7 -0
- package/app/reports/interfaces/report-viewer-feature.type.d.ts +1 -0
- package/app/reports/interfaces/report-views.interface.d.ts +7 -0
- package/app/reports/interfaces/report.interface.d.ts +27 -3
- package/app/reports/interfaces/tile-load-result.interface.d.ts +4 -0
- package/app/reports/mark-click.d.ts +20 -0
- package/app/reports/option-builder.d.ts +12 -1
- package/app/reports/report-chat-viewer-state.d.ts +8 -0
- package/app/reports/report-date-presets.d.ts +2 -0
- package/app/reports/report-filter-items.d.ts +27 -22
- package/app/reports/report-tile.d.ts +2 -0
- package/app/reports/report-url-state.d.ts +27 -10
- package/app/reports/report-view-config.d.ts +36 -0
- package/app/reports/report-view-menu.d.ts +15 -0
- package/app/reports/report-viewer-features.d.ts +5 -0
- package/app/reports/services/report-filter-options.service.d.ts +26 -0
- package/app/reports/services/report-filter-state.service.d.ts +64 -1
- package/app/reports/services/report-view.service.d.ts +51 -0
- package/app/reports/tile-data-state.d.ts +7 -0
- package/app/reports/tile-loads.d.ts +4 -0
- package/app/reports/views/report/fs-ai-report.component.d.ts +9 -1
- package/app/reports/views/report/report.component.d.ts +6 -0
- package/esm2022/app/reports/anchor-at-point.mjs +49 -0
- package/esm2022/app/reports/canvas-landing-page.mjs +25 -0
- package/esm2022/app/reports/components/component-chart/component-chart.component.mjs +97 -5
- package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +11 -4
- package/esm2022/app/reports/components/component-list/component-list.component.mjs +7 -1
- package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +47 -32
- package/esm2022/app/reports/components/report-component/report-component.component.mjs +257 -61
- package/esm2022/app/reports/components/report-view-picker/report-view-picker.component.mjs +115 -0
- package/esm2022/app/reports/data/report.data.mjs +87 -10
- package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +106 -51
- package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +86 -90
- package/esm2022/app/reports/dialogs/report-view/report-view-dialog.component.mjs +52 -0
- package/esm2022/app/reports/drill-crumbs.mjs +73 -0
- package/esm2022/app/reports/export/report-export-collector.service.mjs +187 -117
- package/esm2022/app/reports/export/report-filter-lines.mjs +235 -0
- package/esm2022/app/reports/export/report-pdf.service.mjs +12 -7
- package/esm2022/app/reports/export/report-pptx.service.mjs +18 -14
- package/esm2022/app/reports/filter-settings-rules.mjs +283 -0
- package/esm2022/app/reports/format.mjs +2 -22
- package/esm2022/app/reports/interfaces/canvas-landing-input.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/component-data-applied.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/component-data-drill.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/filter-bar-placement.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/filter-component-toggle-state.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/filter-settings-option.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/filter-type-select-state.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chart-hit.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chat-viewer-cross-filter-field.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chat-viewer-cross-filter.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chat-viewer-detail.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chat-viewer-drill-step.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chat-viewer-drill.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chat-viewer-filter.interface.mjs +1 -1
- package/esm2022/app/reports/interfaces/report-chat-viewer-selection.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chat-viewer-state.interface.mjs +1 -1
- package/esm2022/app/reports/interfaces/report-drill-crumb.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-drill-refusal.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-drill-step.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-export-line-kind.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-export-line.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-export-lines-input.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-export-snapshot.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-line-context.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-line-form.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-match.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-option-pair.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-options-ask.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-options-list.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-options-request.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-options-stream.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-options.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-skip.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-mark-action.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-mark-click.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-mark-context.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-mark-decision.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-mark-event.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-mark-point.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-temporary-state.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-tile-state.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-url-link.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-url-value-name.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-url-write.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view-config.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view-create.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view-deleted.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view-dialog-data.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view-dropped.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view-menu-item.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view-summary.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-viewer-feature.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-views.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
- package/esm2022/app/reports/interfaces/tile-load-result.interface.mjs +2 -0
- package/esm2022/app/reports/mark-click.mjs +193 -0
- package/esm2022/app/reports/option-builder.mjs +159 -15
- package/esm2022/app/reports/report-chat-viewer-state.mjs +34 -0
- package/esm2022/app/reports/report-date-presets.mjs +18 -0
- package/esm2022/app/reports/report-filter-items.mjs +343 -72
- package/esm2022/app/reports/report-tile.mjs +12 -0
- package/esm2022/app/reports/report-url-state.mjs +596 -108
- package/esm2022/app/reports/report-view-config.mjs +697 -0
- package/esm2022/app/reports/report-view-menu.mjs +119 -0
- package/esm2022/app/reports/report-viewer-features.mjs +42 -0
- package/esm2022/app/reports/services/report-filter-options.service.mjs +238 -0
- package/esm2022/app/reports/services/report-filter-state.service.mjs +697 -62
- package/esm2022/app/reports/services/report-view.service.mjs +358 -0
- package/esm2022/app/reports/tile-data-state.mjs +127 -0
- package/esm2022/app/reports/tile-loads.mjs +38 -0
- package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +177 -46
- package/esm2022/app/reports/views/report/report.component.mjs +103 -23
- package/esm2022/public_api.mjs +23 -1
- package/fesm2022/{firestitch-report-echarts-DBMOHmBF.mjs → firestitch-report-echarts-UBg8Wlhd.mjs} +2 -2
- package/fesm2022/{firestitch-report-echarts-DBMOHmBF.mjs.map → firestitch-report-echarts-UBg8Wlhd.mjs.map} +1 -1
- package/fesm2022/{firestitch-report-firestitch-report-CqbXT1gh.mjs → firestitch-report-firestitch-report-B1keNrcK.mjs} +9063 -4272
- package/fesm2022/firestitch-report-firestitch-report-B1keNrcK.mjs.map +1 -0
- package/fesm2022/firestitch-report.mjs +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +22 -0
- package/fesm2022/firestitch-report-firestitch-report-CqbXT1gh.mjs.map +0 -1
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { RELATIVE_RANGE_NAMES, isRelativeRange } from './report-view-config';
|
|
2
|
+
import { offersExclude } from './report-viewer-features';
|
|
3
|
+
// The Type select's choices. A column that can be either holds both.
|
|
4
|
+
export const FILTER_TYPE_OPTIONS = [
|
|
5
|
+
{ value: 'select', name: 'Values' },
|
|
6
|
+
{ value: 'numberRange', name: 'Number range' },
|
|
7
|
+
];
|
|
8
|
+
export const TYPE_LOCKED_TOOLTIP = 'Remove the filter to change its type.';
|
|
9
|
+
export const PAGE_FILTER_TOOLTIP = 'A page filter shows in the page bar only.';
|
|
10
|
+
export const COMPONENT_TOGGLE_TOOLTIP = 'Show on this component';
|
|
11
|
+
// The Default period select's value for a range of fixed days. No relative
|
|
12
|
+
// range is named this.
|
|
13
|
+
export const FIXED_DATES_PERIOD = 'fixed';
|
|
14
|
+
// How many decimals a Default minimum or Default maximum takes.
|
|
15
|
+
export const DEFAULT_BOUND_SCALE = 6;
|
|
16
|
+
// Every Report bar choice, in the order the select lists them.
|
|
17
|
+
const BAR_PLACEMENT_OPTIONS = [
|
|
18
|
+
{ value: 'off', name: 'Off' },
|
|
19
|
+
{ value: 'every', name: 'Every page' },
|
|
20
|
+
{ value: 'page', name: 'This page only' },
|
|
21
|
+
];
|
|
22
|
+
// A number with its group commas in place ('1,250.5', '-12,000').
|
|
23
|
+
const GROUPED_DECIMAL = /^-?\d{1,3}(,\d{3})+(\.\d*)?$/;
|
|
24
|
+
// A plain decimal number ('1250.5', '-3', '0', '.5'). Hex, binary, octal,
|
|
25
|
+
// exponents and inner spaces do not match, though Number() reads some.
|
|
26
|
+
const PLAIN_DECIMAL = /^-?(\d+(\.\d*)?|\.\d+)$/;
|
|
27
|
+
// A default range end as typed. An empty field is no end. A number input
|
|
28
|
+
// with a mask hands back text with its group commas ('1,250.5'), so those go
|
|
29
|
+
// before Number() reads it; 0 is an end like any other. Anything that is not
|
|
30
|
+
// a decimal number is no end.
|
|
31
|
+
export function parseDefaultBound(raw) {
|
|
32
|
+
if (typeof raw === 'number') {
|
|
33
|
+
return Number.isFinite(raw) ? raw : null;
|
|
34
|
+
}
|
|
35
|
+
if (typeof raw !== 'string') {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const trimmed = raw.trim();
|
|
39
|
+
const text = GROUPED_DECIMAL.test(trimmed) ? trimmed.replace(/,/g, '') : trimmed;
|
|
40
|
+
if (!PLAIN_DECIMAL.test(text)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const value = Number(text);
|
|
44
|
+
return Number.isFinite(value) ? value : null;
|
|
45
|
+
}
|
|
46
|
+
// Why two range ends cannot be saved, in the server's words, or null. An open
|
|
47
|
+
// end is always fine.
|
|
48
|
+
export function boundsError(min, max) {
|
|
49
|
+
if (min === null || max === null || min <= max) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
return `min (${min}) is above max (${max}).`;
|
|
53
|
+
}
|
|
54
|
+
// The Type select of a column on the component settings' Filters tab. It
|
|
55
|
+
// shows when the column can take either type and the server serves number
|
|
56
|
+
// ranges (an older server lists no features). A filter's type cannot change,
|
|
57
|
+
// so it is locked while the column has a filter on this component.
|
|
58
|
+
export function typeSelectState(types, hasFilterOnThisComponent, features) {
|
|
59
|
+
const show = (features ?? []).includes('numberRange')
|
|
60
|
+
&& FILTER_TYPE_OPTIONS.every((option) => (types ?? []).includes(option.value));
|
|
61
|
+
if (!show) {
|
|
62
|
+
return { show: false, disabled: false, tooltip: null };
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
show: true,
|
|
66
|
+
disabled: hasFilterOnThisComponent,
|
|
67
|
+
tooltip: hasFilterOnThisComponent ? TYPE_LOCKED_TOOLTIP : null,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// The levels a new or moved filter can take on a component. This page only
|
|
71
|
+
// needs a server that serves page filters and a component on a page (a
|
|
72
|
+
// header or footer component is on no page).
|
|
73
|
+
export function filterLevelChoices(features, onPage) {
|
|
74
|
+
const levels = ['component', 'report', 'both'];
|
|
75
|
+
return onPage && (features ?? []).includes('pageScope')
|
|
76
|
+
? [...levels, 'page']
|
|
77
|
+
: levels;
|
|
78
|
+
}
|
|
79
|
+
// The Report bar select's choices for the levels on offer. The choice a row
|
|
80
|
+
// already holds is always listed, so the select never shows blank.
|
|
81
|
+
export function barPlacementOptions(levelChoices, current = 'off') {
|
|
82
|
+
return BAR_PLACEMENT_OPTIONS.filter((option) => {
|
|
83
|
+
switch (option.value) {
|
|
84
|
+
case 'every':
|
|
85
|
+
return levelChoices.includes('report') || levelChoices.includes('both') || current === 'every';
|
|
86
|
+
case 'page':
|
|
87
|
+
return levelChoices.includes('page') || current === 'page';
|
|
88
|
+
default:
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// A value's Report bar choices. A value has no strip of its own and its
|
|
94
|
+
// group may be shared, so a pick never lowers the group (the inline values
|
|
95
|
+
// rule): This page only is offered for a new filter, or for a group that is
|
|
96
|
+
// already a page group, never to move a shared group to one page.
|
|
97
|
+
export function valuePlacementOptions(levelChoices, current) {
|
|
98
|
+
const choices = !current || current === 'page'
|
|
99
|
+
? levelChoices
|
|
100
|
+
: levelChoices.filter((level) => level !== 'page');
|
|
101
|
+
return barPlacementOptions(choices, barPlacement(current));
|
|
102
|
+
}
|
|
103
|
+
// The level a value's filter group ends at after a Report bar pick, or null
|
|
104
|
+
// when the value leaves it. Off unlinks this value alone and the group keeps
|
|
105
|
+
// its other members. A new filter takes the pick's level. Every page raises a
|
|
106
|
+
// strip-only group to both, keeping its strips, and a page group to the
|
|
107
|
+
// report bar. Nothing else moves the group, so a value never lowers it.
|
|
108
|
+
export function valueFilterLevel(placement, current) {
|
|
109
|
+
if (placement === 'off') {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
if (!current) {
|
|
113
|
+
return placement === 'page' ? 'page' : 'report';
|
|
114
|
+
}
|
|
115
|
+
if (placement !== 'every') {
|
|
116
|
+
return current;
|
|
117
|
+
}
|
|
118
|
+
switch (current) {
|
|
119
|
+
case 'component':
|
|
120
|
+
return 'both';
|
|
121
|
+
case 'page':
|
|
122
|
+
return 'report';
|
|
123
|
+
default:
|
|
124
|
+
return current;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Where a group of a level shows in the report bar. No group (no filter) is
|
|
128
|
+
// off.
|
|
129
|
+
export function barPlacement(level) {
|
|
130
|
+
switch (level) {
|
|
131
|
+
case 'report':
|
|
132
|
+
case 'both':
|
|
133
|
+
return 'every';
|
|
134
|
+
case 'page':
|
|
135
|
+
return 'page';
|
|
136
|
+
default:
|
|
137
|
+
return 'off';
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Whether a group of a level shows on its components.
|
|
141
|
+
export function shownOnComponent(level) {
|
|
142
|
+
return level === 'component' || level === 'both';
|
|
143
|
+
}
|
|
144
|
+
// The level the two controls of a row ask for, or null when they ask for no
|
|
145
|
+
// filter at all. A page filter shows in its page's bar only, so This page
|
|
146
|
+
// only ignores the This component toggle.
|
|
147
|
+
export function filterLevel(placement, component) {
|
|
148
|
+
switch (placement) {
|
|
149
|
+
case 'page':
|
|
150
|
+
return 'page';
|
|
151
|
+
case 'every':
|
|
152
|
+
return component ? 'both' : 'report';
|
|
153
|
+
default:
|
|
154
|
+
return component ? 'component' : null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// The This component toggle of a row: locked while This page only is picked.
|
|
158
|
+
export function componentToggleState(placement) {
|
|
159
|
+
return placement === 'page'
|
|
160
|
+
? { disabled: true, tooltip: PAGE_FILTER_TOOLTIP }
|
|
161
|
+
: { disabled: false, tooltip: COMPONENT_TOGGLE_TOOLTIP };
|
|
162
|
+
}
|
|
163
|
+
// The groups the report settings' Filters tab lists defaults for: those of
|
|
164
|
+
// the report bar, every page or one, in bar order.
|
|
165
|
+
export function defaultRowGroups(groups) {
|
|
166
|
+
return (groups ?? [])
|
|
167
|
+
.filter((group) => group.level === 'report' || group.level === 'both' || group.level === 'page')
|
|
168
|
+
.sort((a, b) => a.order - b.order);
|
|
169
|
+
}
|
|
170
|
+
// A default row's label: a page group names its page, 'Region (page
|
|
171
|
+
// "Overview")'. A page with no name reads as the canvas names it ('Page 2').
|
|
172
|
+
// A page this report no longer holds adds nothing.
|
|
173
|
+
export function defaultRowLabel(group, pages) {
|
|
174
|
+
const label = group.label || group.filters?.[0]?.filterColumn || 'Filter';
|
|
175
|
+
if (group.level !== 'page') {
|
|
176
|
+
return label;
|
|
177
|
+
}
|
|
178
|
+
const index = (pages ?? []).findIndex((page) => page.id === group.pageId);
|
|
179
|
+
if (index < 0) {
|
|
180
|
+
return label;
|
|
181
|
+
}
|
|
182
|
+
return `${label} (page "${pages[index].name || `Page ${index + 1}`}")`;
|
|
183
|
+
}
|
|
184
|
+
// The Default period select's choices: Fixed dates, then every relative
|
|
185
|
+
// range in the server enum's order, named by `labels`. A stored range this
|
|
186
|
+
// viewer does not know is listed last, so the select still shows it.
|
|
187
|
+
export function defaultPeriodOptions(labels, stored = null) {
|
|
188
|
+
const options = [
|
|
189
|
+
{ value: FIXED_DATES_PERIOD, name: 'Fixed dates' },
|
|
190
|
+
...RELATIVE_RANGE_NAMES.map((relative) => ({ value: relative, name: labels(relative) })),
|
|
191
|
+
];
|
|
192
|
+
return stored && stored !== FIXED_DATES_PERIOD && !isRelativeRange(stored)
|
|
193
|
+
? [...options, { value: stored, name: labels(stored) }]
|
|
194
|
+
: options;
|
|
195
|
+
}
|
|
196
|
+
// The Default period a stored date range default opens on: its relative
|
|
197
|
+
// range, else Fixed dates (the days, or none).
|
|
198
|
+
export function defaultPeriod(stored) {
|
|
199
|
+
return stored?.relative && !stored.start && !stored.end
|
|
200
|
+
? stored.relative
|
|
201
|
+
: FIXED_DATES_PERIOD;
|
|
202
|
+
}
|
|
203
|
+
// A date range default in its stored shape: the relative range picked, else
|
|
204
|
+
// the fixed days, or null when there are none. Never both: the server
|
|
205
|
+
// refuses a relative range with days.
|
|
206
|
+
export function dateRangeDefault(period, start, end) {
|
|
207
|
+
if (period !== FIXED_DATES_PERIOD) {
|
|
208
|
+
return { relative: period };
|
|
209
|
+
}
|
|
210
|
+
if (!start && !end) {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
return { ...(start ? { start } : {}), ...(end ? { end } : {}) };
|
|
214
|
+
}
|
|
215
|
+
// A select default in its stored shape: the picks kept, or left out while
|
|
216
|
+
// Exclude these values is on, or null when nothing is picked.
|
|
217
|
+
export function selectDefault(values, exclude) {
|
|
218
|
+
if (!values.length) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
return exclude ? { excludeValues: values } : { values };
|
|
222
|
+
}
|
|
223
|
+
// A number range default in its stored shape from the ends as typed: an
|
|
224
|
+
// open end is left out, 0 is kept, and two open ends are no default.
|
|
225
|
+
export function numberRangeDefault(rawMin, rawMax) {
|
|
226
|
+
const min = parseDefaultBound(rawMin);
|
|
227
|
+
const max = parseDefaultBound(rawMax);
|
|
228
|
+
if (min === null && max === null) {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
return { ...(min !== null ? { min } : {}), ...(max !== null ? { max } : {}) };
|
|
232
|
+
}
|
|
233
|
+
// Whether a select group's default row offers Exclude these values: the
|
|
234
|
+
// report bar's rule (offersExclude), so not on a server that does not serve
|
|
235
|
+
// exclude (an older server lists no features) nor on a group with a member
|
|
236
|
+
// that binds several columns (multiColumn). A default that already leaves
|
|
237
|
+
// values out keeps the toggle, so it can be turned off.
|
|
238
|
+
export function showExcludeToggle(group, features) {
|
|
239
|
+
if (group.type === 'select' && group.config?.default?.excludeValues?.length) {
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
return offersExclude(group, features);
|
|
243
|
+
}
|
|
244
|
+
// A stored or draft default in a stable form for comparing: empty and
|
|
245
|
+
// absent keys are dropped, so a no-op edit does not read as a change. 0 is an
|
|
246
|
+
// end like any other. Nothing left is null.
|
|
247
|
+
export function normalizeDefault(value) {
|
|
248
|
+
if (!value) {
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
const normalized = {};
|
|
252
|
+
if (value.start) {
|
|
253
|
+
normalized.start = value.start;
|
|
254
|
+
}
|
|
255
|
+
if (value.end) {
|
|
256
|
+
normalized.end = value.end;
|
|
257
|
+
}
|
|
258
|
+
if (value.values?.length) {
|
|
259
|
+
normalized.values = value.values;
|
|
260
|
+
}
|
|
261
|
+
if (value.excludeValues?.length) {
|
|
262
|
+
normalized.excludeValues = value.excludeValues;
|
|
263
|
+
}
|
|
264
|
+
if (typeof value.min === 'number') {
|
|
265
|
+
normalized.min = value.min;
|
|
266
|
+
}
|
|
267
|
+
if (typeof value.max === 'number') {
|
|
268
|
+
normalized.max = value.max;
|
|
269
|
+
}
|
|
270
|
+
if (value.value) {
|
|
271
|
+
normalized.value = value.value;
|
|
272
|
+
}
|
|
273
|
+
if (value.relative) {
|
|
274
|
+
normalized.relative = value.relative;
|
|
275
|
+
}
|
|
276
|
+
return Object.keys(normalized).length ? normalized : null;
|
|
277
|
+
}
|
|
278
|
+
// Whether a row's draft default differs from the group's stored one. Only a
|
|
279
|
+
// changed row is saved.
|
|
280
|
+
export function defaultChanged(stored, draft) {
|
|
281
|
+
return JSON.stringify(normalizeDefault(stored)) !== JSON.stringify(normalizeDefault(draft));
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLXNldHRpbmdzLXJ1bGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2ZpbHRlci1zZXR0aW5ncy1ydWxlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFtQkEsT0FBTyxFQUFFLG9CQUFvQixFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUd6RCxxRUFBcUU7QUFDckUsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQTZDO0lBQzNFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO0lBQ25DLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFO0NBQy9DLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyx1Q0FBdUMsQ0FBQztBQUMzRSxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRywyQ0FBMkMsQ0FBQztBQUMvRSxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBRyx3QkFBd0IsQ0FBQztBQUVqRSwyRUFBMkU7QUFDM0UsdUJBQXVCO0FBQ3ZCLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQztBQUUxQyxnRUFBZ0U7QUFDaEUsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO0FBRXJDLCtEQUErRDtBQUMvRCxNQUFNLHFCQUFxQixHQUErQztJQUN4RSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRTtJQUM3QixFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRTtJQUN0QyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFO0NBQzFDLENBQUM7QUFHRixrRUFBa0U7QUFDbEUsTUFBTSxlQUFl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TUFBTSxVQUFVLGNBQWMsQ0FDNUIsTUFBNkMsRUFDN0MsS0FBNEM7SUFFNUMsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzlGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGUgcnVsZXMgYmVoaW5kIHRoZSB0d28gZmlsdGVyIHNldHRpbmdzIGRpYWxvZ3MsIGtlcHQgcHVyZSBzbyB0aGUgbm9kZVxuLy8gaGFybmVzcyBjaGVja3MgdGhlbSB3aXRob3V0IGEgZGlhbG9nLiBUaGUgY29tcG9uZW50IHNldHRpbmdzJyBGaWx0ZXJzIHRhYlxuLy8gcmVhZHMgdGhlIFR5cGUgc2VsZWN0LCB0aGUgUmVwb3J0IGJhciBzZWxlY3QgYW5kIHRoZSBUaGlzIGNvbXBvbmVudCB0b2dnbGVcbi8vIGZyb20gaGVyZTsgdGhlIHJlcG9ydCBzZXR0aW5ncycgRmlsdGVycyB0YWIgcmVhZHMgaXRzIGRlZmF1bHQgcm93cyAodGhlXG4vLyBwZXJpb2QsIHRoZSBleGNsdWRlIHRvZ2dsZSwgdGhlIG51bWJlciByYW5nZSBlbmRzIGFuZCB0aGVpciBjaGVjaykgZnJvbVxuLy8gaGVyZS4gVGhlIGRpYWxvZ3Mgb25seSBjYWxsIHRoZXNlLlxuaW1wb3J0IHsgRmlsdGVyQmFyUGxhY2VtZW50IH0gZnJvbSAnLi9pbnRlcmZhY2VzL2ZpbHRlci1iYXItcGxhY2VtZW50LnR5cGUnO1xuaW1wb3J0IHsgRmlsdGVyQ29tcG9uZW50VG9nZ2xlU3RhdGUgfSBmcm9tICcuL2ludGVyZmFjZXMvZmlsdGVyLWNvbXBvbmVudC10b2dnbGUtc3RhdGUuaW50ZXJmYWNlJztcbmltcG9ydCB7IEZpbHRlclNldHRpbmdzT3B0aW9uIH0gZnJvbSAnLi9pbnRlcmZhY2VzL2ZpbHRlci1zZXR0aW5ncy1vcHRpb24uaW50ZXJmYWNlJztcbmltcG9ydCB7IEZpbHRlclR5cGVTZWxlY3RTdGF0ZSB9IGZyb20gJy4vaW50ZXJmYWNlcy9maWx0ZXItdHlwZS1zZWxlY3Qtc3RhdGUuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlcG9ydFZpZXdlckZlYXR1cmUgfSBmcm9tICcuL2ludGVyZmFjZXMvcmVwb3J0LXZpZXdlci1mZWF0dXJlLnR5cGUnO1xuaW1wb3J0IHtcbiAgRmlsdGVyR3JvdXBEZWZhdWx0LFxuICBSZXBvcnRGaWx0ZXJHcm91cCxcbiAgUmVwb3J0RmlsdGVyTGV2ZWwsXG4gIFJlcG9ydEZpbHRlclR5cGUsXG4gIFJlcG9ydFBhZ2UsXG4gIFJlcG9ydFJlbGF0aXZlUmFuZ2UsXG59IGZyb20gJy4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJFTEFUSVZFX1JBTkdFX05BTUVTLCBpc1JlbGF0aXZlUmFuZ2UgfSBmcm9tICcuL3JlcG9ydC12aWV3LWNvbmZpZyc7XG5pbXBvcnQgeyBvZmZlcnNFeGNsdWRlIH0gZnJvbSAnLi9yZXBvcnQtdmlld2VyLWZlYXR1cmVzJztcblxuXG4vLyBUaGUgVHlwZSBzZWxlY3QncyBjaG9pY2VzLiBBIGNvbHVtbiB0aGF0IGNhbiBiZSBlaXRoZXIgaG9sZHMgYm90aC5cbmV4cG9ydCBjb25zdCBGSUxURVJfVFlQRV9PUFRJT05TOiBGaWx0ZXJTZXR0aW5nc09wdGlvbjxSZXBvcnRGaWx0ZXJUeXBlPltdID0gW1xuICB7IHZhbHVlOiAnc2VsZWN0JywgbmFtZTogJ1ZhbHVlcycgfSxcbiAgeyB2YWx1ZTogJ251bWJlclJhbmdlJywgbmFtZTogJ051bWJlciByYW5nZScgfSxcbl07XG5cbmV4cG9ydCBjb25zdCBUWVBFX0xPQ0tFRF9UT09MVElQID0gJ1JlbW92ZSB0aGUgZmlsdGVyIHRvIGNoYW5nZSBpdHMgdHlwZS4nO1xuZXhwb3J0IGNvbnN0IFBBR0VfRklMVEVSX1RPT0xUSVAgPSAnQSBwYWdlIGZpbHRlciBzaG93cyBpbiB0aGUgcGFnZSBiYXIgb25seS4nO1xuZXhwb3J0IGNvbnN0IENPTVBPTkVOVF9UT0dHTEVfVE9PTFRJUCA9ICdTaG93IG9uIHRoaXMgY29tcG9uZW50JztcblxuLy8gVGhlIERlZmF1bHQgcGVyaW9kIHNlbGVjdCdzIHZhbHVlIGZvciBhIHJhbmdlIG9mIGZpeGVkIGRheXMuIE5vIHJlbGF0aXZlXG4vLyByYW5nZSBpcyBuYW1lZCB0aGlzLlxuZXhwb3J0IGNvbnN0IEZJWEVEX0RBVEVTX1BFUklPRCA9ICdmaXhlZCc7XG5cbi8vIEhvdyBtYW55IGRlY2ltYWxzIGEgRGVmYXVsdCBtaW5pbXVtIG9yIERlZmF1bHQgbWF4aW11bSB0YWtlcy5cbmV4cG9ydCBjb25zdCBERUZBVUxUX0JPVU5EX1NDQUxFID0gNjtcblxuLy8gRXZlcnkgUmVwb3J0IGJhciBjaG9pY2UsIGluIHRoZSBvcmRlciB0aGUgc2VsZWN0IGxpc3RzIHRoZW0uXG5jb25zdCBCQVJfUExBQ0VNRU5UX09QVElPTlM6IEZpbHRlclNldHRpbmdzT3B0aW9uPEZpbHRlckJhclBsYWNlbWVudD5bXSA9IFtcbiAgeyB2YWx1ZTogJ29mZicsIG5hbWU6ICdPZmYnIH0sXG4gIHsgdmFsdWU6ICdldmVyeScsIG5hbWU6ICdFdmVyeSBwYWdlJyB9LFxuICB7IHZhbHVlOiAncGFnZScsIG5hbWU6ICdUaGlzIHBhZ2Ugb25seScgfSxcbl07XG5cblxuLy8gQSBudW1iZXIgd2l0aCBpdHMgZ3JvdXAgY29tbWFzIGluIHBsYWNlICgnMSwyNTAuNScsICctMTIsMDAwJykuXG5jb25zdCBHUk9VUEVEX0RFQ0lNQUwgPSAvXi0/XFxkezEsM30oLFxcZHszfSkrKFxcLlxcZCopPyQvO1xuLy8gQSBwbGFpbiBkZWNpbWFsIG51bWJlciAoJzEyNTAuNScsICctMycsICcwJywgJy41JykuIEhleCwgYmluYXJ5LCBvY3RhbCxcbi8vIGV4cG9uZW50cyBhbmQgaW5uZXIgc3BhY2VzIGRvIG5vdCBtYXRjaCwgdGhvdWdoIE51bWJlcigpIHJlYWRzIHNvbWUuXG5jb25zdCBQTEFJTl9ERUNJTUFMID0gL14tPyhcXGQrKFxcLlxcZCopP3xcXC5cXGQrKSQvO1xuXG4vLyBBIGRlZmF1bHQgcmFuZ2UgZW5kIGFzIHR5cGVkLiBBbiBlbXB0eSBmaWVsZCBpcyBubyBlbmQuIEEgbnVtYmVyIGlucHV0XG4vLyB3aXRoIGEgbWFzayBoYW5kcyBiYWNrIHRleHQgd2l0aCBpdHMgZ3JvdXAgY29tbWFzICgnMSwyNTAuNScpLCBzbyB0aG9zZSBnb1xuLy8gYmVmb3JlIE51bWJlcigpIHJlYWRzIGl0OyAwIGlzIGFuIGVuZCBsaWtlIGFueSBvdGhlci4gQW55dGhpbmcgdGhhdCBpcyBub3Rcbi8vIGEgZGVjaW1hbCBudW1iZXIgaXMgbm8gZW5kLlxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlRGVmYXVsdEJvdW5kKHJhdzogdW5rbm93bik6IG51bWJlciB8IG51bGwge1xuICBpZiAodHlwZW9mIHJhdyA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKHJhdykgPyByYXcgOiBudWxsO1xuICB9XG5cbiAgaWYgKHR5cGVvZiByYXcgIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCB0cmltbWVkID0gcmF3LnRyaW0oKTtcbiAgY29uc3QgdGV4dCA9IEdST1VQRURfREVDSU1BTC50ZXN0KHRyaW1tZWQpID8gdHJpbW1lZC5yZXBsYWNlKC8sL2csICcnKSA6IHRyaW1tZWQ7XG4gIGlmICghUExBSU5fREVDSU1BTC50ZXN0KHRleHQpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCB2YWx1ZSA9IE51bWJlcih0ZXh0KTtcblxuICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKHZhbHVlKSA/IHZhbHVlIDogbnVsbDtcbn1cblxuLy8gV2h5IHR3byByYW5nZSBlbmRzIGNhbm5vdCBiZSBzYXZlZCwgaW4gdGhlIHNlcnZlcidzIHdvcmRzLCBvciBudWxsLiBBbiBvcGVuXG4vLyBlbmQgaXMgYWx3YXlzIGZpbmUuXG5leHBvcnQgZnVuY3Rpb24gYm91bmRzRXJyb3IobWluOiBudW1iZXIgfCBudWxsLCBtYXg6IG51bWJlciB8IG51bGwpOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKG1pbiA9PT0gbnVsbCB8fCBtYXggPT09IG51bGwgfHwgbWluIDw9IG1heCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIGBtaW4gKCR7bWlufSkgaXMgYWJvdmUgbWF4ICgke21heH0pLmA7XG59XG5cbi8vIFRoZSBUeXBlIHNlbGVjdCBvZiBhIGNvbHVtbiBvbiB0aGUgY29tcG9uZW50IHNldHRpbmdzJyBGaWx0ZXJzIHRhYi4gSXRcbi8vIHNob3dzIHdoZW4gdGhlIGNvbHVtbiBjYW4gdGFrZSBlaXRoZXIgdHlwZSBhbmQgdGhlIHNlcnZlciBzZXJ2ZXMgbnVtYmVyXG4vLyByYW5nZXMgKGFuIG9sZGVyIHNlcnZlciBsaXN0cyBubyBmZWF0dXJlcykuIEEgZmlsdGVyJ3MgdHlwZSBjYW5ub3QgY2hhbmdlLFxuLy8gc28gaXQgaXMgbG9ja2VkIHdoaWxlIHRoZSBjb2x1bW4gaGFzIGEgZmlsdGVyIG9uIHRoaXMgY29tcG9uZW50LlxuZXhwb3J0IGZ1bmN0aW9uIHR5cGVTZWxlY3RTdGF0ZShcbiAgdHlwZXM6IFJlcG9ydEZpbHRlclR5cGVbXSB8IG51bGwgfCB1bmRlZmluZWQsXG4gIGhhc0ZpbHRlck9uVGhpc0NvbXBvbmVudDogYm9vbGVhbixcbiAgZmVhdHVyZXM6IFJlcG9ydFZpZXdlckZlYXR1cmVbXSB8IG51bGwgfCB1bmRlZmluZWQsXG4pOiBGaWx0ZXJUeXBlU2VsZWN0U3RhdGUge1xuICBjb25zdCBzaG93ID0gKGZlYXR1cmVzID8/IFtdKS5pbmNsdWRlcygnbnVtYmVyUmFuZ2UnKVxuICAgICYmIEZJTFRFUl9UWVBFX09QVElPTlMuZXZlcnkoKG9wdGlvbikgPT4gKHR5cGVzID8/IFtdKS5pbmNsdWRlcyhvcHRpb24udmFsdWUpKTtcblxuICBpZiAoIXNob3cpIHtcbiAgICByZXR1cm4geyBzaG93OiBmYWxzZSwgZGlzYWJsZWQ6IGZhbHNlLCB0b29sdGlwOiBudWxsIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHNob3c6IHRydWUsXG4gICAgZGlzYWJsZWQ6IGhhc0ZpbHRlck9uVGhpc0NvbXBvbmVudCxcbiAgICB0b29sdGlwOiBoYXNGaWx0ZXJPblRoaXNDb21wb25lbnQgPyBUWVBFX0xPQ0tFRF9UT09MVElQIDogbnVsbCxcbiAgfTtcbn1cblxuLy8gVGhlIGxldmVscyBhIG5ldyBvciBtb3ZlZCBmaWx0ZXIgY2FuIHRha2Ugb24gYSBjb21wb25lbnQuIFRoaXMgcGFnZSBvbmx5XG4vLyBuZWVkcyBhIHNlcnZlciB0aGF0IHNlcnZlcyBwYWdlIGZpbHRlcnMgYW5kIGEgY29tcG9uZW50IG9uIGEgcGFnZSAoYVxuLy8gaGVhZGVyIG9yIGZvb3RlciBjb21wb25lbnQgaXMgb24gbm8gcGFnZSkuXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyTGV2ZWxDaG9pY2VzKFxuICBmZWF0dXJlczogUmVwb3J0Vmlld2VyRmVhdHVyZVtdIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgb25QYWdlOiBib29sZWFuLFxuKTogUmVwb3J0RmlsdGVyTGV2ZWxbXSB7XG4gIGNvbnN0IGxldmVsczogUmVwb3J0RmlsdGVyTGV2ZWxbXSA9IFsnY29tcG9uZW50JywgJ3JlcG9ydCcsICdib3RoJ107XG5cbiAgcmV0dXJuIG9uUGFnZSAmJiAoZmVhdHVyZXMgPz8gW10pLmluY2x1ZGVzKCdwYWdlU2NvcGUnKVxuICAgID8gWy4uLmxldmVscywgJ3BhZ2UnXVxuICAgIDogbGV2ZWxzO1xufVxuXG4vLyBUaGUgUmVwb3J0IGJhciBzZWxlY3QncyBjaG9pY2VzIGZvciB0aGUgbGV2ZWxzIG9uIG9mZmVyLiBUaGUgY2hvaWNlIGEgcm93XG4vLyBhbHJlYWR5IGhvbGRzIGlzIGFsd2F5cyBsaXN0ZWQsIHNvIHRoZSBzZWxlY3QgbmV2ZXIgc2hvd3MgYmxhbmsuXG5leHBvcnQgZnVuY3Rpb24gYmFyUGxhY2VtZW50T3B0aW9ucyhcbiAgbGV2ZWxDaG9pY2VzOiBSZXBvcnRGaWx0ZXJMZXZlbFtdLFxuICBjdXJyZW50OiBGaWx0ZXJCYXJQbGFjZW1lbnQgPSAnb2ZmJyxcbik6IEZpbHRlclNldHRpbmdzT3B0aW9uPEZpbHRlckJhclBsYWNlbWVudD5bXSB7XG4gIHJldHVybiBCQVJfUExBQ0VNRU5UX09QVElPTlMuZmlsdGVyKChvcHRpb24pID0+IHtcbiAgICBzd2l0Y2ggKG9wdGlvbi52YWx1ZSkge1xuICAgICAgY2FzZSAnZXZlcnknOlxuICAgICAgICByZXR1cm4gbGV2ZWxDaG9pY2VzLmluY2x1ZGVzKCdyZXBvcnQnKSB8fCBsZXZlbENob2ljZXMuaW5jbHVkZXMoJ2JvdGgnKSB8fCBjdXJyZW50ID09PSAnZXZlcnknO1xuICAgICAgY2FzZSAncGFnZSc6XG4gICAgICAgIHJldHVybiBsZXZlbENob2ljZXMuaW5jbHVkZXMoJ3BhZ2UnKSB8fCBjdXJyZW50ID09PSAncGFnZSc7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xufVxuXG4vLyBBIHZhbHVlJ3MgUmVwb3J0IGJhciBjaG9pY2VzLiBBIHZhbHVlIGhhcyBubyBzdHJpcCBvZiBpdHMgb3duIGFuZCBpdHNcbi8vIGdyb3VwIG1heSBiZSBzaGFyZWQsIHNvIGEgcGljayBuZXZlciBsb3dlcnMgdGhlIGdyb3VwICh0aGUgaW5saW5lIHZhbHVlc1xuLy8gcnVsZSk6IFRoaXMgcGFnZSBvbmx5IGlzIG9mZmVyZWQgZm9yIGEgbmV3IGZpbHRlciwgb3IgZm9yIGEgZ3JvdXAgdGhhdCBpc1xuLy8gYWxyZWFkeSBhIHBhZ2UgZ3JvdXAsIG5ldmVyIHRvIG1vdmUgYSBzaGFyZWQgZ3JvdXAgdG8gb25lIHBhZ2UuXG5leHBvcnQgZnVuY3Rpb24gdmFsdWVQbGFjZW1lbnRPcHRpb25zKFxuICBsZXZlbENob2ljZXM6IFJlcG9ydEZpbHRlckxldmVsW10sXG4gIGN1cnJlbnQ6IFJlcG9ydEZpbHRlckxldmVsIHwgbnVsbCB8IHVuZGVmaW5lZCxcbik6IEZpbHRlclNldHRpbmdzT3B0aW9uPEZpbHRlckJhclBsYWNlbWVudD5bXSB7XG4gIGNvbnN0IGNob2ljZXMgPSAhY3VycmVudCB8fCBjdXJyZW50ID09PSAncGFnZSdcbiAgICA/IGxldmVsQ2hvaWNlc1xuICAgIDogbGV2ZWxDaG9pY2VzLmZpbHRlcigobGV2ZWwpID0+IGxldmVsICE9PSAncGFnZScpO1xuXG4gIHJldHVybiBiYXJQbGFjZW1lbnRPcHRpb25zKGNob2ljZXMsIGJhclBsYWNlbWVudChjdXJyZW50KSk7XG59XG5cbi8vIFRoZSBsZXZlbCBhIHZhbHVlJ3MgZmlsdGVyIGdyb3VwIGVuZHMgYXQgYWZ0ZXIgYSBSZXBvcnQgYmFyIHBpY2ssIG9yIG51bGxcbi8vIHdoZW4gdGhlIHZhbHVlIGxlYXZlcyBpdC4gT2ZmIHVubGlua3MgdGhpcyB2YWx1ZSBhbG9uZSBhbmQgdGhlIGdyb3VwIGtlZXBzXG4vLyBpdHMgb3RoZXIgbWVtYmVycy4gQSBuZXcgZmlsdGVyIHRha2VzIHRoZSBwaWNrJ3MgbGV2ZWwuIEV2ZXJ5IHBhZ2UgcmFpc2VzIGFcbi8vIHN0cmlwLW9ubHkgZ3JvdXAgdG8gYm90aCwga2VlcGluZyBpdHMgc3RyaXBzLCBhbmQgYSBwYWdlIGdyb3VwIHRvIHRoZVxuLy8gcmVwb3J0IGJhci4gTm90aGluZyBlbHNlIG1vdmVzIHRoZSBncm91cCwgc28gYSB2YWx1ZSBuZXZlciBsb3dlcnMgaXQuXG5leHBvcnQgZnVuY3Rpb24gdmFsdWVGaWx0ZXJMZXZlbChcbiAgcGxhY2VtZW50OiBGaWx0ZXJCYXJQbGFjZW1lbnQsXG4gIGN1cnJlbnQ6IFJlcG9ydEZpbHRlckxldmVsIHwgbnVsbCB8IHVuZGVmaW5lZCxcbik6IFJlcG9ydEZpbHRlckxldmVsIHwgbnVsbCB7XG4gIGlmIChwbGFjZW1lbnQgPT09ICdvZmYnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoIWN1cnJlbnQpIHtcbiAgICByZXR1cm4gcGxhY2VtZW50ID09PSAncGFnZScgPyAncGFnZScgOiAncmVwb3J0JztcbiAgfVxuXG4gIGlmIChwbGFjZW1lbnQgIT09ICdldmVyeScpIHtcbiAgICByZXR1cm4gY3VycmVudDtcbiAgfVxuXG4gIHN3aXRjaCAoY3VycmVudCkge1xuICAgIGNhc2UgJ2NvbXBvbmVudCc6XG4gICAgICByZXR1cm4gJ2JvdGgnO1xuICAgIGNhc2UgJ3BhZ2UnOlxuICAgICAgcmV0dXJuICdyZXBvcnQnO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gY3VycmVudDtcbiAgfVxufVxuXG4vLyBXaGVyZSBhIGdyb3VwIG9mIGEgbGV2ZWwgc2hvd3MgaW4gdGhlIHJlcG9ydCBiYXIuIE5vIGdyb3VwIChubyBmaWx0ZXIpIGlzXG4vLyBvZmYuXG5leHBvcnQgZnVuY3Rpb24gYmFyUGxhY2VtZW50KGxldmVsOiBSZXBvcnRGaWx0ZXJMZXZlbCB8IG51bGwgfCB1bmRlZmluZWQpOiBGaWx0ZXJCYXJQbGFjZW1lbnQge1xuICBzd2l0Y2ggKGxldmVsKSB7XG4gICAgY2FzZSAncmVwb3J0JzpcbiAgICBjYXNlICdib3RoJzpcbiAgICAgIHJldHVybiAnZXZlcnknO1xuICAgIGNhc2UgJ3BhZ2UnOlxuICAgICAgcmV0dXJuICdwYWdlJztcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuICdvZmYnO1xuICB9XG59XG5cbi8vIFdoZXRoZXIgYSBncm91cCBvZiBhIGxldmVsIHNob3dzIG9uIGl0cyBjb21wb25lbnRzLlxuZXhwb3J0IGZ1bmN0aW9uIHNob3duT25Db21wb25lbnQobGV2ZWw6IFJlcG9ydEZpbHRlckxldmVsIHwgbnVsbCB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICByZXR1cm4gbGV2ZWwgPT09ICdjb21wb25lbnQnIHx8IGxldmVsID09PSAnYm90aCc7XG59XG5cbi8vIFRoZSBsZXZlbCB0aGUgdHdvIGNvbnRyb2xzIG9mIGEgcm93IGFzayBmb3IsIG9yIG51bGwgd2hlbiB0aGV5IGFzayBmb3Igbm9cbi8vIGZpbHRlciBhdCBhbGwuIEEgcGFnZSBmaWx0ZXIgc2hvd3MgaW4gaXRzIHBhZ2UncyBiYXIgb25seSwgc28gVGhpcyBwYWdlXG4vLyBvbmx5IGlnbm9yZXMgdGhlIFRoaXMgY29tcG9uZW50IHRvZ2dsZS5cbmV4cG9ydCBmdW5jdGlvbiBmaWx0ZXJMZXZlbChwbGFjZW1lbnQ6IEZpbHRlckJhclBsYWNlbWVudCwgY29tcG9uZW50OiBib29sZWFuKTogUmVwb3J0RmlsdGVyTGV2ZWwgfCBudWxsIHtcbiAgc3dpdGNoIChwbGFjZW1lbnQpIHtcbiAgICBjYXNlICdwYWdlJzpcbiAgICAgIHJldHVybiAncGFnZSc7XG4gICAgY2FzZSAnZXZlcnknOlxuICAgICAgcmV0dXJuIGNvbXBvbmVudCA/ICdib3RoJyA6ICdyZXBvcnQnO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gY29tcG9uZW50ID8gJ2NvbXBvbmVudCcgOiBudWxsO1xuICB9XG59XG5cbi8vIFRoZSBUaGlzIGNvbXBvbmVudCB0b2dnbGUgb2YgYSByb3c6IGxvY2tlZCB3aGlsZSBUaGlzIHBhZ2Ugb25seSBpcyBwaWNrZWQuXG5leHBvcnQgZnVuY3Rpb24gY29tcG9uZW50VG9nZ2xlU3RhdGUocGxhY2VtZW50OiBGaWx0ZXJCYXJQbGFjZW1lbnQpOiBGaWx0ZXJDb21wb25lbnRUb2dnbGVTdGF0ZSB7XG4gIHJldHVybiBwbGFjZW1lbnQgPT09ICdwYWdlJ1xuICAgID8geyBkaXNhYmxlZDogdHJ1ZSwgdG9vbHRpcDogUEFHRV9GSUxURVJfVE9PTFRJUCB9XG4gICAgOiB7IGRpc2FibGVkOiBmYWxzZSwgdG9vbHRpcDogQ09NUE9ORU5UX1RPR0dMRV9UT09MVElQIH07XG59XG5cbi8vIFRoZSBncm91cHMgdGhlIHJlcG9ydCBzZXR0aW5ncycgRmlsdGVycyB0YWIgbGlzdHMgZGVmYXVsdHMgZm9yOiB0aG9zZSBvZlxuLy8gdGhlIHJlcG9ydCBiYXIsIGV2ZXJ5IHBhZ2Ugb3Igb25lLCBpbiBiYXIgb3JkZXIuXG5leHBvcnQgZnVuY3Rpb24gZGVmYXVsdFJvd0dyb3Vwcyhncm91cHM6IFJlcG9ydEZpbHRlckdyb3VwW10gfCBudWxsIHwgdW5kZWZpbmVkKTogUmVwb3J0RmlsdGVyR3JvdXBbXSB7XG4gIHJldHVybiAoZ3JvdXBzID8/IFtdKVxuICAgIC5maWx0ZXIoKGdyb3VwKSA9PiBncm91cC5sZXZlbCA9PT0gJ3JlcG9ydCcgfHwgZ3JvdXAubGV2ZWwgPT09ICdib3RoJyB8fCBncm91cC5sZXZlbCA9PT0gJ3BhZ2UnKVxuICAgIC5zb3J0KChhLCBiKSA9PiBhLm9yZGVyIC0gYi5vcmRlcik7XG59XG5cbi8vIEEgZGVmYXVsdCByb3cncyBsYWJlbDogYSBwYWdlIGdyb3VwIG5hbWVzIGl0cyBwYWdlLCAnUmVnaW9uIChwYWdlXG4vLyBcIk92ZXJ2aWV3XCIpJy4gQSBwYWdlIHdpdGggbm8gbmFtZSByZWFkcyBhcyB0aGUgY2FudmFzIG5hbWVzIGl0ICgnUGFnZSAyJykuXG4vLyBBIHBhZ2UgdGhpcyByZXBvcnQgbm8gbG9uZ2VyIGhvbGRzIGFkZHMgbm90aGluZy5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0Um93TGFiZWwoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwLCBwYWdlczogUmVwb3J0UGFnZVtdIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gIGNvbnN0IGxhYmVsID0gZ3JvdXAubGFiZWwgfHwgZ3JvdXAuZmlsdGVycz8uWzBdPy5maWx0ZXJDb2x1bW4gfHwgJ0ZpbHRlcic7XG5cbiAgaWYgKGdyb3VwLmxldmVsICE9PSAncGFnZScpIHtcbiAgICByZXR1cm4gbGFiZWw7XG4gIH1cblxuICBjb25zdCBpbmRleCA9IChwYWdlcyA/PyBbXSkuZmluZEluZGV4KChwYWdlKSA9PiBwYWdlLmlkID09PSBncm91cC5wYWdlSWQpO1xuICBpZiAoaW5kZXggPCAwKSB7XG4gICAgcmV0dXJuIGxhYmVsO1xuICB9XG5cbiAgcmV0dXJuIGAke2xhYmVsfSAocGFnZSBcIiR7cGFnZXNbaW5kZXhdLm5hbWUgfHwgYFBhZ2UgJHtpbmRleCArIDF9YH1cIilgO1xufVxuXG4vLyBUaGUgRGVmYXVsdCBwZXJpb2Qgc2VsZWN0J3MgY2hvaWNlczogRml4ZWQgZGF0ZXMsIHRoZW4gZXZlcnkgcmVsYXRpdmVcbi8vIHJhbmdlIGluIHRoZSBzZXJ2ZXIgZW51bSdzIG9yZGVyLCBuYW1lZCBieSBgbGFiZWxzYC4gQSBzdG9yZWQgcmFuZ2UgdGhpc1xuLy8gdmlld2VyIGRvZXMgbm90IGtub3cgaXMgbGlzdGVkIGxhc3QsIHNvIHRoZSBzZWxlY3Qgc3RpbGwgc2hvd3MgaXQuXG5leHBvcnQgZnVuY3Rpb24gZGVmYXVsdFBlcmlvZE9wdGlvbnMoXG4gIGxhYmVsczogKHJlbGF0aXZlOiBSZXBvcnRSZWxhdGl2ZVJhbmdlKSA9PiBzdHJpbmcsXG4gIHN0b3JlZDogc3RyaW5nIHwgbnVsbCA9IG51bGwsXG4pOiBGaWx0ZXJTZXR0aW5nc09wdGlvbltdIHtcbiAgY29uc3Qgb3B0aW9uczogRmlsdGVyU2V0dGluZ3NPcHRpb25bXSA9IFtcbiAgICB7IHZhbHVlOiBGSVhFRF9EQVRFU19QRVJJT0QsIG5hbWU6ICdGaXhlZCBkYXRlcycgfSxcbiAgICAuLi5SRUxBVElWRV9SQU5HRV9OQU1FUy5tYXAoKHJlbGF0aXZlKSA9PiAoeyB2YWx1ZTogcmVsYXRpdmUsIG5hbWU6IGxhYmVscyhyZWxhdGl2ZSkgfSkpLFxuICBdO1xuXG4gIHJldHVybiBzdG9yZWQgJiYgc3RvcmVkICE9PSBGSVhFRF9EQVRFU19QRVJJT0QgJiYgIWlzUmVsYXRpdmVSYW5nZShzdG9yZWQpXG4gICAgPyBbLi4ub3B0aW9ucywgeyB2YWx1ZTogc3RvcmVkLCBuYW1lOiBsYWJlbHMoc3RvcmVkIGFzIFJlcG9ydFJlbGF0aXZlUmFuZ2UpIH1dXG4gICAgOiBvcHRpb25zO1xufVxuXG4vLyBUaGUgRGVmYXVsdCBwZXJpb2QgYSBzdG9yZWQgZGF0ZSByYW5nZSBkZWZhdWx0IG9wZW5zIG9uOiBpdHMgcmVsYXRpdmVcbi8vIHJhbmdlLCBlbHNlIEZpeGVkIGRhdGVzICh0aGUgZGF5cywgb3Igbm9uZSkuXG5leHBvcnQgZnVuY3Rpb24gZGVmYXVsdFBlcmlvZChzdG9yZWQ6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICByZXR1cm4gc3RvcmVkPy5yZWxhdGl2ZSAmJiAhc3RvcmVkLnN0YXJ0ICYmICFzdG9yZWQuZW5kXG4gICAgPyBzdG9yZWQucmVsYXRpdmVcbiAgICA6IEZJWEVEX0RBVEVTX1BFUklPRDtcbn1cblxuLy8gQSBkYXRlIHJhbmdlIGRlZmF1bHQgaW4gaXRzIHN0b3JlZCBzaGFwZTogdGhlIHJlbGF0aXZlIHJhbmdlIHBpY2tlZCwgZWxzZVxuLy8gdGhlIGZpeGVkIGRheXMsIG9yIG51bGwgd2hlbiB0aGVyZSBhcmUgbm9uZS4gTmV2ZXIgYm90aDogdGhlIHNlcnZlclxuLy8gcmVmdXNlcyBhIHJlbGF0aXZlIHJhbmdlIHdpdGggZGF5cy5cbmV4cG9ydCBmdW5jdGlvbiBkYXRlUmFuZ2VEZWZhdWx0KFxuICBwZXJpb2Q6IHN0cmluZyxcbiAgc3RhcnQ6IHN0cmluZyB8IG51bGwsXG4gIGVuZDogc3RyaW5nIHwgbnVsbCxcbik6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwge1xuICBpZiAocGVyaW9kICE9PSBGSVhFRF9EQVRFU19QRVJJT0QpIHtcbiAgICByZXR1cm4geyByZWxhdGl2ZTogcGVyaW9kIH07XG4gIH1cblxuICBpZiAoIXN0YXJ0ICYmICFlbmQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB7IC4uLihzdGFydCA/IHsgc3RhcnQgfSA6IHt9KSwgLi4uKGVuZCA/IHsgZW5kIH0gOiB7fSkgfTtcbn1cblxuLy8gQSBzZWxlY3QgZGVmYXVsdCBpbiBpdHMgc3RvcmVkIHNoYXBlOiB0aGUgcGlja3Mga2VwdCwgb3IgbGVmdCBvdXQgd2hpbGVcbi8vIEV4Y2x1ZGUgdGhlc2UgdmFsdWVzIGlzIG9uLCBvciBudWxsIHdoZW4gbm90aGluZyBpcyBwaWNrZWQuXG5leHBvcnQgZnVuY3Rpb24gc2VsZWN0RGVmYXVsdCh2YWx1ZXM6IHVua25vd25bXSwgZXhjbHVkZTogYm9vbGVhbik6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwge1xuICBpZiAoIXZhbHVlcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBleGNsdWRlID8geyBleGNsdWRlVmFsdWVzOiB2YWx1ZXMgfSA6IHsgdmFsdWVzIH07XG59XG5cbi8vIEEgbnVtYmVyIHJhbmdlIGRlZmF1bHQgaW4gaXRzIHN0b3JlZCBzaGFwZSBmcm9tIHRoZSBlbmRzIGFzIHR5cGVkOiBhblxuLy8gb3BlbiBlbmQgaXMgbGVmdCBvdXQsIDAgaXMga2VwdCwgYW5kIHR3byBvcGVuIGVuZHMgYXJlIG5vIGRlZmF1bHQuXG5leHBvcnQgZnVuY3Rpb24gbnVtYmVyUmFuZ2VEZWZhdWx0KHJhd01pbjogdW5rbm93biwgcmF3TWF4OiB1bmtub3duKTogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCB7XG4gIGNvbnN0IG1pbiA9IHBhcnNlRGVmYXVsdEJvdW5kKHJhd01pbik7XG4gIGNvbnN0IG1heCA9IHBhcnNlRGVmYXVsdEJvdW5kKHJhd01heCk7XG5cbiAgaWYgKG1pbiA9PT0gbnVsbCAmJiBtYXggPT09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB7IC4uLihtaW4gIT09IG51bGwgPyB7IG1pbiB9IDoge30pLCAuLi4obWF4ICE9PSBudWxsID8geyBtYXggfSA6IHt9KSB9O1xufVxuXG4vLyBXaGV0aGVyIGEgc2VsZWN0IGdyb3VwJ3MgZGVmYXVsdCByb3cgb2ZmZXJzIEV4Y2x1ZGUgdGhlc2UgdmFsdWVzOiB0aGVcbi8vIHJlcG9ydCBiYXIncyBydWxlIChvZmZlcnNFeGNsdWRlKSwgc28gbm90IG9uIGEgc2VydmVyIHRoYXQgZG9lcyBub3Qgc2VydmVcbi8vIGV4Y2x1ZGUgKGFuIG9sZGVyIHNlcnZlciBsaXN0cyBubyBmZWF0dXJlcykgbm9yIG9uIGEgZ3JvdXAgd2l0aCBhIG1lbWJlclxuLy8gdGhhdCBiaW5kcyBzZXZlcmFsIGNvbHVtbnMgKG11bHRpQ29sdW1uKS4gQSBkZWZhdWx0IHRoYXQgYWxyZWFkeSBsZWF2ZXNcbi8vIHZhbHVlcyBvdXQga2VlcHMgdGhlIHRvZ2dsZSwgc28gaXQgY2FuIGJlIHR1cm5lZCBvZmYuXG5leHBvcnQgZnVuY3Rpb24gc2hvd0V4Y2x1ZGVUb2dnbGUoXG4gIGdyb3VwOiBSZXBvcnRGaWx0ZXJHcm91cCxcbiAgZmVhdHVyZXM6IFJlcG9ydFZpZXdlckZlYXR1cmVbXSB8IG51bGwgfCB1bmRlZmluZWQsXG4pOiBib29sZWFuIHtcbiAgaWYgKGdyb3VwLnR5cGUgPT09ICdzZWxlY3QnICYmIGdyb3VwLmNvbmZpZz8uZGVmYXVsdD8uZXhjbHVkZVZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gb2ZmZXJzRXhjbHVkZShncm91cCwgZmVhdHVyZXMpO1xufVxuXG4vLyBBIHN0b3JlZCBvciBkcmFmdCBkZWZhdWx0IGluIGEgc3RhYmxlIGZvcm0gZm9yIGNvbXBhcmluZzogZW1wdHkgYW5kXG4vLyBhYnNlbnQga2V5cyBhcmUgZHJvcHBlZCwgc28gYSBuby1vcCBlZGl0IGRvZXMgbm90IHJlYWQgYXMgYSBjaGFuZ2UuIDAgaXMgYW5cbi8vIGVuZCBsaWtlIGFueSBvdGhlci4gTm90aGluZyBsZWZ0IGlzIG51bGwuXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplRGVmYXVsdCh2YWx1ZTogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCB8IHVuZGVmaW5lZCk6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwge1xuICBpZiAoIXZhbHVlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBub3JtYWxpemVkOiBGaWx0ZXJHcm91cERlZmF1bHQgPSB7fTtcbiAgaWYgKHZhbHVlLnN0YXJ0KSB7XG4gICAgbm9ybWFsaXplZC5zdGFydCA9IHZhbHVlLnN0YXJ0O1xuICB9XG4gIGlmICh2YWx1ZS5lbmQpIHtcbiAgICBub3JtYWxpemVkLmVuZCA9IHZhbHVlLmVuZDtcbiAgfVxuICBpZiAodmFsdWUudmFsdWVzPy5sZW5ndGgpIHtcbiAgICBub3JtYWxpemVkLnZhbHVlcyA9IHZhbHVlLnZhbHVlcztcbiAgfVxuICBpZiAodmFsdWUuZXhjbHVkZVZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgbm9ybWFsaXplZC5leGNsdWRlVmFsdWVzID0gdmFsdWUuZXhjbHVkZVZhbHVlcztcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlLm1pbiA9PT0gJ251bWJlcicpIHtcbiAgICBub3JtYWxpemVkLm1pbiA9IHZhbHVlLm1pbjtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlLm1heCA9PT0gJ251bWJlcicpIHtcbiAgICBub3JtYWxpemVkLm1heCA9IHZhbHVlLm1heDtcbiAgfVxuICBpZiAodmFsdWUudmFsdWUpIHtcbiAgICBub3JtYWxpemVkLnZhbHVlID0gdmFsdWUudmFsdWU7XG4gIH1cbiAgaWYgKHZhbHVlLnJlbGF0aXZlKSB7XG4gICAgbm9ybWFsaXplZC5yZWxhdGl2ZSA9IHZhbHVlLnJlbGF0aXZlO1xuICB9XG5cbiAgcmV0dXJuIE9iamVjdC5rZXlzKG5vcm1hbGl6ZWQpLmxlbmd0aCA/IG5vcm1hbGl6ZWQgOiBudWxsO1xufVxuXG4vLyBXaGV0aGVyIGEgcm93J3MgZHJhZnQgZGVmYXVsdCBkaWZmZXJzIGZyb20gdGhlIGdyb3VwJ3Mgc3RvcmVkIG9uZS4gT25seSBhXG4vLyBjaGFuZ2VkIHJvdyBpcyBzYXZlZC5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0Q2hhbmdlZChcbiAgc3RvcmVkOiBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsIHwgdW5kZWZpbmVkLFxuICBkcmFmdDogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCB8IHVuZGVmaW5lZCxcbik6IGJvb2xlYW4ge1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkobm9ybWFsaXplRGVmYXVsdChzdG9yZWQpKSAhPT0gSlNPTi5zdHJpbmdpZnkobm9ybWFsaXplRGVmYXVsdChkcmFmdCkpO1xufVxuIl19
|