@rivet-health/design-system 40.9.0 → 40.9.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/esm2020/lib/table/table/clipboard.mjs +182 -0
- package/esm2020/lib/table/table/table/table.component.mjs +35 -2
- package/fesm2015/rivet-health-design-system.mjs +217 -2
- package/fesm2015/rivet-health-design-system.mjs.map +1 -1
- package/fesm2020/rivet-health-design-system.mjs +215 -2
- package/fesm2020/rivet-health-design-system.mjs.map +1 -1
- package/lib/table/table/clipboard.d.ts +38 -0
- package/lib/table/table/table/table.component.d.ts +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { sumBy } from 'lodash';
|
|
2
|
+
/**
|
|
3
|
+
* Clipboard serialization for `riv-table`.
|
|
4
|
+
*
|
|
5
|
+
* Rows that have a link render as `<a class="row-link">` rather than `<tr>`, and
|
|
6
|
+
* the browser's clipboard serializer does not treat those as table rows — the
|
|
7
|
+
* copied content pastes into a spreadsheet as one lateral run instead of a grid.
|
|
8
|
+
* These helpers rebuild the rendered grid so that copied content pastes as rows
|
|
9
|
+
* and columns.
|
|
10
|
+
*/
|
|
11
|
+
export var RivTableClipboard;
|
|
12
|
+
(function (RivTableClipboard) {
|
|
13
|
+
/** Cells that hold controls rather than data. */
|
|
14
|
+
const controlCellSelector = 'th.selection-head, th.menu-head, td.selection-body, td.menu-body';
|
|
15
|
+
/** The column name within a header cell; the rest of the cell is controls. */
|
|
16
|
+
const headerLabelSelector = '.header-wrapper';
|
|
17
|
+
/** Elements whose text exists for assistive technology only. */
|
|
18
|
+
const assistiveTextSelector = 'riv-sr-only';
|
|
19
|
+
/** Rows that stand in for data rather than carrying it. */
|
|
20
|
+
const fillerRowSelector = 'riv-zero-state';
|
|
21
|
+
/** Elements that own their own clipboard behavior. */
|
|
22
|
+
const editableSelector = 'input, textarea, select, [contenteditable=""], [contenteditable="true"]';
|
|
23
|
+
/** Whether the copy came from a control that serializes its own value. */
|
|
24
|
+
function isEditable(target) {
|
|
25
|
+
return (target instanceof Element && target.closest(editableSelector) !== null);
|
|
26
|
+
}
|
|
27
|
+
RivTableClipboard.isEditable = isEditable;
|
|
28
|
+
/**
|
|
29
|
+
* Whether `host` is the first element of its kind that the selection touches.
|
|
30
|
+
* A selection can span several tables; deferring to the first keeps instances
|
|
31
|
+
* from overwriting each other's clipboard data.
|
|
32
|
+
*/
|
|
33
|
+
function ownsSelection(host, isSelected) {
|
|
34
|
+
return (Array.from(document.querySelectorAll(host.localName)).find(element => isSelected(element)) === host);
|
|
35
|
+
}
|
|
36
|
+
RivTableClipboard.ownsSelection = ownsSelection;
|
|
37
|
+
/**
|
|
38
|
+
* Serializes the selected region of `tables` (one per row group), or null when
|
|
39
|
+
* the selection covers at most one cell — those are left to the browser so
|
|
40
|
+
* that copying part of a cell's text keeps working.
|
|
41
|
+
*
|
|
42
|
+
* `endpoints` are where the selection starts and ends, which narrow the copied
|
|
43
|
+
* columns to that span. A selection is a linear range in reading order, so
|
|
44
|
+
* dragging down one column touches every column in between; the endpoints are
|
|
45
|
+
* what distinguish "this column" from "these rows".
|
|
46
|
+
*/
|
|
47
|
+
function extract(tables, isSelected, endpoints = []) {
|
|
48
|
+
const layouts = tables.map(layout);
|
|
49
|
+
const columns = selectedColumns(layouts, isSelected, endpoints);
|
|
50
|
+
const headers = layouts.flatMap(l => l.header);
|
|
51
|
+
const rows = layouts
|
|
52
|
+
.flatMap(l => l.body)
|
|
53
|
+
.filter(row => selectedCount(row, isSelected) > 0);
|
|
54
|
+
// Header cells own the pointer for column reordering, so a drag cannot
|
|
55
|
+
// reach them; the header comes along with any copied data instead.
|
|
56
|
+
const header = headers.find(row => selectedCount(row, isSelected) > 0) ??
|
|
57
|
+
(rows.length > 0 ? headers[0] : undefined);
|
|
58
|
+
if (columns.length === 0 ||
|
|
59
|
+
sumBy([...(header ? [header] : []), ...rows], row => selectedCount(row, isSelected)) < 2)
|
|
60
|
+
return null;
|
|
61
|
+
return {
|
|
62
|
+
text: toText(header, rows, columns),
|
|
63
|
+
html: toHtml(header, rows, columns),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
RivTableClipboard.extract = extract;
|
|
67
|
+
function toText(header, rows, columns) {
|
|
68
|
+
return [
|
|
69
|
+
...(header ? [columns.map(column => headerText(header[column]))] : []),
|
|
70
|
+
...rows.map(row => columns.map(column => text(row[column]))),
|
|
71
|
+
]
|
|
72
|
+
.map(cells => cells.join('\t'))
|
|
73
|
+
.join('\n');
|
|
74
|
+
}
|
|
75
|
+
function toHtml(header, rows, columns) {
|
|
76
|
+
const cells = (values, tag) => values.map(value => `<${tag}>${escapeHtml(value)}</${tag}>`).join('');
|
|
77
|
+
return [
|
|
78
|
+
'<table>',
|
|
79
|
+
header
|
|
80
|
+
? `<thead><tr>${cells(columns.map(column => headerText(header[column])), 'th')}</tr></thead>`
|
|
81
|
+
: '',
|
|
82
|
+
`<tbody>${rows
|
|
83
|
+
.map(row => `<tr>${cells(columns.map(column => text(row[column])), 'td')}</tr>`)
|
|
84
|
+
.join('')}</tbody>`,
|
|
85
|
+
'</table>',
|
|
86
|
+
].join('');
|
|
87
|
+
}
|
|
88
|
+
function layout(table) {
|
|
89
|
+
return {
|
|
90
|
+
header: grid(Array.from(table.querySelectorAll(':scope > thead > tr')).filter(isDataRow)),
|
|
91
|
+
body: grid(Array.from(table.querySelectorAll(':scope > tbody > tr, :scope > tbody > a.row-link')).filter(isDataRow)),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Maps rows onto a column grid. Cells covered by a rowspan repeat the spanning
|
|
96
|
+
* cell so that every line has one value per column, matching how CSV export
|
|
97
|
+
* flattens spans.
|
|
98
|
+
*/
|
|
99
|
+
function grid(rows) {
|
|
100
|
+
const cells = rows.map(() => []);
|
|
101
|
+
rows.forEach((row, rowIndex) => {
|
|
102
|
+
let column = 0;
|
|
103
|
+
for (const cell of dataCells(row)) {
|
|
104
|
+
while (cells[rowIndex][column] !== undefined)
|
|
105
|
+
column++;
|
|
106
|
+
const rowSpan = Math.max(1, cell.rowSpan);
|
|
107
|
+
const colSpan = Math.max(1, cell.colSpan);
|
|
108
|
+
for (let r = rowIndex; r <= Math.min(rows.length - 1, rowIndex + rowSpan - 1); r++)
|
|
109
|
+
for (let c = column; c < column + colSpan; c++)
|
|
110
|
+
cells[r][c] = cell;
|
|
111
|
+
column += colSpan;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
return cells;
|
|
115
|
+
}
|
|
116
|
+
function dataCells(row) {
|
|
117
|
+
return Array.from(row.querySelectorAll(':scope > td, :scope > th')).filter(cell => !cell.matches(controlCellSelector));
|
|
118
|
+
}
|
|
119
|
+
/** Excludes the zero-state row, which spans every column. */
|
|
120
|
+
function isDataRow(row) {
|
|
121
|
+
return (row.querySelector(fillerRowSelector) === null &&
|
|
122
|
+
dataCells(row).every(cell => cell.colSpan <= 1));
|
|
123
|
+
}
|
|
124
|
+
function selectedColumns(layouts, isSelected, endpoints) {
|
|
125
|
+
const columns = new Set();
|
|
126
|
+
for (const { header, body } of layouts)
|
|
127
|
+
for (const row of [...header, ...body])
|
|
128
|
+
row.forEach((cell, column) => {
|
|
129
|
+
if (cell !== undefined && isSelected(cell))
|
|
130
|
+
columns.add(column);
|
|
131
|
+
});
|
|
132
|
+
const touched = [...columns].sort((a, b) => a - b);
|
|
133
|
+
// Both ends have to land in a cell to describe a span; anything else (a
|
|
134
|
+
// select-all, an endpoint on a row rather than a cell) keeps every column.
|
|
135
|
+
const span = endpoints
|
|
136
|
+
.map(node => (node ? columnOf(layouts, node) : undefined))
|
|
137
|
+
.filter((column) => column !== undefined);
|
|
138
|
+
return span.length === endpoints.length && span.length > 1
|
|
139
|
+
? touched.filter(column => column >= Math.min(...span) && column <= Math.max(...span))
|
|
140
|
+
: touched;
|
|
141
|
+
}
|
|
142
|
+
function columnOf(layouts, node) {
|
|
143
|
+
for (const { header, body } of layouts)
|
|
144
|
+
for (const row of [...header, ...body]) {
|
|
145
|
+
const column = row.findIndex(cell => cell?.contains(node) === true);
|
|
146
|
+
if (column >= 0)
|
|
147
|
+
return column;
|
|
148
|
+
}
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
function selectedCount(row, isSelected) {
|
|
152
|
+
return row.filter(cell => cell !== undefined && isSelected(cell)).length;
|
|
153
|
+
}
|
|
154
|
+
function headerText(cell) {
|
|
155
|
+
return text(cell?.querySelector(headerLabelSelector) ?? cell);
|
|
156
|
+
}
|
|
157
|
+
function text(cell) {
|
|
158
|
+
return cell ? visibleText(cell).replace(/\s+/g, ' ').trim() : '';
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Template indentation lands in the DOM as newlines and runs of spaces, which
|
|
162
|
+
* split a single row across several spreadsheet rows unless collapsed by the
|
|
163
|
+
* caller. Comment anchors and screen-reader-only content are dropped, and
|
|
164
|
+
* sibling nodes are separated so that adjacent elements do not run together.
|
|
165
|
+
*/
|
|
166
|
+
function visibleText(node) {
|
|
167
|
+
if (node instanceof Text)
|
|
168
|
+
return node.nodeValue ?? '';
|
|
169
|
+
if (node instanceof Element)
|
|
170
|
+
return node.matches(assistiveTextSelector)
|
|
171
|
+
? ''
|
|
172
|
+
: Array.from(node.childNodes).map(visibleText).join(' ');
|
|
173
|
+
return '';
|
|
174
|
+
}
|
|
175
|
+
function escapeHtml(value) {
|
|
176
|
+
return value
|
|
177
|
+
.replace(/&/g, '&')
|
|
178
|
+
.replace(/</g, '<')
|
|
179
|
+
.replace(/>/g, '>');
|
|
180
|
+
}
|
|
181
|
+
})(RivTableClipboard || (RivTableClipboard = {}));
|
|
182
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpcGJvYXJkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcml2L3NyYy9saWIvdGFibGUvdGFibGUvY2xpcGJvYXJkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFFL0I7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLEtBQVcsaUJBQWlCLENBMlFqQztBQTNRRCxXQUFpQixpQkFBaUI7SUFDaEMsaURBQWlEO0lBQ2pELE1BQU0sbUJBQW1CLEdBQ3ZCLGtFQUFrRSxDQUFDO0lBRXJFLDhFQUE4RTtJQUM5RSxNQUFNLG1CQUFtQixHQUFHLGlCQUFpQixDQUFDO0lBRTlDLGdFQUFnRTtJQUNoRSxNQUFNLHFCQUFxQixHQUFHLGFBQWEsQ0FBQztJQUU1QywyREFBMkQ7SUFDM0QsTUFBTSxpQkFBaUIsR0FBRyxnQkFBZ0IsQ0FBQztJQUUzQyxzREFBc0Q7SUFDdEQsTUFBTSxnQkFBZ0IsR0FDcEIseUVBQXlFLENBQUM7SUFvQjVFLDBFQUEwRTtJQUMxRSxTQUFnQixVQUFVLENBQUMsTUFBMEI7UUFDbkQsT0FBTyxDQUNMLE1BQU0sWUFBWSxPQUFPLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLElBQUksQ0FDdkUsQ0FBQztJQUNKLENBQUM7SUFKZSw0QkFBVSxhQUl6QixDQUFBO0lBRUQ7Ozs7T0FJRztJQUNILFNBQWdCLGFBQWEsQ0FDM0IsSUFBYSxFQUNiLFVBQXlCO1FBRXpCLE9BQU8sQ0FDTCxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FDbkUsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUNwQixLQUFLLElBQUksQ0FDWCxDQUFDO0lBQ0osQ0FBQztJQVRlLCtCQUFhLGdC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LENBQUMsSUFBZ0M7UUFDNUMsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDbkUsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsU0FBUyxXQUFXLENBQUMsSUFBVTtRQUM3QixJQUFJLElBQUksWUFBWSxJQUFJO1lBQUUsT0FBTyxJQUFJLENBQUMsU0FBUyxJQUFJLEVBQUUsQ0FBQztRQUN0RCxJQUFJLElBQUksWUFBWSxPQUFPO1lBQ3pCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQztnQkFDeEMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ0osQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDN0QsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsU0FBUyxVQUFVLENBQUMsS0FBYTtRQUMvQixPQUFPLEtBQUs7YUFDVCxPQUFPLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQzthQUN0QixPQUFPLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQzthQUNyQixPQUFPLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzNCLENBQUM7QUFDSCxDQUFDLEVBM1FnQixpQkFBaUIsS0FBakIsaUJBQWlCLFFBMlFqQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHN1bUJ5IH0gZnJvbSAnbG9kYXNoJztcblxuLyoqXG4gKiBDbGlwYm9hcmQgc2VyaWFsaXphdGlvbiBmb3IgYHJpdi10YWJsZWAuXG4gKlxuICogUm93cyB0aGF0IGhhdmUgYSBsaW5rIHJlbmRlciBhcyBgPGEgY2xhc3M9XCJyb3ctbGlua1wiPmAgcmF0aGVyIHRoYW4gYDx0cj5gLCBhbmRcbiAqIHRoZSBicm93c2VyJ3MgY2xpcGJvYXJkIHNlcmlhbGl6ZXIgZG9lcyBub3QgdHJlYXQgdGhvc2UgYXMgdGFibGUgcm93cyDigJQgdGhlXG4gKiBjb3BpZWQgY29udGVudCBwYXN0ZXMgaW50byBhIHNwcmVhZHNoZWV0IGFzIG9uZSBsYXRlcmFsIHJ1biBpbnN0ZWFkIG9mIGEgZ3JpZC5cbiAqIFRoZXNlIGhlbHBlcnMgcmVidWlsZCB0aGUgcmVuZGVyZWQgZ3JpZCBzbyB0aGF0IGNvcGllZCBjb250ZW50IHBhc3RlcyBhcyByb3dzXG4gKiBhbmQgY29sdW1ucy5cbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBSaXZUYWJsZUNsaXBib2FyZCB7XG4gIC8qKiBDZWxscyB0aGF0IGhvbGQgY29udHJvbHMgcmF0aGVyIHRoYW4gZGF0YS4gKi9cbiAgY29uc3QgY29udHJvbENlbGxTZWxlY3RvciA9XG4gICAgJ3RoLnNlbGVjdGlvbi1oZWFkLCB0aC5tZW51LWhlYWQsIHRkLnNlbGVjdGlvbi1ib2R5LCB0ZC5tZW51LWJvZHknO1xuXG4gIC8qKiBUaGUgY29sdW1uIG5hbWUgd2l0aGluIGEgaGVhZGVyIGNlbGw7IHRoZSByZXN0IG9mIHRoZSBjZWxsIGlzIGNvbnRyb2xzLiAqL1xuICBjb25zdCBoZWFkZXJMYWJlbFNlbGVjdG9yID0gJy5oZWFkZXItd3JhcHBlcic7XG5cbiAgLyoqIEVsZW1lbnRzIHdob3NlIHRleHQgZXhpc3RzIGZvciBhc3Npc3RpdmUgdGVjaG5vbG9neSBvbmx5LiAqL1xuICBjb25zdCBhc3Npc3RpdmVUZXh0U2VsZWN0b3IgPSAncml2LXNyLW9ubHknO1xuXG4gIC8qKiBSb3dzIHRoYXQgc3RhbmQgaW4gZm9yIGRhdGEgcmF0aGVyIHRoYW4gY2FycnlpbmcgaXQuICovXG4gIGNvbnN0IGZpbGxlclJvd1NlbGVjdG9yID0gJ3Jpdi16ZXJvLXN0YXRlJztcblxuICAvKiogRWxlbWVudHMgdGhhdCBvd24gdGhlaXIgb3duIGNsaXBib2FyZCBiZWhhdmlvci4gKi9cbiAgY29uc3QgZWRpdGFibGVTZWxlY3RvciA9XG4gICAgJ2lucHV0LCB0ZXh0YXJlYSwgc2VsZWN0LCBbY29udGVudGVkaXRhYmxlPVwiXCJdLCBbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXSc7XG5cbiAgZXhwb3J0IHR5cGUgUGF5bG9hZCA9IHtcbiAgICAvKiogVGFiLWRlbGltaXRlZCByb3dzLCBvbmUgbGluZSBwZXIgcm93LiAqL1xuICAgIHRleHQ6IHN0cmluZztcbiAgICAvKiogRXF1aXZhbGVudCB0YWJsZSBtYXJrdXAsIGZvciB0YXJnZXRzIHRoYXQgcHJlZmVyIHJpY2ggY29udGVudC4gKi9cbiAgICBodG1sOiBzdHJpbmc7XG4gIH07XG5cbiAgLyoqIFByZWRpY2F0ZSBmb3Igd2hldGhlciBhIG5vZGUgZmFsbHMgd2l0aGluIHRoZSB1c2VyJ3Mgc2VsZWN0aW9uLiAqL1xuICBleHBvcnQgdHlwZSBTZWxlY3Rpb25UZXN0ID0gKG5vZGU6IE5vZGUpID0+IGJvb2xlYW47XG5cbiAgLyoqIEEgcmVuZGVyZWQgcm93LCBob2xkaW5nIHRoZSBjZWxsIG9jY3VweWluZyBlYWNoIGRhdGEgY29sdW1uLiAqL1xuICB0eXBlIFJvdyA9IHJlYWRvbmx5IChFbGVtZW50IHwgdW5kZWZpbmVkKVtdO1xuXG4gIHR5cGUgTGF5b3V0ID0ge1xuICAgIGhlYWRlcjogcmVhZG9ubHkgUm93W107XG4gICAgYm9keTogcmVhZG9ubHkgUm93W107XG4gIH07XG5cbiAgLyoqIFdoZXRoZXIgdGhlIGNvcHkgY2FtZSBmcm9tIGEgY29udHJvbCB0aGF0IHNlcmlhbGl6ZXMgaXRzIG93biB2YWx1ZS4gKi9cbiAgZXhwb3J0IGZ1bmN0aW9uIGlzRWRpdGFibGUodGFyZ2V0OiBFdmVudFRhcmdldCB8IG51bGwpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGFyZ2V0IGluc3RhbmNlb2YgRWxlbWVudCAmJiB0YXJnZXQuY2xvc2VzdChlZGl0YWJsZVNlbGVjdG9yKSAhPT0gbnVsbFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogV2hldGhlciBgaG9zdGAgaXMgdGhlIGZpcnN0IGVsZW1lbnQgb2YgaXRzIGtpbmQgdGhhdCB0aGUgc2VsZWN0aW9uIHRvdWNoZXMuXG4gICAqIEEgc2VsZWN0aW9uIGNhbiBzcGFuIHNldmVyYWwgdGFibGVzOyBkZWZlcnJpbmcgdG8gdGhlIGZpcnN0IGtlZXBzIGluc3RhbmNlc1xuICAgKiBmcm9tIG92ZXJ3cml0aW5nIGVhY2ggb3RoZXIncyBjbGlwYm9hcmQgZGF0YS5cbiAgICovXG4gIGV4cG9ydCBmdW5jdGlvbiBvd25zU2VsZWN0aW9uKFxuICAgIGhvc3Q6IEVsZW1lbnQsXG4gICAgaXNTZWxlY3RlZDogU2VsZWN0aW9uVGVzdCxcbiAgKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChob3N0LmxvY2FsTmFtZSkpLmZpbmQoZWxlbWVudCA9PlxuICAgICAgICBpc1NlbGVjdGVkKGVsZW1lbnQpLFxuICAgICAgKSA9PT0gaG9zdFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogU2VyaWFsaXplcyB0aGUgc2VsZWN0ZWQgcmVnaW9uIG9mIGB0YWJsZXNgIChvbmUgcGVyIHJvdyBncm91cCksIG9yIG51bGwgd2hlblxuICAgKiB0aGUgc2VsZWN0aW9uIGNvdmVycyBhdCBtb3N0IG9uZSBjZWxsIOKAlCB0aG9zZSBhcmUgbGVmdCB0byB0aGUgYnJvd3NlciBzb1xuICAgKiB0aGF0IGNvcHlpbmcgcGFydCBvZiBhIGNlbGwncyB0ZXh0IGtlZXBzIHdvcmtpbmcuXG4gICAqXG4gICAqIGBlbmRwb2ludHNgIGFyZSB3aGVyZSB0aGUgc2VsZWN0aW9uIHN0YXJ0cyBhbmQgZW5kcywgd2hpY2ggbmFycm93IHRoZSBjb3BpZWRcbiAgICogY29sdW1ucyB0byB0aGF0IHNwYW4uIEEgc2VsZWN0aW9uIGlzIGEgbGluZWFyIHJhbmdlIGluIHJlYWRpbmcgb3JkZXIsIHNvXG4gICAqIGRyYWdnaW5nIGRvd24gb25lIGNvbHVtbiB0b3VjaGVzIGV2ZXJ5IGNvbHVtbiBpbiBiZXR3ZWVuOyB0aGUgZW5kcG9pbnRzIGFyZVxuICAgKiB3aGF0IGRpc3Rpbmd1aXNoIFwidGhpcyBjb2x1bW5cIiBmcm9tIFwidGhlc2Ugcm93c1wiLlxuICAgKi9cbiAgZXhwb3J0IGZ1bmN0aW9uIGV4dHJhY3QoXG4gICAgdGFibGVzOiByZWFkb25seSBIVE1MVGFibGVFbGVtZW50W10sXG4gICAgaXNTZWxlY3RlZDogU2VsZWN0aW9uVGVzdCxcbiAgICBlbmRwb2ludHM6IHJlYWRvbmx5IChOb2RlIHwgbnVsbCB8IHVuZGVmaW5lZClbXSA9IFtdLFxuICApOiBQYXlsb2FkIHwgbnVsbCB7XG4gICAgY29uc3QgbGF5b3V0cyA9IHRhYmxlcy5tYXAobGF5b3V0KTtcbiAgICBjb25zdCBjb2x1bW5zID0gc2VsZWN0ZWRDb2x1bW5zKGxheW91dHMsIGlzU2VsZWN0ZWQsIGVuZHBvaW50cyk7XG4gICAgY29uc3QgaGVhZGVycyA9IGxheW91dHMuZmxhdE1hcChsID0+IGwuaGVhZGVyKTtcbiAgICBjb25zdCByb3dzID0gbGF5b3V0c1xuICAgICAgLmZsYXRNYXAobCA9PiBsLmJvZHkpXG4gICAgICAuZmlsdGVyKHJvdyA9PiBzZWxlY3RlZENvdW50KHJvdywgaXNTZWxlY3RlZCkgPiAwKTtcbiAgICAvLyBIZWFkZXIgY2VsbHMgb3duIHRoZSBwb2ludGVyIGZvciBjb2x1bW4gcmVvcmRlcmluZywgc28gYSBkcmFnIGNhbm5vdFxuICAgIC8vIHJlYWNoIHRoZW07IHRoZSBoZWFkZXIgY29tZXMgYWxvbmcgd2l0aCBhbnkgY29waWVkIGRhdGEgaW5zdGVhZC5cbiAgICBjb25zdCBoZWFkZXIgPVxuICAgICAgaGVhZGVycy5maW5kKHJvdyA9PiBzZWxlY3RlZENvdW50KHJvdywgaXNTZWxlY3RlZCkgPiAwKSA/P1xuICAgICAgKHJvd3MubGVuZ3RoID4gMCA/IGhlYWRlcnNbMF0gOiB1bmRlZmluZWQpO1xuXG4gICAgaWYgKFxuICAgICAgY29sdW1ucy5sZW5ndGggPT09IDAgfHxcbiAgICAgIHN1bUJ5KFsuLi4oaGVhZGVyID8gW2hlYWRlcl0gOiBbXSksIC4uLnJvd3NdLCByb3cgPT5cbiAgICAgICAgc2VsZWN0ZWRDb3VudChyb3csIGlzU2VsZWN0ZWQpLFxuICAgICAgKSA8IDJcbiAgICApXG4gICAgICByZXR1cm4gbnVsbDtcblxuICAgIHJldHVybiB7XG4gICAgICB0ZXh0OiB0b1RleHQoaGVhZGVyLCByb3dzLCBjb2x1bW5zKSxcbiAgICAgIGh0bWw6IHRvSHRtbChoZWFkZXIsIHJvd3MsIGNvbHVtbnMpLFxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiB0b1RleHQoXG4gICAgaGVhZGVyOiBSb3cgfCB1bmRlZmluZWQsXG4gICAgcm93czogcmVhZG9ubHkgUm93W10sXG4gICAgY29sdW1uczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IHN0cmluZyB7XG4gICAgcmV0dXJuIFtcbiAgICAgIC4uLihoZWFkZXIgPyBbY29sdW1ucy5tYXAoY29sdW1uID0+IGhlYWRlclRleHQoaGVhZGVyW2NvbHVtbl0pKV0gOiBbXSksXG4gICAgICAuLi5yb3dzLm1hcChyb3cgPT4gY29sdW1ucy5tYXAoY29sdW1uID0+IHRleHQocm93W2NvbHVtbl0pKSksXG4gICAgXVxuICAgICAgLm1hcChjZWxscyA9PiBjZWxscy5qb2luKCdcXHQnKSlcbiAgICAgIC5qb2luKCdcXG4nKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvSHRtbChcbiAgICBoZWFkZXI6IFJvdyB8IHVuZGVmaW5lZCxcbiAgICByb3dzOiByZWFkb25seSBSb3dbXSxcbiAgICBjb2x1bW5zOiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogc3RyaW5nIHtcbiAgICBjb25zdCBjZWxscyA9ICh2YWx1ZXM6IHJlYWRvbmx5IHN0cmluZ1tdLCB0YWc6ICd0aCcgfCAndGQnKSA9PlxuICAgICAgdmFsdWVzLm1hcCh2YWx1ZSA9PiBgPCR7dGFnfT4ke2VzY2FwZUh0bWwodmFsdWUpfTwvJHt0YWd9PmApLmpvaW4oJycpO1xuICAgIHJldHVybiBbXG4gICAgICAnPHRhYmxlPicsXG4gICAgICBoZWFkZXJcbiAgICAgICAgPyBgPHRoZWFkPjx0cj4ke2NlbGxzKFxuICAgICAgICAgICAgY29sdW1ucy5tYXAoY29sdW1uID0+IGhlYWRlclRleHQoaGVhZGVyW2NvbHVtbl0pKSxcbiAgICAgICAgICAgICd0aCcsXG4gICAgICAgICAgKX08L3RyPjwvdGhlYWQ+YFxuICAgICAgICA6ICcnLFxuICAgICAgYDx0Ym9keT4ke3Jvd3NcbiAgICAgICAgLm1hcChcbiAgICAgICAgICByb3cgPT5cbiAgICAgICAgICAgIGA8dHI+JHtjZWxscyhcbiAgICAgICAgICAgICAgY29sdW1ucy5tYXAoY29sdW1uID0+IHRleHQocm93W2NvbHVtbl0pKSxcbiAgICAgICAgICAgICAgJ3RkJyxcbiAgICAgICAgICAgICl9PC90cj5gLFxuICAgICAgICApXG4gICAgICAgIC5qb2luKCcnKX08L3Rib2R5PmAsXG4gICAgICAnPC90YWJsZT4nLFxuICAgIF0uam9pbignJyk7XG4gIH1cblxuICBmdW5jdGlvbiBsYXlvdXQodGFibGU6IEhUTUxUYWJsZUVsZW1lbnQpOiBMYXlvdXQge1xuICAgIHJldHVybiB7XG4gICAgICBoZWFkZXI6IGdyaWQoXG4gICAgICAgIEFycmF5LmZyb20odGFibGUucXVlcnlTZWxlY3RvckFsbCgnOnNjb3BlID4gdGhlYWQgPiB0cicpKS5maWx0ZXIoXG4gICAgICAgICAgaXNEYXRhUm93LFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICAgIGJvZHk6IGdyaWQoXG4gICAgICAgIEFycmF5LmZyb20oXG4gICAgICAgICAgdGFibGUucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgICAgICc6c2NvcGUgPiB0Ym9keSA+IHRyLCA6c2NvcGUgPiB0Ym9keSA+IGEucm93LWxpbmsnLFxuICAgICAgICAgICksXG4gICAgICAgICkuZmlsdGVyKGlzRGF0YVJvdyksXG4gICAgICApLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogTWFwcyByb3dzIG9udG8gYSBjb2x1bW4gZ3JpZC4gQ2VsbHMgY292ZXJlZCBieSBhIHJvd3NwYW4gcmVwZWF0IHRoZSBzcGFubmluZ1xuICAgKiBjZWxsIHNvIHRoYXQgZXZlcnkgbGluZSBoYXMgb25lIHZhbHVlIHBlciBjb2x1bW4sIG1hdGNoaW5nIGhvdyBDU1YgZXhwb3J0XG4gICAqIGZsYXR0ZW5zIHNwYW5zLlxuICAgKi9cbiAgZnVuY3Rpb24gZ3JpZChyb3dzOiByZWFkb25seSBFbGVtZW50W10pOiBSb3dbXSB7XG4gICAgY29uc3QgY2VsbHM6IChFbGVtZW50IHwgdW5kZWZpbmVkKVtdW10gPSByb3dzLm1hcCgoKSA9PiBbXSk7XG4gICAgcm93cy5mb3JFYWNoKChyb3csIHJvd0luZGV4KSA9PiB7XG4gICAgICBsZXQgY29sdW1uID0gMDtcbiAgICAgIGZvciAoY29uc3QgY2VsbCBvZiBkYXRhQ2VsbHMocm93KSkge1xuICAgICAgICB3aGlsZSAoY2VsbHNbcm93SW5kZXhdW2NvbHVtbl0gIT09IHVuZGVmaW5lZCkgY29sdW1uKys7XG4gICAgICAgIGNvbnN0IHJvd1NwYW4gPSBNYXRoLm1heCgxLCBjZWxsLnJvd1NwYW4pO1xuICAgICAgICBjb25zdCBjb2xTcGFuID0gTWF0aC5tYXgoMSwgY2VsbC5jb2xTcGFuKTtcbiAgICAgICAgZm9yIChcbiAgICAgICAgICBsZXQgciA9IHJvd0luZGV4O1xuICAgICAgICAgIHIgPD0gTWF0aC5taW4ocm93cy5sZW5ndGggLSAxLCByb3dJbmRleCArIHJvd1NwYW4gLSAxKTtcbiAgICAgICAgICByKytcbiAgICAgICAgKVxuICAgICAgICAgIGZvciAobGV0IGMgPSBjb2x1bW47IGMgPCBjb2x1bW4gKyBjb2xTcGFuOyBjKyspIGNlbGxzW3JdW2NdID0gY2VsbDtcbiAgICAgICAgY29sdW1uICs9IGNvbFNwYW47XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGNlbGxzO1xuICB9XG5cbiAgZnVuY3Rpb24gZGF0YUNlbGxzKHJvdzogRWxlbWVudCk6IEhUTUxUYWJsZUNlbGxFbGVtZW50W10ge1xuICAgIHJldHVybiBBcnJheS5mcm9tKFxuICAgICAgcm93LnF1ZXJ5U2VsZWN0b3JBbGw8SFRNTFRhYmxlQ2VsbEVsZW1lbnQ+KCc6c2NvcGUgPiB0ZCwgOnNjb3BlID4gdGgnKSxcbiAgICApLmZpbHRlcihjZWxsID0+ICFjZWxsLm1hdGNoZXMoY29udHJvbENlbGxTZWxlY3RvcikpO1xuICB9XG5cbiAgLyoqIEV4Y2x1ZGVzIHRoZSB6ZXJvLXN0YXRlIHJvdywgd2hpY2ggc3BhbnMgZXZlcnkgY29sdW1uLiAqL1xuICBmdW5jdGlvbiBpc0RhdGFSb3cocm93OiBFbGVtZW50KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHJvdy5xdWVyeVNlbGVjdG9yKGZpbGxlclJvd1NlbGVjdG9yKSA9PT0gbnVsbCAmJlxuICAgICAgZGF0YUNlbGxzKHJvdykuZXZlcnkoY2VsbCA9PiBjZWxsLmNvbFNwYW4gPD0gMSlcbiAgICApO1xuICB9XG5cbiAgZnVuY3Rpb24gc2VsZWN0ZWRDb2x1bW5zKFxuICAgIGxheW91dHM6IHJlYWRvbmx5IExheW91dFtdLFxuICAgIGlzU2VsZWN0ZWQ6IFNlbGVjdGlvblRlc3QsXG4gICAgZW5kcG9pbnRzOiByZWFkb25seSAoTm9kZSB8IG51bGwgfCB1bmRlZmluZWQpW10sXG4gICk6IG51bWJlcltdIHtcbiAgICBjb25zdCBjb2x1bW5zID0gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgZm9yIChjb25zdCB7IGhlYWRlciwgYm9keSB9IG9mIGxheW91dHMpXG4gICAgICBmb3IgKGNvbnN0IHJvdyBvZiBbLi4uaGVhZGVyLCAuLi5ib2R5XSlcbiAgICAgICAgcm93LmZvckVhY2goKGNlbGwsIGNvbHVtbikgPT4ge1xuICAgICAgICAgIGlmIChjZWxsICE9PSB1bmRlZmluZWQgJiYgaXNTZWxlY3RlZChjZWxsKSkgY29sdW1ucy5hZGQoY29sdW1uKTtcbiAgICAgICAgfSk7XG4gICAgY29uc3QgdG91Y2hlZCA9IFsuLi5jb2x1bW5zXS5zb3J0KChhLCBiKSA9PiBhIC0gYik7XG5cbiAgICAvLyBCb3RoIGVuZHMgaGF2ZSB0byBsYW5kIGluIGEgY2VsbCB0byBkZXNjcmliZSBhIHNwYW47IGFueXRoaW5nIGVsc2UgKGFcbiAgICAvLyBzZWxlY3QtYWxsLCBhbiBlbmRwb2ludCBvbiBhIHJvdyByYXRoZXIgdGhhbiBhIGNlbGwpIGtlZXBzIGV2ZXJ5IGNvbHVtbi5cbiAgICBjb25zdCBzcGFuID0gZW5kcG9pbnRzXG4gICAgICAubWFwKG5vZGUgPT4gKG5vZGUgPyBjb2x1bW5PZihsYXlvdXRzLCBub2RlKSA6IHVuZGVmaW5lZCkpXG4gICAgICAuZmlsdGVyKChjb2x1bW4pOiBjb2x1bW4gaXMgbnVtYmVyID0+IGNvbHVtbiAhPT0gdW5kZWZpbmVkKTtcbiAgICByZXR1cm4gc3Bhbi5sZW5ndGggPT09IGVuZHBvaW50cy5sZW5ndGggJiYgc3Bhbi5sZW5ndGggPiAxXG4gICAgICA/IHRvdWNoZWQuZmlsdGVyKFxuICAgICAgICAgIGNvbHVtbiA9PiBjb2x1bW4gPj0gTWF0aC5taW4oLi4uc3BhbikgJiYgY29sdW1uIDw9IE1hdGgubWF4KC4uLnNwYW4pLFxuICAgICAgICApXG4gICAgICA6IHRvdWNoZWQ7XG4gIH1cblxuICBmdW5jdGlvbiBjb2x1bW5PZihcbiAgICBsYXlvdXRzOiByZWFkb25seSBMYXlvdXRbXSxcbiAgICBub2RlOiBOb2RlLFxuICApOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgIGZvciAoY29uc3QgeyBoZWFkZXIsIGJvZHkgfSBvZiBsYXlvdXRzKVxuICAgICAgZm9yIChjb25zdCByb3cgb2YgWy4uLmhlYWRlciwgLi4uYm9keV0pIHtcbiAgICAgICAgY29uc3QgY29sdW1uID0gcm93LmZpbmRJbmRleChjZWxsID0+IGNlbGw/LmNvbnRhaW5zKG5vZGUpID09PSB0cnVlKTtcbiAgICAgICAgaWYgKGNvbHVtbiA+PSAwKSByZXR1cm4gY29sdW1uO1xuICAgICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBmdW5jdGlvbiBzZWxlY3RlZENvdW50KHJvdzogUm93LCBpc1NlbGVjdGVkOiBTZWxlY3Rpb25UZXN0KTogbnVtYmVyIHtcbiAgICByZXR1cm4gcm93LmZpbHRlcihjZWxsID0+IGNlbGwgIT09IHVuZGVmaW5lZCAmJiBpc1NlbGVjdGVkKGNlbGwpKS5sZW5ndGg7XG4gIH1cblxuICBmdW5jdGlvbiBoZWFkZXJUZXh0KGNlbGw6IEVsZW1lbnQgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICAgIHJldHVybiB0ZXh0KGNlbGw/LnF1ZXJ5U2VsZWN0b3IoaGVhZGVyTGFiZWxTZWxlY3RvcikgPz8gY2VsbCk7XG4gIH1cblxuICBmdW5jdGlvbiB0ZXh0KGNlbGw6IEVsZW1lbnQgfCB1bmRlZmluZWQgfCBudWxsKTogc3RyaW5nIHtcbiAgICByZXR1cm4gY2VsbCA/IHZpc2libGVUZXh0KGNlbGwpLnJlcGxhY2UoL1xccysvZywgJyAnKS50cmltKCkgOiAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUZW1wbGF0ZSBpbmRlbnRhdGlvbiBsYW5kcyBpbiB0aGUgRE9NIGFzIG5ld2xpbmVzIGFuZCBydW5zIG9mIHNwYWNlcywgd2hpY2hcbiAgICogc3BsaXQgYSBzaW5nbGUgcm93IGFjcm9zcyBzZXZlcmFsIHNwcmVhZHNoZWV0IHJvd3MgdW5sZXNzIGNvbGxhcHNlZCBieSB0aGVcbiAgICogY2FsbGVyLiBDb21tZW50IGFuY2hvcnMgYW5kIHNjcmVlbi1yZWFkZXItb25seSBjb250ZW50IGFyZSBkcm9wcGVkLCBhbmRcbiAgICogc2libGluZyBub2RlcyBhcmUgc2VwYXJhdGVkIHNvIHRoYXQgYWRqYWNlbnQgZWxlbWVudHMgZG8gbm90IHJ1biB0b2dldGhlci5cbiAgICovXG4gIGZ1bmN0aW9uIHZpc2libGVUZXh0KG5vZGU6IE5vZGUpOiBzdHJpbmcge1xuICAgIGlmIChub2RlIGluc3RhbmNlb2YgVGV4dCkgcmV0dXJuIG5vZGUubm9kZVZhbHVlID8/ICcnO1xuICAgIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudClcbiAgICAgIHJldHVybiBub2RlLm1hdGNoZXMoYXNzaXN0aXZlVGV4dFNlbGVjdG9yKVxuICAgICAgICA/ICcnXG4gICAgICAgIDogQXJyYXkuZnJvbShub2RlLmNoaWxkTm9kZXMpLm1hcCh2aXNpYmxlVGV4dCkuam9pbignICcpO1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGZ1bmN0aW9uIGVzY2FwZUh0bWwodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHZhbHVlXG4gICAgICAucmVwbGFjZSgvJi9nLCAnJmFtcDsnKVxuICAgICAgLnJlcGxhY2UoLzwvZywgJyZsdDsnKVxuICAgICAgLnJlcGxhY2UoLz4vZywgJyZndDsnKTtcbiAgfVxufVxuIl19
|