@firestitch/report 18.8.1 → 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/component-text/component-text.component.d.ts +47 -2
- package/app/reports/components/component-text/value-embed.plugin.d.ts +67 -0
- package/app/reports/components/report-canvas/report-canvas.component.d.ts +37 -9
- package/app/reports/components/report-component/report-component.component.d.ts +45 -2
- package/app/reports/components/report-view-picker/report-view-picker.component.d.ts +21 -0
- package/app/reports/data/report.data.d.ts +18 -2
- package/app/reports/dialogs/component-settings/component-settings.component.d.ts +25 -2
- 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/enums/report-value-formula.enum.d.ts +6 -0
- package/app/reports/export/report-export-collector.service.d.ts +35 -4
- package/app/reports/export/report-export.service.d.ts +3 -1
- package/app/reports/export/report-filter-lines.d.ts +18 -0
- package/app/reports/export/report-pdf.service.d.ts +18 -2
- package/app/reports/export/report-pptx.service.d.ts +15 -2
- package/app/reports/export/report-text-layout.service.d.ts +35 -0
- package/app/reports/filter-settings-rules.d.ts +33 -0
- package/app/reports/format.d.ts +2 -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 +48 -5
- package/app/reports/interfaces/tile-load-result.interface.d.ts +4 -0
- package/app/reports/layout.d.ts +2 -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 +65 -2
- package/app/reports/services/report-view.service.d.ts +51 -0
- package/app/reports/text.d.ts +50 -0
- package/app/reports/tile-data-state.d.ts +7 -0
- package/app/reports/tile-loads.d.ts +4 -0
- package/app/reports/values.d.ts +17 -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/component-text/component-text.component.mjs +213 -16
- package/esm2022/app/reports/components/component-text/value-embed.plugin.mjs +484 -0
- package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +296 -55
- package/esm2022/app/reports/components/report-component/report-component.component.mjs +318 -76
- package/esm2022/app/reports/components/report-view-picker/report-view-picker.component.mjs +115 -0
- package/esm2022/app/reports/data/report.data.mjs +103 -8
- package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +210 -44
- 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/enums/report-value-formula.enum.mjs +14 -0
- package/esm2022/app/reports/export/report-export-collector.service.mjs +299 -125
- package/esm2022/app/reports/export/report-export.service.mjs +57 -19
- package/esm2022/app/reports/export/report-filter-lines.mjs +235 -0
- package/esm2022/app/reports/export/report-pdf.service.mjs +315 -71
- package/esm2022/app/reports/export/report-pptx.service.mjs +293 -71
- package/esm2022/app/reports/export/report-text-layout.service.mjs +241 -0
- package/esm2022/app/reports/filter-settings-rules.mjs +283 -0
- package/esm2022/app/reports/format.mjs +13 -30
- 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/layout.mjs +11 -1
- 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 +715 -71
- package/esm2022/app/reports/services/report-view.service.mjs +358 -0
- package/esm2022/app/reports/text.mjs +293 -85
- package/esm2022/app/reports/tile-data-state.mjs +127 -0
- package/esm2022/app/reports/tile-loads.mjs +38 -0
- package/esm2022/app/reports/values.mjs +183 -0
- package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +180 -46
- package/esm2022/app/reports/views/report/report.component.mjs +106 -23
- package/esm2022/public_api.mjs +24 -1
- package/fesm2022/{firestitch-report-echarts-CFnbJx44.mjs → firestitch-report-echarts-UBg8Wlhd.mjs} +2 -2
- package/fesm2022/{firestitch-report-echarts-CFnbJx44.mjs.map → firestitch-report-echarts-UBg8Wlhd.mjs.map} +1 -1
- package/fesm2022/{firestitch-report-firestitch-report-CSylkyko.mjs → firestitch-report-firestitch-report-B1keNrcK.mjs} +11315 -4201
- 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 +23 -0
- package/fesm2022/firestitch-report-firestitch-report-CSylkyko.mjs.map +0 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
export const VIEWS_LABEL = 'Views';
|
|
2
|
+
export const EDITED_TOOLTIP = 'The screen differs from this view';
|
|
3
|
+
export const SAVE_AS_TITLE = 'Save as new view';
|
|
4
|
+
export const RENAME_TITLE = 'Rename view';
|
|
5
|
+
export const CROSS_FILTER_NOTE = 'Cross-filters are temporary and are not saved.';
|
|
6
|
+
export const VIEW_NAME_BLANK = 'Enter a name';
|
|
7
|
+
// The server's limit on a view's name.
|
|
8
|
+
export const VIEW_NAME_MAX_LENGTH = 100;
|
|
9
|
+
// The menu for the open view (null when none is open), the views the viewer
|
|
10
|
+
// may see, whether the screen differs from the open view, and whether the
|
|
11
|
+
// viewer may share its views.
|
|
12
|
+
export function viewMenuItems(open, views, edited, canShare) {
|
|
13
|
+
const rows = [
|
|
14
|
+
...views.filter((view) => view.mine),
|
|
15
|
+
...views.filter((view) => !view.mine),
|
|
16
|
+
].map((view) => viewRow(view, open, edited));
|
|
17
|
+
const actions = openViewActions(open, edited, canShare);
|
|
18
|
+
const resets = [
|
|
19
|
+
...(open && edited ? [action('resetToView', `Reset to "${open.name}"`)] : []),
|
|
20
|
+
action('resetToDefaults', 'Reset to report defaults'),
|
|
21
|
+
];
|
|
22
|
+
return [
|
|
23
|
+
...rows,
|
|
24
|
+
...withDivider(actions, rows.length > 0),
|
|
25
|
+
...withDivider(resets, true),
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
// The picker's label: 'Views', or the open view's name, marked while the
|
|
29
|
+
// screen differs from it.
|
|
30
|
+
export function pickerLabel(open, edited) {
|
|
31
|
+
if (!open) {
|
|
32
|
+
return VIEWS_LABEL;
|
|
33
|
+
}
|
|
34
|
+
return edited ? `${open.name} (edited)` : open.name;
|
|
35
|
+
}
|
|
36
|
+
// The picker's tooltip: only while the screen differs from the open view.
|
|
37
|
+
export function pickerTooltip(open, edited) {
|
|
38
|
+
return open && edited ? EDITED_TOOLTIP : null;
|
|
39
|
+
}
|
|
40
|
+
// The question before a view is deleted. A shared view says that everyone
|
|
41
|
+
// loses it.
|
|
42
|
+
export function deletePromptText(view) {
|
|
43
|
+
const question = `Delete the view "${view.name}"?`;
|
|
44
|
+
return view.shared ? `${question} Everyone it is shared with loses it.` : question;
|
|
45
|
+
}
|
|
46
|
+
// The line the save dialog shows under the name, or null: a cross-filter is
|
|
47
|
+
// on, and it does not go into the view.
|
|
48
|
+
export function saveDialogNote(hasCrossFilter) {
|
|
49
|
+
return hasCrossFilter ? CROSS_FILTER_NOTE : null;
|
|
50
|
+
}
|
|
51
|
+
// A name made of spaces only is no name; the server trims it.
|
|
52
|
+
export function viewNameError(name) {
|
|
53
|
+
return (name ?? '').trim() ? null : VIEW_NAME_BLANK;
|
|
54
|
+
}
|
|
55
|
+
function viewRow(view, open, edited) {
|
|
56
|
+
const isOpen = view.id === open?.id;
|
|
57
|
+
return {
|
|
58
|
+
kind: 'view',
|
|
59
|
+
label: view.name,
|
|
60
|
+
disabled: isOpen && !edited,
|
|
61
|
+
tooltip: viewTooltip(view),
|
|
62
|
+
divider: false,
|
|
63
|
+
viewId: view.id,
|
|
64
|
+
open: isOpen,
|
|
65
|
+
icon: viewIcon(view),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// Who shared a view of someone else's; whether one of the viewer's own opens
|
|
69
|
+
// by default or is shared.
|
|
70
|
+
function viewTooltip(view) {
|
|
71
|
+
if (!view.mine) {
|
|
72
|
+
return view.ownerName ? `Shared by ${view.ownerName}` : 'Shared with everyone';
|
|
73
|
+
}
|
|
74
|
+
if (view.personalDefault && view.shared) {
|
|
75
|
+
return 'Opens by default, shared with everyone';
|
|
76
|
+
}
|
|
77
|
+
if (view.personalDefault) {
|
|
78
|
+
return 'Opens by default';
|
|
79
|
+
}
|
|
80
|
+
return view.shared ? 'Shared with everyone' : null;
|
|
81
|
+
}
|
|
82
|
+
// The open row keeps this icon too; its check is drawn beside it.
|
|
83
|
+
function viewIcon(view) {
|
|
84
|
+
if (!view.mine) {
|
|
85
|
+
return 'people';
|
|
86
|
+
}
|
|
87
|
+
return view.personalDefault ? 'star' : null;
|
|
88
|
+
}
|
|
89
|
+
// The rows that act on the open view; with none open, only Save as new view.
|
|
90
|
+
function openViewActions(open, edited, canShare) {
|
|
91
|
+
const items = [];
|
|
92
|
+
if (open?.canChange && edited) {
|
|
93
|
+
items.push(action('saveChanges', 'Save changes'));
|
|
94
|
+
}
|
|
95
|
+
items.push(action('saveAsNew', 'Save as new view...'));
|
|
96
|
+
if (open?.canChange) {
|
|
97
|
+
items.push(action('rename', 'Rename...'));
|
|
98
|
+
}
|
|
99
|
+
if (open?.mine) {
|
|
100
|
+
items.push(open.personalDefault
|
|
101
|
+
? action('clearDefault', 'Stop opening it by default')
|
|
102
|
+
: action('setDefault', 'Make it my default'));
|
|
103
|
+
}
|
|
104
|
+
if (open?.mine && canShare) {
|
|
105
|
+
items.push(open.shared ? action('unshare', 'Stop sharing') : action('share', 'Share with everyone'));
|
|
106
|
+
}
|
|
107
|
+
if (open?.canDelete) {
|
|
108
|
+
items.push(action('delete', 'Delete...'));
|
|
109
|
+
}
|
|
110
|
+
return items;
|
|
111
|
+
}
|
|
112
|
+
function action(kind, label) {
|
|
113
|
+
return { kind, label, disabled: false, tooltip: null, divider: false, viewId: null, open: false, icon: null };
|
|
114
|
+
}
|
|
115
|
+
// The same rows, the first with a line above it when `divider` is set.
|
|
116
|
+
function withDivider(items, divider) {
|
|
117
|
+
return items.map((item, index) => (index === 0 && divider ? { ...item, divider: true } : item));
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LXZpZXctbWVudS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9yZXBvcnQtdmlldy1tZW51LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQW9CQSxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDO0FBQ25DLE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxtQ0FBbUMsQ0FBQztBQUNsRSxNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsa0JBQWtCLENBQUM7QUFDaEQsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLGFBQWEsQ0FBQztBQUMxQyxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxnREFBZ0QsQ0FBQztBQUNsRixNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsY0FBYyxDQUFDO0FBRTlDLHVDQUF1QztBQUN2QyxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxHQUFHLENBQUM7QUFHeEMsNEVBQTRFO0FBQzVFLDBFQUEwRTtBQUMxRSw4QkFBOEI7QUFDOUIsTUFBTSxVQUFVLGFBQWEsQ0FDM0IsSUFBOEIsRUFDOUIsS0FBbUMsRUFDbkMsTUFBZSxFQUNmLFFBQWlCO0lBRWpCLE1BQU0sSUFBSSxHQUFHO1FBQ1gsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQ3BDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO0tBQ3RDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sT0FBTyxHQUFHLGVBQWUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lB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Ly8gV2hhdCB0aGUgVmlld3MgcGlja2VyIHNob3dzOiBpdHMgbGFiZWwsIGl0cyBtZW51IGFuZCB0aGUgd29yZHMgb2YgaXRzXG4vLyBwcm9tcHRzLiBQdXJlLCBzbyB0aGUgbm9kZSBoYXJuZXNzIHJ1bnMgZXZlcnkgY2FzZTsgdGhlIHBpY2tlclxuLy8gKFJlcG9ydFZpZXdQaWNrZXJDb21wb25lbnQpIG9ubHkgZHJhd3MgdGhlIHJvd3MgYW5kIHJ1bnMgdGhlIG9uZSBjbGlja2VkLlxuLy9cbi8vIFRoZSBtZW51LCB0b3AgdG8gYm90dG9tOlxuLy8gLSBUaGUgdmlld2VyJ3Mgb3duIHZpZXdzLCB0aGVuIHRoZSB2aWV3cyBvdGhlcnMgc2hhcmUgKGEgcGVvcGxlIGljb24gYW5kXG4vLyAgICdTaGFyZWQgYnkgPG5hbWU+JykuIFRoZSBvcGVuIHZpZXcgaGFzIGEgY2hlY2sgYmVzaWRlIGl0cyBvd24gaWNvbiBhbmRcbi8vICAgY2Fubm90IGJlIHBpY2tlZCBhZ2FpbiB3aGlsZSB0aGUgc2NyZWVuIHN0aWxsIHNob3dzIGl0OyB0aGUgdmlld2VyJ3Ncbi8vICAgZGVmYXVsdCBoYXMgYSBzdGFyLlxuLy8gLSBUaGUgYWN0aW9ucyBvbiB0aGUgb3BlbiB2aWV3LiBTYXZlIGNoYW5nZXMgb25seSB3aGlsZSB0aGUgc2NyZWVuXG4vLyAgIGRpZmZlcnMgZnJvbSBhIHZpZXcgdGhlIHZpZXdlciBtYXkgY2hhbmdlOyBSZW5hbWUgb25seSBvbiBhIHZpZXcgdGhlXG4vLyAgIHZpZXdlciBtYXkgY2hhbmdlOyB0aGUgZGVmYXVsdCBhbmQgc2hhcmluZyByb3dzIG9ubHkgb24gdGhlIHZpZXdlcidzXG4vLyAgIG93biB2aWV3LCBhbmQgc2hhcmluZyBvbmx5IHdoZW4gdGhlIHZpZXdlciBtYXkgc2hhcmU7IERlbGV0ZSBvbmx5IG9uIGFcbi8vICAgdmlldyB0aGUgdmlld2VyIG1heSBkZWxldGUuIFNhdmUgYXMgbmV3IHZpZXcgaXMgYWx3YXlzIHRoZXJlLlxuLy8gLSBSZXNldCB0byB0aGUgb3BlbiB2aWV3IHdoaWxlIHRoZSBzY3JlZW4gZGlmZmVycyBmcm9tIGl0LCBhbmQgUmVzZXQgdG9cbi8vICAgcmVwb3J0IGRlZmF1bHRzLlxuaW1wb3J0IHsgUmVwb3J0Vmlld01lbnVJdGVtIH0gZnJvbSAnLi9pbnRlcmZhY2VzL3JlcG9ydC12aWV3LW1lbnUtaXRlbS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0Vmlld1N1bW1hcnkgfSBmcm9tICcuL2ludGVyZmFjZXMvcmVwb3J0LXZpZXctc3VtbWFyeS5pbnRlcmZhY2UnO1xuXG5cbmV4cG9ydCBjb25zdCBWSUVXU19MQUJFTCA9ICdWaWV3cyc7XG5leHBvcnQgY29uc3QgRURJVEVEX1RPT0xUSVAgPSAnVGhlIHNjcmVlbiBkaWZmZXJzIGZyb20gdGhpcyB2aWV3JztcbmV4cG9ydCBjb25zdCBTQVZFX0FTX1RJVExFID0gJ1NhdmUgYXMgbmV3IHZpZXcnO1xuZXhwb3J0IGNvbnN0IFJFTkFNRV9USVRMRSA9ICdSZW5hbWUgdmlldyc7XG5leHBvcnQgY29uc3QgQ1JPU1NfRklMVEVSX05PVEUgPSAnQ3Jvc3MtZmlsdGVycyBhcmUgdGVtcG9yYXJ5IGFuZCBhcmUgbm90IHNhdmVkLic7XG5leHBvcnQgY29uc3QgVklFV19OQU1FX0JMQU5LID0gJ0VudGVyIGEgbmFtZSc7XG5cbi8vIFRoZSBzZXJ2ZXIncyBsaW1pdCBvbiBhIHZpZXcncyBuYW1lLlxuZXhwb3J0IGNvbnN0IFZJRVdfTkFNRV9NQVhfTEVOR1RIID0gMTAwO1xuXG5cbi8vIFRoZSBtZW51IGZvciB0aGUgb3BlbiB2aWV3IChudWxsIHdoZW4gbm9uZSBpcyBvcGVuKSwgdGhlIHZpZXdzIHRoZSB2aWV3ZXJcbi8vIG1heSBzZWUsIHdoZXRoZXIgdGhlIHNjcmVlbiBkaWZmZXJzIGZyb20gdGhlIG9wZW4gdmlldywgYW5kIHdoZXRoZXIgdGhlXG4vLyB2aWV3ZXIgbWF5IHNoYXJlIGl0cyB2aWV3cy5cbmV4cG9ydCBmdW5jdGlvbiB2aWV3TWVudUl0ZW1zKFxuICBvcGVuOiBSZXBvcnRWaWV3U3VtbWFyeSB8IG51bGwsXG4gIHZpZXdzOiByZWFkb25seSBSZXBvcnRWaWV3U3VtbWFyeVtdLFxuICBlZGl0ZWQ6IGJvb2xlYW4sXG4gIGNhblNoYXJlOiBib29sZWFuLFxuKTogUmVwb3J0Vmlld01lbnVJdGVtW10ge1xuICBjb25zdCByb3dzID0gW1xuICAgIC4uLnZpZXdzLmZpbHRlcigodmlldykgPT4gdmlldy5taW5lKSxcbiAgICAuLi52aWV3cy5maWx0ZXIoKHZpZXcpID0+ICF2aWV3Lm1pbmUpLFxuICBdLm1hcCgodmlldykgPT4gdmlld1Jvdyh2aWV3LCBvcGVuLCBlZGl0ZWQpKTtcbiAgY29uc3QgYWN0aW9ucyA9IG9wZW5WaWV3QWN0aW9ucyhvcGVuLCBlZGl0ZWQsIGNhblNoYXJlKTtcbiAgY29uc3QgcmVzZXRzOiBSZXBvcnRWaWV3TWVudUl0ZW1bXSA9IFtcbiAgICAuLi4ob3BlbiAmJiBlZGl0ZWQgPyBbYWN0aW9uKCdyZXNldFRvVmlldycsIGBSZXNldCB0byBcIiR7b3Blbi5uYW1lfVwiYCldIDogW10pLFxuICAgIGFjdGlvbigncmVzZXRUb0RlZmF1bHRzJywgJ1Jlc2V0IHRvIHJlcG9ydCBkZWZhdWx0cycpLFxuICBdO1xuXG4gIHJldHVybiBbXG4gICAgLi4ucm93cyxcbiAgICAuLi53aXRoRGl2aWRlcihhY3Rpb25zLCByb3dzLmxlbmd0aCA+IDApLFxuICAgIC4uLndpdGhEaXZpZGVyKHJlc2V0cywgdHJ1ZSksXG4gIF07XG59XG5cbi8vIFRoZSBwaWNrZXIncyBsYWJlbDogJ1ZpZXdzJywgb3IgdGhlIG9wZW4gdmlldydzIG5hbWUsIG1hcmtlZCB3aGlsZSB0aGVcbi8vIHNjcmVlbiBkaWZmZXJzIGZyb20gaXQuXG5leHBvcnQgZnVuY3Rpb24gcGlja2VyTGFiZWwob3BlbjogUGljazxSZXBvcnRWaWV3U3VtbWFyeSwgJ25hbWUnPiB8IG51bGwsIGVkaXRlZDogYm9vbGVhbik6IHN0cmluZyB7XG4gIGlmICghb3Blbikge1xuICAgIHJldHVybiBWSUVXU19MQUJFTDtcbiAgfVxuXG4gIHJldHVybiBlZGl0ZWQgPyBgJHtvcGVuLm5hbWV9IChlZGl0ZWQpYCA6IG9wZW4ubmFtZTtcbn1cblxuLy8gVGhlIHBpY2tlcidzIHRvb2x0aXA6IG9ubHkgd2hpbGUgdGhlIHNjcmVlbiBkaWZmZXJzIGZyb20gdGhlIG9wZW4gdmlldy5cbmV4cG9ydCBmdW5jdGlvbiBwaWNrZXJUb29sdGlwKG9wZW46IFBpY2s8UmVwb3J0Vmlld1N1bW1hcnksICduYW1lJz4gfCBudWxsLCBlZGl0ZWQ6IGJvb2xlYW4pOiBzdHJpbmcgfCBudWxsIHtcbiAgcmV0dXJuIG9wZW4gJiYgZWRpdGVkID8gRURJVEVEX1RPT0xUSVAgOiBudWxsO1xufVxuXG4vLyBUaGUgcXVlc3Rpb24gYmVmb3JlIGEgdmlldyBpcyBkZWxldGVkLiBBIHNoYXJlZCB2aWV3IHNheXMgdGhhdCBldmVyeW9uZVxuLy8gbG9zZXMgaXQuXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlUHJvbXB0VGV4dCh2aWV3OiBQaWNrPFJlcG9ydFZpZXdTdW1tYXJ5LCAnbmFtZScgfCAnc2hhcmVkJz4pOiBzdHJpbmcge1xuICBjb25zdCBxdWVzdGlvbiA9IGBEZWxldGUgdGhlIHZpZXcgXCIke3ZpZXcubmFtZX1cIj9gO1xuXG4gIHJldHVybiB2aWV3LnNoYXJlZCA/IGAke3F1ZXN0aW9ufSBFdmVyeW9uZSBpdCBpcyBzaGFyZWQgd2l0aCBsb3NlcyBpdC5gIDogcXVlc3Rpb247XG59XG5cbi8vIFRoZSBsaW5lIHRoZSBzYXZlIGRpYWxvZyBzaG93cyB1bmRlciB0aGUgbmFtZSwgb3IgbnVsbDogYSBjcm9zcy1maWx0ZXIgaXNcbi8vIG9uLCBhbmQgaXQgZG9lcyBub3QgZ28gaW50byB0aGUgdmlldy5cbmV4cG9ydCBmdW5jdGlvbiBzYXZlRGlhbG9nTm90ZShoYXNDcm9zc0ZpbHRlcjogYm9vbGVhbik6IHN0cmluZyB8IG51bGwge1xuICByZXR1cm4gaGFzQ3Jvc3NGaWx0ZXIgPyBDUk9TU19GSUxURVJfTk9URSA6IG51bGw7XG59XG5cbi8vIEEgbmFtZSBtYWRlIG9mIHNwYWNlcyBvbmx5IGlzIG5vIG5hbWU7IHRoZSBzZXJ2ZXIgdHJpbXMgaXQuXG5leHBvcnQgZnVuY3Rpb24gdmlld05hbWVFcnJvcihuYW1lOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgbnVsbCB7XG4gIHJldHVybiAobmFtZSA/PyAnJykudHJpbSgpID8gbnVsbCA6IFZJRVdfTkFNRV9CTEFOSztcbn1cblxuXG5mdW5jdGlvbiB2aWV3Um93KHZpZXc6IFJlcG9ydFZpZXdTdW1tYXJ5LCBvcGVuOiBSZXBvcnRWaWV3U3VtbWFyeSB8IG51bGwsIGVkaXRlZDogYm9vbGVhbik6IFJlcG9ydFZpZXdNZW51SXRlbSB7XG4gIGNvbnN0IGlzT3BlbiA9IHZpZXcuaWQgPT09IG9wZW4/LmlkO1xuXG4gIHJldHVybiB7XG4gICAga2luZDogJ3ZpZXcnLFxuICAgIGxhYmVsOiB2aWV3Lm5hbWUsXG4gICAgZGlzYWJsZWQ6IGlzT3BlbiAmJiAhZWRpdGVkLFxuICAgIHRvb2x0aXA6IHZpZXdUb29sdGlwKHZpZXcpLFxuICAgIGRpdmlkZXI6IGZhbHNlLFxuICAgIHZpZXdJZDogdmlldy5pZCxcbiAgICBvcGVuOiBpc09wZW4sXG4gICAgaWNvbjogdmlld0ljb24odmlldyksXG4gIH07XG59XG5cbi8vIFdobyBzaGFyZWQgYSB2aWV3IG9mIHNvbWVvbmUgZWxzZSdzOyB3aGV0aGVyIG9uZSBvZiB0aGUgdmlld2VyJ3Mgb3duIG9wZW5zXG4vLyBieSBkZWZhdWx0IG9yIGlzIHNoYXJlZC5cbmZ1bmN0aW9uIHZpZXdUb29sdGlwKHZpZXc6IFJlcG9ydFZpZXdTdW1tYXJ5KTogc3RyaW5nIHwgbnVsbCB7XG4gIGlmICghdmlldy5taW5lKSB7XG4gICAgcmV0dXJuIHZpZXcub3duZXJOYW1lID8gYFNoYXJlZCBieSAke3ZpZXcub3duZXJOYW1lfWAgOiAnU2hhcmVkIHdpdGggZXZlcnlvbmUnO1xuICB9XG5cbiAgaWYgKHZpZXcucGVyc29uYWxEZWZhdWx0ICYmIHZpZXcuc2hhcmVkKSB7XG4gICAgcmV0dXJuICdPcGVucyBieSBkZWZhdWx0LCBzaGFyZWQgd2l0aCBldmVyeW9uZSc7XG4gIH1cblxuICBpZiAodmlldy5wZXJzb25hbERlZmF1bHQpIHtcbiAgICByZXR1cm4gJ09wZW5zIGJ5IGRlZmF1bHQnO1xuICB9XG5cbiAgcmV0dXJuIHZpZXcuc2hhcmVkID8gJ1NoYXJlZCB3aXRoIGV2ZXJ5b25lJyA6IG51bGw7XG59XG5cbi8vIFRoZSBvcGVuIHJvdyBrZWVwcyB0aGlzIGljb24gdG9vOyBpdHMgY2hlY2sgaXMgZHJhd24gYmVzaWRlIGl0LlxuZnVuY3Rpb24gdmlld0ljb24odmlldzogUmVwb3J0Vmlld1N1bW1hcnkpOiBSZXBvcnRWaWV3TWVudUl0ZW1bJ2ljb24nXSB7XG4gIGlmICghdmlldy5taW5lKSB7XG4gICAgcmV0dXJuICdwZW9wbGUnO1xuICB9XG5cbiAgcmV0dXJuIHZpZXcucGVyc29uYWxEZWZhdWx0ID8gJ3N0YXInIDogbnVsbDtcbn1cblxuLy8gVGhlIHJvd3MgdGhhdCBhY3Qgb24gdGhlIG9wZW4gdmlldzsgd2l0aCBub25lIG9wZW4sIG9ubHkgU2F2ZSBhcyBuZXcgdmlldy5cbmZ1bmN0aW9uIG9wZW5WaWV3QWN0aW9ucyhvcGVuOiBSZXBvcnRWaWV3U3VtbWFyeSB8IG51bGwsIGVkaXRlZDogYm9vbGVhbiwgY2FuU2hhcmU6IGJvb2xlYW4pOiBSZXBvcnRWaWV3TWVudUl0ZW1bXSB7XG4gIGNvbnN0IGl0ZW1zOiBSZXBvcnRWaWV3TWVudUl0ZW1bXSA9IFtdO1xuXG4gIGlmIChvcGVuPy5jYW5DaGFuZ2UgJiYgZWRpdGVkKSB7XG4gICAgaXRlbXMucHVzaChhY3Rpb24oJ3NhdmVDaGFuZ2VzJywgJ1NhdmUgY2hhbmdlcycpKTtcbiAgfVxuXG4gIGl0ZW1zLnB1c2goYWN0aW9uKCdzYXZlQXNOZXcnLCAnU2F2ZSBhcyBuZXcgdmlldy4uLicpKTtcblxuICBpZiAob3Blbj8uY2FuQ2hhbmdlKSB7XG4gICAgaXRlbXMucHVzaChhY3Rpb24oJ3JlbmFtZScsICdSZW5hbWUuLi4nKSk7XG4gIH1cblxuICBpZiAob3Blbj8ubWluZSkge1xuICAgIGl0ZW1zLnB1c2gob3Blbi5wZXJzb25hbERlZmF1bHRcbiAgICAgID8gYWN0aW9uKCdjbGVhckRlZmF1bHQnLCAnU3RvcCBvcGVuaW5nIGl0IGJ5IGRlZmF1bHQnKVxuICAgICAgOiBhY3Rpb24oJ3NldERlZmF1bHQnLCAnTWFrZSBpdCBteSBkZWZhdWx0JykpO1xuICB9XG5cbiAgaWYgKG9wZW4/Lm1pbmUgJiYgY2FuU2hhcmUpIHtcbiAgICBpdGVtcy5wdXNoKG9wZW4uc2hhcmVkID8gYWN0aW9uKCd1bnNoYXJlJywgJ1N0b3Agc2hhcmluZycpIDogYWN0aW9uKCdzaGFyZScsICdTaGFyZSB3aXRoIGV2ZXJ5b25lJykpO1xuICB9XG5cbiAgaWYgKG9wZW4/LmNhbkRlbGV0ZSkge1xuICAgIGl0ZW1zLnB1c2goYWN0aW9uKCdkZWxldGUnLCAnRGVsZXRlLi4uJykpO1xuICB9XG5cbiAgcmV0dXJuIGl0ZW1zO1xufVxuXG5mdW5jdGlvbiBhY3Rpb24oa2luZDogUmVwb3J0Vmlld01lbnVJdGVtWydraW5kJ10sIGxhYmVsOiBzdHJpbmcpOiBSZXBvcnRWaWV3TWVudUl0ZW0ge1xuICByZXR1cm4geyBraW5kLCBsYWJlbCwgZGlzYWJsZWQ6IGZhbHNlLCB0b29sdGlwOiBudWxsLCBkaXZpZGVyOiBmYWxzZSwgdmlld0lkOiBudWxsLCBvcGVuOiBmYWxzZSwgaWNvbjogbnVsbCB9O1xufVxuXG4vLyBUaGUgc2FtZSByb3dzLCB0aGUgZmlyc3Qgd2l0aCBhIGxpbmUgYWJvdmUgaXQgd2hlbiBgZGl2aWRlcmAgaXMgc2V0LlxuZnVuY3Rpb24gd2l0aERpdmlkZXIoaXRlbXM6IFJlcG9ydFZpZXdNZW51SXRlbVtdLCBkaXZpZGVyOiBib29sZWFuKTogUmVwb3J0Vmlld01lbnVJdGVtW10ge1xuICByZXR1cm4gaXRlbXMubWFwKChpdGVtLCBpbmRleCkgPT4gKGluZGV4ID09PSAwICYmIGRpdmlkZXIgPyB7IC4uLml0ZW0sIGRpdmlkZXI6IHRydWUgfSA6IGl0ZW0pKTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// The viewer features this viewer implements: the report GET names them
|
|
2
|
+
// (features=<comma list>), and the server assembles the report for exactly
|
|
3
|
+
// these. A feature joins the list in the change that builds its control, never
|
|
4
|
+
// before: the server sends a group only in a shape the viewer says it can show
|
|
5
|
+
// and clear, and a listed feature without its control would get a filter the
|
|
6
|
+
// viewer can neither show nor clear.
|
|
7
|
+
//
|
|
8
|
+
// scopeFilters needs no control of its own: a scope member is an ordinary
|
|
9
|
+
// filter row on its tile. excludeValues is a select's 'Exclude these' row,
|
|
10
|
+
// numberRange its min/max control, matchAny the report bar's Match select,
|
|
11
|
+
// and pageScope shows a page's groups in the report bar of that page.
|
|
12
|
+
// cascadingOptions narrows a select's list by the other filters of its tile
|
|
13
|
+
// (ReportFilterOptionsService). views is the Views picker in the report's
|
|
14
|
+
// header (ReportViewPickerComponent). drill is a time chart's click down, with
|
|
15
|
+
// the tile header's breadcrumb and its menu's Drill up and Back to top as the
|
|
16
|
+
// way back.
|
|
17
|
+
export const VIEWER_FEATURES = [
|
|
18
|
+
'scopeFilters',
|
|
19
|
+
'excludeValues',
|
|
20
|
+
'numberRange',
|
|
21
|
+
'matchAny',
|
|
22
|
+
'pageScope',
|
|
23
|
+
'cascadingOptions',
|
|
24
|
+
'views',
|
|
25
|
+
'drill',
|
|
26
|
+
];
|
|
27
|
+
// The features a report offers on this screen: the ones its server serves
|
|
28
|
+
// (Report.viewerFeatures) that this viewer also implements.
|
|
29
|
+
export function offeredViewerFeatures(served) {
|
|
30
|
+
return (served ?? []).filter((feature) => VIEWER_FEATURES.includes(feature));
|
|
31
|
+
}
|
|
32
|
+
// Whether a select group offers 'Exclude these': the one rule the report bar,
|
|
33
|
+
// the tile headers and the report settings' default row share. The server
|
|
34
|
+
// must serve excludeValues, and no enabled member may bind several columns
|
|
35
|
+
// (multiColumn), since the server cannot leave values out there (an older
|
|
36
|
+
// server sends no multiColumn, and the toggle shows as before).
|
|
37
|
+
export function offersExclude(group, features) {
|
|
38
|
+
return group.type === 'select'
|
|
39
|
+
&& !group.multiColumn
|
|
40
|
+
&& (features ?? []).includes('excludeValues');
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LXZpZXdlci1mZWF0dXJlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9yZXBvcnQtdmlld2VyLWZlYXR1cmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUlBLHdFQUF3RTtBQUN4RSwyRUFBMkU7QUFDM0UsK0VBQStFO0FBQy9FLCtFQUErRTtBQUMvRSw2RUFBNkU7QUFDN0UscUNBQXFDO0FBQ3JDLEVBQUU7QUFDRiwwRUFBMEU7QUFDMUUsMkVBQTJFO0FBQzNFLDJFQUEyRTtBQUMzRSxzRUFBc0U7QUFDdEUsNEVBQTRFO0FBQzVFLDBFQUEwRTtBQUMxRSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLFlBQVk7QUFDWixNQUFNLENBQUMsTUFBTSxlQUFlLEdBQW1DO0lBQzdELGNBQWM7SUFDZCxlQUFlO0lBQ2YsYUFBYTtJQUNiLFVBQVU7SUFDVixXQUFXO0lBQ1gsa0JBQWtCO0lBQ2xCLE9BQU87SUFDUCxPQUFPO0NBQ1IsQ0FBQztBQUVGLDBFQUEwRTtBQUMxRSw0REFBNEQ7QUFDNUQsTUFBTSxVQUFVLHFCQUFxQixDQUFDLE1BQXlEO0lBQzdGLE9BQU8sQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDL0UsQ0FBQztBQUVELDhFQUE4RTtBQUM5RSwwRUFBMEU7QUFDMUUsMkVBQTJFO0FBQzNFLDBFQUEwRTtBQUMxRSxnRUFBZ0U7QUFDaEUsTUFBTSxVQUFVLGFBQWEsQ0FDM0IsS0FBc0QsRUFDdEQsUUFBMkQ7SUFFM0QsT0FBTyxLQUFLLENBQUMsSUFBSSxLQUFLLFFBQVE7V0FDekIsQ0FBQyxLQUFLLENBQUMsV0FBVztXQUNsQixDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDbEQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlcG9ydFZpZXdlckZlYXR1cmUgfSBmcm9tICcuL2ludGVyZmFjZXMvcmVwb3J0LXZpZXdlci1mZWF0dXJlLnR5cGUnO1xuaW1wb3J0IHsgUmVwb3J0RmlsdGVyR3JvdXAgfSBmcm9tICcuL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7XG5cblxuLy8gVGhlIHZpZXdlciBmZWF0dXJlcyB0aGlzIHZpZXdlciBpbXBsZW1lbnRzOiB0aGUgcmVwb3J0IEdFVCBuYW1lcyB0aGVtXG4vLyAoZmVhdHVyZXM9PGNvbW1hIGxpc3Q+KSwgYW5kIHRoZSBzZXJ2ZXIgYXNzZW1ibGVzIHRoZSByZXBvcnQgZm9yIGV4YWN0bHlcbi8vIHRoZXNlLiBBIGZlYXR1cmUgam9pbnMgdGhlIGxpc3QgaW4gdGhlIGNoYW5nZSB0aGF0IGJ1aWxkcyBpdHMgY29udHJvbCwgbmV2ZXJcbi8vIGJlZm9yZTogdGhlIHNlcnZlciBzZW5kcyBhIGdyb3VwIG9ubHkgaW4gYSBzaGFwZSB0aGUgdmlld2VyIHNheXMgaXQgY2FuIHNob3dcbi8vIGFuZCBjbGVhciwgYW5kIGEgbGlzdGVkIGZlYXR1cmUgd2l0aG91dCBpdHMgY29udHJvbCB3b3VsZCBnZXQgYSBmaWx0ZXIgdGhlXG4vLyB2aWV3ZXIgY2FuIG5laXRoZXIgc2hvdyBub3IgY2xlYXIuXG4vL1xuLy8gc2NvcGVGaWx0ZXJzIG5lZWRzIG5vIGNvbnRyb2wgb2YgaXRzIG93bjogYSBzY29wZSBtZW1iZXIgaXMgYW4gb3JkaW5hcnlcbi8vIGZpbHRlciByb3cgb24gaXRzIHRpbGUuIGV4Y2x1ZGVWYWx1ZXMgaXMgYSBzZWxlY3QncyAnRXhjbHVkZSB0aGVzZScgcm93LFxuLy8gbnVtYmVyUmFuZ2UgaXRzIG1pbi9tYXggY29udHJvbCwgbWF0Y2hBbnkgdGhlIHJlcG9ydCBiYXIncyBNYXRjaCBzZWxlY3QsXG4vLyBhbmQgcGFnZVNjb3BlIHNob3dzIGEgcGFnZSdzIGdyb3VwcyBpbiB0aGUgcmVwb3J0IGJhciBvZiB0aGF0IHBhZ2UuXG4vLyBjYXNjYWRpbmdPcHRpb25zIG5hcnJvd3MgYSBzZWxlY3QncyBsaXN0IGJ5IHRoZSBvdGhlciBmaWx0ZXJzIG9mIGl0cyB0aWxlXG4vLyAoUmVwb3J0RmlsdGVyT3B0aW9uc1NlcnZpY2UpLiB2aWV3cyBpcyB0aGUgVmlld3MgcGlja2VyIGluIHRoZSByZXBvcnQnc1xuLy8gaGVhZGVyIChSZXBvcnRWaWV3UGlja2VyQ29tcG9uZW50KS4gZHJpbGwgaXMgYSB0aW1lIGNoYXJ0J3MgY2xpY2sgZG93biwgd2l0aFxuLy8gdGhlIHRpbGUgaGVhZGVyJ3MgYnJlYWRjcnVtYiBhbmQgaXRzIG1lbnUncyBEcmlsbCB1cCBhbmQgQmFjayB0byB0b3AgYXMgdGhlXG4vLyB3YXkgYmFjay5cbmV4cG9ydCBjb25zdCBWSUVXRVJfRkVBVFVSRVM6IHJlYWRvbmx5IFJlcG9ydFZpZXdlckZlYXR1cmVbXSA9IFtcbiAgJ3Njb3BlRmlsdGVycycsXG4gICdleGNsdWRlVmFsdWVzJyxcbiAgJ251bWJlclJhbmdlJyxcbiAgJ21hdGNoQW55JyxcbiAgJ3BhZ2VTY29wZScsXG4gICdjYXNjYWRpbmdPcHRpb25zJyxcbiAgJ3ZpZXdzJyxcbiAgJ2RyaWxsJyxcbl07XG5cbi8vIFRoZSBmZWF0dXJlcyBhIHJlcG9ydCBvZmZlcnMgb24gdGhpcyBzY3JlZW46IHRoZSBvbmVzIGl0cyBzZXJ2ZXIgc2VydmVzXG4vLyAoUmVwb3J0LnZpZXdlckZlYXR1cmVzKSB0aGF0IHRoaXMgdmlld2VyIGFsc28gaW1wbGVtZW50cy5cbmV4cG9ydCBmdW5jdGlvbiBvZmZlcmVkVmlld2VyRmVhdHVyZXMoc2VydmVkOiByZWFkb25seSBSZXBvcnRWaWV3ZXJGZWF0dXJlW10gfCBudWxsIHwgdW5kZWZpbmVkKTogUmVwb3J0Vmlld2VyRmVhdHVyZVtdIHtcbiAgcmV0dXJuIChzZXJ2ZWQgPz8gW10pLmZpbHRlcigoZmVhdHVyZSkgPT4gVklFV0VSX0ZFQVRVUkVTLmluY2x1ZGVzKGZlYXR1cmUpKTtcbn1cblxuLy8gV2hldGhlciBhIHNlbGVjdCBncm91cCBvZmZlcnMgJ0V4Y2x1ZGUgdGhlc2UnOiB0aGUgb25lIHJ1bGUgdGhlIHJlcG9ydCBiYXIsXG4vLyB0aGUgdGlsZSBoZWFkZXJzIGFuZCB0aGUgcmVwb3J0IHNldHRpbmdzJyBkZWZhdWx0IHJvdyBzaGFyZS4gVGhlIHNlcnZlclxuLy8gbXVzdCBzZXJ2ZSBleGNsdWRlVmFsdWVzLCBhbmQgbm8gZW5hYmxlZCBtZW1iZXIgbWF5IGJpbmQgc2V2ZXJhbCBjb2x1bW5zXG4vLyAobXVsdGlDb2x1bW4pLCBzaW5jZSB0aGUgc2VydmVyIGNhbm5vdCBsZWF2ZSB2YWx1ZXMgb3V0IHRoZXJlIChhbiBvbGRlclxuLy8gc2VydmVyIHNlbmRzIG5vIG11bHRpQ29sdW1uLCBhbmQgdGhlIHRvZ2dsZSBzaG93cyBhcyBiZWZvcmUpLlxuZXhwb3J0IGZ1bmN0aW9uIG9mZmVyc0V4Y2x1ZGUoXG4gIGdyb3VwOiBQaWNrPFJlcG9ydEZpbHRlckdyb3VwLCAndHlwZScgfCAnbXVsdGlDb2x1bW4nPixcbiAgZmVhdHVyZXM6IHJlYWRvbmx5IFJlcG9ydFZpZXdlckZlYXR1cmVbXSB8IG51bGwgfCB1bmRlZmluZWQsXG4pOiBib29sZWFuIHtcbiAgcmV0dXJuIGdyb3VwLnR5cGUgPT09ICdzZWxlY3QnXG4gICAgJiYgIWdyb3VwLm11bHRpQ29sdW1uXG4gICAgJiYgKGZlYXR1cmVzID8/IFtdKS5pbmNsdWRlcygnZXhjbHVkZVZhbHVlcycpO1xufVxuIl19
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { DestroyRef, Injectable, inject } from '@angular/core';
|
|
2
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
3
|
+
import { Subject, defer, of } from 'rxjs';
|
|
4
|
+
import { catchError, filter, map, shareReplay, switchMap, take, tap } from 'rxjs/operators';
|
|
5
|
+
import { ReportData } from '../data/report.data';
|
|
6
|
+
import { isMatchAnyGroup } from '../report-filter-items';
|
|
7
|
+
import { tileDataState, tilePageId, valuesMatchAnyGroupIds } from '../tile-data-state';
|
|
8
|
+
import { reportComponents } from '../values';
|
|
9
|
+
import { ReportFilterStateService } from './report-filter-state.service';
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
// The most picks one request asks names for: the server's option cap.
|
|
12
|
+
const SELECTED_CAP = 500;
|
|
13
|
+
// The options a select group's control offers. When the server serves
|
|
14
|
+
// cascadingOptions, a group's list is narrowed by the other entries of its
|
|
15
|
+
// host tile (the narrowed options POST); otherwise it is the full list (the
|
|
16
|
+
// options GET), fetched once per group while its host stays the same. The
|
|
17
|
+
// host is the member whose list the group shows (optionsHost).
|
|
18
|
+
//
|
|
19
|
+
// A list is replayed while its request's signature holds: the host's entries
|
|
20
|
+
// without the group's own, without a cross-filter entry and, while the
|
|
21
|
+
// groups match 'any', without the other groups this one combines with. A new
|
|
22
|
+
// signature fetches again, and a request still in flight for an older one is
|
|
23
|
+
// dropped (switchMap). fs-filter asks on focus and on each keystroke, so a
|
|
24
|
+
// list is fetched on the first of them after a change and replayed for the
|
|
25
|
+
// rest; typing filters the replayed list in the viewer (matchOptions).
|
|
26
|
+
//
|
|
27
|
+
// Every list and every 'selected' answer teaches label() the names of the
|
|
28
|
+
// values it holds, so a pick the narrowed list leaves out keeps its name.
|
|
29
|
+
//
|
|
30
|
+
// Each load of the report (the first, and every reload after a chat or
|
|
31
|
+
// dialog edit) starts again: no list is replayed and no name is kept from an
|
|
32
|
+
// earlier load, so an edit to a tile's source or to an option's name shows on
|
|
33
|
+
// the next ask, as when every bar build fetched its list.
|
|
34
|
+
export class ReportFilterOptionsService {
|
|
35
|
+
_reportData = inject(ReportData);
|
|
36
|
+
_filterState = inject(ReportFilterStateService);
|
|
37
|
+
_destroyRef = inject(DestroyRef);
|
|
38
|
+
_streams = new Map();
|
|
39
|
+
_labels = new Map();
|
|
40
|
+
// The picks each group has asked names for, so a value the server cannot
|
|
41
|
+
// name (its entity was deleted) is asked for once, not on every keystroke.
|
|
42
|
+
_asked = new Map();
|
|
43
|
+
// The report load the lists and names above belong to (the object init()
|
|
44
|
+
// last read).
|
|
45
|
+
_loaded = null;
|
|
46
|
+
// The options the group's control offers now. Nothing is read or sent
|
|
47
|
+
// until the list is subscribed to, so the signature is the one of the
|
|
48
|
+
// moment the control asks.
|
|
49
|
+
options(group, report) {
|
|
50
|
+
return defer(() => {
|
|
51
|
+
const narrowed = !!report?.viewerFeatures?.includes('cascadingOptions');
|
|
52
|
+
const host = optionsHost(group, narrowed);
|
|
53
|
+
if (!host || !report) {
|
|
54
|
+
return of([]);
|
|
55
|
+
}
|
|
56
|
+
this._syncLoad();
|
|
57
|
+
const stream = this._stream(group.id);
|
|
58
|
+
const seq = this._ask(stream, group, report, host, narrowed);
|
|
59
|
+
return stream.lists$
|
|
60
|
+
.pipe(filter((list) => list.seq >= seq), take(1), map((list) => list.options));
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
// The name a value of the group was last listed or labeled with in this
|
|
64
|
+
// load of the report, or null when no list or answer has named it yet.
|
|
65
|
+
label(groupId, value) {
|
|
66
|
+
this._syncLoad();
|
|
67
|
+
return this._labels.get(groupId)?.get(String(value)) ?? null;
|
|
68
|
+
}
|
|
69
|
+
// Whether the group's latest list was cut at 500.
|
|
70
|
+
truncated(groupId) {
|
|
71
|
+
this._syncLoad();
|
|
72
|
+
return this._streams.get(groupId)?.truncated ?? false;
|
|
73
|
+
}
|
|
74
|
+
// Whether the group's latest request failed. Its list is then empty, and
|
|
75
|
+
// the next ask fetches again.
|
|
76
|
+
failed(groupId) {
|
|
77
|
+
this._syncLoad();
|
|
78
|
+
return this._streams.get(groupId)?.failed ?? false;
|
|
79
|
+
}
|
|
80
|
+
// Sends a request when the signature moved, or when a pick has no name
|
|
81
|
+
// yet and was never asked for. Returns the number of the request whose
|
|
82
|
+
// answer the caller takes: the one sent, else the latest.
|
|
83
|
+
_ask(stream, group, report, host, narrowed) {
|
|
84
|
+
const body = narrowed ? this._request(group, report, host) : null;
|
|
85
|
+
// The host member is part of it: a report edit that moves the group's
|
|
86
|
+
// list to another member or column lists again.
|
|
87
|
+
const signature = JSON.stringify([host.id, host.filterColumn, body?.filters ?? null, body?.matchAnyGroupIds ?? []]);
|
|
88
|
+
const unnamed = (body?.selected ?? [])
|
|
89
|
+
.filter((value) => this.label(group.id, value) === null && !this._askedFor(group.id).has(String(value)));
|
|
90
|
+
if (signature === stream.signature && !unnamed.length) {
|
|
91
|
+
return stream.seq;
|
|
92
|
+
}
|
|
93
|
+
unnamed.forEach((value) => this._askedFor(group.id).add(String(value)));
|
|
94
|
+
stream.signature = signature;
|
|
95
|
+
stream.seq += 1;
|
|
96
|
+
stream.requests$.next({ seq: stream.seq, fetch: this._fetch(stream, group.id, report.id, host.id, body) });
|
|
97
|
+
return stream.seq;
|
|
98
|
+
}
|
|
99
|
+
// The narrowed request for the group: what its host tile's data request
|
|
100
|
+
// carries now, minus the entries that must not narrow the group's list.
|
|
101
|
+
_request(group, report, host) {
|
|
102
|
+
const tile = reportComponents(report).find((component) => component.id === host.componentId) ?? null;
|
|
103
|
+
const selected = groupPicks(this._filterState.value(group.id));
|
|
104
|
+
if (!tile) {
|
|
105
|
+
return { filters: [], ...(selected.length ? { selected } : {}) };
|
|
106
|
+
}
|
|
107
|
+
const snapshot = this._filterState.snapshot();
|
|
108
|
+
// A group whose only members are inline values lists through a value,
|
|
109
|
+
// which combines its groups by the tile rule over its own page.
|
|
110
|
+
const matchAnyGroupIds = tile.type === 'value'
|
|
111
|
+
? valuesMatchAnyGroupIds(report, tilePageId(report, tile, snapshot), snapshot)
|
|
112
|
+
: tileDataState(report, tile, snapshot).matchAnyGroupIds ?? [];
|
|
113
|
+
// Under 'any' another group this one combines with does not limit which
|
|
114
|
+
// of its values can show rows, so the list leaves it out.
|
|
115
|
+
const combined = matchAnyGroupIds.length && isMatchAnyGroup(group, tilePageId(report, tile, snapshot))
|
|
116
|
+
? matchAnyGroupIds
|
|
117
|
+
: [];
|
|
118
|
+
const groupOf = new Map((tile.filters ?? []).map((member) => [member.id, member.filterGroupId]));
|
|
119
|
+
const filters = this._filterState.resolveForComponent(tile)
|
|
120
|
+
.filter((entry) => {
|
|
121
|
+
const groupId = groupOf.get(entry.filterId) ?? null;
|
|
122
|
+
return !isCrossEntry(entry) && groupId !== group.id && !combined.includes(groupId);
|
|
123
|
+
});
|
|
124
|
+
return {
|
|
125
|
+
filters,
|
|
126
|
+
...(matchAnyGroupIds.length ? { matchAnyGroupIds } : {}),
|
|
127
|
+
...(selected.length ? { selected } : {}),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// One request's answer as a list. A failed request answers an empty list
|
|
131
|
+
// marked failed, and clears the signature, so the next ask fetches again.
|
|
132
|
+
_fetch(stream, groupId, reportId, filterId, body) {
|
|
133
|
+
const seq = stream.seq;
|
|
134
|
+
// An answer that lands after the report loaded again teaches no name.
|
|
135
|
+
const loaded = this._filterState.report();
|
|
136
|
+
const answer$ = body
|
|
137
|
+
? this._reportData.filterOptionsNarrowed(reportId, filterId, body)
|
|
138
|
+
: this._reportData.filterOptions(reportId, filterId)
|
|
139
|
+
.pipe(map((options) => ({ options, truncated: false, narrowedBy: [], selected: [] })));
|
|
140
|
+
return answer$
|
|
141
|
+
.pipe(tap((answer) => {
|
|
142
|
+
if (this._filterState.report() === loaded) {
|
|
143
|
+
this._remember(groupId, [...(answer?.options ?? []), ...(answer?.selected ?? [])]);
|
|
144
|
+
}
|
|
145
|
+
}), map((answer) => ({
|
|
146
|
+
seq,
|
|
147
|
+
truncated: !!answer?.truncated,
|
|
148
|
+
failed: false,
|
|
149
|
+
options: (answer?.options ?? []).map((option) => ({ name: option.label, value: option.value })),
|
|
150
|
+
})), catchError(() => {
|
|
151
|
+
stream.signature = null;
|
|
152
|
+
return of({ seq, truncated: false, failed: true, options: [] });
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
// The group's stream, opened on its first ask. It is subscribed to here,
|
|
156
|
+
// for the life of the report view, so an answer is kept for the next ask
|
|
157
|
+
// even when the control that asked has moved on. When the view goes, the
|
|
158
|
+
// stream ends: a request still in flight is dropped, whoever still listens.
|
|
159
|
+
_stream(groupId) {
|
|
160
|
+
const existing = this._streams.get(groupId);
|
|
161
|
+
if (existing) {
|
|
162
|
+
return existing;
|
|
163
|
+
}
|
|
164
|
+
const requests$ = new Subject();
|
|
165
|
+
const stream = {
|
|
166
|
+
signature: null,
|
|
167
|
+
seq: 0,
|
|
168
|
+
truncated: false,
|
|
169
|
+
failed: false,
|
|
170
|
+
requests$,
|
|
171
|
+
lists$: requests$
|
|
172
|
+
.pipe(switchMap((request) => request.fetch), tap((list) => {
|
|
173
|
+
stream.truncated = list.truncated;
|
|
174
|
+
stream.failed = list.failed;
|
|
175
|
+
}), takeUntilDestroyed(this._destroyRef), shareReplay({ bufferSize: 1, refCount: false })),
|
|
176
|
+
};
|
|
177
|
+
// Ends with the stream, when the view goes.
|
|
178
|
+
stream.lists$.subscribe();
|
|
179
|
+
this._streams.set(groupId, stream);
|
|
180
|
+
return stream;
|
|
181
|
+
}
|
|
182
|
+
// A new load of the report (init() read another report object) drops what
|
|
183
|
+
// the last load learned: every signature, so each list is fetched again on
|
|
184
|
+
// its next ask, and every name and asked pick.
|
|
185
|
+
_syncLoad() {
|
|
186
|
+
const loaded = this._filterState.report();
|
|
187
|
+
if (loaded === this._loaded) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
this._loaded = loaded;
|
|
191
|
+
this._streams.forEach((stream) => {
|
|
192
|
+
stream.signature = null;
|
|
193
|
+
});
|
|
194
|
+
this._labels.clear();
|
|
195
|
+
this._asked.clear();
|
|
196
|
+
}
|
|
197
|
+
_remember(groupId, options) {
|
|
198
|
+
const labels = this._labels.get(groupId) ?? new Map();
|
|
199
|
+
for (const option of options) {
|
|
200
|
+
if (option && typeof option.label === 'string') {
|
|
201
|
+
labels.set(String(option.value), option.label);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
this._labels.set(groupId, labels);
|
|
205
|
+
}
|
|
206
|
+
_askedFor(groupId) {
|
|
207
|
+
const asked = this._asked.get(groupId) ?? new Set();
|
|
208
|
+
this._asked.set(groupId, asked);
|
|
209
|
+
return asked;
|
|
210
|
+
}
|
|
211
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportFilterOptionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
212
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportFilterOptionsService });
|
|
213
|
+
}
|
|
214
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportFilterOptionsService, decorators: [{
|
|
215
|
+
type: Injectable
|
|
216
|
+
}] });
|
|
217
|
+
// The member whose list a group shows. The narrowed POST names the server's
|
|
218
|
+
// host: the first enabled member with options, else the first with options.
|
|
219
|
+
// The options GET keeps its older rule, the first member with options, as
|
|
220
|
+
// loadGroupOptions does, so an older server is asked what it always was.
|
|
221
|
+
function optionsHost(group, narrowed) {
|
|
222
|
+
const members = (group.filters ?? []).filter((member) => member.hasOptions);
|
|
223
|
+
return (narrowed ? members.find((member) => member.enabled) : null) ?? members[0] ?? null;
|
|
224
|
+
}
|
|
225
|
+
// A cross-filter entry rides in the same filters array as the group entries
|
|
226
|
+
// and carries its crossFilterId. It never narrows a list: a click is a
|
|
227
|
+
// temporary look, and the chip of the cross-filter already shows it.
|
|
228
|
+
function isCrossEntry(entry) {
|
|
229
|
+
return 'crossFilterId' in entry;
|
|
230
|
+
}
|
|
231
|
+
// A select group's picks, kept or left out, that a request can name: text
|
|
232
|
+
// and numbers, at most SELECTED_CAP.
|
|
233
|
+
function groupPicks(value) {
|
|
234
|
+
return [...(value?.values ?? []), ...(value?.excludeValues ?? [])]
|
|
235
|
+
.filter((pick) => typeof pick === 'string' || typeof pick === 'number')
|
|
236
|
+
.slice(0, SELECTED_CAP);
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWZpbHRlci1vcHRpb25zLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3JlcG9ydHMvc2VydmljZXMvcmVwb3J0LWZpbHRlci1vcHRpb25zLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9ELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRWhFLE9BQU8sRUFBYyxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFNUYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBVWpELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3ZGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUU3QyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQzs7QUFHekUsc0VBQXNFO0FBQ3RFLE1BQU0sWUFBWSxHQUFHLEdBQUcsQ0FBQztBQUV6QixzRUFBc0U7QUFDdEUsMkVBQTJFO0FBQzNFLDRFQUE0RTtBQUM1RSwwRUFBMEU7QUFDMUUsK0RBQStEO0FBQy9ELEVBQUU7QUFDRiw2RUFBNkU7QUFDN0UsdUVBQXVFO0FBQ3ZFLDZFQUE2RTtBQUM3RSw2RUFBNkU7QUFDN0UsMkVBQTJFO0FBQzNFLDJFQUEyRTtBQUMzRSx1RUFBdUU7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QUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUM7QUFDNUYsQ0FBQztBQUVELDRFQUE0RTtBQUM1RSx1RUFBdUU7QUFDdkUscUVBQXFFO0FBQ3JFLFNBQVMsWUFBWSxDQUFDLEtBQTBCO0lBQzlDLE9BQU8sZUFBZSxJQUFJLEtBQUssQ0FBQztBQUNsQyxDQUFDO0FBRUQsMEVBQTBFO0FBQzFFLHFDQUFxQztBQUNyQyxTQUFTLFVBQVUsQ0FBQyxLQUFtQztJQUNyRCxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxNQUFNLElBQUksRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEtBQUssRUFBRSxhQUFhLElBQUksRUFBRSxDQUFDLENBQUM7U0FDL0QsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUEyQixFQUFFLENBQUMsT0FBTyxJQUFJLEtBQUssUUFBUSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsQ0FBQztTQUMvRixLQUFLLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDO0FBQzVCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEZXN0cm95UmVmLCBJbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCwgZGVmZXIsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBmaWx0ZXIsIG1hcCwgc2hhcmVSZXBsYXksIHN3aXRjaE1hcCwgdGFrZSwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBSZXBvcnREYXRhIH0gZnJvbSAnLi4vZGF0YS9yZXBvcnQuZGF0YSc7XG5pbXBvcnQgeyBSZXBvcnRGaWx0ZXJPcHRpb25QYWlyIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtZmlsdGVyLW9wdGlvbi1wYWlyLmludGVyZmFjZSc7XG5pbXBvcnQgeyBSZXBvcnRGaWx0ZXJPcHRpb25zQXNrIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtZmlsdGVyLW9wdGlvbnMtYXNrLmludGVyZmFjZSc7XG5pbXBvcnQgeyBSZXBvcnRGaWx0ZXJPcHRpb25zTGlzdCB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LWZpbHRlci1vcHRpb25zLWxpc3QuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlcG9ydEZpbHRlck9wdGlvbnNSZXF1ZXN0IH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtZmlsdGVyLW9wdGlvbnMtcmVxdWVzdC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0RmlsdGVyT3B0aW9uc1N0cmVhbSB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LWZpbHRlci1vcHRpb25zLXN0cmVhbS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0RmlsdGVyT3B0aW9ucyB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LWZpbHRlci1vcHRpb25zLmludGVyZmFjZSc7XG5pbXBvcnQge1xuICBGaWx0ZXJHcm91cFZhbHVlLCBSZXBvcnQsIFJlcG9ydEZpbHRlciwgUmVwb3J0RmlsdGVyR3JvdXAsIFJlcG9ydEZpbHRlck9wdGlvbiwgUmVzb2x2ZWRGaWx0ZXJWYWx1ZSxcbn0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IGlzTWF0Y2hBbnlHcm91cCB9IGZyb20gJy4uL3JlcG9ydC1maWx0ZXItaXRlbXMnO1xuaW1wb3J0IHsgdGlsZURhdGFTdGF0ZSwgdGlsZVBhZ2VJZCwgdmFsdWVzTWF0Y2hBbnlHcm91cElkcyB9IGZyb20gJy4uL3RpbGUtZGF0YS1zdGF0ZSc7XG5pbXBvcnQgeyByZXBvcnRDb21wb25lbnRzIH0gZnJvbSAnLi4vdmFsdWVzJztcblxuaW1wb3J0IHsgUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi9yZXBvcnQtZmlsdGVyLXN0YXRlLnNlcnZpY2UnO1xuXG5cbi8vIFRoZSBtb3N0IHBpY2tzIG9uZSByZXF1ZXN0IGFza3MgbmFtZXMgZm9yOiB0aGUgc2VydmVyJ3Mgb3B0aW9uIGNhcC5cbmNvbnN0IFNFTEVDVEVEX0NBUCA9IDUwMDtcblxuLy8gVGhlIG9wdGlvbnMgYSBzZWxlY3QgZ3JvdXAncyBjb250cm9sIG9mZmVycy4gV2hlbiB0aGUgc2VydmVyIHNlcnZlc1xuLy8gY2FzY2FkaW5nT3B0aW9ucywgYSBncm91cCdzIGxpc3QgaXMgbmFycm93ZWQgYnkgdGhlIG90aGVyIGVudHJpZXMgb2YgaXRzXG4vLyBob3N0IHRpbGUgKHRoZSBuYXJyb3dlZCBvcHRpb25zIFBPU1QpOyBvdGhlcndpc2UgaXQgaXMgdGhlIGZ1bGwgbGlzdCAodGhlXG4vLyBvcHRpb25zIEdFVCksIGZldGNoZWQgb25jZSBwZXIgZ3JvdXAgd2hpbGUgaXRzIGhvc3Qgc3RheXMgdGhlIHNhbWUuIFRoZVxuLy8gaG9zdCBpcyB0aGUgbWVtYmVyIHdob3NlIGxpc3QgdGhlIGdyb3VwIHNob3dzIChvcHRpb25zSG9zdCkuXG4vL1xuLy8gQSBsaXN0IGlzIHJlcGxheWVkIHdoaWxlIGl0cyByZXF1ZXN0J3Mgc2lnbmF0dXJlIGhvbGRzOiB0aGUgaG9zdCdzIGVudHJpZXNcbi8vIHdpdGhvdXQgdGhlIGdyb3VwJ3Mgb3duLCB3aXRob3V0IGEgY3Jvc3MtZmlsdGVyIGVudHJ5IGFuZCwgd2hpbGUgdGhlXG4vLyBncm91cHMgbWF0Y2ggJ2FueScsIHdpdGhvdXQgdGhlIG90aGVyIGdyb3VwcyB0aGlzIG9uZSBjb21iaW5lcyB3aXRoLiBBIG5ld1xuLy8gc2lnbmF0dXJlIGZldGNoZXMgYWdhaW4sIGFuZCBhIHJlcXVlc3Qgc3RpbGwgaW4gZmxpZ2h0IGZvciBhbiBvbGRlciBvbmUgaXNcbi8vIGRyb3BwZWQgKHN3aXRjaE1hcCkuIGZzLWZpbHRlciBhc2tzIG9uIGZvY3VzIGFuZCBvbiBlYWNoIGtleXN0cm9rZSwgc28gYVxuLy8gbGlzdCBpcyBmZXRjaGVkIG9uIHRoZSBmaXJzdCBvZiB0aGVtIGFmdGVyIGEgY2hhbmdlIGFuZCByZXBsYXllZCBmb3IgdGhlXG4vLyByZXN0OyB0eXBpbmcgZmlsdGVycyB0aGUgcmVwbGF5ZWQgbGlzdCBpbiB0aGUgdmlld2VyIChtYXRjaE9wdGlvbnMpLlxuLy9cbi8vIEV2ZXJ5IGxpc3QgYW5kIGV2ZXJ5ICdzZWxlY3RlZCcgYW5zd2VyIHRlYWNoZXMgbGFiZWwoKSB0aGUgbmFtZXMgb2YgdGhlXG4vLyB2YWx1ZXMgaXQgaG9sZHMsIHNvIGEgcGljayB0aGUgbmFycm93ZWQgbGlzdCBsZWF2ZXMgb3V0IGtlZXBzIGl0cyBuYW1lLlxuLy9cbi8vIEVhY2ggbG9hZCBvZiB0aGUgcmVwb3J0ICh0aGUgZmlyc3QsIGFuZCBldmVyeSByZWxvYWQgYWZ0ZXIgYSBjaGF0IG9yXG4vLyBkaWFsb2cgZWRpdCkgc3RhcnRzIGFnYWluOiBubyBsaXN0IGlzIHJlcGxheWVkIGFuZCBubyBuYW1lIGlzIGtlcHQgZnJvbSBhblxuLy8gZWFybGllciBsb2FkLCBzbyBhbiBlZGl0IHRvIGEgdGlsZSdzIHNvdXJjZSBvciB0byBhbiBvcHRpb24ncyBuYW1lIHNob3dzIG9uXG4vLyB0aGUgbmV4dCBhc2ssIGFzIHdoZW4gZXZlcnkgYmFyIGJ1aWxkIGZldGNoZWQgaXRzIGxpc3QuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUmVwb3J0RmlsdGVyT3B0aW9uc1NlcnZpY2Uge1xuXG4gIHByaXZhdGUgX3JlcG9ydERhdGEgPSBpbmplY3QoUmVwb3J0RGF0YSk7XG4gIHByaXZhdGUgX2ZpbHRlclN0YXRlID0gaW5qZWN0KFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSk7XG4gIHByaXZhdGUgX2Rlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG4gIHByaXZhdGUgX3N0cmVhbXMgPSBuZXcgTWFwPG51bWJlciwgUmVwb3J0RmlsdGVyT3B0aW9uc1N0cmVhbT4oKTtcbiAgcHJpdmF0ZSBfbGFiZWxzID0gbmV3IE1hcDxudW1iZXIsIE1hcDxzdHJpbmcsIHN0cmluZz4+KCk7XG4gIC8vIFRoZSBwaWNrcyBlYWNoIGdyb3VwIGhhcyBhc2tlZCBuYW1lcyBmb3IsIHNvIGEgdmFsdWUgdGhlIHNlcnZlciBjYW5ub3RcbiAgLy8gbmFtZSAoaXRzIGVudGl0eSB3YXMgZGVsZXRlZCkgaXMgYXNrZWQgZm9yIG9uY2UsIG5vdCBvbiBldmVyeSBrZXlzdHJva2UuXG4gIHByaXZhdGUgX2Fza2VkID0gbmV3IE1hcDxudW1iZXIsIFNldDxzdHJpbmc+PigpO1xuICAvLyBUaGUgcmVwb3J0IGxvYWQgdGhlIGxpc3RzIGFuZCBuYW1lcyBhYm92ZSBiZWxvbmcgdG8gKHRoZSBvYmplY3QgaW5pdCgpXG4gIC8vIGxhc3QgcmVhZCkuXG4gIHByaXZhdGUgX2xvYWRlZDogUmVwb3J0IHwgbnVsbCA9IG51bGw7XG5cbiAgLy8gVGhlIG9wdGlvbnMgdGhlIGdyb3VwJ3MgY29udHJvbCBvZmZlcnMgbm93LiBOb3RoaW5nIGlzIHJlYWQgb3Igc2VudFxuICAvLyB1bnRpbCB0aGUgbGlzdCBpcyBzdWJzY3JpYmVkIHRvLCBzbyB0aGUgc2lnbmF0dXJlIGlzIHRoZSBvbmUgb2YgdGhlXG4gIC8vIG1vbWVudCB0aGUgY29udHJvbCBhc2tzLlxuICBwdWJsaWMgb3B0aW9ucyhncm91cDogUmVwb3J0RmlsdGVyR3JvdXAsIHJlcG9ydDogUmVwb3J0IHwgbnVsbCk6IE9ic2VydmFibGU8UmVwb3J0RmlsdGVyT3B0aW9uUGFpcltdPiB7XG4gICAgcmV0dXJuIGRlZmVyKCgpID0+IHtcbiAgICAgIGNvbnN0IG5hcnJvd2VkID0gISFyZXBvcnQ/LnZpZXdlckZlYXR1cmVzPy5pbmNsdWRlcygnY2FzY2FkaW5nT3B0aW9ucycpO1xuICAgICAgY29uc3QgaG9zdCA9IG9wdGlvbnNIb3N0KGdyb3VwLCBuYXJyb3dlZCk7XG5cbiAgICAgIGlmICghaG9zdCB8fCAhcmVwb3J0KSB7XG4gICAgICAgIHJldHVybiBvZihbXSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3N5bmNMb2FkKCk7XG4gICAgICBjb25zdCBzdHJlYW0gPSB0aGlzLl9zdHJlYW0oZ3JvdXAuaWQpO1xuICAgICAgY29uc3Qgc2VxID0gdGhpcy5fYXNrKHN0cmVhbSwgZ3JvdXAsIHJlcG9ydCwgaG9zdCwgbmFycm93ZWQpO1xuXG4gICAgICByZXR1cm4gc3RyZWFtLmxpc3RzJFxuICAgICAgICAucGlwZShcbiAgICAgICAgICBmaWx0ZXIoKGxpc3QpID0+IGxpc3Quc2VxID49IHNlcSksXG4gICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICBtYXAoKGxpc3QpID0+IGxpc3Qub3B0aW9ucyksXG4gICAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBUaGUgbmFtZSBhIHZhbHVlIG9mIHRoZSBncm91cCB3YXMgbGFzdCBsaXN0ZWQgb3IgbGFiZWxlZCB3aXRoIGluIHRoaXNcbiAgLy8gbG9hZCBvZiB0aGUgcmVwb3J0LCBvciBudWxsIHdoZW4gbm8gbGlzdCBvciBhbnN3ZXIgaGFzIG5hbWVkIGl0IHlldC5cbiAgcHVibGljIGxhYmVsKGdyb3VwSWQ6IG51bWJlciwgdmFsdWU6IHVua25vd24pOiBzdHJpbmcgfCBudWxsIHtcbiAgICB0aGlzLl9zeW5jTG9hZCgpO1xuXG4gICAgcmV0dXJuIHRoaXMuX2xhYmVscy5nZXQoZ3JvdXBJZCk/LmdldChTdHJpbmcodmFsdWUpKSA/PyBudWxsO1xuICB9XG5cbiAgLy8gV2hldGhlciB0aGUgZ3JvdXAncyBsYXRlc3QgbGlzdCB3YXMgY3V0IGF0IDUwMC5cbiAgcHVibGljIHRydW5jYXRlZChncm91cElkOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICB0aGlzLl9zeW5jTG9hZCgpO1xuXG4gICAgcmV0dXJuIHRoaXMuX3N0cmVhbXMuZ2V0KGdyb3VwSWQpPy50cnVuY2F0ZWQgPz8gZmFsc2U7XG4gIH1cblxuICAvLyBXaGV0aGVyIHRoZSBncm91cCdzIGxhdGVzdCByZXF1ZXN0IGZhaWxlZC4gSXRzIGxpc3QgaXMgdGhlbiBlbXB0eSwgYW5kXG4gIC8vIHRoZSBuZXh0IGFzayBmZXRjaGVzIGFnYWluLlxuICBwdWJsaWMgZmFpbGVkKGdyb3VwSWQ6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHRoaXMuX3N5bmNMb2FkKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fc3RyZWFtcy5nZXQoZ3JvdXBJZCk/LmZhaWxlZCA/PyBmYWxzZTtcbiAgfVxuXG4gIC8vIFNlbmRzIGEgcmVxdWVzdCB3aGVuIHRoZSBzaWduYXR1cmUgbW92ZWQsIG9yIHdoZW4gYSBwaWNrIGhhcyBubyBuYW1lXG4gIC8vIHlldCBhbmQgd2FzIG5ldmVyIGFza2VkIGZvci4gUmV0dXJucyB0aGUgbnVtYmVyIG9mIHRoZSByZXF1ZXN0IHdob3NlXG4gIC8vIGFuc3dlciB0aGUgY2FsbGVyIHRha2VzOiB0aGUgb25lIHNlbnQsIGVsc2UgdGhlIGxhdGVzdC5cbiAgcHJpdmF0ZSBfYXNrKFxuICAgIHN0cmVhbTogUmVwb3J0RmlsdGVyT3B0aW9uc1N0cmVhbSxcbiAgICBncm91cDogUmVwb3J0RmlsdGVyR3JvdXAsXG4gICAgcmVwb3J0OiBSZXBvcnQsXG4gICAgaG9zdDogUmVwb3J0RmlsdGVyLFxuICAgIG5hcnJvd2VkOiBib29sZWFuLFxuICApOiBudW1iZXIge1xuICAgIGNvbnN0IGJvZHkgPSBuYXJyb3dlZCA/IHRoaXMuX3JlcXVlc3QoZ3JvdXAsIHJlcG9ydCwgaG9zdCkgOiBudWxsO1xuICAgIC8vIFRoZSBob3N0IG1lbWJlciBpcyBwYXJ0IG9mIGl0OiBhIHJlcG9ydCBlZGl0IHRoYXQgbW92ZXMgdGhlIGdyb3VwJ3NcbiAgICAvLyBsaXN0IHRvIGFub3RoZXIgbWVtYmVyIG9yIGNvbHVtbiBsaXN0cyBhZ2Fpbi5cbiAgICBjb25zdCBzaWduYXR1cmUgPSBKU09OLnN0cmluZ2lmeShbaG9zdC5pZCwgaG9zdC5maWx0ZXJDb2x1bW4sIGJvZHk/LmZpbHRlcnMgPz8gbnVsbCwgYm9keT8ubWF0Y2hBbnlHcm91cElkcyA/PyBbXV0pO1xuICAgIGNvbnN0IHVubmFtZWQgPSAoYm9keT8uc2VsZWN0ZWQgPz8gW10pXG4gICAgICAuZmlsdGVyKCh2YWx1ZSkgPT4gdGhpcy5sYWJlbChncm91cC5pZCwgdmFsdWUpID09PSBudWxsICYmICF0aGlzLl9hc2tlZEZvcihncm91cC5pZCkuaGFzKFN0cmluZyh2YWx1ZSkpKTtcblxuICAgIGlmIChzaWduYXR1cmUgPT09IHN0cmVhbS5zaWduYXR1cmUgJiYgIXVubmFtZWQubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gc3RyZWFtLnNlcTtcbiAgICB9XG5cbiAgICB1bm5hbWVkLmZvckVhY2goKHZhbHVlKSA9PiB0aGlzLl9hc2tlZEZvcihncm91cC5pZCkuYWRkKFN0cmluZyh2YWx1ZSkpKTtcbiAgICBzdHJlYW0uc2lnbmF0dXJlID0gc2lnbmF0dXJlO1xuICAgIHN0cmVhbS5zZXEgKz0gMTtcbiAgICBzdHJlYW0ucmVxdWVzdHMkLm5leHQoeyBzZXE6IHN0cmVhbS5zZXEsIGZldGNoOiB0aGlzLl9mZXRjaChzdHJlYW0sIGdyb3VwLmlkLCByZXBvcnQuaWQsIGhvc3QuaWQsIGJvZHkpIH0pO1xuXG4gICAgcmV0dXJuIHN0cmVhbS5zZXE7XG4gIH1cblxuICAvLyBUaGUgbmFycm93ZWQgcmVxdWVzdCBmb3IgdGhlIGdyb3VwOiB3aGF0IGl0cyBob3N0IHRpbGUncyBkYXRhIHJlcXVlc3RcbiAgLy8gY2FycmllcyBub3csIG1pbnVzIHRoZSBlbnRyaWVzIHRoYXQgbXVzdCBub3QgbmFycm93IHRoZSBncm91cCdzIGxpc3QuXG4gIHByaXZhdGUgX3JlcXVlc3QoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwLCByZXBvcnQ6IFJlcG9ydCwgaG9zdDogUmVwb3J0RmlsdGVyKTogUmVwb3J0RmlsdGVyT3B0aW9uc1JlcXVlc3Qge1xuICAgIGNvbnN0IHRpbGUgPSByZXBvcnRDb21wb25lbnRzKHJlcG9ydCkuZmluZCgoY29tcG9uZW50KSA9PiBjb21wb25lbnQuaWQgPT09IGhvc3QuY29tcG9uZW50SWQpID8/IG51bGw7XG4gICAgY29uc3Qgc2VsZWN0ZWQgPSBncm91cFBpY2tzKHRoaXMuX2ZpbHRlclN0YXRlLnZhbHVlKGdyb3VwLmlkKSk7XG5cbiAgICBpZiAoIXRpbGUpIHtcbiAgICAgIHJldHVybiB7IGZpbHRlcnM6IFtdLCAuLi4oc2VsZWN0ZWQubGVuZ3RoID8geyBzZWxlY3RlZCB9IDoge30pIH07XG4gICAgfVxuXG4gICAgY29uc3Qgc25hcHNob3QgPSB0aGlzLl9maWx0ZXJTdGF0ZS5zbmFwc2hvdCgpO1xuICAgIC8vIEEgZ3JvdXAgd2hvc2Ugb25seSBtZW1iZXJzIGFyZSBpbmxpbmUgdmFsdWVzIGxpc3RzIHRocm91Z2ggYSB2YWx1ZSxcbiAgICAvLyB3aGljaCBjb21iaW5lcyBpdHMgZ3JvdXBzIGJ5IHRoZSB0aWxlIHJ1bGUgb3ZlciBpdHMgb3duIHBhZ2UuXG4gICAgY29uc3QgbWF0Y2hBbnlHcm91cElkcyA9IHRpbGUudHlwZSA9PT0gJ3ZhbHVlJ1xuICAgICAgPyB2YWx1ZXNNYXRjaEFueUdyb3VwSWRzKHJlcG9ydCwgdGlsZVBhZ2VJZChyZXBvcnQsIHRpbGUsIHNuYXBzaG90KSwgc25hcHNob3QpXG4gICAgICA6IHRpbGVEYXRhU3RhdGUocmVwb3J0LCB0aWxlLCBzbmFwc2hvdCkubWF0Y2hBbnlHcm91cElkcyA/PyBbXTtcbiAgICAvLyBVbmRlciAnYW55JyBhbm90aGVyIGdyb3VwIHRoaXMgb25lIGNvbWJpbmVzIHdpdGggZG9lcyBub3QgbGltaXQgd2hpY2hcbiAgICAvLyBvZiBpdHMgdmFsdWVzIGNhbiBzaG93IHJvd3MsIHNvIHRoZSBsaXN0IGxlYXZlcyBpdCBvdXQuXG4gICAgY29uc3QgY29tYmluZWQgPSBtYXRjaEFueUdyb3VwSWRzLmxlbmd0aCAmJiBpc01hdGNoQW55R3JvdXAoZ3JvdXAsIHRpbGVQYWdlSWQocmVwb3J0LCB0aWxlLCBzbmFwc2hvdCkpXG4gICAgICA/IG1hdGNoQW55R3JvdXBJZHNcbiAgICAgIDogW107XG4gICAgY29uc3QgZ3JvdXBPZiA9IG5ldyBNYXAoKHRpbGUuZmlsdGVycyA/PyBbXSkubWFwKChtZW1iZXIpID0+IFttZW1iZXIuaWQsIG1lbWJlci5maWx0ZXJHcm91cElkXSkpO1xuICAgIGNvbnN0IGZpbHRlcnMgPSB0aGlzLl9maWx0ZXJTdGF0ZS5yZXNvbHZlRm9yQ29tcG9uZW50KHRpbGUpXG4gICAgICAuZmlsdGVyKChlbnRyeSkgPT4ge1xuICAgICAgICBjb25zdCBncm91cElkID0gZ3JvdXBPZi5nZXQoZW50cnkuZmlsdGVySWQpID8/IG51bGw7XG5cbiAgICAgICAgcmV0dXJuICFpc0Nyb3NzRW50cnkoZW50cnkpICYmIGdyb3VwSWQgIT09IGdyb3VwLmlkICYmICFjb21iaW5lZC5pbmNsdWRlcyhncm91cElkKTtcbiAgICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGZpbHRlcnMsXG4gICAgICAuLi4obWF0Y2hBbnlHcm91cElkcy5sZW5ndGggPyB7IG1hdGNoQW55R3JvdXBJZHMgfSA6IHt9KSxcbiAgICAgIC4uLihzZWxlY3RlZC5sZW5ndGggPyB7IHNlbGVjdGVkIH0gOiB7fSksXG4gICAgfTtcbiAgfVxuXG4gIC8vIE9uZSByZXF1ZXN0J3MgYW5zd2VyIGFzIGEgbGlzdC4gQSBmYWlsZWQgcmVxdWVzdCBhbnN3ZXJzIGFuIGVtcHR5IGxpc3RcbiAgLy8gbWFya2VkIGZhaWxlZCwgYW5kIGNsZWFycyB0aGUgc2lnbmF0dXJlLCBzbyB0aGUgbmV4dCBhc2sgZmV0Y2hlcyBhZ2Fpbi5cbiAgcHJpdmF0ZSBfZmV0Y2goXG4gICAgc3RyZWFtOiBSZXBvcnRGaWx0ZXJPcHRpb25zU3RyZWFtLFxuICAgIGdyb3VwSWQ6IG51bWJlcixcbiAgICByZXBvcnRJZDogbnVtYmVyLFxuICAgIGZpbHRlcklkOiBudW1iZXIsXG4gICAgYm9keTogUmVwb3J0RmlsdGVyT3B0aW9uc1JlcXVlc3QgfCBudWxsLFxuICApOiBPYnNlcnZhYmxlPFJlcG9ydEZpbHRlck9wdGlvbnNMaXN0PiB7XG4gICAgY29uc3Qgc2VxID0gc3RyZWFtLnNlcTtcbiAgICAvLyBBbiBhbnN3ZXIgdGhhdCBsYW5kcyBhZnRlciB0aGUgcmVwb3J0IGxvYWRlZCBhZ2FpbiB0ZWFjaGVzIG5vIG5hbWUuXG4gICAgY29uc3QgbG9hZGVkID0gdGhpcy5fZmlsdGVyU3RhdGUucmVwb3J0KCk7XG4gICAgY29uc3QgYW5zd2VyJDogT2JzZXJ2YWJsZTxSZXBvcnRGaWx0ZXJPcHRpb25zPiA9IGJvZHlcbiAgICAgID8gdGhpcy5fcmVwb3J0RGF0YS5maWx0ZXJPcHRpb25zTmFycm93ZWQocmVwb3J0SWQsIGZpbHRlcklkLCBib2R5KVxuICAgICAgOiB0aGlzLl9yZXBvcnREYXRhLmZpbHRlck9wdGlvbnMocmVwb3J0SWQsIGZpbHRlcklkKVxuICAgICAgICAucGlwZShtYXAoKG9wdGlvbnM6IFJlcG9ydEZpbHRlck9wdGlvbltdKSA9PiAoeyBvcHRpb25zLCB0cnVuY2F0ZWQ6IGZhbHNlLCBuYXJyb3dlZEJ5OiBbXSwgc2VsZWN0ZWQ6IFtdIH0pKSk7XG5cbiAgICByZXR1cm4gYW5zd2VyJFxuICAgICAgLnBpcGUoXG4gICAgICAgIHRhcCgoYW5zd2VyKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMuX2ZpbHRlclN0YXRlLnJlcG9ydCgpID09PSBsb2FkZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlbWVtYmVyKGdyb3VwSWQsIFsuLi4oYW5zd2VyPy5vcHRpb25zID8/IFtdKSwgLi4uKGFuc3dlcj8uc2VsZWN0ZWQgPz8gW10pXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICAgICAgbWFwKChhbnN3ZXIpID0+ICh7XG4gICAgICAgICAgc2VxLFxuICAgICAgICAgIHRydW5jYXRlZDogISFhbnN3ZXI/LnRydW5jYXRlZCxcbiAgICAgICAgICBmYWlsZWQ6IGZhbHNlLFxuICAgICAgICAgIG9wdGlvbnM6IChhbnN3ZXI/Lm9wdGlvbnMgPz8gW10pLm1hcCgob3B0aW9uKSA9PiAoeyBuYW1lOiBvcHRpb24ubGFiZWwsIHZhbHVlOiBvcHRpb24udmFsdWUgfSkpLFxuICAgICAgICB9KSksXG4gICAgICAgIGNhdGNoRXJyb3IoKCkgPT4ge1xuICAgICAgICAgIHN0cmVhbS5zaWduYXR1cmUgPSBudWxsO1xuXG4gICAgICAgICAgcmV0dXJuIG9mKHsgc2VxLCB0cnVuY2F0ZWQ6IGZhbHNlLCBmYWlsZWQ6IHRydWUsIG9wdGlvbnM6IFtdIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH1cblxuICAvLyBUaGUgZ3JvdXAncyBzdHJlYW0sIG9wZW5lZCBvbiBpdHMgZmlyc3QgYXNrLiBJdCBpcyBzdWJzY3JpYmVkIHRvIGhlcmUsXG4gIC8vIGZvciB0aGUgbGlmZSBvZiB0aGUgcmVwb3J0IHZpZXcsIHNvIGFuIGFuc3dlciBpcyBrZXB0IGZvciB0aGUgbmV4dCBhc2tcbiAgLy8gZXZlbiB3aGVuIHRoZSBjb250cm9sIHRoYXQgYXNrZWQgaGFzIG1vdmVkIG9uLiBXaGVuIHRoZSB2aWV3IGdvZXMsIHRoZVxuICAvLyBzdHJlYW0gZW5kczogYSByZXF1ZXN0IHN0aWxsIGluIGZsaWdodCBpcyBkcm9wcGVkLCB3aG9ldmVyIHN0aWxsIGxpc3RlbnMuXG4gIHByaXZhdGUgX3N0cmVhbShncm91cElkOiBudW1iZXIpOiBSZXBvcnRGaWx0ZXJPcHRpb25zU3RyZWFtIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuX3N0cmVhbXMuZ2V0KGdyb3VwSWQpO1xuICAgIGlmIChleGlzdGluZykge1xuICAgICAgcmV0dXJuIGV4aXN0aW5nO1xuICAgIH1cblxuICAgIGNvbnN0IHJlcXVlc3RzJCA9IG5ldyBTdWJqZWN0PFJlcG9ydEZpbHRlck9wdGlvbnNBc2s+KCk7XG4gICAgY29uc3Qgc3RyZWFtOiBSZXBvcnRGaWx0ZXJPcHRpb25zU3RyZWFtID0ge1xuICAgICAgc2lnbmF0dXJlOiBudWxsLFxuICAgICAgc2VxOiAwLFxuICAgICAgdHJ1bmNhdGVkOiBmYWxzZSxcbiAgICAgIGZhaWxlZDogZmFsc2UsXG4gICAgICByZXF1ZXN0cyQsXG4gICAgICBsaXN0cyQ6IHJlcXVlc3RzJFxuICAgICAgICAucGlwZShcbiAgICAgICAgICBzd2l0Y2hNYXAoKHJlcXVlc3QpID0+IHJlcXVlc3QuZmV0Y2gpLFxuICAgICAgICAgIHRhcCgobGlzdCkgPT4ge1xuICAgICAgICAgICAgc3RyZWFtLnRydW5jYXRlZCA9IGxpc3QudHJ1bmNhdGVkO1xuICAgICAgICAgICAgc3RyZWFtLmZhaWxlZCA9IGxpc3QuZmFpbGVkO1xuICAgICAgICAgIH0pLFxuICAgICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgICAgICBzaGFyZVJlcGxheSh7IGJ1ZmZlclNpemU6IDEsIHJlZkNvdW50OiBmYWxzZSB9KSxcbiAgICAgICAgKSxcbiAgICB9O1xuXG4gICAgLy8gRW5kcyB3aXRoIHRoZSBzdHJlYW0sIHdoZW4gdGhlIHZpZXcgZ29lcy5cbiAgICBzdHJlYW0ubGlzdHMkLnN1YnNjcmliZSgpO1xuICAgIHRoaXMuX3N0cmVhbXMuc2V0KGdyb3VwSWQsIHN0cmVhbSk7XG5cbiAgICByZXR1cm4gc3RyZWFtO1xuICB9XG5cbiAgLy8gQSBuZXcgbG9hZCBvZiB0aGUgcmVwb3J0IChpbml0KCkgcmVhZCBhbm90aGVyIHJlcG9ydCBvYmplY3QpIGRyb3BzIHdoYXRcbiAgLy8gdGhlIGxhc3QgbG9hZCBsZWFybmVkOiBldmVyeSBzaWduYXR1cmUsIHNvIGVhY2ggbGlzdCBpcyBmZXRjaGVkIGFnYWluIG9uXG4gIC8vIGl0cyBuZXh0IGFzaywgYW5kIGV2ZXJ5IG5hbWUgYW5kIGFza2VkIHBpY2suXG4gIHByaXZhdGUgX3N5bmNMb2FkKCk6IHZvaWQge1xuICAgIGNvbnN0IGxvYWRlZCA9IHRoaXMuX2ZpbHRlclN0YXRlLnJlcG9ydCgpO1xuICAgIGlmIChsb2FkZWQgPT09IHRoaXMuX2xvYWRlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2xvYWRlZCA9IGxvYWRlZDtcbiAgICB0aGlzLl9zdHJlYW1zLmZvckVhY2goKHN0cmVhbSkgPT4ge1xuICAgICAgc3RyZWFtLnNpZ25hdHVyZSA9IG51bGw7XG4gICAgfSk7XG4gICAgdGhpcy5fbGFiZWxzLmNsZWFyKCk7XG4gICAgdGhpcy5fYXNrZWQuY2xlYXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlbWVtYmVyKGdyb3VwSWQ6IG51bWJlciwgb3B0aW9uczogUmVwb3J0RmlsdGVyT3B0aW9uW10pOiB2b2lkIHtcbiAgICBjb25zdCBsYWJlbHMgPSB0aGlzLl9sYWJlbHMuZ2V0KGdyb3VwSWQpID8/IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG5cbiAgICBmb3IgKGNvbnN0IG9wdGlvbiBvZiBvcHRpb25zKSB7XG4gICAgICBpZiAob3B0aW9uICYmIHR5cGVvZiBvcHRpb24ubGFiZWwgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGxhYmVscy5zZXQoU3RyaW5nKG9wdGlvbi52YWx1ZSksIG9wdGlvbi5sYWJlbCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fbGFiZWxzLnNldChncm91cElkLCBsYWJlbHMpO1xuICB9XG5cbiAgcHJpdmF0ZSBfYXNrZWRGb3IoZ3JvdXBJZDogbnVtYmVyKTogU2V0PHN0cmluZz4ge1xuICAgIGNvbnN0IGFza2VkID0gdGhpcy5fYXNrZWQuZ2V0KGdyb3VwSWQpID8/IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIHRoaXMuX2Fza2VkLnNldChncm91cElkLCBhc2tlZCk7XG5cbiAgICByZXR1cm4gYXNrZWQ7XG4gIH1cbn1cblxuXG4vLyBUaGUgbWVtYmVyIHdob3NlIGxpc3QgYSBncm91cCBzaG93cy4gVGhlIG5hcnJvd2VkIFBPU1QgbmFtZXMgdGhlIHNlcnZlcidzXG4vLyBob3N0OiB0aGUgZmlyc3QgZW5hYmxlZCBtZW1iZXIgd2l0aCBvcHRpb25zLCBlbHNlIHRoZSBmaXJzdCB3aXRoIG9wdGlvbnMuXG4vLyBUaGUgb3B0aW9ucyBHRVQga2VlcHMgaXRzIG9sZGVyIHJ1bGUsIHRoZSBmaXJzdCBtZW1iZXIgd2l0aCBvcHRpb25zLCBhc1xuLy8gbG9hZEdyb3VwT3B0aW9ucyBkb2VzLCBzbyBhbiBvbGRlciBzZXJ2ZXIgaXMgYXNrZWQgd2hhdCBpdCBhbHdheXMgd2FzLlxuZnVuY3Rpb24gb3B0aW9uc0hvc3QoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwLCBuYXJyb3dlZDogYm9vbGVhbik6IFJlcG9ydEZpbHRlciB8IG51bGwge1xuICBjb25zdCBtZW1iZXJzID0gKGdyb3VwLmZpbHRlcnMgPz8gW10pLmZpbHRlcigobWVtYmVyKSA9PiBtZW1iZXIuaGFzT3B0aW9ucyk7XG5cbiAgcmV0dXJuIChuYXJyb3dlZCA/IG1lbWJlcnMuZmluZCgobWVtYmVyKSA9PiBtZW1iZXIuZW5hYmxlZCkgOiBudWxsKSA/PyBtZW1iZXJzWzBdID8/IG51bGw7XG59XG5cbi8vIEEgY3Jvc3MtZmlsdGVyIGVudHJ5IHJpZGVzIGluIHRoZSBzYW1lIGZpbHRlcnMgYXJyYXkgYXMgdGhlIGdyb3VwIGVudHJpZXNcbi8vIGFuZCBjYXJyaWVzIGl0cyBjcm9zc0ZpbHRlcklkLiBJdCBuZXZlciBuYXJyb3dzIGEgbGlzdDogYSBjbGljayBpcyBhXG4vLyB0ZW1wb3JhcnkgbG9vaywgYW5kIHRoZSBjaGlwIG9mIHRoZSBjcm9zcy1maWx0ZXIgYWxyZWFkeSBzaG93cyBpdC5cbmZ1bmN0aW9uIGlzQ3Jvc3NFbnRyeShlbnRyeTogUmVzb2x2ZWRGaWx0ZXJWYWx1ZSk6IGJvb2xlYW4ge1xuICByZXR1cm4gJ2Nyb3NzRmlsdGVySWQnIGluIGVudHJ5O1xufVxuXG4vLyBBIHNlbGVjdCBncm91cCdzIHBpY2tzLCBrZXB0IG9yIGxlZnQgb3V0LCB0aGF0IGEgcmVxdWVzdCBjYW4gbmFtZTogdGV4dFxuLy8gYW5kIG51bWJlcnMsIGF0IG1vc3QgU0VMRUNURURfQ0FQLlxuZnVuY3Rpb24gZ3JvdXBQaWNrcyh2YWx1ZTogRmlsdGVyR3JvdXBWYWx1ZSB8IHVuZGVmaW5lZCk6IChzdHJpbmcgfCBudW1iZXIpW10ge1xuICByZXR1cm4gWy4uLih2YWx1ZT8udmFsdWVzID8/IFtdKSwgLi4uKHZhbHVlPy5leGNsdWRlVmFsdWVzID8/IFtdKV1cbiAgICAuZmlsdGVyKChwaWNrKTogcGljayBpcyBzdHJpbmcgfCBudW1iZXIgPT4gdHlwZW9mIHBpY2sgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBwaWNrID09PSAnbnVtYmVyJylcbiAgICAuc2xpY2UoMCwgU0VMRUNURURfQ0FQKTtcbn1cbiJdfQ==
|