@firestitch/report 18.7.0 → 18.8.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.
Files changed (64) hide show
  1. package/app/reports/components/component-kpi/component-kpi.component.d.ts +12 -3
  2. package/app/reports/components/component-kpi/components/sparkline/sparkline.component.d.ts +8 -0
  3. package/app/reports/components/component-list/component-list.component.d.ts +7 -1
  4. package/app/reports/components/component-note/component-note.component.d.ts +12 -0
  5. package/app/reports/components/report-canvas/report-canvas.component.d.ts +0 -9
  6. package/app/reports/components/report-component/report-component.component.d.ts +2 -11
  7. package/app/reports/data/report.data.d.ts +0 -2
  8. package/app/reports/dialogs/component-settings/component-settings.component.d.ts +34 -2
  9. package/app/reports/dialogs/report-settings/report-settings.component.d.ts +0 -1
  10. package/app/reports/enums/report-change-polarity.enum.d.ts +5 -0
  11. package/app/reports/enums/report-kpi-trend.enum.d.ts +5 -0
  12. package/app/reports/export/report-export-collector.service.d.ts +29 -1
  13. package/app/reports/export/report-pdf.service.d.ts +5 -0
  14. package/app/reports/export/report-pptx.service.d.ts +7 -0
  15. package/app/reports/format.d.ts +29 -1
  16. package/app/reports/interfaces/report-chat-viewer-filter.interface.d.ts +2 -0
  17. package/app/reports/interfaces/report.interface.d.ts +124 -4
  18. package/app/reports/kpi-card.d.ts +48 -0
  19. package/app/reports/layout.d.ts +0 -9
  20. package/app/reports/list-config.d.ts +8 -1
  21. package/app/reports/option-builder.d.ts +7 -0
  22. package/app/reports/output-notes.d.ts +14 -0
  23. package/app/reports/pipes/report-output.pipe.d.ts +10 -0
  24. package/app/reports/services/report-filter-state.service.d.ts +1 -0
  25. package/app/reports/theme/palette.d.ts +5 -0
  26. package/app/reports/theme/typography.d.ts +1 -0
  27. package/esm2022/app/reports/components/component-chart/component-chart.component.mjs +8 -4
  28. package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +50 -17
  29. package/esm2022/app/reports/components/component-kpi/components/sparkline/sparkline.component.mjs +19 -0
  30. package/esm2022/app/reports/components/component-list/component-list.component.mjs +66 -6
  31. package/esm2022/app/reports/components/component-note/component-note.component.mjs +30 -0
  32. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +7 -56
  33. package/esm2022/app/reports/components/report-component/report-component.component.mjs +21 -82
  34. package/esm2022/app/reports/data/report.data.mjs +5 -5
  35. package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +133 -13
  36. package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +4 -8
  37. package/esm2022/app/reports/enums/report-change-polarity.enum.mjs +11 -0
  38. package/esm2022/app/reports/enums/report-kpi-trend.enum.mjs +10 -0
  39. package/esm2022/app/reports/export/report-export-collector.service.mjs +123 -10
  40. package/esm2022/app/reports/export/report-pdf.service.mjs +257 -44
  41. package/esm2022/app/reports/export/report-pptx.service.mjs +324 -51
  42. package/esm2022/app/reports/format.mjs +452 -3
  43. package/esm2022/app/reports/interfaces/report-chat-viewer-filter.interface.mjs +1 -1
  44. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  45. package/esm2022/app/reports/kpi-card.mjs +187 -0
  46. package/esm2022/app/reports/layout.mjs +1 -46
  47. package/esm2022/app/reports/list-config.mjs +33 -1
  48. package/esm2022/app/reports/option-builder.mjs +637 -54
  49. package/esm2022/app/reports/output-notes.mjs +204 -0
  50. package/esm2022/app/reports/pipes/report-output.pipe.mjs +28 -0
  51. package/esm2022/app/reports/services/report-filter-state.service.mjs +40 -3
  52. package/esm2022/app/reports/theme/palette.mjs +22 -1
  53. package/esm2022/app/reports/theme/typography.mjs +5 -1
  54. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +2 -2
  55. package/esm2022/app/reports/views/report/report.component.mjs +3 -4
  56. package/esm2022/public_api.mjs +2 -1
  57. package/fesm2022/{firestitch-report-echarts-u5ImuZT5.mjs → firestitch-report-echarts-CFnbJx44.mjs} +2 -2
  58. package/fesm2022/{firestitch-report-echarts-u5ImuZT5.mjs.map → firestitch-report-echarts-CFnbJx44.mjs.map} +1 -1
  59. package/fesm2022/{firestitch-report-firestitch-report-Cz-kA_id.mjs → firestitch-report-firestitch-report-CSylkyko.mjs} +2735 -507
  60. package/fesm2022/firestitch-report-firestitch-report-CSylkyko.mjs.map +1 -0
  61. package/fesm2022/firestitch-report.mjs +1 -1
  62. package/package.json +1 -1
  63. package/public_api.d.ts +1 -0
  64. package/fesm2022/firestitch-report-firestitch-report-Cz-kA_id.mjs.map +0 -1
@@ -0,0 +1,204 @@
1
+ import { comparisonNoteText, comparisonOffsetLabel, formatDayRange, formatDayWindow, formatReadingDay, isReadOnOneDay, kpiNoteText, windowNoteText, windowText, } from './format';
2
+ // Between the current window and each prior one on the windows line.
3
+ const WINDOWS_SEPARATOR = ' · ';
4
+ // Ranks and shares are computed after the viewer's filters, never before.
5
+ const FILTERED_ROWS_SENTENCE = 'Computed over the rows the filters keep.';
6
+ const ROLE_LEADS = {
7
+ current: 'Value',
8
+ prior: 'Prior value',
9
+ change: 'Change',
10
+ percent_change: 'Percent change',
11
+ };
12
+ // The note's lines, in order: the windows, then the comparison's notes and a
13
+ // KPI's delta note, then the windowed values' descriptions and notes. A line is never repeated (two
14
+ // windowed values often share a note). Empty when the data has none of the
15
+ // keys, or none of the parts asked for.
16
+ export function componentNoteLines(data, context, parts = {}) {
17
+ if (!data) {
18
+ return [];
19
+ }
20
+ const lines = [
21
+ parts.windows === false ? '' : componentWindowsLine(data, context),
22
+ ...comparisonNotes(data.comparison),
23
+ kpiNote(data.kpi, data.comparison),
24
+ ...(parts.windowDescriptions ? windowDescriptions(data, context.locale) : []),
25
+ ...(parts.windowNotes === false ? [] : windowNotes(data, context.locale)),
26
+ ];
27
+ return [...new Set(lines.filter((line) => !!line))];
28
+ }
29
+ // What one output column holds, for its header's tooltip: the windows a
30
+ // compared value covers, a rank's or a share's scope, and how a windowed value
31
+ // was computed. A cross-tab cell column reads its measure's meaning through
32
+ // cellMeasures. '' for a plain column.
33
+ export function outputColumnNote(column, data, locale) {
34
+ const alias = data?.cellMeasures?.[column] ?? column;
35
+ const output = data?.outputs?.[alias];
36
+ if (!output) {
37
+ return '';
38
+ }
39
+ return [
40
+ comparisonSentence(output, data.comparison, locale),
41
+ rankSentence(output, data.outputs),
42
+ shareSentence(output, data.outputs),
43
+ windowSentences(data.windows?.[alias], locale, data),
44
+ ]
45
+ .filter((sentence) => !!sentence)
46
+ .join(' ');
47
+ }
48
+ // 'Sep 1 – 15, 2026 · vs previous month: Aug 1 – 15, 2026'. A comparison
49
+ // with no current window yet has no line (its no_window note says so); a
50
+ // component without a comparison shows its timeframe's days. '' when the data
51
+ // has neither. The note's first line, and the PDF and PowerPoint exports'
52
+ // subtitle under a chart's or a list's title.
53
+ export function componentWindowsLine(data, context) {
54
+ const comparison = data.comparison;
55
+ if (comparison) {
56
+ return comparison.current ? comparisonWindowsLine(comparison, comparison.current, context.locale) : '';
57
+ }
58
+ return data.timeframe ? formatDayWindow(data.timeframe, context.timezone, context.locale) : '';
59
+ }
60
+ // Read on one day, the line names the days the values are read on: 'On Sep
61
+ // 15, 2026 · vs previous month: Aug 31, 2026'.
62
+ function comparisonWindowsLine(comparison, currentWindow, locale) {
63
+ if (isReadOnOneDay(comparison)) {
64
+ const priors = (comparison.offsets ?? []).map((offset, index) => {
65
+ const prior = comparison.priors?.[index];
66
+ const day = prior ? formatDayRange(prior.end, prior.end, locale) : '';
67
+ return day ? `${comparisonOffsetLabel(offset)}: ${day}` : comparisonOffsetLabel(offset);
68
+ });
69
+ return [formatReadingDay(currentWindow, locale, true), ...priors]
70
+ .filter((part) => !!part)
71
+ .join(WINDOWS_SEPARATOR);
72
+ }
73
+ const current = formatDayWindow(currentWindow, comparison.timezone, locale);
74
+ const priors = (comparison.offsets ?? []).map((offset, index) => {
75
+ return priorWindowText(offset, comparison.priors?.[index], comparison.timezone, locale);
76
+ });
77
+ return [current, ...priors]
78
+ .filter((part) => !!part)
79
+ .join(WINDOWS_SEPARATOR);
80
+ }
81
+ // One prior lane: 'vs previous month: Aug 1 – 15, 2026', or its label alone
82
+ // when the server sends no window for it.
83
+ function priorWindowText(offset, prior, timezone, locale) {
84
+ const label = comparisonOffsetLabel(offset);
85
+ const days = prior ? formatDayWindow(prior, timezone, locale) : '';
86
+ return days ? `${label}: ${days}` : label;
87
+ }
88
+ function comparisonNotes(comparison) {
89
+ return (comparison?.notes ?? []).map((code) => comparisonNoteText(code, comparison));
90
+ }
91
+ // Why a KPI card's delta reads as it does ('No baseline: the previous period
92
+ // has no data.'), naming the baseline by what the first lane compares against.
93
+ function kpiNote(kpi, comparison) {
94
+ return kpi?.note ? kpiNoteText(kpi.note, comparison?.offsets?.[0]?.against) : '';
95
+ }
96
+ // One line per windowed value, named by its column when there are several.
97
+ function windowDescriptions(data, locale) {
98
+ const windows = Object.entries(data.windows ?? {});
99
+ return windows.map(([alias, meta]) => {
100
+ const text = windowText(meta, locale, data.granularity);
101
+ return windows.length > 1 ? `${alias}: ${text}` : text;
102
+ });
103
+ }
104
+ function windowNotes(data, locale) {
105
+ return Object.values(data.windows ?? {})
106
+ .flatMap((meta) => (meta.notes ?? []).map((code) => windowNoteText(code, meta, locale, data.granularity)));
107
+ }
108
+ // A compared column's windows. In range mode every row compares the same two
109
+ // windows, so they are named, and read on one day the days the values are
110
+ // read on are; over a series or a spine of periods each row compares its own
111
+ // period, so only the lane is.
112
+ function comparisonSentence(output, comparison, locale) {
113
+ if (!output.role || !comparison) {
114
+ return '';
115
+ }
116
+ const offset = comparison.offsets?.[(output.offset ?? 1) - 1] ?? null;
117
+ const current = comparison.current ? formatDayWindow(comparison.current, comparison.timezone, locale) : '';
118
+ const priorWindow = comparison.priors?.[(output.offset ?? 1) - 1];
119
+ const prior = priorWindow ? formatDayWindow(priorWindow, comparison.timezone, locale) : '';
120
+ if (comparison.mode === 'range' && current && (output.role === 'current' || prior)) {
121
+ return rangeSentence(output.role, current, prior, offset);
122
+ }
123
+ if (isReadOnOneDay(comparison) && comparison.current && priorWindow) {
124
+ return readingDaySentence(output.role, comparison.current, priorWindow, offset, locale);
125
+ }
126
+ return output.role === 'current' || !offset ? '' : `${ROLE_LEADS[output.role]} ${comparisonOffsetLabel(offset)}.`;
127
+ }
128
+ function rangeSentence(role, current, prior, offset) {
129
+ switch (role) {
130
+ case 'current':
131
+ return `Value for ${current}.`;
132
+ case 'prior':
133
+ return offset ? `Prior value for ${prior} (${comparisonOffsetLabel(offset)}).` : `Prior value for ${prior}.`;
134
+ default:
135
+ return `${ROLE_LEADS[role]} from ${prior} to ${current}.`;
136
+ }
137
+ }
138
+ // A column of a comparison read on one day, named by the days its values are
139
+ // read on: 'Prior value on Aug 31, 2026 (vs previous month).'
140
+ function readingDaySentence(role, currentWindow, priorWindow, offset, locale) {
141
+ const current = formatReadingDay(currentWindow, locale);
142
+ const prior = formatReadingDay(priorWindow, locale);
143
+ switch (role) {
144
+ case 'current':
145
+ return `Value ${current}.`;
146
+ case 'prior':
147
+ return offset ? `Prior value ${prior} (${comparisonOffsetLabel(offset)}).` : `Prior value ${prior}.`;
148
+ default:
149
+ return `${ROLE_LEADS[role]} from the value ${prior} to the value ${current}.`;
150
+ }
151
+ }
152
+ // 'Rank by Revenue, 1 being the largest, within each Region. Tied values share
153
+ // a rank (1, 1, 3).' A measure written as its own rank ranks by the value it
154
+ // would otherwise show, so it names no other measure ('Rank, 1 being the
155
+ // largest, across all rows.').
156
+ function rankSentence(output, outputs) {
157
+ const rank = output.kind === 'rank' ? output.rank : null;
158
+ if (!rank) {
159
+ return '';
160
+ }
161
+ const end = rank.direction === 'asc' ? 'smallest' : 'largest';
162
+ const scope = rank.within?.length ? `within each ${joinNames(rank.within)}` : 'across all rows';
163
+ const ties = rank.method === 'dense' ? '1, 1, 2' : '1, 1, 3';
164
+ const by = isOwnOutput(output, outputs) ? '' : ` by ${output.measure}`;
165
+ return `Rank${by}, 1 being the ${end}, ${scope}. Tied values share a rank (${ties}). `
166
+ + FILTERED_ROWS_SENTENCE;
167
+ }
168
+ // 'Share of the total Revenue within each Region.' A measure written as its
169
+ // own share names no other measure ('Share of the total within each
170
+ // Region.', 'Share of the total across all rows.').
171
+ function shareSentence(output, outputs) {
172
+ const share = output.kind === 'share' ? output.share : null;
173
+ if (!share) {
174
+ return '';
175
+ }
176
+ if (isOwnOutput(output, outputs)) {
177
+ const scope = share.within?.length ? `within each ${joinNames(share.within)}` : 'across all rows';
178
+ return `Share of the total ${scope}. ${FILTERED_ROWS_SENTENCE}`;
179
+ }
180
+ const scope = share.within?.length ? ` within each ${joinNames(share.within)}` : '';
181
+ return `Share of the total ${output.measure}${scope}. ${FILTERED_ROWS_SENTENCE}`;
182
+ }
183
+ // Whether a rank or a share is its measure's own output: the server writes a
184
+ // measure with a rank or a share as that rank or share, so its measure is a
185
+ // column of the same kind (itself, or for a prior or a change the current
186
+ // column), never a value of its own to name.
187
+ function isOwnOutput(output, outputs) {
188
+ return outputs?.[output.measure]?.kind === output.kind;
189
+ }
190
+ // A windowed column: what it is, then why it reads as it does.
191
+ function windowSentences(meta, locale, data) {
192
+ if (!meta) {
193
+ return '';
194
+ }
195
+ const notes = (meta.notes ?? []).map((code) => windowNoteText(code, meta, locale, data.granularity));
196
+ return [`${windowText(meta, locale, data.granularity)}.`, ...notes].join(' ');
197
+ }
198
+ // 'Region', 'Region and Channel', 'Region, Channel and Plan'.
199
+ function joinNames(names) {
200
+ return names.length > 1
201
+ ? `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`
202
+ : names.join('');
203
+ }
204
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3V0cHV0LW5vdGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL291dHB1dC1ub3Rlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLHFCQUFxQixFQUNyQixjQUFjLEVBQ2QsZUFBZSxFQUNmLGdCQUFnQixFQUNoQixjQUFjLEVBQ2QsV0FBVyxFQUNYLGNBQWMsRUFDZCxVQUFVLEdBQ1gsTUFBTSxVQUFVLENBQUM7QUE4Q2xCLHFFQUFxRTtBQUNyRSxNQUFNLGlCQUFpQixHQUFHLEtBQUssQ0FBQztBQUVoQywwRUFBMEU7QUFDMUUsTUFBTSxzQkFBc0IsR0FBRywwQ0FBMEMsQ0FBQztBQUUxRSxNQUFNLFVBQVUsR0FBK0I7SUFDN0MsT0FBTyxFQUFFLE9BQU87SUFDaEIsS0FBSyxFQUFFLGFBQWE7SUFDcEIsTUFBTSxFQUFFLFFBQVE7SUFDaEIsY0FBYyxFQUFFLGdCQUFnQjtDQUNqQyxDQUFDO0FBRUYsNkVBQTZFO0FBQzdFLG9HQUFvRztBQUNwRywyRUFBMkU7QUFDM0Usd0NBQXdDO0FBQ3hDLE1BQU0sVUFBVSxrQkFBa0IsQ0FDaEMsSUFBMEMsRUFDMUMsT0FBNkIsRUFDN0IsUUFBNEIsRUFBRTtJQUU5QixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDVixPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRCxNQUFNLEtBQUssR0FBRztRQUNaLEtBQUssQ0FBQyxPQUFPLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLElBQUksRUFBRSxPQUFPLENBQUM7UUFDbEUsR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUNuQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQ2xDLEdBQUcsQ0FBQyxLQUFLLENBQUMsa0JBQWtC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QUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2hGLENBQUM7QUFFRCw4REFBOEQ7QUFDOUQsU0FBUyxTQUFTLENBQUMsS0FBZTtJQUNoQyxPQUFPLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQztRQUNyQixDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsRUFBRTtRQUNuRSxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNyQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgY29tcGFyaXNvbk5vdGVUZXh0LFxuICBjb21wYXJpc29uT2Zmc2V0TGFiZWwsXG4gIGZvcm1hdERheVJhbmdlLFxuICBmb3JtYXREYXlXaW5kb3csXG4gIGZvcm1hdFJlYWRpbmdEYXksXG4gIGlzUmVhZE9uT25lRGF5LFxuICBrcGlOb3RlVGV4dCxcbiAgd2luZG93Tm90ZVRleHQsXG4gIHdpbmRvd1RleHQsXG59IGZyb20gJy4vZm9ybWF0JztcbmltcG9ydCB7XG4gIENvbXBhcmlzb25PZmZzZXQsXG4gIENvbXBhcmlzb25XaW5kb3csXG4gIENvbXBvbmVudENvbXBhcmlzb24sXG4gIENvbXBvbmVudERhdGEsXG4gIENvbXBvbmVudEtwaSxcbiAgT3V0cHV0TWV0YSxcbiAgT3V0cHV0Um9sZSxcbiAgUmVwb3J0TG9jYWxlVGFnLFxuICBXaW5kb3dNZXRhLFxufSBmcm9tICcuL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7XG5cblxuLy8gVGhlIG5vdGVzIGEgY29tcG9uZW50IHNob3dzIGFib3V0IHRoZSBudW1iZXJzIGl0IGRyYXdzOiB3aGljaCBkYXlzIGFcbi8vIGNvbXBhcmlzb24gY29tcGFyZXMsIHdoeSBpdCByZWFkcyBhcyBpdCBkb2VzLCBhbmQgaG93IGl0cyB3aW5kb3dlZCB2YWx1ZXNcbi8vIHdlcmUgY29tcHV0ZWQuIFRoZSBzZXJ2ZXIgc2VuZHMgd2luZG93cywgZmllbGRzIGFuZCBjb2RlczsgZXZlcnkgc2VudGVuY2UgaXNcbi8vIHdvcmRlZCBoZXJlLCB0aHJvdWdoIGZvcm1hdC50cywgaW4gRW5nbGlzaCB3aXRoIHRoZSBkYXlzIGluIHRoZSByZXBvcnQnc1xuLy8gbG9jYWxlLiBBIGNvbXBvbmVudCB3aG9zZSBkYXRhIGNhcnJpZXMgbm9uZSBvZiB0aG9zZSBrZXlzIGhhcyBubyBub3RlLlxuXG4vLyBUaGUgQ29tcG9uZW50RGF0YSBrZXlzIGEgbm90ZSByZWFkcy5cbmV4cG9ydCB0eXBlIENvbXBvbmVudE5vdGVEYXRhID0gUGljazxcbiAgQ29tcG9uZW50RGF0YSxcbiAgJ2NvbXBhcmlzb24nIHwgJ3RpbWVmcmFtZScgfCAnb3V0cHV0cycgfCAnY2VsbE1lYXN1cmVzJyB8ICd3aW5kb3dzJyB8ICdncmFudWxhcml0eScgfCAna3BpJ1xuPjtcblxuLy8gVGhlIHJlcG9ydCB0aGUgbm90ZSBpcyB3cml0dGVuIGZvcjogaXRzIGxvY2FsZSwgYW5kIHRoZSB6b25lIGEgdGltZWZyYW1lJ3Ncbi8vIGN1dCB0aW1lIHJlYWRzIGluIChhIGNvbXBhcmlzb24gbmFtZXMgaXRzIG93bikuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudE5vdGVDb250ZXh0IHtcbiAgbG9jYWxlOiBSZXBvcnRMb2NhbGVUYWc7XG4gIHRpbWV6b25lOiBzdHJpbmc7XG59XG5cbi8vIFdoaWNoIHBhcnRzIG9mIHRoZSBub3RlIGEgY29tcG9uZW50IHNob3dzLiBPbWl0dGVkLCBhIHBhcnQgaXMgc2hvd24sIGV4Y2VwdFxuLy8gdGhlIHdpbmRvdyBkZXNjcmlwdGlvbnMsIHdoaWNoIGEgY2hhcnQncyB0b29sdGlwcyBhbmQgYSBsaXN0J3MgaGVhZGVycyBjYXJyeVxuLy8gaW5zdGVhZC5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcG9uZW50Tm90ZVBhcnRzIHtcbiAgLy8gVGhlIGRheXMgdGhlIGNvbXBvbmVudCByZWFkczogaXRzIGNvbXBhcmlzb24ncyBjdXJyZW50IGFuZCBwcmlvciB3aW5kb3dzLFxuICAvLyBlbHNlIGl0cyB0aW1lZnJhbWUncyBkYXlzLlxuICB3aW5kb3dzPzogYm9vbGVhbjtcbiAgLy8gV2hhdCBlYWNoIHdpbmRvd2VkIHZhbHVlIGlzICgnUm9sbGluZyAzLW1vbnRoIHRvdGFsLCBTZXAgMSDigJMgMzAsIDIwMjYnKS5cbiAgd2luZG93RGVzY3JpcHRpb25zPzogYm9vbGVhbjtcbiAgLy8gV2h5IHRoZSB3aW5kb3dlZCB2YWx1ZXMgcmVhZCBhcyB0aGV5IGRvLlxuICB3aW5kb3dOb3Rlcz86IGJvb2xlYW47XG59XG5cbi8vIEJldHdlZW4gdGhlIGN1cnJlbnQgd2luZG93IGFuZCBlYWNoIHByaW9yIG9uZSBvbiB0aGUgd2luZG93cyBsaW5lLlxuY29uc3QgV0lORE9XU19TRVBBUkFUT1IgPSAnIMK3ICc7XG5cbi8vIFJhbmtzIGFuZCBzaGFyZXMgYXJlIGNvbXB1dGVkIGFmdGVyIHRoZSB2aWV3ZXIncyBmaWx0ZXJzLCBuZXZlciBiZWZvcmUuXG5jb25zdCBGSUxURVJFRF9ST1dTX1NFTlRFTkNFID0gJ0NvbXB1dGVkIG92ZXIgdGhlIHJvd3MgdGhlIGZpbHRlcnMga2VlcC4nO1xuXG5jb25zdCBST0xFX0xFQURTOiBSZWNvcmQ8T3V0cHV0Um9sZSwgc3RyaW5nPiA9IHtcbiAgY3VycmVudDogJ1ZhbHVlJyxcbiAgcHJpb3I6ICdQcmlvciB2YWx1ZScsXG4gIGNoYW5nZTogJ0NoYW5nZScsXG4gIHBlcmNlbnRfY2hhbmdlOiAnUGVyY2VudCBjaGFuZ2UnLFxufTtcblxuLy8gVGhlIG5vdGUncyBsaW5lcywgaW4gb3JkZXI6IHRoZSB3aW5kb3dzLCB0aGVuIHRoZSBjb21wYXJpc29uJ3Mgbm90ZXMgYW5kIGFcbi8vIEtQSSdzIGRlbHRhIG5vdGUsIHRoZW4gdGhlIHdpbmRvd2VkIHZhbHVlcycgZGVzY3JpcHRpb25zIGFuZCBub3Rlcy4gQSBsaW5lIGlzIG5ldmVyIHJlcGVhdGVkICh0d29cbi8vIHdpbmRvd2VkIHZhbHVlcyBvZnRlbiBzaGFyZSBhIG5vdGUpLiBFbXB0eSB3aGVuIHRoZSBkYXRhIGhhcyBub25lIG9mIHRoZVxuLy8ga2V5cywgb3Igbm9uZSBvZiB0aGUgcGFydHMgYXNrZWQgZm9yLlxuZXhwb3J0IGZ1bmN0aW9uIGNvbXBvbmVudE5vdGVMaW5lcyhcbiAgZGF0YTogQ29tcG9uZW50Tm90ZURhdGEgfCBudWxsIHwgdW5kZWZpbmVkLFxuICBjb250ZXh0OiBDb21wb25lbnROb3RlQ29udGV4dCxcbiAgcGFydHM6IENvbXBvbmVudE5vdGVQYXJ0cyA9IHt9LFxuKTogc3RyaW5nW10ge1xuICBpZiAoIWRhdGEpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBsaW5lcyA9IFtcbiAgICBwYXJ0cy53aW5kb3dzID09PSBmYWxzZSA/ICcnIDogY29tcG9uZW50V2luZG93c0xpbmUoZGF0YSwgY29udGV4dCksXG4gICAgLi4uY29tcGFyaXNvbk5vdGVzKGRhdGEuY29tcGFyaXNvbiksXG4gICAga3BpTm90ZShkYXRhLmtwaSwgZGF0YS5jb21wYXJpc29uKSxcbiAgICAuLi4ocGFydHMud2luZG93RGVzY3JpcHRpb25zID8gd2luZG93RGVzY3JpcHRpb25zKGRhdGEsIGNvbnRleHQubG9jYWxlKSA6IFtdKSxcbiAgICAuLi4ocGFydHMud2luZG93Tm90ZXMgPT09IGZhbHNlID8gW10gOiB3aW5kb3dOb3RlcyhkYXRhLCBjb250ZXh0LmxvY2FsZSkpLFxuICBdO1xuXG4gIHJldHVybiBbLi4ubmV3IFNldChsaW5lcy5maWx0ZXIoKGxpbmUpID0+ICEhbGluZSkpXTtcbn1cblxuLy8gV2hhdCBvbmUgb3V0cHV0IGNvbHVtbiBob2xkcywgZm9yIGl0cyBoZWFkZXIncyB0b29sdGlwOiB0aGUgd2luZG93cyBhXG4vLyBjb21wYXJlZCB2YWx1ZSBjb3ZlcnMsIGEgcmFuaydzIG9yIGEgc2hhcmUncyBzY29wZSwgYW5kIGhvdyBhIHdpbmRvd2VkIHZhbHVlXG4vLyB3YXMgY29tcHV0ZWQuIEEgY3Jvc3MtdGFiIGNlbGwgY29sdW1uIHJlYWRzIGl0cyBtZWFzdXJlJ3MgbWVhbmluZyB0aHJvdWdoXG4vLyBjZWxsTWVhc3VyZXMuICcnIGZvciBhIHBsYWluIGNvbHVtbi5cbmV4cG9ydCBmdW5jdGlvbiBvdXRwdXRDb2x1bW5Ob3RlKFxuICBjb2x1bW46IHN0cmluZyxcbiAgZGF0YTogQ29tcG9uZW50Tm90ZURhdGEgfCBudWxsIHwgdW5kZWZpbmVkLFxuICBsb2NhbGU6IFJlcG9ydExvY2FsZVRhZyxcbik6IHN0cmluZyB7XG4gIGNvbnN0IGFsaWFzID0gZGF0YT8uY2VsbE1lYXN1cmVzPy5bY29sdW1uXSA/PyBjb2x1bW47XG4gIGNvbnN0IG91dHB1dCA9IGRhdGE/Lm91dHB1dHM/LlthbGlhc107XG5cbiAgaWYgKCFvdXRwdXQpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICByZXR1cm4gW1xuICAgIGNvbXBhcmlzb25TZW50ZW5jZShvdXRwdXQsIGRhdGEuY29tcGFyaXNvbiwgbG9jYWxlKSxcbiAgICByYW5rU2VudGVuY2Uob3V0cHV0LCBkYXRhLm91dHB1dHMpLFxuICAgIHNoYXJlU2VudGVuY2Uob3V0cHV0LCBkYXRhLm91dHB1dHMpLFxuICAgIHdpbmRvd1NlbnRlbmNlcyhkYXRhLndpbmRvd3M/LlthbGlhc10sIGxvY2FsZSwgZGF0YSksXG4gIF1cbiAgICAuZmlsdGVyKChzZW50ZW5jZSkgPT4gISFzZW50ZW5jZSlcbiAgICAuam9pbignICcpO1xufVxuXG4vLyAnU2VwIDEg4oCTIDE1LCAyMDI2IMK3IHZzIHByZXZpb3VzIG1vbnRoOiBBdWcgMSDigJMgMTUsIDIwMjYnLiBBIGNvbXBhcmlzb25cbi8vIHdpdGggbm8gY3VycmVudCB3aW5kb3cgeWV0IGhhcyBubyBsaW5lIChpdHMgbm9fd2luZG93IG5vdGUgc2F5cyBzbyk7IGFcbi8vIGNvbXBvbmVudCB3aXRob3V0IGEgY29tcGFyaXNvbiBzaG93cyBpdHMgdGltZWZyYW1lJ3MgZGF5cy4gJycgd2hlbiB0aGUgZGF0YVxuLy8gaGFzIG5laXRoZXIuIFRoZSBub3RlJ3MgZmlyc3QgbGluZSwgYW5kIHRoZSBQREYgYW5kIFBvd2VyUG9pbnQgZXhwb3J0cydcbi8vIHN1YnRpdGxlIHVuZGVyIGEgY2hhcnQncyBvciBhIGxpc3QncyB0aXRsZS5cbmV4cG9ydCBmdW5jdGlvbiBjb21wb25lbnRXaW5kb3dzTGluZShkYXRhOiBDb21wb25lbnROb3RlRGF0YSwgY29udGV4dDogQ29tcG9uZW50Tm90ZUNvbnRleHQpOiBzdHJpbmcge1xuICBjb25zdCBjb21wYXJpc29uID0gZGF0YS5jb21wYXJpc29uO1xuXG4gIGlmIChjb21wYXJpc29uKSB7XG4gICAgcmV0dXJuIGNvbXBhcmlzb24uY3VycmVudCA/IGNvbXBhcmlzb25XaW5kb3dzTGluZShjb21wYXJpc29uLCBjb21wYXJpc29uLmN1cnJlbnQsIGNvbnRleHQubG9jYWxlKSA6ICcnO1xuICB9XG5cbiAgcmV0dXJuIGRhdGEudGltZWZyYW1lID8gZm9ybWF0RGF5V2luZG93KGRhdGEudGltZWZyYW1lLCBjb250ZXh0LnRpbWV6b25lLCBjb250ZXh0LmxvY2FsZSkgOiAnJztcbn1cblxuLy8gUmVhZCBvbiBvbmUgZGF5LCB0aGUgbGluZSBuYW1lcyB0aGUgZGF5cyB0aGUgdmFsdWVzIGFyZSByZWFkIG9uOiAnT24gU2VwXG4vLyAxNSwgMjAyNiDCtyB2cyBwcmV2aW91cyBtb250aDogQXVnIDMxLCAyMDI2Jy5cbmZ1bmN0aW9uIGNvbXBhcmlzb25XaW5kb3dzTGluZShcbiAgY29tcGFyaXNvbjogQ29tcG9uZW50Q29tcGFyaXNvbixcbiAgY3VycmVudFdpbmRvdzogQ29tcGFyaXNvbldpbmRvdyxcbiAgbG9jYWxlOiBSZXBvcnRMb2NhbGVUYWcsXG4pOiBzdHJpbmcge1xuICBpZiAoaXNSZWFkT25PbmVEYXkoY29tcGFyaXNvbikpIHtcbiAgICBjb25zdCBwcmlvcnMgPSAoY29tcGFyaXNvbi5vZmZzZXRzID8/IFtdKS5tYXAoKG9mZnNldCwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IHByaW9yID0gY29tcGFyaXNvbi5wcmlvcnM/LltpbmRleF07XG4gICAgICBjb25zdCBkYXkgPSBwcmlvciA/IGZvcm1hdERheVJhbmdlKHByaW9yLmVuZCwgcHJpb3IuZW5kLCBsb2NhbGUpIDogJyc7XG5cbiAgICAgIHJldHVybiBkYXkgPyBgJHtjb21wYXJpc29uT2Zmc2V0TGFiZWwob2Zmc2V0KX06ICR7ZGF5fWAgOiBjb21wYXJpc29uT2Zmc2V0TGFiZWwob2Zmc2V0KTtcbiAgICB9KTtcblxuICAgIHJldHVybiBbZm9ybWF0UmVhZGluZ0RheShjdXJyZW50V2luZG93LCBsb2NhbGUsIHRydWUpLCAuLi5wcmlvcnNdXG4gICAgICAuZmlsdGVyKChwYXJ0KSA9PiAhIXBhcnQpXG4gICAgICAuam9pbihXSU5ET1dTX1NFUEFSQVRPUik7XG4gIH1cblxuICBjb25zdCBjdXJyZW50ID0gZm9ybWF0RGF5V2luZG93KGN1cnJlbnRXaW5kb3csIGNvbXBhcmlzb24udGltZXpvbmUsIGxvY2FsZSk7XG4gIGNvbnN0IHByaW9ycyA9IChjb21wYXJpc29uLm9mZnNldHMgPz8gW10pLm1hcCgob2Zmc2V0LCBpbmRleCkgPT4ge1xuICAgIHJldHVybiBwcmlvcldpbmRvd1RleHQob2Zmc2V0LCBjb21wYXJpc29uLnByaW9ycz8uW2luZGV4XSwgY29tcGFyaXNvbi50aW1lem9uZSwgbG9jYWxlKTtcbiAgfSk7XG5cbiAgcmV0dXJuIFtjdXJyZW50LCAuLi5wcmlvcnNdXG4gICAgLmZpbHRlcigocGFydCkgPT4gISFwYXJ0KVxuICAgIC5qb2luKFdJTkRPV1NfU0VQQVJBVE9SKTtcbn1cblxuLy8gT25lIHByaW9yIGxhbmU6ICd2cyBwcmV2aW91cyBtb250aDogQXVnIDEg4oCTIDE1LCAyMDI2Jywgb3IgaXRzIGxhYmVsIGFsb25lXG4vLyB3aGVuIHRoZSBzZXJ2ZXIgc2VuZHMgbm8gd2luZG93IGZvciBpdC5cbmZ1bmN0aW9uIHByaW9yV2luZG93VGV4dChcbiAgb2Zmc2V0OiBDb21wYXJpc29uT2Zmc2V0LFxuICBwcmlvcjogQ29tcGFyaXNvbldpbmRvdyB8IHVuZGVmaW5lZCxcbiAgdGltZXpvbmU6IHN0cmluZyxcbiAgbG9jYWxlOiBSZXBvcnRMb2NhbGVUYWcsXG4pOiBzdHJpbmcge1xuICBjb25zdCBsYWJlbCA9IGNvbXBhcmlzb25PZmZzZXRMYWJlbChvZmZzZXQpO1xuICBjb25zdCBkYXlzID0gcHJpb3IgPyBmb3JtYXREYXlXaW5kb3cocHJpb3IsIHRpbWV6b25lLCBsb2NhbGUpIDogJyc7XG5cbiAgcmV0dXJuIGRheXMgPyBgJHtsYWJlbH06ICR7ZGF5c31gIDogbGFiZWw7XG59XG5cbmZ1bmN0aW9uIGNvbXBhcmlzb25Ob3Rlcyhjb21wYXJpc29uOiBDb21wb25lbnRDb21wYXJpc29uIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIChjb21wYXJpc29uPy5ub3RlcyA/PyBbXSkubWFwKChjb2RlKSA9PiBjb21wYXJpc29uTm90ZVRleHQoY29kZSwgY29tcGFyaXNvbikpO1xufVxuXG4vLyBXaHkgYSBLUEkgY2FyZCdzIGRlbHRhIHJlYWRzIGFzIGl0IGRvZXMgKCdObyBiYXNlbGluZTogdGhlIHByZXZpb3VzIHBlcmlvZFxuLy8gaGFzIG5vIGRhdGEuJyksIG5hbWluZyB0aGUgYmFzZWxpbmUgYnkgd2hhdCB0aGUgZmlyc3QgbGFuZSBjb21wYXJlcyBhZ2FpbnN0LlxuZnVuY3Rpb24ga3BpTm90ZShcbiAga3BpOiBDb21wb25lbnRLcGkgfCBudWxsIHwgdW5kZWZpbmVkLFxuICBjb21wYXJpc29uOiBDb21wb25lbnRDb21wYXJpc29uIHwgbnVsbCB8IHVuZGVmaW5lZCxcbik6IHN0cmluZyB7XG4gIHJldHVybiBrcGk/Lm5vdGUgPyBrcGlOb3RlVGV4dChrcGkubm90ZSwgY29tcGFyaXNvbj8ub2Zmc2V0cz8uWzBdPy5hZ2FpbnN0KSA6ICcnO1xufVxuXG4vLyBPbmUgbGluZSBwZXIgd2luZG93ZWQgdmFsdWUsIG5hbWVkIGJ5IGl0cyBjb2x1bW4gd2hlbiB0aGVyZSBhcmUgc2V2ZXJhbC5cbmZ1bmN0aW9uIHdpbmRvd0Rlc2NyaXB0aW9ucyhkYXRhOiBDb21wb25lbnROb3RlRGF0YSwgbG9jYWxlOiBSZXBvcnRMb2NhbGVUYWcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHdpbmRvd3MgPSBPYmplY3QuZW50cmllcyhkYXRhLndpbmRvd3MgPz8ge30pO1xuXG4gIHJldHVybiB3aW5kb3dzLm1hcCgoW2FsaWFzLCBtZXRhXSkgPT4ge1xuICAgIGNvbnN0IHRleHQgPSB3aW5kb3dUZXh0KG1ldGEsIGxvY2FsZSwgZGF0YS5ncmFudWxhcml0eSk7XG5cbiAgICByZXR1cm4gd2luZG93cy5sZW5ndGggPiAxID8gYCR7YWxpYXN9OiAke3RleHR9YCA6IHRleHQ7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiB3aW5kb3dOb3RlcyhkYXRhOiBDb21wb25lbnROb3RlRGF0YSwgbG9jYWxlOiBSZXBvcnRMb2NhbGVUYWcpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBPYmplY3QudmFsdWVzKGRhdGEud2luZG93cyA/PyB7fSlcbiAgICAuZmxhdE1hcCgobWV0YSkgPT4gKG1ldGEubm90ZXMgPz8gW10pLm1hcCgoY29kZSkgPT4gd2luZG93Tm90ZVRleHQoY29kZSwgbWV0YSwgbG9jYWxlLCBkYXRhLmdyYW51bGFyaXR5KSkpO1xufVxuXG4vLyBBIGNvbXBhcmVkIGNvbHVtbidzIHdpbmRvd3MuIEluIHJhbmdlIG1vZGUgZXZlcnkgcm93IGNvbXBhcmVzIHRoZSBzYW1lIHR3b1xuLy8gd2luZG93cywgc28gdGhleSBhcmUgbmFtZWQsIGFuZCByZWFkIG9uIG9uZSBkYXkgdGhlIGRheXMgdGhlIHZhbHVlcyBhcmVcbi8vIHJlYWQgb24gYXJlOyBvdmVyIGEgc2VyaWVzIG9yIGEgc3BpbmUgb2YgcGVyaW9kcyBlYWNoIHJvdyBjb21wYXJlcyBpdHMgb3duXG4vLyBwZXJpb2QsIHNvIG9ubHkgdGhlIGxhbmUgaXMuXG5mdW5jdGlvbiBjb21wYXJpc29uU2VudGVuY2UoXG4gIG91dHB1dDogT3V0cHV0TWV0YSxcbiAgY29tcGFyaXNvbjogQ29tcG9uZW50Q29tcGFyaXNvbiB8IG51bGwgfCB1bmRlZmluZWQsXG4gIGxvY2FsZTogUmVwb3J0TG9jYWxlVGFnLFxuKTogc3RyaW5nIHtcbiAgaWYgKCFvdXRwdXQucm9sZSB8fCAhY29tcGFyaXNvbikge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGNvbnN0IG9mZnNldCA9IGNvbXBhcmlzb24ub2Zmc2V0cz8uWyhvdXRwdXQub2Zmc2V0ID8/IDEpIC0gMV0gPz8gbnVsbDtcbiAgY29uc3QgY3VycmVudCA9IGNvbXBhcmlzb24uY3VycmVudCA/IGZvcm1hdERheVdpbmRvdyhjb21wYXJpc29uLmN1cnJlbnQsIGNvbXBhcmlzb24udGltZXpvbmUsIGxvY2FsZSkgOiAnJztcbiAgY29uc3QgcHJpb3JXaW5kb3cgPSBjb21wYXJpc29uLnByaW9ycz8uWyhvdXRwdXQub2Zmc2V0ID8/IDEpIC0gMV07XG4gIGNvbnN0IHByaW9yID0gcHJpb3JXaW5kb3cgPyBmb3JtYXREYXlXaW5kb3cocHJpb3JXaW5kb3csIGNvbXBhcmlzb24udGltZXpvbmUsIGxvY2FsZSkgOiAnJztcblxuICBpZiAoY29tcGFyaXNvbi5tb2RlID09PSAncmFuZ2UnICYmIGN1cnJlbnQgJiYgKG91dHB1dC5yb2xlID09PSAnY3VycmVudCcgfHwgcHJpb3IpKSB7XG4gICAgcmV0dXJuIHJhbmdlU2VudGVuY2Uob3V0cHV0LnJvbGUsIGN1cnJlbnQsIHByaW9yLCBvZmZzZXQpO1xuICB9XG5cbiAgaWYgKGlzUmVhZE9uT25lRGF5KGNvbXBhcmlzb24pICYmIGNvbXBhcmlzb24uY3VycmVudCAmJiBwcmlvcldpbmRvdykge1xuICAgIHJldHVybiByZWFkaW5nRGF5U2VudGVuY2Uob3V0cHV0LnJvbGUsIGNvbXBhcmlzb24uY3VycmVudCwgcHJpb3JXaW5kb3csIG9mZnNldCwgbG9jYWxlKTtcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQucm9sZSA9PT0gJ2N1cnJlbnQnIHx8ICFvZmZzZXQgPyAnJyA6IGAke1JPTEVfTEVBRFNbb3V0cHV0LnJvbGVdfSAke2NvbXBhcmlzb25PZmZzZXRMYWJlbChvZmZzZXQpfS5gO1xufVxuXG5mdW5jdGlvbiByYW5nZVNlbnRlbmNlKHJvbGU6IE91dHB1dFJvbGUsIGN1cnJlbnQ6IHN0cmluZywgcHJpb3I6IHN0cmluZywgb2Zmc2V0OiBDb21wYXJpc29uT2Zmc2V0IHwgbnVsbCk6IHN0cmluZyB7XG4gIHN3aXRjaCAocm9sZSkge1xuICAgIGNhc2UgJ2N1cnJlbnQnOlxuICAgICAgcmV0dXJuIGBWYWx1ZSBmb3IgJHtjdXJyZW50fS5gO1xuICAgIGNhc2UgJ3ByaW9yJzpcbiAgICAgIHJldHVybiBvZmZzZXQgPyBgUHJpb3IgdmFsdWUgZm9yICR7cHJpb3J9ICgke2NvbXBhcmlzb25PZmZzZXRMYWJlbChvZmZzZXQpfSkuYCA6IGBQcmlvciB2YWx1ZSBmb3IgJHtwcmlvcn0uYDtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGAke1JPTEVfTEVBRFNbcm9sZV19IGZyb20gJHtwcmlvcn0gdG8gJHtjdXJyZW50fS5gO1xuICB9XG59XG5cbi8vIEEgY29sdW1uIG9mIGEgY29tcGFyaXNvbiByZWFkIG9uIG9uZSBkYXksIG5hbWVkIGJ5IHRoZSBkYXlzIGl0cyB2YWx1ZXMgYXJlXG4vLyByZWFkIG9uOiAnUHJpb3IgdmFsdWUgb24gQXVnIDMxLCAyMDI2ICh2cyBwcmV2aW91cyBtb250aCkuJ1xuZnVuY3Rpb24gcmVhZGluZ0RheVNlbnRlbmNlKFxuICByb2xlOiBPdXRwdXRSb2xlLFxuICBjdXJyZW50V2luZG93OiBDb21wYXJpc29uV2luZG93LFxuICBwcmlvcldpbmRvdzogQ29tcGFyaXNvbldpbmRvdyxcbiAgb2Zmc2V0OiBDb21wYXJpc29uT2Zmc2V0IHwgbnVsbCxcbiAgbG9jYWxlOiBSZXBvcnRMb2NhbGVUYWcsXG4pOiBzdHJpbmcge1xuICBjb25zdCBjdXJyZW50ID0gZm9ybWF0UmVhZGluZ0RheShjdXJyZW50V2luZG93LCBsb2NhbGUpO1xuICBjb25zdCBwcmlvciA9IGZvcm1hdFJlYWRpbmdEYXkocHJpb3JXaW5kb3csIGxvY2FsZSk7XG5cbiAgc3dpdGNoIChyb2xlKSB7XG4gICAgY2FzZSAnY3VycmVudCc6XG4gICAgICByZXR1cm4gYFZhbHVlICR7Y3VycmVudH0uYDtcbiAgICBjYXNlICdwcmlvcic6XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gYFByaW9yIHZhbHVlICR7cHJpb3J9ICgke2NvbXBhcmlzb25PZmZzZXRMYWJlbChvZmZzZXQpfSkuYCA6IGBQcmlvciB2YWx1ZSAke3ByaW9yfS5gO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gYCR7Uk9MRV9MRUFEU1tyb2xlXX0gZnJvbSB0aGUgdmFsdWUgJHtwcmlvcn0gdG8gdGhlIHZhbHVlICR7Y3VycmVudH0uYDtcbiAgfVxufVxuXG4vLyAnUmFuayBieSBSZXZlbnVlLCAxIGJlaW5nIHRoZSBsYXJnZXN0LCB3aXRoaW4gZWFjaCBSZWdpb24uIFRpZWQgdmFsdWVzIHNoYXJlXG4vLyBhIHJhbmsgKDEsIDEsIDMpLicgQSBtZWFzdXJlIHdyaXR0ZW4gYXMgaXRzIG93biByYW5rIHJhbmtzIGJ5IHRoZSB2YWx1ZSBpdFxuLy8gd291bGQgb3RoZXJ3aXNlIHNob3csIHNvIGl0IG5hbWVzIG5vIG90aGVyIG1lYXN1cmUgKCdSYW5rLCAxIGJlaW5nIHRoZVxuLy8gbGFyZ2VzdCwgYWNyb3NzIGFsbCByb3dzLicpLlxuZnVuY3Rpb24gcmFua1NlbnRlbmNlKG91dHB1dDogT3V0cHV0TWV0YSwgb3V0cHV0czogUmVjb3JkPHN0cmluZywgT3V0cHV0TWV0YT4gfCBudWxsIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcbiAgY29uc3QgcmFuayA9IG91dHB1dC5raW5kID09PSAncmFuaycgPyBvdXRwdXQucmFuayA6IG51bGw7XG5cbiAgaWYgKCFyYW5rKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgY29uc3QgZW5kID0gcmFuay5kaXJlY3Rpb24gPT09ICdhc2MnID8gJ3NtYWxsZXN0JyA6ICdsYXJnZXN0JztcbiAgY29uc3Qgc2NvcGUgPSByYW5rLndpdGhpbj8ubGVuZ3RoID8gYHdpdGhpbiBlYWNoICR7am9pbk5hbWVzKHJhbmsud2l0aGluKX1gIDogJ2Fjcm9zcyBhbGwgcm93cyc7XG4gIGNvbnN0IHRpZXMgPSByYW5rLm1ldGhvZCA9PT0gJ2RlbnNlJyA/ICcxLCAxLCAyJyA6ICcxLCAxLCAzJztcbiAgY29uc3QgYnkgPSBpc093bk91dHB1dChvdXRwdXQsIG91dHB1dHMpID8gJycgOiBgIGJ5ICR7b3V0cHV0Lm1lYXN1cmV9YDtcblxuICByZXR1cm4gYFJhbmske2J5fSwgMSBiZWluZyB0aGUgJHtlbmR9LCAke3Njb3BlfS4gVGllZCB2YWx1ZXMgc2hhcmUgYSByYW5rICgke3RpZXN9KS4gYFxuICAgICsgRklMVEVSRURfUk9XU19TRU5URU5DRTtcbn1cblxuLy8gJ1NoYXJlIG9mIHRoZSB0b3RhbCBSZXZlbnVlIHdpdGhpbiBlYWNoIFJlZ2lvbi4nIEEgbWVhc3VyZSB3cml0dGVuIGFzIGl0c1xuLy8gb3duIHNoYXJlIG5hbWVzIG5vIG90aGVyIG1lYXN1cmUgKCdTaGFyZSBvZiB0aGUgdG90YWwgd2l0aGluIGVhY2hcbi8vIFJlZ2lvbi4nLCAnU2hhcmUgb2YgdGhlIHRvdGFsIGFjcm9zcyBhbGwgcm93cy4nKS5cbmZ1bmN0aW9uIHNoYXJlU2VudGVuY2Uob3V0cHV0OiBPdXRwdXRNZXRhLCBvdXRwdXRzOiBSZWNvcmQ8c3RyaW5nLCBPdXRwdXRNZXRhPiB8IG51bGwgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICBjb25zdCBzaGFyZSA9IG91dHB1dC5raW5kID09PSAnc2hhcmUnID8gb3V0cHV0LnNoYXJlIDogbnVsbDtcblxuICBpZiAoIXNoYXJlKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgaWYgKGlzT3duT3V0cHV0KG91dHB1dCwgb3V0cHV0cykpIHtcbiAgICBjb25zdCBzY29wZSA9IHNoYXJlLndpdGhpbj8ubGVuZ3RoID8gYHdpdGhpbiBlYWNoICR7am9pbk5hbWVzKHNoYXJlLndpdGhpbil9YCA6ICdhY3Jvc3MgYWxsIHJvd3MnO1xuXG4gICAgcmV0dXJuIGBTaGFyZSBvZiB0aGUgdG90YWwgJHtzY29wZX0uICR7RklMVEVSRURfUk9XU19TRU5URU5DRX1gO1xuICB9XG5cbiAgY29uc3Qgc2NvcGUgPSBzaGFyZS53aXRoaW4/Lmxlbmd0aCA/IGAgd2l0aGluIGVhY2ggJHtqb2luTmFtZXMoc2hhcmUud2l0aGluKX1gIDogJyc7XG5cbiAgcmV0dXJuIGBTaGFyZSBvZiB0aGUgdG90YWwgJHtvdXRwdXQubWVhc3VyZX0ke3Njb3BlfS4gJHtGSUxURVJFRF9ST1dTX1NFTlRFTkNFfWA7XG59XG5cbi8vIFdoZXRoZXIgYSByYW5rIG9yIGEgc2hhcmUgaXMgaXRzIG1lYXN1cmUncyBvd24gb3V0cHV0OiB0aGUgc2VydmVyIHdyaXRlcyBhXG4vLyBtZWFzdXJlIHdpdGggYSByYW5rIG9yIGEgc2hhcmUgYXMgdGhhdCByYW5rIG9yIHNoYXJlLCBzbyBpdHMgbWVhc3VyZSBpcyBhXG4vLyBjb2x1bW4gb2YgdGhlIHNhbWUga2luZCAoaXRzZWxmLCBvciBmb3IgYSBwcmlvciBvciBhIGNoYW5nZSB0aGUgY3VycmVudFxuLy8gY29sdW1uKSwgbmV2ZXIgYSB2YWx1ZSBvZiBpdHMgb3duIHRvIG5hbWUuXG5mdW5jdGlvbiBpc093bk91dHB1dChvdXRwdXQ6IE91dHB1dE1ldGEsIG91dHB1dHM6IFJlY29yZDxzdHJpbmcsIE91dHB1dE1ldGE+IHwgbnVsbCB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICByZXR1cm4gb3V0cHV0cz8uW291dHB1dC5tZWFzdXJlXT8ua2luZCA9PT0gb3V0cHV0LmtpbmQ7XG59XG5cbi8vIEEgd2luZG93ZWQgY29sdW1uOiB3aGF0IGl0IGlzLCB0aGVuIHdoeSBpdCByZWFkcyBhcyBpdCBkb2VzLlxuZnVuY3Rpb24gd2luZG93U2VudGVuY2VzKFxuICBtZXRhOiBXaW5kb3dNZXRhIHwgdW5kZWZpbmVkLFxuICBsb2NhbGU6IFJlcG9ydExvY2FsZVRhZyxcbiAgZGF0YTogQ29tcG9uZW50Tm90ZURhdGEsXG4pOiBzdHJpbmcge1xuICBpZiAoIW1ldGEpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBjb25zdCBub3RlcyA9IChtZXRhLm5vdGVzID8/IFtdKS5tYXAoKGNvZGUpID0+IHdpbmRvd05vdGVUZXh0KGNvZGUsIG1ldGEsIGxvY2FsZSwgZGF0YS5ncmFudWxhcml0eSkpO1xuXG4gIHJldHVybiBbYCR7d2luZG93VGV4dChtZXRhLCBsb2NhbGUsIGRhdGEuZ3JhbnVsYXJpdHkpfS5gLCAuLi5ub3Rlc10uam9pbignICcpO1xufVxuXG4vLyAnUmVnaW9uJywgJ1JlZ2lvbiBhbmQgQ2hhbm5lbCcsICdSZWdpb24sIENoYW5uZWwgYW5kIFBsYW4nLlxuZnVuY3Rpb24gam9pbk5hbWVzKG5hbWVzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIHJldHVybiBuYW1lcy5sZW5ndGggPiAxXG4gICAgPyBgJHtuYW1lcy5zbGljZSgwLCAtMSkuam9pbignLCAnKX0gYW5kICR7bmFtZXNbbmFtZXMubGVuZ3RoIC0gMV19YFxuICAgIDogbmFtZXMuam9pbignJyk7XG59XG4iXX0=
@@ -0,0 +1,28 @@
1
+ import { Pipe } from '@angular/core';
2
+ import { formatOutputValue } from '../format';
3
+ import * as i0 from "@angular/core";
4
+ // A list cell (or a totals cell) of an output column, written by what it holds:
5
+ // a prior or a change in its measure's format, a signed percent change, a
6
+ // change of a rate in points, a rank as a whole number, a share as a percent.
7
+ // It reads the whole row, since a change looks up its prior beside it to tell
8
+ // a missing baseline ('—') from a zero one ('n/a'). An empty value reads ''.
9
+ export class ReportOutputPipe {
10
+ transform(row, column, output, context) {
11
+ return formatOutputValue(row?.[column.column], output.output, column, context, {
12
+ measureSpec: output.measureSpec,
13
+ prior: output.priorAlias && row ? row[output.priorAlias] : undefined,
14
+ floor: output.floor,
15
+ empty: '',
16
+ });
17
+ }
18
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportOutputPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
19
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: ReportOutputPipe, isStandalone: true, name: "fsReportOutput" });
20
+ }
21
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportOutputPipe, decorators: [{
22
+ type: Pipe,
23
+ args: [{
24
+ name: 'fsReportOutput',
25
+ standalone: true,
26
+ }]
27
+ }] });
28
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LW91dHB1dC5waXBlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL3BpcGVzL3JlcG9ydC1vdXRwdXQucGlwZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFpQixNQUFNLGVBQWUsQ0FBQztBQUVwRCxPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sV0FBVyxDQUFDOztBQUtwRSxnRkFBZ0Y7QUFDaEYsMEVBQTBFO0FBQzFFLDhFQUE4RTtBQUM5RSw4RUFBOEU7QUFDOUUsNkVBQTZFO0FBSzdFLE1BQU0sT0FBTyxnQkFBZ0I7SUFFcEIsU0FBUyxDQUNkLEdBQStDLEVBQy9DLE1BQWtCLEVBQ2xCLE1BQXdCLEVBQ3hCLE9BQTRCO1FBRTVCLE9BQU8saUJBQWlCLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRTtZQUM3RSxXQUFXLEVBQUUsTUFBTSxDQUFDLFdBQVc7WUFDL0IsS0FBSyxFQUFFLE1BQU0sQ0FBQyxVQUFVLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTO1lBQ3BFLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSztZQUNuQixLQUFLLEVBQUUsRUFBRTtTQUNWLENBQUMsQ0FBQztJQUNMLENBQUM7d0dBZFUsZ0JBQWdCO3NHQUFoQixnQkFBZ0I7OzRGQUFoQixnQkFBZ0I7a0JBSjVCLElBQUk7bUJBQUM7b0JBQ0osSUFBSSxFQUFFLGdCQUFnQjtvQkFDdEIsVUFBVSxFQUFFLElBQUk7aUJBQ2pCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBGb3JtYXR0ZWRPdXRwdXRWYWx1ZSwgZm9ybWF0T3V0cHV0VmFsdWUgfSBmcm9tICcuLi9mb3JtYXQnO1xuaW1wb3J0IHsgTGlzdENvbHVtbiwgUmVwb3J0Rm9ybWF0Q29udGV4dCB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7XG5pbXBvcnQgeyBMaXN0T3V0cHV0Q29sdW1uIH0gZnJvbSAnLi4vbGlzdC1jb25maWcnO1xuXG5cbi8vIEEgbGlzdCBjZWxsIChvciBhIHRvdGFscyBjZWxsKSBvZiBhbiBvdXRwdXQgY29sdW1uLCB3cml0dGVuIGJ5IHdoYXQgaXQgaG9sZHM6XG4vLyBhIHByaW9yIG9yIGEgY2hhbmdlIGluIGl0cyBtZWFzdXJlJ3MgZm9ybWF0LCBhIHNpZ25lZCBwZXJjZW50IGNoYW5nZSwgYVxuLy8gY2hhbmdlIG9mIGEgcmF0ZSBpbiBwb2ludHMsIGEgcmFuayBhcyBhIHdob2xlIG51bWJlciwgYSBzaGFyZSBhcyBhIHBlcmNlbnQuXG4vLyBJdCByZWFkcyB0aGUgd2hvbGUgcm93LCBzaW5jZSBhIGNoYW5nZSBsb29rcyB1cCBpdHMgcHJpb3IgYmVzaWRlIGl0IHRvIHRlbGxcbi8vIGEgbWlzc2luZyBiYXNlbGluZSAoJ+KAlCcpIGZyb20gYSB6ZXJvIG9uZSAoJ24vYScpLiBBbiBlbXB0eSB2YWx1ZSByZWFkcyAnJy5cbkBQaXBlKHtcbiAgbmFtZTogJ2ZzUmVwb3J0T3V0cHV0JyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgUmVwb3J0T3V0cHV0UGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuXG4gIHB1YmxpYyB0cmFuc2Zvcm0oXG4gICAgcm93OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IG51bGwgfCB1bmRlZmluZWQsXG4gICAgY29sdW1uOiBMaXN0Q29sdW1uLFxuICAgIG91dHB1dDogTGlzdE91dHB1dENvbHVtbixcbiAgICBjb250ZXh0OiBSZXBvcnRGb3JtYXRDb250ZXh0LFxuICApOiBGb3JtYXR0ZWRPdXRwdXRWYWx1ZSB7XG4gICAgcmV0dXJuIGZvcm1hdE91dHB1dFZhbHVlKHJvdz8uW2NvbHVtbi5jb2x1bW5dLCBvdXRwdXQub3V0cHV0LCBjb2x1bW4sIGNvbnRleHQsIHtcbiAgICAgIG1lYXN1cmVTcGVjOiBvdXRwdXQubWVhc3VyZVNwZWMsXG4gICAgICBwcmlvcjogb3V0cHV0LnByaW9yQWxpYXMgJiYgcm93ID8gcm93W291dHB1dC5wcmlvckFsaWFzXSA6IHVuZGVmaW5lZCxcbiAgICAgIGZsb29yOiBvdXRwdXQuZmxvb3IsXG4gICAgICBlbXB0eTogJycsXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==