@firestitch/report 18.6.1 → 18.8.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.
Files changed (97) hide show
  1. package/app/reports/components/component-chart/component-chart.component.d.ts +6 -7
  2. package/app/reports/components/component-kpi/component-kpi.component.d.ts +17 -9
  3. package/app/reports/components/component-kpi/components/sparkline/sparkline.component.d.ts +8 -0
  4. package/app/reports/components/component-list/component-list.component.d.ts +39 -10
  5. package/app/reports/components/component-note/component-note.component.d.ts +12 -0
  6. package/app/reports/components/report-canvas/report-canvas.component.d.ts +0 -10
  7. package/app/reports/components/report-component/report-component.component.d.ts +5 -12
  8. package/app/reports/data/report.data.d.ts +2 -3
  9. package/app/reports/dialogs/component-settings/component-settings.component.d.ts +34 -2
  10. package/app/reports/dialogs/list-columns/list-columns.component.d.ts +23 -0
  11. package/app/reports/dialogs/report-settings/report-locale-patch.d.ts +5 -0
  12. package/app/reports/dialogs/report-settings/report-settings.component.d.ts +20 -2
  13. package/app/reports/enums/report-change-polarity.enum.d.ts +5 -0
  14. package/app/reports/enums/report-chart-color.enum.d.ts +12 -0
  15. package/app/reports/enums/report-chart-data-labels.enum.d.ts +6 -0
  16. package/app/reports/enums/report-chart-date-label.enum.d.ts +5 -0
  17. package/app/reports/enums/report-chart-line-style.enum.d.ts +5 -0
  18. package/app/reports/enums/report-chart-mark-stat.enum.d.ts +6 -0
  19. package/app/reports/enums/report-kpi-trend.enum.d.ts +5 -0
  20. package/app/reports/enums/report-list-column-format.enum.d.ts +6 -0
  21. package/app/reports/enums/report-number-units.enum.d.ts +6 -0
  22. package/app/reports/enums/report-value-format.enum.d.ts +5 -0
  23. package/app/reports/export/offscreen-chart.d.ts +2 -2
  24. package/app/reports/export/report-export-collector.service.d.ts +37 -8
  25. package/app/reports/export/report-pdf.service.d.ts +6 -0
  26. package/app/reports/export/report-pptx.service.d.ts +24 -0
  27. package/app/reports/format.d.ts +64 -3
  28. package/app/reports/interfaces/report-chat-viewer-filter.interface.d.ts +2 -0
  29. package/app/reports/interfaces/report.interface.d.ts +205 -14
  30. package/app/reports/kpi-card.d.ts +48 -0
  31. package/app/reports/layout.d.ts +0 -9
  32. package/app/reports/list-config.d.ts +16 -0
  33. package/app/reports/option-builder.d.ts +76 -9
  34. package/app/reports/output-notes.d.ts +14 -0
  35. package/app/reports/pipes/report-date.pipe.d.ts +2 -1
  36. package/app/reports/pipes/report-number.pipe.d.ts +8 -0
  37. package/app/reports/pipes/report-output.pipe.d.ts +10 -0
  38. package/app/reports/report-filter-items.d.ts +5 -2
  39. package/app/reports/report-url-state.d.ts +4 -0
  40. package/app/reports/services/report-filter-state.service.d.ts +27 -2
  41. package/app/reports/theme/palette.d.ts +6 -0
  42. package/app/reports/theme/typography.d.ts +2 -0
  43. package/esm2022/app/reports/components/component-chart/component-chart.component.mjs +23 -20
  44. package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +56 -29
  45. package/esm2022/app/reports/components/component-kpi/components/sparkline/sparkline.component.mjs +19 -0
  46. package/esm2022/app/reports/components/component-list/component-list.component.mjs +218 -32
  47. package/esm2022/app/reports/components/component-note/component-note.component.mjs +30 -0
  48. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +7 -61
  49. package/esm2022/app/reports/components/report-component/report-component.component.mjs +99 -100
  50. package/esm2022/app/reports/data/report.data.mjs +20 -7
  51. package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +133 -13
  52. package/esm2022/app/reports/dialogs/list-columns/list-columns.component.mjs +56 -0
  53. package/esm2022/app/reports/dialogs/report-settings/report-locale-patch.mjs +13 -0
  54. package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +138 -20
  55. package/esm2022/app/reports/enums/report-change-polarity.enum.mjs +11 -0
  56. package/esm2022/app/reports/enums/report-chart-color.enum.mjs +19 -0
  57. package/esm2022/app/reports/enums/report-chart-data-labels.enum.mjs +13 -0
  58. package/esm2022/app/reports/enums/report-chart-date-label.enum.mjs +13 -0
  59. package/esm2022/app/reports/enums/report-chart-line-style.enum.mjs +12 -0
  60. package/esm2022/app/reports/enums/report-chart-mark-stat.enum.mjs +12 -0
  61. package/esm2022/app/reports/enums/report-kpi-trend.enum.mjs +10 -0
  62. package/esm2022/app/reports/enums/report-list-column-format.enum.mjs +14 -0
  63. package/esm2022/app/reports/enums/report-number-units.enum.mjs +14 -0
  64. package/esm2022/app/reports/enums/report-value-format.enum.mjs +13 -0
  65. package/esm2022/app/reports/export/offscreen-chart.mjs +5 -4
  66. package/esm2022/app/reports/export/report-export-collector.service.mjs +186 -40
  67. package/esm2022/app/reports/export/report-pdf.service.mjs +332 -67
  68. package/esm2022/app/reports/export/report-pptx.service.mjs +765 -106
  69. package/esm2022/app/reports/format.mjs +917 -57
  70. package/esm2022/app/reports/interfaces/report-chat-viewer-filter.interface.mjs +1 -1
  71. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  72. package/esm2022/app/reports/kpi-card.mjs +174 -0
  73. package/esm2022/app/reports/layout.mjs +1 -46
  74. package/esm2022/app/reports/list-config.mjs +106 -0
  75. package/esm2022/app/reports/option-builder.mjs +1457 -117
  76. package/esm2022/app/reports/output-notes.mjs +158 -0
  77. package/esm2022/app/reports/pipes/report-date.pipe.mjs +7 -6
  78. package/esm2022/app/reports/pipes/report-number.pipe.mjs +25 -0
  79. package/esm2022/app/reports/pipes/report-output.pipe.mjs +28 -0
  80. package/esm2022/app/reports/report-filter-items.mjs +28 -3
  81. package/esm2022/app/reports/report-url-state.mjs +56 -15
  82. package/esm2022/app/reports/services/report-filter-state.service.mjs +274 -22
  83. package/esm2022/app/reports/theme/echarts.mjs +8 -2
  84. package/esm2022/app/reports/theme/palette.mjs +35 -1
  85. package/esm2022/app/reports/theme/typography.mjs +8 -1
  86. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +2 -2
  87. package/esm2022/app/reports/views/report/report.component.mjs +3 -4
  88. package/esm2022/public_api.mjs +10 -1
  89. package/fesm2022/{firestitch-report-echarts-Djtmaxj1.mjs → firestitch-report-echarts-qCBE3LqM.mjs} +9 -3
  90. package/fesm2022/firestitch-report-echarts-qCBE3LqM.mjs.map +1 -0
  91. package/fesm2022/{firestitch-report-firestitch-report-D3zseBZc.mjs → firestitch-report-firestitch-report-DbsWbE-j.mjs} +5523 -875
  92. package/fesm2022/firestitch-report-firestitch-report-DbsWbE-j.mjs.map +1 -0
  93. package/fesm2022/firestitch-report.mjs +1 -1
  94. package/package.json +1 -1
  95. package/public_api.d.ts +9 -0
  96. package/fesm2022/firestitch-report-echarts-Djtmaxj1.mjs.map +0 -1
  97. package/fesm2022/firestitch-report-firestitch-report-D3zseBZc.mjs.map +0 -1
@@ -0,0 +1,106 @@
1
+ import { laneOutputAlias } from './format';
2
+ // The most leading columns a list can keep in view while it scrolls sideways.
3
+ // Mirrors the server's ListConfig::MAX_PINNED_COLUMNS, which refuses more.
4
+ export const MAX_PINNED_COLUMNS = 3;
5
+ // A list's authored sort, most important first. A list sort is a list of
6
+ // terms, but a list saved before multi-key sorting stores one object and is
7
+ // never rewritten, so both shapes are read here. This is the one reader of a
8
+ // list's config.sort: the config type intersects the chart and list configs,
9
+ // so a direct `config.sort.column` still compiles and silently misreads an
10
+ // array. A term without a column orders nothing and is dropped.
11
+ export function listSortTerms(config) {
12
+ const sort = config?.sort;
13
+ if (!sort) {
14
+ return [];
15
+ }
16
+ return (Array.isArray(sort) ? sort : [sort])
17
+ .filter((term) => !!term?.column);
18
+ }
19
+ // The columns a viewer can hide on a list, by name: a plain list's configured
20
+ // columns. A cross-tab offers none, since its columns are pivot values that
21
+ // come and go with the data.
22
+ export function listHideableColumns(config) {
23
+ return config?.pivotBy?.column
24
+ ? []
25
+ : (config?.columns ?? []).map((column) => column.column);
26
+ }
27
+ // The hidden column names a list honors: only columns it can hide, each once,
28
+ // in the list's own order, and none at all when they would hide every column
29
+ // (a list always shows one, and the server ignores such a CSV list too). The
30
+ // filter state, the screen and every export read this one rule.
31
+ export function listHiddenColumns(config, names) {
32
+ const hideable = listHideableColumns(config);
33
+ const hidden = hideable.filter((name) => names.includes(name));
34
+ return hidden.length < hideable.length ? hidden : [];
35
+ }
36
+ // How many leading columns stay in view while a wide list scrolls sideways.
37
+ // Unset, a cross-tab pins its row-key column and a plain list pins none. A
38
+ // cross-tab pins at most that one column, since the rest are pivot values; a
39
+ // stored config that asks for more is clamped here, as the server refuses it
40
+ // only on save.
41
+ export function listPinnedColumns(config) {
42
+ const crossTab = !!config?.pivotBy?.column;
43
+ const pinned = config?.pinnedColumns ?? (crossTab ? 1 : 0);
44
+ return Math.min(Math.max(Math.floor(Number(pinned) || 0), 0), crossTab ? 1 : MAX_PINNED_COLUMNS);
45
+ }
46
+ // The classes a list column carries on its header, cells and footer. fs-list
47
+ // copies a column's classes once, when it builds the column, so they are
48
+ // static: `report-pin-{index}` names the column's place among the pinned ones
49
+ // (its left offset is a CSS variable the list measures), `report-pin-last`
50
+ // draws the separator after the last pinned column, and `report-nowrap` keeps
51
+ // the column's cells on one line.
52
+ export function columnClasses(column, index, pinned) {
53
+ const classes = [];
54
+ if (index < pinned) {
55
+ classes.push('report-pinned', `report-pin-${index}`);
56
+ if (index === pinned - 1) {
57
+ classes.push('report-pin-last');
58
+ }
59
+ }
60
+ if (column.wrap === false) {
61
+ classes.push('report-nowrap');
62
+ }
63
+ return classes.join(' ');
64
+ }
65
+ // The label a list's totals row writes, on screen and in the PDF and deck.
66
+ export const LIST_TOTAL_LABEL = 'Total';
67
+ // The column of a totals row that carries LIST_TOTAL_LABEL, among the columns
68
+ // shown, in order: the first one, unless it holds a total itself, in which
69
+ // case the row has no label. A cross-tab's first column is its row key, which
70
+ // never holds one.
71
+ export function listTotalsLabelColumn(columns, totals) {
72
+ const first = columns[0];
73
+ return first && totals?.[first.column] === undefined ? first.column : null;
74
+ }
75
+ // The output columns among a list's columns, by column name, from the
76
+ // metadata its data carries. A cross-tab cell column takes its measure's
77
+ // meaning through cellMeasures; its cells all share the grid's cellFormat and
78
+ // have no prior beside them, since a cross-tab never compares. A column with
79
+ // no output metadata (a plain measure or dimension, an older server) is left
80
+ // out and written as before.
81
+ export function listOutputColumns(columns, data, authored) {
82
+ const outputs = data?.outputs ?? {};
83
+ const resolved = {};
84
+ columns.forEach((column) => {
85
+ const cellMeasure = data?.cellMeasures?.[column.column];
86
+ const alias = cellMeasure ?? column.column;
87
+ const output = outputs[alias];
88
+ if (output) {
89
+ resolved[column.column] = {
90
+ output,
91
+ measureSpec: authored.find((source) => source.column === output.measure) ?? null,
92
+ priorAlias: cellMeasure ? null : listPriorAlias(outputs, alias, output),
93
+ floor: data?.comparison?.floor ?? null,
94
+ };
95
+ }
96
+ });
97
+ return resolved;
98
+ }
99
+ // A change's or a percent change's prior in the same lane; null for any other
100
+ // output.
101
+ function listPriorAlias(outputs, alias, output) {
102
+ return output.role === 'change' || output.role === 'percent_change'
103
+ ? laneOutputAlias(outputs, alias, 'prior')
104
+ : null;
105
+ }
106
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC1jb25maWcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL3JlcG9ydHMvbGlzdC1jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQVczQyw4RUFBOEU7QUFDOUUsMkVBQTJFO0FBQzNFLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLENBQUMsQ0FBQztBQUVwQyx5RUFBeUU7QUFDekUsNEVBQTRFO0FBQzVFLDZFQUE2RTtBQUM3RSw2RUFBNkU7QUFDN0UsMkVBQTJFO0FBQzNFLGdFQUFnRTtBQUNoRSxNQUFNLFVBQVUsYUFBYSxDQUFDLE1BQXFDO0lBQ2pFLE1BQU0sSUFBSSxHQUFHLE1BQU0sRUFBRSxJQUFJLENBQUM7SUFFMUIsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ1YsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUN6QyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDdEMsQ0FBQztBQUVELDhFQUE4RTtBQUM5RSw0RUFBNEU7QUFDNUUsNkJBQTZCO0FBQzdCLE1BQU0sVUFBVSxtQkFBbUIsQ0FBQyxNQUFxQztJQUN2RSxPQUFPLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTTtRQUM1QixDQUFDLENBQUMsRUFBRTtRQUNKLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxPQUFPLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDN0QsQ0FBQztBQUVE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QyxDQUFDLElBQUksQ0FBQztBQUNYLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBsYW5lT3V0cHV0QWxpYXMgfSBmcm9tICcuL2Zvcm1hdCc7XG5pbXBvcnQge1xuICBDb21wb25lbnREYXRhLFxuICBMaXN0Q29sdW1uLFxuICBMaXN0Q29uZmlnLFxuICBOdW1iZXJGb3JtYXRTcGVjLFxuICBPdXRwdXRNZXRhLFxuICBSZXBvcnRTb3J0LFxufSBmcm9tICcuL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7XG5cblxuLy8gVGhlIG1vc3QgbGVhZGluZyBjb2x1bW5zIGEgbGlzdCBjYW4ga2VlcCBpbiB2aWV3IHdoaWxlIGl0IHNjcm9sbHMgc2lkZXdheXMuXG4vLyBNaXJyb3JzIHRoZSBzZXJ2ZXIncyBMaXN0Q29uZmlnOjpNQVhfUElOTkVEX0NPTFVNTlMsIHdoaWNoIHJlZnVzZXMgbW9yZS5cbmV4cG9ydCBjb25zdCBNQVhfUElOTkVEX0NPTFVNTlMgPSAzO1xuXG4vLyBBIGxpc3QncyBhdXRob3JlZCBzb3J0LCBtb3N0IGltcG9ydGFudCBmaXJzdC4gQSBsaXN0IHNvcnQgaXMgYSBsaXN0IG9mXG4vLyB0ZXJtcywgYnV0IGEgbGlzdCBzYXZlZCBiZWZvcmUgbXVsdGkta2V5IHNvcnRpbmcgc3RvcmVzIG9uZSBvYmplY3QgYW5kIGlzXG4vLyBuZXZlciByZXdyaXR0ZW4sIHNvIGJvdGggc2hhcGVzIGFyZSByZWFkIGhlcmUuIFRoaXMgaXMgdGhlIG9uZSByZWFkZXIgb2YgYVxuLy8gbGlzdCdzIGNvbmZpZy5zb3J0OiB0aGUgY29uZmlnIHR5cGUgaW50ZXJzZWN0cyB0aGUgY2hhcnQgYW5kIGxpc3QgY29uZmlncyxcbi8vIHNvIGEgZGlyZWN0IGBjb25maWcuc29ydC5jb2x1bW5gIHN0aWxsIGNvbXBpbGVzIGFuZCBzaWxlbnRseSBtaXNyZWFkcyBhblxuLy8gYXJyYXkuIEEgdGVybSB3aXRob3V0IGEgY29sdW1uIG9yZGVycyBub3RoaW5nIGFuZCBpcyBkcm9wcGVkLlxuZXhwb3J0IGZ1bmN0aW9uIGxpc3RTb3J0VGVybXMoY29uZmlnOiBMaXN0Q29uZmlnIHwgbnVsbCB8IHVuZGVmaW5lZCk6IFJlcG9ydFNvcnRbXSB7XG4gIGNvbnN0IHNvcnQgPSBjb25maWc/LnNvcnQ7XG5cbiAgaWYgKCFzb3J0KSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgcmV0dXJuIChBcnJheS5pc0FycmF5KHNvcnQpID8gc29ydCA6IFtzb3J0XSlcbiAgICAuZmlsdGVyKCh0ZXJtKSA9PiAhIXRlcm0/LmNvbHVtbik7XG59XG5cbi8vIFRoZSBjb2x1bW5zIGEgdmlld2VyIGNhbiBoaWRlIG9uIGEgbGlzdCwgYnkgbmFtZTogYSBwbGFpbiBsaXN0J3MgY29uZmlndXJlZFxuLy8gY29sdW1ucy4gQSBjcm9zcy10YWIgb2ZmZXJzIG5vbmUsIHNpbmNlIGl0cyBjb2x1bW5zIGFyZSBwaXZvdCB2YWx1ZXMgdGhhdFxuLy8gY29tZSBhbmQgZ28gd2l0aCB0aGUgZGF0YS5cbmV4cG9ydCBmdW5jdGlvbiBsaXN0SGlkZWFibGVDb2x1bW5zKGNvbmZpZzogTGlzdENvbmZpZyB8IG51bGwgfCB1bmRlZmluZWQpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBjb25maWc/LnBpdm90Qnk/LmNvbHVtblxuICAgID8gW11cbiAgICA6IChjb25maWc/LmNvbHVtbnMgPz8gW10pLm1hcCgoY29sdW1uKSA9PiBjb2x1bW4uY29sdW1uKTtcbn1cblxuLy8gVGhlIGhpZGRlbiBjb2x1bW4gbmFtZXMgYSBsaXN0IGhvbm9yczogb25seSBjb2x1bW5zIGl0IGNhbiBoaWRlLCBlYWNoIG9uY2UsXG4vLyBpbiB0aGUgbGlzdCdzIG93biBvcmRlciwgYW5kIG5vbmUgYXQgYWxsIHdoZW4gdGhleSB3b3VsZCBoaWRlIGV2ZXJ5IGNvbHVtblxuLy8gKGEgbGlzdCBhbHdheXMgc2hvd3Mgb25lLCBhbmQgdGhlIHNlcnZlciBpZ25vcmVzIHN1Y2ggYSBDU1YgbGlzdCB0b28pLiBUaGVcbi8vIGZpbHRlciBzdGF0ZSwgdGhlIHNjcmVlbiBhbmQgZXZlcnkgZXhwb3J0IHJlYWQgdGhpcyBvbmUgcnVsZS5cbmV4cG9ydCBmdW5jdGlvbiBsaXN0SGlkZGVuQ29sdW1ucyhjb25maWc6IExpc3RDb25maWcgfCBudWxsIHwgdW5kZWZpbmVkLCBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGhpZGVhYmxlID0gbGlzdEhpZGVhYmxlQ29sdW1ucyhjb25maWcpO1xuICBjb25zdCBoaWRkZW4gPSBoaWRlYWJsZS5maWx0ZXIoKG5hbWUpID0+IG5hbWVzLmluY2x1ZGVzKG5hbWUpKTtcblxuICByZXR1cm4gaGlkZGVuLmxlbmd0aCA8IGhpZGVhYmxlLmxlbmd0aCA/IGhpZGRlbiA6IFtdO1xufVxuXG4vLyBIb3cgbWFueSBsZWFkaW5nIGNvbHVtbnMgc3RheSBpbiB2aWV3IHdoaWxlIGEgd2lkZSBsaXN0IHNjcm9sbHMgc2lkZXdheXMuXG4vLyBVbnNldCwgYSBjcm9zcy10YWIgcGlucyBpdHMgcm93LWtleSBjb2x1bW4gYW5kIGEgcGxhaW4gbGlzdCBwaW5zIG5vbmUuIEFcbi8vIGNyb3NzLXRhYiBwaW5zIGF0IG1vc3QgdGhhdCBvbmUgY29sdW1uLCBzaW5jZSB0aGUgcmVzdCBhcmUgcGl2b3QgdmFsdWVzOyBhXG4vLyBzdG9yZWQgY29uZmlnIHRoYXQgYXNrcyBmb3IgbW9yZSBpcyBjbGFtcGVkIGhlcmUsIGFzIHRoZSBzZXJ2ZXIgcmVmdXNlcyBpdFxuLy8gb25seSBvbiBzYXZlLlxuZXhwb3J0IGZ1bmN0aW9uIGxpc3RQaW5uZWRDb2x1bW5zKGNvbmZpZzogTGlzdENvbmZpZyB8IG51bGwgfCB1bmRlZmluZWQpOiBudW1iZXIge1xuICBjb25zdCBjcm9zc1RhYiA9ICEhY29uZmlnPy5waXZvdEJ5Py5jb2x1bW47XG4gIGNvbnN0IHBpbm5lZCA9IGNvbmZpZz8ucGlubmVkQ29sdW1ucyA/PyAoY3Jvc3NUYWIgPyAxIDogMCk7XG5cbiAgcmV0dXJuIE1hdGgubWluKE1hdGgubWF4KE1hdGguZmxvb3IoTnVtYmVyKHBpbm5lZCkgfHwgMCksIDApLCBjcm9zc1RhYiA/IDEgOiBNQVhfUElOTkVEX0NPTFVNTlMpO1xufVxuXG4vLyBUaGUgY2xhc3NlcyBhIGxpc3QgY29sdW1uIGNhcnJpZXMgb24gaXRzIGhlYWRlciwgY2VsbHMgYW5kIGZvb3Rlci4gZnMtbGlzdFxuLy8gY29waWVzIGEgY29sdW1uJ3MgY2xhc3NlcyBvbmNlLCB3aGVuIGl0IGJ1aWxkcyB0aGUgY29sdW1uLCBzbyB0aGV5IGFyZVxuLy8gc3RhdGljOiBgcmVwb3J0LXBpbi17aW5kZXh9YCBuYW1lcyB0aGUgY29sdW1uJ3MgcGxhY2UgYW1vbmcgdGhlIHBpbm5lZCBvbmVzXG4vLyAoaXRzIGxlZnQgb2Zmc2V0IGlzIGEgQ1NTIHZhcmlhYmxlIHRoZSBsaXN0IG1lYXN1cmVzKSwgYHJlcG9ydC1waW4tbGFzdGBcbi8vIGRyYXdzIHRoZSBzZXBhcmF0b3IgYWZ0ZXIgdGhlIGxhc3QgcGlubmVkIGNvbHVtbiwgYW5kIGByZXBvcnQtbm93cmFwYCBrZWVwc1xuLy8gdGhlIGNvbHVtbidzIGNlbGxzIG9uIG9uZSBsaW5lLlxuZXhwb3J0IGZ1bmN0aW9uIGNvbHVtbkNsYXNzZXMoY29sdW1uOiBMaXN0Q29sdW1uLCBpbmRleDogbnVtYmVyLCBwaW5uZWQ6IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IGNsYXNzZXM6IHN0cmluZ1tdID0gW107XG5cbiAgaWYgKGluZGV4IDwgcGlubmVkKSB7XG4gICAgY2xhc3Nlcy5wdXNoKCdyZXBvcnQtcGlubmVkJywgYHJlcG9ydC1waW4tJHtpbmRleH1gKTtcblxuICAgIGlmIChpbmRleCA9PT0gcGlubmVkIC0gMSkge1xuICAgICAgY2xhc3Nlcy5wdXNoKCdyZXBvcnQtcGluLWxhc3QnKTtcbiAgICB9XG4gIH1cblxuICBpZiAoY29sdW1uLndyYXAgPT09IGZhbHNlKSB7XG4gICAgY2xhc3Nlcy5wdXNoKCdyZXBvcnQtbm93cmFwJyk7XG4gIH1cblxuICByZXR1cm4gY2xhc3Nlcy5qb2luKCcgJyk7XG59XG5cbi8vIFRoZSBsYWJlbCBhIGxpc3QncyB0b3RhbHMgcm93IHdyaXRlcywgb24gc2NyZWVuIGFuZCBpbiB0aGUgUERGIGFuZCBkZWNrLlxuZXhwb3J0IGNvbnN0IExJU1RfVE9UQUxfTEFCRUwgPSAnVG90YWwnO1xuXG4vLyBUaGUgY29sdW1uIG9mIGEgdG90YWxzIHJvdyB0aGF0IGNhcnJpZXMgTElTVF9UT1RBTF9MQUJFTCwgYW1vbmcgdGhlIGNvbHVtbnNcbi8vIHNob3duLCBpbiBvcmRlcjogdGhlIGZpcnN0IG9uZSwgdW5sZXNzIGl0IGhvbGRzIGEgdG90YWwgaXRzZWxmLCBpbiB3aGljaFxuLy8gY2FzZSB0aGUgcm93IGhhcyBubyBsYWJlbC4gQSBjcm9zcy10YWIncyBmaXJzdCBjb2x1bW4gaXMgaXRzIHJvdyBrZXksIHdoaWNoXG4vLyBuZXZlciBob2xkcyBvbmUuXG5leHBvcnQgZnVuY3Rpb24gbGlzdFRvdGFsc0xhYmVsQ29sdW1uKFxuICBjb2x1bW5zOiByZWFkb25seSBMaXN0Q29sdW1uW10sXG4gIHRvdGFsczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBudWxsIHwgdW5kZWZpbmVkLFxuKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IGZpcnN0ID0gY29sdW1uc1swXTtcblxuICByZXR1cm4gZmlyc3QgJiYgdG90YWxzPy5bZmlyc3QuY29sdW1uXSA9PT0gdW5kZWZpbmVkID8gZmlyc3QuY29sdW1uIDogbnVsbDtcbn1cblxuLy8gSG93IGEgbGlzdCBjb2x1bW4gdGhhdCBob2xkcyBhIGNvbXBhcmVkLCB3aW5kb3dlZCwgcmFua2VkIG9yIHNoYXJlZCBvdXRwdXRcbi8vIGlzIHdyaXR0ZW4gKGZvcm1hdC50cyBmb3JtYXRPdXRwdXRWYWx1ZSk6IHdoYXQgaXQgaG9sZHMsIHRoZSBmb3JtYXQgb2YgaXRzXG4vLyBzb3VyY2UgbWVhc3VyZSdzIGNvbHVtbiwgd2hpY2ggYSBwcmlvciBvciBhIGNoYW5nZSB0YWtlcyB3aGVuIGl0IG5hbWVzIG5vbmUsXG4vLyB0aGUgYWxpYXMgb2YgdGhlIHByaW9yIGluIGl0cyBsYW5lLCB3aG9zZSB2YWx1ZSBpbiB0aGUgc2FtZSByb3cgdGVsbHMgYVxuLy8gbWlzc2luZyBiYXNlbGluZSBmcm9tIGEgemVybyBvbmUsIGFuZCB0aGUgZmlyc3QgZGF5IHdpdGggZGF0YS5cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdE91dHB1dENvbHVtbiB7XG4gIG91dHB1dDogT3V0cHV0TWV0YTtcbiAgbWVhc3VyZVNwZWM6IE51bWJlckZvcm1hdFNwZWMgfCBudWxsO1xuICBwcmlvckFsaWFzOiBzdHJpbmcgfCBudWxsO1xuICBmbG9vcjogc3RyaW5nIHwgbnVsbDtcbn1cblxuLy8gVGhlIG91dHB1dCBjb2x1bW5zIGFtb25nIGEgbGlzdCdzIGNvbHVtbnMsIGJ5IGNvbHVtbiBuYW1lLCBmcm9tIHRoZVxuLy8gbWV0YWRhdGEgaXRzIGRhdGEgY2Fycmllcy4gQSBjcm9zcy10YWIgY2VsbCBjb2x1bW4gdGFrZXMgaXRzIG1lYXN1cmUnc1xuLy8gbWVhbmluZyB0aHJvdWdoIGNlbGxNZWFzdXJlczsgaXRzIGNlbGxzIGFsbCBzaGFyZSB0aGUgZ3JpZCdzIGNlbGxGb3JtYXQgYW5kXG4vLyBoYXZlIG5vIHByaW9yIGJlc2lkZSB0aGVtLCBzaW5jZSBhIGNyb3NzLXRhYiBuZXZlciBjb21wYXJlcy4gQSBjb2x1bW4gd2l0aFxuLy8gbm8gb3V0cHV0IG1ldGFkYXRhIChhIHBsYWluIG1lYXN1cmUgb3IgZGltZW5zaW9uLCBhbiBvbGRlciBzZXJ2ZXIpIGlzIGxlZnRcbi8vIG91dCBhbmQgd3JpdHRlbiBhcyBiZWZvcmUuXG5leHBvcnQgZnVuY3Rpb24gbGlzdE91dHB1dENvbHVtbnMoXG4gIGNvbHVtbnM6IHJlYWRvbmx5IExpc3RDb2x1bW5bXSxcbiAgZGF0YTogUGljazxDb21wb25lbnREYXRhLCAnb3V0cHV0cycgfCAnY2VsbE1lYXN1cmVzJyB8ICdjb21wYXJpc29uJz4gfCBudWxsIHwgdW5kZWZpbmVkLFxuICBhdXRob3JlZDogcmVhZG9ubHkgTGlzdENvbHVtbltdLFxuKTogUmVjb3JkPHN0cmluZywgTGlzdE91dHB1dENvbHVtbj4ge1xuICBjb25zdCBvdXRwdXRzID0gZGF0YT8ub3V0cHV0cyA/PyB7fTtcbiAgY29uc3QgcmVzb2x2ZWQ6IFJlY29yZDxzdHJpbmcsIExpc3RPdXRwdXRDb2x1bW4+ID0ge307XG5cbiAgY29sdW1ucy5mb3JFYWNoKChjb2x1bW4pID0+IHtcbiAgICBjb25zdCBjZWxsTWVhc3VyZSA9IGRhdGE/LmNlbGxNZWFzdXJlcz8uW2NvbHVtbi5jb2x1bW5dO1xuICAgIGNvbnN0IGFsaWFzID0gY2VsbE1lYXN1cmUgPz8gY29sdW1uLmNvbHVtbjtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRzW2FsaWFzXTtcblxuICAgIGlmIChvdXRwdXQpIHtcbiAgICAgIHJlc29sdmVkW2NvbHVtbi5jb2x1bW5dID0ge1xuICAgICAgICBvdXRwdXQsXG4gICAgICAgIG1lYXN1cmVTcGVjOiBhdXRob3JlZC5maW5kKChzb3VyY2UpID0+IHNvdXJjZS5jb2x1bW4gPT09IG91dHB1dC5tZWFzdXJlKSA/PyBudWxsLFxuICAgICAgICBwcmlvckFsaWFzOiBjZWxsTWVhc3VyZSA/IG51bGwgOiBsaXN0UHJpb3JBbGlhcyhvdXRwdXRzLCBhbGlhcywgb3V0cHV0KSxcbiAgICAgICAgZmxvb3I6IGRhdGE/LmNvbXBhcmlzb24/LmZsb29yID8/IG51bGwsXG4gICAgICB9O1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHJlc29sdmVkO1xufVxuXG4vLyBBIGNoYW5nZSdzIG9yIGEgcGVyY2VudCBjaGFuZ2UncyBwcmlvciBpbiB0aGUgc2FtZSBsYW5lOyBudWxsIGZvciBhbnkgb3RoZXJcbi8vIG91dHB1dC5cbmZ1bmN0aW9uIGxpc3RQcmlvckFsaWFzKG91dHB1dHM6IFJlY29yZDxzdHJpbmcsIE91dHB1dE1ldGE+LCBhbGlhczogc3RyaW5nLCBvdXRwdXQ6IE91dHB1dE1ldGEpOiBzdHJpbmcgfCBudWxsIHtcbiAgcmV0dXJuIG91dHB1dC5yb2xlID09PSAnY2hhbmdlJyB8fCBvdXRwdXQucm9sZSA9PT0gJ3BlcmNlbnRfY2hhbmdlJ1xuICAgID8gbGFuZU91dHB1dEFsaWFzKG91dHB1dHMsIGFsaWFzLCAncHJpb3InKVxuICAgIDogbnVsbDtcbn1cbiJdfQ==