@firestitch/report 18.9.0 → 18.10.1
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 +20 -7
- package/app/reports/dialogs/component-settings/component-settings.component.d.ts +18 -3
- package/app/reports/dialogs/report-settings/report-settings.component.d.ts +45 -8
- 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 +37 -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-group-changes.interface.d.ts +7 -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-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 -16
- 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 +20 -21
- package/app/reports/report-tile.d.ts +2 -0
- package/app/reports/report-view-config.d.ts +34 -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 -11
- package/app/reports/services/report-view.service.d.ts +39 -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 +10 -8
- 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 +26 -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 +11 -5
- package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +56 -40
- package/esm2022/app/reports/components/report-component/report-component.component.mjs +261 -65
- package/esm2022/app/reports/components/report-view-picker/report-view-picker.component.mjs +115 -0
- package/esm2022/app/reports/data/report.data.mjs +94 -14
- package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +106 -51
- package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +248 -104
- 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 +290 -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-group-changes.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-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 +263 -72
- package/esm2022/app/reports/report-tile.mjs +12 -0
- package/esm2022/app/reports/report-view-config.mjs +587 -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 +668 -210
- package/esm2022/app/reports/services/report-view.service.mjs +218 -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 +194 -127
- package/esm2022/app/reports/views/report/report.component.mjs +112 -29
- package/esm2022/public_api.mjs +23 -1
- package/fesm2022/{firestitch-report-echarts-DBMOHmBF.mjs → firestitch-report-echarts-DHEH_K_q.mjs} +2 -2
- package/fesm2022/{firestitch-report-echarts-DBMOHmBF.mjs.map → firestitch-report-echarts-DHEH_K_q.mjs.map} +1 -1
- package/fesm2022/{firestitch-report-firestitch-report-CqbXT1gh.mjs → firestitch-report-firestitch-report-ZcHTnNKq.mjs} +8222 -4447
- package/fesm2022/firestitch-report-firestitch-report-ZcHTnNKq.mjs.map +1 -0
- package/fesm2022/firestitch-report.mjs +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +22 -0
- package/app/reports/report-url-state.d.ts +0 -19
- package/esm2022/app/reports/report-url-state.mjs +0 -189
- package/fesm2022/firestitch-report-firestitch-report-CqbXT1gh.mjs.map +0 -1
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { forkJoin, of } from 'rxjs';
|
|
2
|
+
import { catchError, map } from 'rxjs/operators';
|
|
3
|
+
import { crumbedTitle, drillCrumbLabels } from '../drill-crumbs';
|
|
4
|
+
import { formatDayRange, formatPlainNumber } from '../format';
|
|
5
|
+
import { GRANULARITY_OPTIONS, } from '../interfaces/report.interface';
|
|
6
|
+
import { dateBoundLabel, dateBoundString, relativeLabel } from '../report-filter-items';
|
|
7
|
+
import { isTile } from '../report-tile';
|
|
8
|
+
import { finiteNumber } from '../report-view-config';
|
|
9
|
+
// The words a file uses for what the screen held: each filter's value, the
|
|
10
|
+
// group-by grain, a drilled tile, the match and the open view. The PDF and
|
|
11
|
+
// PowerPoint covers print these lines, and the zip sends them (filterLines,
|
|
12
|
+
// with filterSummary as their text for an older server), so every export
|
|
13
|
+
// words one filter one way. Pure, so the node harness checks every wording.
|
|
14
|
+
// The match while the report bar's filters combine with 'any': the chip's
|
|
15
|
+
// words, and the cover's line. The zip's notes carry the server's own
|
|
16
|
+
// sentence instead.
|
|
17
|
+
export const MATCH_ANY_CHIP = 'Match: any filter';
|
|
18
|
+
export const MATCH_ANY_LINE = 'Filters in the report bar: match any';
|
|
19
|
+
// The report bar's Match chip while the filters combine with 'all'. A file
|
|
20
|
+
// prints no line for it.
|
|
21
|
+
export const MATCH_ALL_CHIP = 'Match: all filters';
|
|
22
|
+
// A group's label when it has none.
|
|
23
|
+
const UNLABELED_GROUP = 'Filter';
|
|
24
|
+
// The label of the group-by line when the report names no control.
|
|
25
|
+
const GROUP_BY_LABEL = 'Group By';
|
|
26
|
+
// One filter group's value as text ('Region: West, East'), or null when the
|
|
27
|
+
// value holds nothing. Values left out say so before the label: 'Exclude
|
|
28
|
+
// Region: West, East'. 'chip' is the short form; 'line' adds what a file
|
|
29
|
+
// reader cannot see on screen:
|
|
30
|
+
// - exclude: 'Exclude Region: West, East (rows with no Region are kept)', or
|
|
31
|
+
// '... are left out' when the blank label (context.blankLabel) is one of
|
|
32
|
+
// the values left out. Without a known blank label the line says nothing
|
|
33
|
+
// about the blank rows;
|
|
34
|
+
// - range: 'Amount: 10 to 50 (both included)'; an open end reads '10 or
|
|
35
|
+
// more' or '50 or less' in both forms;
|
|
36
|
+
// - a live preset: 'Report Period: Last 30 days (Sep 3 – Oct 2, 2026)';
|
|
37
|
+
// - a page group: 'Cohort (page "Retention" only): 2025'.
|
|
38
|
+
// Numbers and dates are written in the report's locale, and 0 is a number
|
|
39
|
+
// like any other.
|
|
40
|
+
export function filterLineText(group, value, context, form) {
|
|
41
|
+
const label = group.label || UNLABELED_GROUP;
|
|
42
|
+
const text = value ? valueText(label, value, context, form) : null;
|
|
43
|
+
if (text === null) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const pageOnly = form === 'line' && group.level === 'page' && context.pageName;
|
|
47
|
+
const name = pageOnly ? `${label} (page "${context.pageName}" only)` : label;
|
|
48
|
+
return `${excludes(value) ? 'Exclude ' : ''}${name}: ${text}`;
|
|
49
|
+
}
|
|
50
|
+
// The match as text while it is 'any', else null; the chip also words 'all'.
|
|
51
|
+
export function matchLineText(match, form) {
|
|
52
|
+
if (match !== 'any') {
|
|
53
|
+
return form === 'chip' && match === 'all' ? MATCH_ALL_CHIP : null;
|
|
54
|
+
}
|
|
55
|
+
return form === 'chip' ? MATCH_ANY_CHIP : MATCH_ANY_LINE;
|
|
56
|
+
}
|
|
57
|
+
// A drilled tile's line: its title and the breadcrumb of its path, in the
|
|
58
|
+
// report's locale ('Revenue by Period › 2026 › Q3').
|
|
59
|
+
export function drillLineText(component, path, formatContext) {
|
|
60
|
+
return crumbedTitle(component.title, drillCrumbLabels(path, formatContext));
|
|
61
|
+
}
|
|
62
|
+
// The cover's line for the open saved view: 'View: "Q3 North" (shared)',
|
|
63
|
+
// with ', changed since it was opened' while the screen differs from it.
|
|
64
|
+
// Null when no view is open.
|
|
65
|
+
export function viewLineText(view, changed) {
|
|
66
|
+
if (!view) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const line = `View: "${(view.name ?? '').trim()}" (${view.shared ? 'shared' : 'personal'})`;
|
|
70
|
+
return changed ? `${line}, changed since it was opened` : line;
|
|
71
|
+
}
|
|
72
|
+
// The filter lines of an export, in order: one per filter group with a
|
|
73
|
+
// value (the report's group order), the group-by line, then one per drilled
|
|
74
|
+
// chart (page order). A This Page export (input.pageId) lists only the
|
|
75
|
+
// groups that reach a tile of that page, and only that page's drilled
|
|
76
|
+
// charts. A select's names are a request, so the lines arrive together once
|
|
77
|
+
// every name is known; a failed name read writes the picks as they are
|
|
78
|
+
// stored.
|
|
79
|
+
export function exportLines(input) {
|
|
80
|
+
const groups$ = exportGroups(input.report, input.pageId)
|
|
81
|
+
.map((group) => groupLine(group, input));
|
|
82
|
+
const rest = [groupByLine(input), ...drillLines(input)]
|
|
83
|
+
.filter((line) => line !== null);
|
|
84
|
+
return (groups$.length ? forkJoin(groups$) : of([]))
|
|
85
|
+
.pipe(map((lines) => [
|
|
86
|
+
...lines.filter((line) => line !== null),
|
|
87
|
+
...rest,
|
|
88
|
+
]));
|
|
89
|
+
}
|
|
90
|
+
// The groups an export's lines may name: every group, or for a This Page
|
|
91
|
+
// export the groups with a member tile on that page. A page group reaches
|
|
92
|
+
// only its own page.
|
|
93
|
+
export function exportGroups(report, pageId) {
|
|
94
|
+
const groups = report.filterGroups ?? [];
|
|
95
|
+
if (!pageId) {
|
|
96
|
+
return groups;
|
|
97
|
+
}
|
|
98
|
+
const page = (report.pages ?? []).find((candidate) => candidate.id === pageId);
|
|
99
|
+
const tileIds = (page?.components ?? [])
|
|
100
|
+
.filter((component) => isTile(component))
|
|
101
|
+
.map((component) => component.id);
|
|
102
|
+
return groups.filter((group) => (group.level !== 'page' || group.pageId === pageId)
|
|
103
|
+
&& groupMemberIds(group).some((componentId) => tileIds.includes(componentId)));
|
|
104
|
+
}
|
|
105
|
+
// The text after the label, or null when the value holds nothing.
|
|
106
|
+
function valueText(label, value, context, form) {
|
|
107
|
+
if (value.start || value.end) {
|
|
108
|
+
return dateText(value, context, form);
|
|
109
|
+
}
|
|
110
|
+
if (value.values?.length) {
|
|
111
|
+
return pickNames(value.values, context).join(', ');
|
|
112
|
+
}
|
|
113
|
+
if (value.excludeValues?.length) {
|
|
114
|
+
return excludeText(label, value.excludeValues, context, form);
|
|
115
|
+
}
|
|
116
|
+
const keyword = typeof value.value === 'string' ? value.value.trim() : '';
|
|
117
|
+
return rangeText(value, context, form) ?? (keyword ? `"${keyword}"` : null);
|
|
118
|
+
}
|
|
119
|
+
// A date range: a live preset by its name (with its days in a line), else
|
|
120
|
+
// its two days ('…' for an open end).
|
|
121
|
+
function dateText(value, context, form) {
|
|
122
|
+
if (context.preset) {
|
|
123
|
+
const name = relativeLabel(context.preset);
|
|
124
|
+
const days = form === 'line'
|
|
125
|
+
? formatDayRange(dateBoundString(value.start), dateBoundString(value.end), context.locale)
|
|
126
|
+
: '';
|
|
127
|
+
return days ? `${name} (${days})` : name;
|
|
128
|
+
}
|
|
129
|
+
return `${dateBoundLabel(value.start, context.locale) ?? '…'} – ${dateBoundLabel(value.end, context.locale) ?? '…'}`;
|
|
130
|
+
}
|
|
131
|
+
// Whether a value is worded as values left out: the same order valueText
|
|
132
|
+
// reads a value in, so a value with days or kept picks is never one.
|
|
133
|
+
function excludes(value) {
|
|
134
|
+
return !value.start && !value.end && !value.values?.length && !!value.excludeValues?.length;
|
|
135
|
+
}
|
|
136
|
+
// The values a select leaves out. A line says what happens to the rows with
|
|
137
|
+
// no value: they stay, unless the group's blank label is one of the values
|
|
138
|
+
// left out. While the blank label is unknown (undefined) the line says
|
|
139
|
+
// nothing about them: a blank label among the picks would make 'are kept'
|
|
140
|
+
// false.
|
|
141
|
+
function excludeText(label, values, context, form) {
|
|
142
|
+
const text = pickNames(values, context).join(', ');
|
|
143
|
+
const blankLabel = context.blankLabel;
|
|
144
|
+
if (form === 'chip' || blankLabel === undefined) {
|
|
145
|
+
return text;
|
|
146
|
+
}
|
|
147
|
+
const blank = blankLabel !== null && values.some((value) => String(value) === blankLabel);
|
|
148
|
+
return `${text} (rows with no ${label} ${blank ? 'are left out' : 'are kept'})`;
|
|
149
|
+
}
|
|
150
|
+
// A number range's ends in the report's locale, or null with neither.
|
|
151
|
+
function rangeText(value, context, form) {
|
|
152
|
+
const min = finiteNumber(value.min);
|
|
153
|
+
const max = finiteNumber(value.max);
|
|
154
|
+
const write = (end) => formatPlainNumber(end, context.locale);
|
|
155
|
+
if (min !== undefined && max !== undefined) {
|
|
156
|
+
return `${write(min)} to ${write(max)}${form === 'line' ? ' (both included)' : ''}`;
|
|
157
|
+
}
|
|
158
|
+
if (min !== undefined) {
|
|
159
|
+
return `${write(min)} or more`;
|
|
160
|
+
}
|
|
161
|
+
return max !== undefined ? `${write(max)} or less` : null;
|
|
162
|
+
}
|
|
163
|
+
// The picks' names: the ones the caller resolved, else each pick as stored.
|
|
164
|
+
function pickNames(values, context) {
|
|
165
|
+
const names = context.names;
|
|
166
|
+
return values.map((value, index) => names?.[index] ?? String(value));
|
|
167
|
+
}
|
|
168
|
+
// One group's line, once its picks are named. An exclude line says what
|
|
169
|
+
// happens to the blank rows from the group's blank label, which the server
|
|
170
|
+
// sends on a select group (null: blank rows have none). An older server
|
|
171
|
+
// sends none, and the line then says nothing about them.
|
|
172
|
+
function groupLine(group, input) {
|
|
173
|
+
const snapshot = input.snapshot;
|
|
174
|
+
const value = snapshot.values[group.id];
|
|
175
|
+
if (!value) {
|
|
176
|
+
return of(null);
|
|
177
|
+
}
|
|
178
|
+
const picks = value.start || value.end ? [] : (value.values?.length ? value.values : value.excludeValues ?? []);
|
|
179
|
+
const names$ = picks.length
|
|
180
|
+
? input.names(group, picks).pipe(catchError(() => of(null)))
|
|
181
|
+
: of(null);
|
|
182
|
+
return names$.pipe(map((names) => {
|
|
183
|
+
const text = filterLineText(group, value, {
|
|
184
|
+
locale: snapshot.formatContext.locale,
|
|
185
|
+
names,
|
|
186
|
+
preset: snapshot.presets[group.id] ?? null,
|
|
187
|
+
pageName: pageName(input.report, group.pageId),
|
|
188
|
+
blankLabel: group.blankLabel,
|
|
189
|
+
}, 'line');
|
|
190
|
+
return text ? { kind: 'group', text, groupId: group.id } : null;
|
|
191
|
+
}));
|
|
192
|
+
}
|
|
193
|
+
// The group-by grain under the report's own name for the control, or null
|
|
194
|
+
// while no grain is picked.
|
|
195
|
+
function groupByLine(input) {
|
|
196
|
+
const frequency = input.snapshot.frequency;
|
|
197
|
+
if (!frequency) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
const option = GRANULARITY_OPTIONS.find((item) => item.value === frequency);
|
|
201
|
+
const label = input.report.config?.groupBy?.label || GROUP_BY_LABEL;
|
|
202
|
+
return { kind: 'groupBy', text: `${label}: ${option?.name ?? frequency}` };
|
|
203
|
+
}
|
|
204
|
+
// One line per drilled chart of the export's pages, while the server drills.
|
|
205
|
+
function drillLines(input) {
|
|
206
|
+
const { report, snapshot, pageId } = input;
|
|
207
|
+
if (!snapshot.features.includes('drill')) {
|
|
208
|
+
return [];
|
|
209
|
+
}
|
|
210
|
+
return (report.pages ?? [])
|
|
211
|
+
.filter((page) => !pageId || page.id === pageId)
|
|
212
|
+
.flatMap((page) => page.components ?? [])
|
|
213
|
+
.filter((component) => component.type === 'chart' && !!snapshot.view.tiles?.[component.id]?.drill?.length)
|
|
214
|
+
.map((component) => ({
|
|
215
|
+
kind: 'drill',
|
|
216
|
+
text: drillLineText(component, snapshot.view.tiles[component.id].drill, snapshot.formatContext),
|
|
217
|
+
componentId: component.id,
|
|
218
|
+
}));
|
|
219
|
+
}
|
|
220
|
+
// The tiles a group's members sit on: the server's list, else the tiles of
|
|
221
|
+
// its enabled members (an older server).
|
|
222
|
+
function groupMemberIds(group) {
|
|
223
|
+
return group.componentIds
|
|
224
|
+
?? (group.filters ?? []).filter((member) => member.enabled).map((member) => member.componentId);
|
|
225
|
+
}
|
|
226
|
+
// A page's name as the export names it ('Page 2' when it has none), or null
|
|
227
|
+
// for no page.
|
|
228
|
+
function pageName(report, pageId) {
|
|
229
|
+
const index = pageId ? (report.pages ?? []).findIndex((page) => page.id === pageId) : -1;
|
|
230
|
+
if (index < 0) {
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
return report.pages[index].name || `Page ${index + 1}`;
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWZpbHRlci1saW5lcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9leHBvcnQvcmVwb3J0LWZpbHRlci1saW5lcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWMsUUFBUSxFQUFFLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNoRCxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWpELE9BQU8sRUFBRSxZQUFZLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsY0FBYyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sV0FBVyxDQUFDO0FBUTlELE9BQU8sRUFFTCxtQkFBbUIsR0FLcEIsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN4QyxPQUFPLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN4RixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBR3JELDJFQUEyRTtBQUMzRSwyRUFBMkU7QUFDM0UsNEVBQTRFO0FBQzVFLHlFQUF5RTtBQUN6RSw0RUFBNEU7QUFHNUUsMEVBQTBFO0FBQzFFLHNFQUFzRTtBQUN0RSxvQkFBb0I7QUFDcEIsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHLG1CQUFtQixDQUFDO0FBQ2xELE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxzQ0FBc0MsQ0FBQztBQUVyRSwyRUFBMkU7QUFDM0UseUJBQXlCO0FBQ3pCLE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxvQkFBb0IsQ0FBQztBQUVuRCxvQ0FBb0M7QUFDcEMsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDO0FBRWpDLG1FQUFtRTtBQUNuRSxNQUFNLGNBQWMsR0FB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LElBQUksS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ2QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksSUFBSSxRQUFRLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQztBQUN6RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgT2JzZXJ2YWJsZSwgZm9ya0pvaW4sIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IGNydW1iZWRUaXRsZSwgZHJpbGxDcnVtYkxhYmVscyB9IGZyb20gJy4uL2RyaWxsLWNydW1icyc7XG5pbXBvcnQgeyBmb3JtYXREYXlSYW5nZSwgZm9ybWF0UGxhaW5OdW1iZXIgfSBmcm9tICcuLi9mb3JtYXQnO1xuaW1wb3J0IHsgUmVwb3J0RHJpbGxTdGVwIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtZHJpbGwtc3RlcC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0RXhwb3J0TGluZSB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LWV4cG9ydC1saW5lLmludGVyZmFjZSc7XG5pbXBvcnQgeyBSZXBvcnRFeHBvcnRMaW5lc0lucHV0IH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtZXhwb3J0LWxpbmVzLWlucHV0LmludGVyZmFjZSc7XG5pbXBvcnQgeyBSZXBvcnRGaWx0ZXJMaW5lQ29udGV4dCB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LWZpbHRlci1saW5lLWNvbnRleHQuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlcG9ydEZpbHRlckxpbmVGb3JtIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtZmlsdGVyLWxpbmUtZm9ybS50eXBlJztcbmltcG9ydCB7IFJlcG9ydEZpbHRlck1hdGNoIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtZmlsdGVyLW1hdGNoLnR5cGUnO1xuaW1wb3J0IHsgUmVwb3J0Vmlld1N1bW1hcnkgfSBmcm9tICcuLi9pbnRlcmZhY2VzL3JlcG9ydC12aWV3LXN1bW1hcnkuaW50ZXJmYWNlJztcbmltcG9ydCB7XG4gIEZpbHRlckdyb3VwVmFsdWUsXG4gIEdSQU5VTEFSSVRZX09QVElPTlMsXG4gIFJlcG9ydCxcbiAgUmVwb3J0Q29tcG9uZW50LFxuICBSZXBvcnRGaWx0ZXJHcm91cCxcbiAgUmVwb3J0Rm9ybWF0Q29udGV4dCxcbn0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IGRhdGVCb3VuZExhYmVsLCBkYXRlQm91bmRTdHJpbmcsIHJlbGF0aXZlTGFiZWwgfSBmcm9tICcuLi9yZXBvcnQtZmlsdGVyLWl0ZW1zJztcbmltcG9ydCB7IGlzVGlsZSB9IGZyb20gJy4uL3JlcG9ydC10aWxlJztcbmltcG9ydCB7IGZpbml0ZU51bWJlciB9IGZyb20gJy4uL3JlcG9ydC12aWV3LWNvbmZpZyc7XG5cblxuLy8gVGhlIHdvcmRzIGEgZmlsZSB1c2VzIGZvciB3aGF0IHRoZSBzY3JlZW4gaGVsZDogZWFjaCBmaWx0ZXIncyB2YWx1ZSwgdGhlXG4vLyBncm91cC1ieSBncmFpbiwgYSBkcmlsbGVkIHRpbGUsIHRoZSBtYXRjaCBhbmQgdGhlIG9wZW4gdmlldy4gVGhlIFBERiBhbmRcbi8vIFBvd2VyUG9pbnQgY292ZXJzIHByaW50IHRoZXNlIGxpbmVzLCBhbmQgdGhlIHppcCBzZW5kcyB0aGVtIChmaWx0ZXJMaW5lcyxcbi8vIHdpdGggZmlsdGVyU3VtbWFyeSBhcyB0aGVpciB0ZXh0IGZvciBhbiBvbGRlciBzZXJ2ZXIpLCBzbyBldmVyeSBleHBvcnRcbi8vIHdvcmRzIG9uZSBmaWx0ZXIgb25lIHdheS4gUHVyZSwgc28gdGhlIG5vZGUgaGFybmVzcyBjaGVja3MgZXZlcnkgd29yZGluZy5cblxuXG4vLyBUaGUgbWF0Y2ggd2hpbGUgdGhlIHJlcG9ydCBiYXIncyBmaWx0ZXJzIGNvbWJpbmUgd2l0aCAnYW55JzogdGhlIGNoaXAnc1xuLy8gd29yZHMsIGFuZCB0aGUgY292ZXIncyBsaW5lLiBUaGUgemlwJ3Mgbm90ZXMgY2FycnkgdGhlIHNlcnZlcidzIG93blxuLy8gc2VudGVuY2UgaW5zdGVhZC5cbmV4cG9ydCBjb25zdCBNQVRDSF9BTllfQ0hJUCA9ICdNYXRjaDogYW55IGZpbHRlcic7XG5leHBvcnQgY29uc3QgTUFUQ0hfQU5ZX0xJTkUgPSAnRmlsdGVycyBpbiB0aGUgcmVwb3J0IGJhcjogbWF0Y2ggYW55JztcblxuLy8gVGhlIHJlcG9ydCBiYXIncyBNYXRjaCBjaGlwIHdoaWxlIHRoZSBmaWx0ZXJzIGNvbWJpbmUgd2l0aCAnYWxsJy4gQSBmaWxlXG4vLyBwcmludHMgbm8gbGluZSBmb3IgaXQuXG5leHBvcnQgY29uc3QgTUFUQ0hfQUxMX0NISVAgPSAnTWF0Y2g6IGFsbCBmaWx0ZXJzJztcblxuLy8gQSBncm91cCdzIGxhYmVsIHdoZW4gaXQgaGFzIG5vbmUuXG5jb25zdCBVTkxBQkVMRURfR1JPVVAgPSAnRmlsdGVyJztcblxuLy8gVGhlIGxhYmVsIG9mIHRoZSBncm91cC1ieSBsaW5lIHdoZW4gdGhlIHJlcG9ydCBuYW1lcyBubyBjb250cm9sLlxuY29uc3QgR1JPVVBfQllfTEFCRUwgPSAnR3JvdXAgQnknO1xuXG5cbi8vIE9uZSBmaWx0ZXIgZ3JvdXAncyB2YWx1ZSBhcyB0ZXh0ICgnUmVnaW9uOiBXZXN0LCBFYXN0JyksIG9yIG51bGwgd2hlbiB0aGVcbi8vIHZhbHVlIGhvbGRzIG5vdGhpbmcuIFZhbHVlcyBsZWZ0IG91dCBzYXkgc28gYmVmb3JlIHRoZSBsYWJlbDogJ0V4Y2x1ZGVcbi8vIFJlZ2lvbjogV2VzdCwgRWFzdCcuICdjaGlwJyBpcyB0aGUgc2hvcnQgZm9ybTsgJ2xpbmUnIGFkZHMgd2hhdCBhIGZpbGVcbi8vIHJlYWRlciBjYW5ub3Qgc2VlIG9uIHNjcmVlbjpcbi8vIC0gZXhjbHVkZTogJ0V4Y2x1ZGUgUmVnaW9uOiBXZXN0LCBFYXN0IChyb3dzIHdpdGggbm8gUmVnaW9uIGFyZSBrZXB0KScsIG9yXG4vLyAgICcuLi4gYXJlIGxlZnQgb3V0JyB3aGVuIHRoZSBibGFuayBsYWJlbCAoY29udGV4dC5ibGFua0xhYmVsKSBpcyBvbmUgb2Zcbi8vICAgdGhlIHZhbHVlcyBsZWZ0IG91dC4gV2l0aG91dCBhIGtub3duIGJsYW5rIGxhYmVsIHRoZSBsaW5lIHNheXMgbm90aGluZ1xuLy8gICBhYm91dCB0aGUgYmxhbmsgcm93cztcbi8vIC0gcmFuZ2U6ICdBbW91bnQ6IDEwIHRvIDUwIChib3RoIGluY2x1ZGVkKSc7IGFuIG9wZW4gZW5kIHJlYWRzICcxMCBvclxuLy8gICBtb3JlJyBvciAnNTAgb3IgbGVzcycgaW4gYm90aCBmb3Jtcztcbi8vIC0gYSBsaXZlIHByZXNldDogJ1JlcG9ydCBQZXJpb2Q6IExhc3QgMzAgZGF5cyAoU2VwIDMg4oCTIE9jdCAyLCAyMDI2KSc7XG4vLyAtIGEgcGFnZSBncm91cDogJ0NvaG9ydCAocGFnZSBcIlJldGVudGlvblwiIG9ubHkpOiAyMDI1Jy5cbi8vIE51bWJlcnMgYW5kIGRhdGVzIGFyZSB3cml0dGVuIGluIHRoZSByZXBvcnQncyBsb2NhbGUsIGFuZCAwIGlzIGEgbnVtYmVyXG4vLyBsaWtlIGFueSBvdGhlci5cbmV4cG9ydCBmdW5jdGlvbiBmaWx0ZXJMaW5lVGV4dChcbiAgZ3JvdXA6IFBpY2s8UmVwb3J0RmlsdGVyR3JvdXAsICdsYWJlbCcgfCAnbGV2ZWwnPixcbiAgdmFsdWU6IEZpbHRlckdyb3VwVmFsdWUgfCBudWxsIHwgdW5kZWZpbmVkLFxuICBjb250ZXh0OiBSZXBvcnRGaWx0ZXJMaW5lQ29udGV4dCxcbiAgZm9ybTogUmVwb3J0RmlsdGVyTGluZUZvcm0sXG4pOiBzdHJpbmcgfCBudWxsIHtcbiAgY29uc3QgbGFiZWwgPSBncm91cC5sYWJlbCB8fCBVTkxBQkVMRURfR1JPVVA7XG4gIGNvbnN0IHRleHQgPSB2YWx1ZSA/IHZhbHVlVGV4dChsYWJlbCwgdmFsdWUsIGNvbnRleHQsIGZvcm0pIDogbnVsbDtcblxuICBpZiAodGV4dCA9PT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgcGFnZU9ubHkgPSBmb3JtID09PSAnbGluZScgJiYgZ3JvdXAubGV2ZWwgPT09ICdwYWdlJyAmJiBjb250ZXh0LnBhZ2VOYW1lO1xuICBjb25zdCBuYW1lID0gcGFnZU9ubHkgPyBgJHtsYWJlbH0gKHBhZ2UgXCIke2NvbnRleHQucGFnZU5hbWV9XCIgb25seSlgIDogbGFiZWw7XG5cbiAgcmV0dXJuIGAke2V4Y2x1ZGVzKHZhbHVlKSA/ICdFeGNsdWRlICcgOiAnJ30ke25hbWV9OiAke3RleHR9YDtcbn1cblxuLy8gVGhlIG1hdGNoIGFzIHRleHQgd2hpbGUgaXQgaXMgJ2FueScsIGVsc2UgbnVsbDsgdGhlIGNoaXAgYWxzbyB3b3JkcyAnYWxsJy5cbmV4cG9ydCBmdW5jdGlvbiBtYXRjaExpbmVUZXh0KG1hdGNoOiBSZXBvcnRGaWx0ZXJNYXRjaCB8IG51bGwgfCB1bmRlZmluZWQsIGZvcm06IFJlcG9ydEZpbHRlckxpbmVGb3JtKTogc3RyaW5nIHwgbnVsbCB7XG4gIGlmIChtYXRjaCAhPT0gJ2FueScpIHtcbiAgICByZXR1cm4gZm9ybSA9PT0gJ2NoaXAnICYmIG1hdGNoID09PSAnYWxsJyA/IE1BVENIX0FMTF9DSElQIDogbnVsbDtcbiAgfVxuXG4gIHJldHVybiBmb3JtID09PSAnY2hpcCcgPyBNQVRDSF9BTllfQ0hJUCA6IE1BVENIX0FOWV9MSU5FO1xufVxuXG4vLyBBIGRyaWxsZWQgdGlsZSdzIGxpbmU6IGl0cyB0aXRsZSBhbmQgdGhlIGJyZWFkY3J1bWIgb2YgaXRzIHBhdGgsIGluIHRoZVxuLy8gcmVwb3J0J3MgbG9jYWxlICgnUmV2ZW51ZSBieSBQZXJpb2Qg4oC6IDIwMjYg4oC6IFEzJykuXG5leHBvcnQgZnVuY3Rpb24gZHJpbGxMaW5lVGV4dChcbiAgY29tcG9uZW50OiBQaWNrPFJlcG9ydENvbXBvbmVudCwgJ3RpdGxlJz4sXG4gIHBhdGg6IHJlYWRvbmx5IFJlcG9ydERyaWxsU3RlcFtdLFxuICBmb3JtYXRDb250ZXh0OiBQaWNrPFJlcG9ydEZvcm1hdENvbnRleHQsICdsb2NhbGUnPixcbik6IHN0cmluZyB7XG4gIHJldHVybiBjcnVtYmVkVGl0bGUoY29tcG9uZW50LnRpdGxlLCBkcmlsbENydW1iTGFiZWxzKHBhdGgsIGZvcm1hdENvbnRleHQpKTtcbn1cblxuLy8gVGhlIGNvdmVyJ3MgbGluZSBmb3IgdGhlIG9wZW4gc2F2ZWQgdmlldzogJ1ZpZXc6IFwiUTMgTm9ydGhcIiAoc2hhcmVkKScsXG4vLyB3aXRoICcsIGNoYW5nZWQgc2luY2UgaXQgd2FzIG9wZW5lZCcgd2hpbGUgdGhlIHNjcmVlbiBkaWZmZXJzIGZyb20gaXQuXG4vLyBOdWxsIHdoZW4gbm8gdmlldyBpcyBvcGVuLlxuZXhwb3J0IGZ1bmN0aW9uIHZpZXdMaW5lVGV4dChcbiAgdmlldzogUGljazxSZXBvcnRWaWV3U3VtbWFyeSwgJ25hbWUnIHwgJ3NoYXJlZCc+IHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgY2hhbmdlZDogYm9vbGVhbixcbik6IHN0cmluZyB8IG51bGwge1xuICBpZiAoIXZpZXcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGxpbmUgPSBgVmlldzogXCIkeyh2aWV3Lm5hbWUgPz8gJycpLnRyaW0oKX1cIiAoJHt2aWV3LnNoYXJlZCA/ICdzaGFyZWQnIDogJ3BlcnNvbmFsJ30pYDtcblxuICByZXR1cm4gY2hhbmdlZCA/IGAke2xpbmV9LCBjaGFuZ2VkIHNpbmNlIGl0IHdhcyBvcGVuZWRgIDogbGluZTtcbn1cblxuLy8gVGhlIGZpbHRlciBsaW5lcyBvZiBhbiBleHBvcnQsIGluIG9yZGVyOiBvbmUgcGVyIGZpbHRlciBncm91cCB3aXRoIGFcbi8vIHZhbHVlICh0aGUgcmVwb3J0J3MgZ3JvdXAgb3JkZXIpLCB0aGUgZ3JvdXAtYnkgbGluZSwgdGhlbiBvbmUgcGVyIGRyaWxsZWRcbi8vIGNoYXJ0IChwYWdlIG9yZGVyKS4gQSBUaGlzIFBhZ2UgZXhwb3J0IChpbnB1dC5wYWdlSWQpIGxpc3RzIG9ubHkgdGhlXG4vLyBncm91cHMgdGhhdCByZWFjaCBhIHRpbGUgb2YgdGhhdCBwYWdlLCBhbmQgb25seSB0aGF0IHBhZ2UncyBkcmlsbGVkXG4vLyBjaGFydHMuIEEgc2VsZWN0J3MgbmFtZXMgYXJlIGEgcmVxdWVzdCwgc28gdGhlIGxpbmVzIGFycml2ZSB0b2dldGhlciBvbmNlXG4vLyBldmVyeSBuYW1lIGlzIGtub3duOyBhIGZhaWxlZCBuYW1lIHJlYWQgd3JpdGVzIHRoZSBwaWNrcyBhcyB0aGV5IGFyZVxuLy8gc3RvcmVkLlxuZXhwb3J0IGZ1bmN0aW9uIGV4cG9ydExpbmVzKGlucHV0OiBSZXBvcnRFeHBvcnRMaW5lc0lucHV0KTogT2JzZXJ2YWJsZTxSZXBvcnRFeHBvcnRMaW5lW10+IHtcbiAgY29uc3QgZ3JvdXBzJCA9IGV4cG9ydEdyb3VwcyhpbnB1dC5yZXBvcnQsIGlucHV0LnBhZ2VJZClcbiAgICAubWFwKChncm91cCkgPT4gZ3JvdXBMaW5lKGdyb3VwLCBpbnB1dCkpO1xuICBjb25zdCByZXN0ID0gW2dyb3VwQnlMaW5lKGlucHV0KSwgLi4uZHJpbGxMaW5lcyhpbnB1dCldXG4gICAgLmZpbHRlcigobGluZSk6IGxpbmUgaXMgUmVwb3J0RXhwb3J0TGluZSA9PiBsaW5lICE9PSBudWxsKTtcblxuICByZXR1cm4gKGdyb3VwcyQubGVuZ3RoID8gZm9ya0pvaW4oZ3JvdXBzJCkgOiBvZihbXSkpXG4gICAgLnBpcGUoXG4gICAgICBtYXAoKGxpbmVzKSA9PiBbXG4gICAgICAgIC4uLmxpbmVzLmZpbHRlcigobGluZSk6IGxpbmUgaXMgUmVwb3J0RXhwb3J0TGluZSA9PiBsaW5lICE9PSBudWxsKSxcbiAgICAgICAgLi4ucmVzdCxcbiAgICAgIF0pLFxuICAgICk7XG59XG5cbi8vIFRoZSBncm91cHMgYW4gZXhwb3J0J3MgbGluZXMgbWF5IG5hbWU6IGV2ZXJ5IGdyb3VwLCBvciBmb3IgYSBUaGlzIFBhZ2Vcbi8vIGV4cG9ydCB0aGUgZ3JvdXBzIHdpdGggYSBtZW1iZXIgdGlsZSBvbiB0aGF0IHBhZ2UuIEEgcGFnZSBncm91cCByZWFjaGVzXG4vLyBvbmx5IGl0cyBvd24gcGFnZS5cbmV4cG9ydCBmdW5jdGlvbiBleHBvcnRHcm91cHMocmVwb3J0OiBSZXBvcnQsIHBhZ2VJZDogbnVtYmVyIHwgbnVsbCk6IFJlcG9ydEZpbHRlckdyb3VwW10ge1xuICBjb25zdCBncm91cHMgPSByZXBvcnQuZmlsdGVyR3JvdXBzID8/IFtdO1xuXG4gIGlmICghcGFnZUlkKSB7XG4gICAgcmV0dXJuIGdyb3VwcztcbiAgfVxuXG4gIGNvbnN0IHBhZ2UgPSAocmVwb3J0LnBhZ2VzID8/IFtdKS5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5pZCA9PT0gcGFnZUlkKTtcbiAgY29uc3QgdGlsZUlkcyA9IChwYWdlPy5jb21wb25lbnRzID8/IFtdKVxuICAgIC5maWx0ZXIoKGNvbXBvbmVudCkgPT4gaXNUaWxlKGNvbXBvbmVudCkpXG4gICAgLm1hcCgoY29tcG9uZW50KSA9PiBjb21wb25lbnQuaWQpO1xuXG4gIHJldHVybiBncm91cHMuZmlsdGVyKChncm91cCkgPT4gKGdyb3VwLmxldmVsICE9PSAncGFnZScgfHwgZ3JvdXAucGFnZUlkID09PSBwYWdlSWQpXG4gICAgJiYgZ3JvdXBNZW1iZXJJZHMoZ3JvdXApLnNvbWUoKGNvbXBvbmVudElkKSA9PiB0aWxlSWRzLmluY2x1ZGVzKGNvbXBvbmVudElkKSkpO1xufVxuXG4vLyBUaGUgdGV4dCBhZnRlciB0aGUgbGFiZWwsIG9yIG51bGwgd2hlbiB0aGUgdmFsdWUgaG9sZHMgbm90aGluZy5cbmZ1bmN0aW9uIHZhbHVlVGV4dChcbiAgbGFiZWw6IHN0cmluZyxcbiAgdmFsdWU6IEZpbHRlckdyb3VwVmFsdWUsXG4gIGNvbnRleHQ6IFJlcG9ydEZpbHRlckxpbmVDb250ZXh0LFxuICBmb3JtOiBSZXBvcnRGaWx0ZXJMaW5lRm9ybSxcbik6IHN0cmluZyB8IG51bGwge1xuICBpZiAodmFsdWUuc3RhcnQgfHwgdmFsdWUuZW5kKSB7XG4gICAgcmV0dXJuIGRhdGVUZXh0KHZhbHVlLCBjb250ZXh0LCBmb3JtKTtcbiAgfVxuXG4gIGlmICh2YWx1ZS52YWx1ZXM/Lmxlbmd0aCkge1xuICAgIHJldHVybiBwaWNrTmFtZXModmFsdWUudmFsdWVzLCBjb250ZXh0KS5qb2luKCcsICcpO1xuICB9XG5cbiAgaWYgKHZhbHVlLmV4Y2x1ZGVWYWx1ZXM/Lmxlbmd0aCkge1xuICAgIHJldHVybiBleGNsdWRlVGV4dChsYWJlbCwgdmFsdWUuZXhjbHVkZVZhbHVlcywgY29udGV4dCwgZm9ybSk7XG4gIH1cblxuICBjb25zdCBrZXl3b3JkID0gdHlwZW9mIHZhbHVlLnZhbHVlID09PSAnc3RyaW5nJyA/IHZhbHVlLnZhbHVlLnRyaW0oKSA6ICcnO1xuXG4gIHJldHVybiByYW5nZVRleHQodmFsdWUsIGNvbnRleHQsIGZvcm0pID8/IChrZXl3b3JkID8gYFwiJHtrZXl3b3JkfVwiYCA6IG51bGwpO1xufVxuXG4vLyBBIGRhdGUgcmFuZ2U6IGEgbGl2ZSBwcmVzZXQgYnkgaXRzIG5hbWUgKHdpdGggaXRzIGRheXMgaW4gYSBsaW5lKSwgZWxzZVxuLy8gaXRzIHR3byBkYXlzICgn4oCmJyBmb3IgYW4gb3BlbiBlbmQpLlxuZnVuY3Rpb24gZGF0ZVRleHQodmFsdWU6IEZpbHRlckdyb3VwVmFsdWUsIGNvbnRleHQ6IFJlcG9ydEZpbHRlckxpbmVDb250ZXh0LCBmb3JtOiBSZXBvcnRGaWx0ZXJMaW5lRm9ybSk6IHN0cmluZyB7XG4gIGlmIChjb250ZXh0LnByZXNldCkge1xuICAgIGNvbnN0IG5hbWUgPSByZWxhdGl2ZUxhYmVsKGNvbnRleHQucHJlc2V0KTtcbiAgICBjb25zdCBkYXlzID0gZm9ybSA9PT0gJ2xpbmUnXG4gICAgICA/IGZvcm1hdERheVJhbmdlKGRhdGVCb3VuZFN0cmluZyh2YWx1ZS5zdGFydCksIGRhdGVCb3VuZFN0cmluZyh2YWx1ZS5lbmQpLCBjb250ZXh0LmxvY2FsZSlcbiAgICAgIDogJyc7XG5cbiAgICByZXR1cm4gZGF5cyA/IGAke25hbWV9ICgke2RheXN9KWAgOiBuYW1lO1xuICB9XG5cbiAgcmV0dXJuIGAke2RhdGVCb3VuZExhYmVsKHZhbHVlLnN0YXJ0LCBjb250ZXh0LmxvY2FsZSkgPz8gJ+KApid9IOKAkyAke2RhdGVCb3VuZExhYmVsKHZhbHVlLmVuZCwgY29udGV4dC5sb2NhbGUpID8/ICfigKYnfWA7XG59XG5cbi8vIFdoZXRoZXIgYSB2YWx1ZSBpcyB3b3JkZWQgYXMgdmFsdWVzIGxlZnQgb3V0OiB0aGUgc2FtZSBvcmRlciB2YWx1ZVRleHRcbi8vIHJlYWRzIGEgdmFsdWUgaW4sIHNvIGEgdmFsdWUgd2l0aCBkYXlzIG9yIGtlcHQgcGlja3MgaXMgbmV2ZXIgb25lLlxuZnVuY3Rpb24gZXhjbHVkZXModmFsdWU6IEZpbHRlckdyb3VwVmFsdWUpOiBib29sZWFuIHtcbiAgcmV0dXJuICF2YWx1ZS5zdGFydCAmJiAhdmFsdWUuZW5kICYmICF2YWx1ZS52YWx1ZXM/Lmxlbmd0aCAmJiAhIXZhbHVlLmV4Y2x1ZGVWYWx1ZXM/Lmxlbmd0aDtcbn1cblxuLy8gVGhlIHZhbHVlcyBhIHNlbGVjdCBsZWF2ZXMgb3V0LiBBIGxpbmUgc2F5cyB3aGF0IGhhcHBlbnMgdG8gdGhlIHJvd3Mgd2l0aFxuLy8gbm8gdmFsdWU6IHRoZXkgc3RheSwgdW5sZXNzIHRoZSBncm91cCdzIGJsYW5rIGxhYmVsIGlzIG9uZSBvZiB0aGUgdmFsdWVzXG4vLyBsZWZ0IG91dC4gV2hpbGUgdGhlIGJsYW5rIGxhYmVsIGlzIHVua25vd24gKHVuZGVmaW5lZCkgdGhlIGxpbmUgc2F5c1xuLy8gbm90aGluZyBhYm91dCB0aGVtOiBhIGJsYW5rIGxhYmVsIGFtb25nIHRoZSBwaWNrcyB3b3VsZCBtYWtlICdhcmUga2VwdCdcbi8vIGZhbHNlLlxuZnVuY3Rpb24gZXhjbHVkZVRleHQoXG4gIGxhYmVsOiBzdHJpbmcsXG4gIHZhbHVlczogdW5rbm93bltdLFxuICBjb250ZXh0OiBSZXBvcnRGaWx0ZXJMaW5lQ29udGV4dCxcbiAgZm9ybTogUmVwb3J0RmlsdGVyTGluZUZvcm0sXG4pOiBzdHJpbmcge1xuICBjb25zdCB0ZXh0ID0gcGlja05hbWVzKHZhbHVlcywgY29udGV4dCkuam9pbignLCAnKTtcbiAgY29uc3QgYmxhbmtMYWJlbCA9IGNvbnRleHQuYmxhbmtMYWJlbDtcblxuICBpZiAoZm9ybSA9PT0gJ2NoaXAnIHx8IGJsYW5rTGFiZWwgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB0ZXh0O1xuICB9XG5cbiAgY29uc3QgYmxhbmsgPSBibGFua0xhYmVsICE9PSBudWxsICYmIHZhbHVlcy5zb21lKCh2YWx1ZSkgPT4gU3RyaW5nKHZhbHVlKSA9PT0gYmxhbmtMYWJlbCk7XG5cbiAgcmV0dXJuIGAke3RleHR9IChyb3dzIHdpdGggbm8gJHtsYWJlbH0gJHtibGFuayA/ICdhcmUgbGVmdCBvdXQnIDogJ2FyZSBrZXB0J30pYDtcbn1cblxuLy8gQSBudW1iZXIgcmFuZ2UncyBlbmRzIGluIHRoZSByZXBvcnQncyBsb2NhbGUsIG9yIG51bGwgd2l0aCBuZWl0aGVyLlxuZnVuY3Rpb24gcmFuZ2VUZXh0KHZhbHVlOiBGaWx0ZXJHcm91cFZhbHVlLCBjb250ZXh0OiBSZXBvcnRGaWx0ZXJMaW5lQ29udGV4dCwgZm9ybTogUmVwb3J0RmlsdGVyTGluZUZvcm0pOiBzdHJpbmcgfCBudWxsIHtcbiAgY29uc3QgbWluID0gZmluaXRlTnVtYmVyKHZhbHVlLm1pbik7XG4gIGNvbnN0IG1heCA9IGZpbml0ZU51bWJlcih2YWx1ZS5tYXgpO1xuICBjb25zdCB3cml0ZSA9IChlbmQ6IG51bWJlcikgPT4gZm9ybWF0UGxhaW5OdW1iZXIoZW5kLCBjb250ZXh0LmxvY2FsZSk7XG5cbiAgaWYgKG1pbiAhPT0gdW5kZWZpbmVkICYmIG1heCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGAke3dyaXRlKG1pbil9IHRvICR7d3JpdGUobWF4KX0ke2Zvcm0gPT09ICdsaW5lJyA/ICcgKGJvdGggaW5jbHVkZWQpJyA6ICcnfWA7XG4gIH1cblxuICBpZiAobWluICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gYCR7d3JpdGUobWluKX0gb3IgbW9yZWA7XG4gIH1cblxuICByZXR1cm4gbWF4ICE9PSB1bmRlZmluZWQgPyBgJHt3cml0ZShtYXgpfSBvciBsZXNzYCA6IG51bGw7XG59XG5cbi8vIFRoZSBwaWNrcycgbmFtZXM6IHRoZSBvbmVzIHRoZSBjYWxsZXIgcmVzb2x2ZWQsIGVsc2UgZWFjaCBwaWNrIGFzIHN0b3JlZC5cbmZ1bmN0aW9uIHBpY2tOYW1lcyh2YWx1ZXM6IHVua25vd25bXSwgY29udGV4dDogUmVwb3J0RmlsdGVyTGluZUNvbnRleHQpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IG5hbWVzID0gY29udGV4dC5uYW1lcztcblxuICByZXR1cm4gdmFsdWVzLm1hcCgodmFsdWUsIGluZGV4KSA9PiBuYW1lcz8uW2luZGV4XSA/PyBTdHJpbmcodmFsdWUpKTtcbn1cblxuLy8gT25lIGdyb3VwJ3MgbGluZSwgb25jZSBpdHMgcGlja3MgYXJlIG5hbWVkLiBBbiBleGNsdWRlIGxpbmUgc2F5cyB3aGF0XG4vLyBoYXBwZW5zIHRvIHRoZSBibGFuayByb3dzIGZyb20gdGhlIGdyb3VwJ3MgYmxhbmsgbGFiZWwsIHdoaWNoIHRoZSBzZXJ2ZXJcbi8vIHNlbmRzIG9uIGEgc2VsZWN0IGdyb3VwIChudWxsOiBibGFuayByb3dzIGhhdmUgbm9uZSkuIEFuIG9sZGVyIHNlcnZlclxuLy8gc2VuZHMgbm9uZSwgYW5kIHRoZSBsaW5lIHRoZW4gc2F5cyBub3RoaW5nIGFib3V0IHRoZW0uXG5mdW5jdGlvbiBncm91cExpbmUoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwLCBpbnB1dDogUmVwb3J0RXhwb3J0TGluZXNJbnB1dCk6IE9ic2VydmFibGU8UmVwb3J0RXhwb3J0TGluZSB8IG51bGw+IHtcbiAgY29uc3Qgc25hcHNob3QgPSBpbnB1dC5zbmFwc2hvdDtcbiAgY29uc3QgdmFsdWUgPSBzbmFwc2hvdC52YWx1ZXNbZ3JvdXAuaWRdO1xuXG4gIGlmICghdmFsdWUpIHtcbiAgICByZXR1cm4gb2YobnVsbCk7XG4gIH1cblxuICBjb25zdCBwaWNrcyA9IHZhbHVlLnN0YXJ0IHx8IHZhbHVlLmVuZCA/IFtdIDogKHZhbHVlLnZhbHVlcz8ubGVuZ3RoID8gdmFsdWUudmFsdWVzIDogdmFsdWUuZXhjbHVkZVZhbHVlcyA/PyBbXSk7XG4gIGNvbnN0IG5hbWVzJCA9IHBpY2tzLmxlbmd0aFxuICAgID8gaW5wdXQubmFtZXMoZ3JvdXAsIHBpY2tzKS5waXBlKGNhdGNoRXJyb3IoKCkgPT4gb2YobnVsbCkpKVxuICAgIDogb2YobnVsbCk7XG5cbiAgcmV0dXJuIG5hbWVzJC5waXBlKFxuICAgIG1hcCgobmFtZXMpOiBSZXBvcnRFeHBvcnRMaW5lIHwgbnVsbCA9PiB7XG4gICAgICBjb25zdCB0ZXh0ID0gZmlsdGVyTGluZVRleHQoZ3JvdXAsIHZhbHVlLCB7XG4gICAgICAgIGxvY2FsZTogc25hcHNob3QuZm9ybWF0Q29udGV4dC5sb2NhbGUsXG4gICAgICAgIG5hbWVzLFxuICAgICAgICBwcmVzZXQ6IHNuYXBzaG90LnByZXNldHNbZ3JvdXAuaWRdID8/IG51bGwsXG4gICAgICAgIHBhZ2VOYW1lOiBwYWdlTmFtZShpbnB1dC5yZXBvcnQsIGdyb3VwLnBhZ2VJZCksXG4gICAgICAgIGJsYW5rTGFiZWw6IGdyb3VwLmJsYW5rTGFiZWwsXG4gICAgICB9LCAnbGluZScpO1xuXG4gICAgICByZXR1cm4gdGV4dCA/IHsga2luZDogJ2dyb3VwJywgdGV4dCwgZ3JvdXBJZDogZ3JvdXAuaWQgfSA6IG51bGw7XG4gICAgfSksXG4gICk7XG59XG5cbi8vIFRoZSBncm91cC1ieSBncmFpbiB1bmRlciB0aGUgcmVwb3J0J3Mgb3duIG5hbWUgZm9yIHRoZSBjb250cm9sLCBvciBudWxsXG4vLyB3aGlsZSBubyBncmFpbiBpcyBwaWNrZWQuXG5mdW5jdGlvbiBncm91cEJ5TGluZShpbnB1dDogUmVwb3J0RXhwb3J0TGluZXNJbnB1dCk6IFJlcG9ydEV4cG9ydExpbmUgfCBudWxsIHtcbiAgY29uc3QgZnJlcXVlbmN5ID0gaW5wdXQuc25hcHNob3QuZnJlcXVlbmN5O1xuXG4gIGlmICghZnJlcXVlbmN5KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBvcHRpb24gPSBHUkFOVUxBUklUWV9PUFRJT05TLmZpbmQoKGl0ZW0pID0+IGl0ZW0udmFsdWUgPT09IGZyZXF1ZW5jeSk7XG4gIGNvbnN0IGxhYmVsID0gaW5wdXQucmVwb3J0LmNvbmZpZz8uZ3JvdXBCeT8ubGFiZWwgfHwgR1JPVVBfQllfTEFCRUw7XG5cbiAgcmV0dXJuIHsga2luZDogJ2dyb3VwQnknLCB0ZXh0OiBgJHtsYWJlbH06ICR7b3B0aW9uPy5uYW1lID8/IGZyZXF1ZW5jeX1gIH07XG59XG5cbi8vIE9uZSBsaW5lIHBlciBkcmlsbGVkIGNoYXJ0IG9mIHRoZSBleHBvcnQncyBwYWdlcywgd2hpbGUgdGhlIHNlcnZlciBkcmlsbHMuXG5mdW5jdGlvbiBkcmlsbExpbmVzKGlucHV0OiBSZXBvcnRFeHBvcnRMaW5lc0lucHV0KTogUmVwb3J0RXhwb3J0TGluZVtdIHtcbiAgY29uc3QgeyByZXBvcnQsIHNuYXBzaG90LCBwYWdlSWQgfSA9IGlucHV0O1xuXG4gIGlmICghc25hcHNob3QuZmVhdHVyZXMuaW5jbHVkZXMoJ2RyaWxsJykpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICByZXR1cm4gKHJlcG9ydC5wYWdlcyA/PyBbXSlcbiAgICAuZmlsdGVyKChwYWdlKSA9PiAhcGFnZUlkIHx8IHBhZ2UuaWQgPT09IHBhZ2VJZClcbiAgICAuZmxhdE1hcCgocGFnZSkgPT4gcGFnZS5jb21wb25lbnRzID8/IFtdKVxuICAgIC5maWx0ZXIoKGNvbXBvbmVudCkgPT4gY29tcG9uZW50LnR5cGUgPT09ICdjaGFydCcgJiYgISFzbmFwc2hvdC52aWV3LnRpbGVzPy5bY29tcG9uZW50LmlkXT8uZHJpbGw/Lmxlbmd0aClcbiAgICAubWFwKChjb21wb25lbnQpOiBSZXBvcnRFeHBvcnRMaW5lID0+ICh7XG4gICAgICBraW5kOiAnZHJpbGwnLFxuICAgICAgdGV4dDogZHJpbGxMaW5lVGV4dChjb21wb25lbnQsIHNuYXBzaG90LnZpZXcudGlsZXNbY29tcG9uZW50LmlkXS5kcmlsbCwgc25hcHNob3QuZm9ybWF0Q29udGV4dCksXG4gICAgICBjb21wb25lbnRJZDogY29tcG9uZW50LmlkLFxuICAgIH0pKTtcbn1cblxuLy8gVGhlIHRpbGVzIGEgZ3JvdXAncyBtZW1iZXJzIHNpdCBvbjogdGhlIHNlcnZlcidzIGxpc3QsIGVsc2UgdGhlIHRpbGVzIG9mXG4vLyBpdHMgZW5hYmxlZCBtZW1iZXJzIChhbiBvbGRlciBzZXJ2ZXIpLlxuZnVuY3Rpb24gZ3JvdXBNZW1iZXJJZHMoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwKTogbnVtYmVyW10ge1xuICByZXR1cm4gZ3JvdXAuY29tcG9uZW50SWRzXG4gICAgPz8gKGdyb3VwLmZpbHRlcnMgPz8gW10pLmZpbHRlcigobWVtYmVyKSA9PiBtZW1iZXIuZW5hYmxlZCkubWFwKChtZW1iZXIpID0+IG1lbWJlci5jb21wb25lbnRJZCk7XG59XG5cbi8vIEEgcGFnZSdzIG5hbWUgYXMgdGhlIGV4cG9ydCBuYW1lcyBpdCAoJ1BhZ2UgMicgd2hlbiBpdCBoYXMgbm9uZSksIG9yIG51bGxcbi8vIGZvciBubyBwYWdlLlxuZnVuY3Rpb24gcGFnZU5hbWUocmVwb3J0OiBSZXBvcnQsIHBhZ2VJZDogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBpbmRleCA9IHBhZ2VJZCA/IChyZXBvcnQucGFnZXMgPz8gW10pLmZpbmRJbmRleCgocGFnZSkgPT4gcGFnZS5pZCA9PT0gcGFnZUlkKSA6IC0xO1xuXG4gIGlmIChpbmRleCA8IDApIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiByZXBvcnQucGFnZXNbaW5kZXhdLm5hbWUgfHwgYFBhZ2UgJHtpbmRleCArIDF9YDtcbn1cbiJdfQ==
|