@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.
@@ -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, '&amp;')
178
+ .replace(/</g, '&lt;')
179
+ .replace(/>/g, '&gt;');
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