@plumile/ui 0.1.156 → 0.1.158
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/lib/esm/admin/organisms/admin_sidebar/adminSidebar.css.js +0 -1
- package/lib/esm/atomic/atoms/error_message/errorMessage.css.js +1 -0
- package/lib/esm/atomic/molecules/markdown/components/MarkdownArticleContainer.css.js +0 -1
- package/lib/esm/atomic/molecules/markdown/components/MarkdownDelete.css.js +1 -0
- package/lib/esm/components/data-table/VirtualizedConnectionTable.js +103 -99
- package/lib/esm/components/data-table/VirtualizedConnectionTable.js.map +1 -1
- package/lib/esm/node_modules/dompurify/dist/purify.es.js +200 -189
- package/lib/esm/node_modules/dompurify/dist/purify.es.js.map +1 -1
- package/lib/types/components/data-table/VirtualizedConnectionTable.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -5,7 +5,7 @@ import { clamp as ee, computeVirtualWindowBounds as te, isVerticallyScrollable a
|
|
|
5
5
|
import { useCallback as d, useEffect as f, useLayoutEffect as p, useMemo as m, useRef as h, useState as re } from "react";
|
|
6
6
|
import { Fragment as ie, jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
7
7
|
//#region src/components/data-table/VirtualizedConnectionTable.tsx
|
|
8
|
-
var
|
|
8
|
+
var ae = (e) => {
|
|
9
9
|
let t = e;
|
|
10
10
|
for (; t != null;) {
|
|
11
11
|
if (u({
|
|
@@ -16,73 +16,77 @@ var v = (e) => {
|
|
|
16
16
|
t = t.parentElement;
|
|
17
17
|
}
|
|
18
18
|
return null;
|
|
19
|
-
},
|
|
20
|
-
let P = h(null), F = h(null), I = h(null), L = h(null), R = h(null), z = h(null), B = h(!1), V =
|
|
19
|
+
}, v = ({ columns: u, rows: v, getRowId: y, emptyState: oe, className: se, headerClassName: ce, bodyClassName: le, rowClassName: b, gridTemplateClassName: x, gridTemplateColumns: S, kind: C, density: w, headerBehavior: ue, rowState: T, classes: E, bodyScrollMode: D = "page", bodyFooterNode: de, virtualization: O, infiniteScroll: k, hasNextPage: A = !1, isLoadingMore: j = !1, onLoadMore: M, ariaLabel: fe, ariaLabelledBy: pe }) => {
|
|
20
|
+
let N = h(null), P = h(null), F = h(null), I = h(null), L = h(null), R = h(null), z = h(null), B = h(!1), V = O?.enabled === !0, H = m(() => {
|
|
21
21
|
if (!V) return null;
|
|
22
|
-
let e =
|
|
22
|
+
let e = O.rowHeightPx;
|
|
23
23
|
return typeof e == "number" && Number.isFinite(e) && e > 0 ? e : 56;
|
|
24
|
-
}, [V,
|
|
24
|
+
}, [V, O]), U = m(() => {
|
|
25
25
|
if (!V) return 0;
|
|
26
|
-
let e = 10, t =
|
|
26
|
+
let e = 10, t = O.overscan;
|
|
27
27
|
return typeof t == "number" && Number.isFinite(t) && (e = t), Math.max(0, e);
|
|
28
|
-
}, [V,
|
|
29
|
-
|
|
30
|
-
}, [
|
|
28
|
+
}, [V, O]), W = k?.thresholdPx ?? 800, G = k?.autoLoad ?? !0, K = k?.enabled === !0, q = D === "contained", J = K && A && !j && M != null, Y = d(() => {
|
|
29
|
+
M?.();
|
|
30
|
+
}, [M]), X = d(() => {
|
|
31
|
+
B.current = !0, z.current != null && window.clearTimeout(z.current), z.current = window.setTimeout(() => {
|
|
32
|
+
B.current = !1, z.current = null;
|
|
33
|
+
}, 250);
|
|
34
|
+
}, []), [me, he] = re(() => ({
|
|
31
35
|
startIndex: 0,
|
|
32
|
-
endIndex: Math.min(
|
|
33
|
-
})),
|
|
36
|
+
endIndex: Math.min(v.length, 50)
|
|
37
|
+
})), ge = d((e, t, n) => {
|
|
34
38
|
let r = {};
|
|
35
39
|
return typeof n == "number" && (r.height = n), /* @__PURE__ */ g(i, {
|
|
36
40
|
row: e,
|
|
37
41
|
index: t,
|
|
38
42
|
columns: u,
|
|
39
|
-
getRowId:
|
|
40
|
-
kind:
|
|
41
|
-
density:
|
|
42
|
-
rowClassName:
|
|
43
|
-
rowState:
|
|
44
|
-
gridTemplateClassName:
|
|
45
|
-
gridTemplateColumns:
|
|
46
|
-
classes:
|
|
43
|
+
getRowId: y,
|
|
44
|
+
kind: C,
|
|
45
|
+
density: w,
|
|
46
|
+
rowClassName: b,
|
|
47
|
+
rowState: T,
|
|
48
|
+
gridTemplateClassName: x,
|
|
49
|
+
gridTemplateColumns: S,
|
|
50
|
+
classes: E,
|
|
47
51
|
style: r,
|
|
48
52
|
cellMode: "singleLine"
|
|
49
|
-
},
|
|
53
|
+
}, y(e, t));
|
|
50
54
|
}, [
|
|
51
|
-
|
|
55
|
+
E,
|
|
52
56
|
u,
|
|
53
|
-
T,
|
|
54
|
-
b,
|
|
55
|
-
S,
|
|
56
|
-
C,
|
|
57
57
|
w,
|
|
58
|
+
y,
|
|
58
59
|
x,
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
S,
|
|
61
|
+
C,
|
|
62
|
+
b,
|
|
63
|
+
T
|
|
64
|
+
]), _e = d(() => {
|
|
61
65
|
if (!V) return;
|
|
62
66
|
let e = H;
|
|
63
67
|
if (e == null) return;
|
|
64
|
-
let t =
|
|
68
|
+
let t = F.current;
|
|
65
69
|
if (t == null) return;
|
|
66
|
-
let n =
|
|
70
|
+
let n = P.current, r = L.current, i = r?.clientHeight ?? window.innerHeight, a = 0;
|
|
67
71
|
if (q && n != null) i = n.clientHeight, a = n.scrollTop;
|
|
68
72
|
else {
|
|
69
73
|
let e = r?.getBoundingClientRect().top ?? 0, n = t.getBoundingClientRect().top - e;
|
|
70
74
|
a = Math.max(0, -n);
|
|
71
75
|
}
|
|
72
|
-
let s = a + i, c =
|
|
73
|
-
rowCount:
|
|
76
|
+
let s = a + i, c = v.length * e, l = ee(s, 0, c), { startIndex: u, endIndex: d } = te({
|
|
77
|
+
rowCount: v.length,
|
|
74
78
|
rowHeightPx: e,
|
|
75
79
|
overscan: U,
|
|
76
80
|
visibleTop: a,
|
|
77
81
|
visibleBottom: s
|
|
78
82
|
});
|
|
79
|
-
|
|
83
|
+
he((e) => e.startIndex === u && e.endIndex === d ? e : {
|
|
80
84
|
startIndex: u,
|
|
81
85
|
endIndex: d
|
|
82
86
|
}), o({
|
|
83
87
|
enabled: K,
|
|
84
|
-
hasNext:
|
|
85
|
-
isLoading:
|
|
88
|
+
hasNext: A,
|
|
89
|
+
isLoading: j,
|
|
86
90
|
autoLoad: G,
|
|
87
91
|
isCoolingDown: B.current
|
|
88
92
|
}) && J && ne({
|
|
@@ -92,64 +96,63 @@ var v = (e) => {
|
|
|
92
96
|
visibleBottom: l,
|
|
93
97
|
thresholdPx: W,
|
|
94
98
|
isCoolingDown: B.current
|
|
95
|
-
}) && (
|
|
96
|
-
B.current = !1;
|
|
97
|
-
}, 250));
|
|
99
|
+
}) && (X(), Y());
|
|
98
100
|
}, [
|
|
99
101
|
G,
|
|
100
102
|
J,
|
|
101
|
-
|
|
103
|
+
A,
|
|
102
104
|
q,
|
|
103
105
|
V,
|
|
104
106
|
K,
|
|
105
|
-
|
|
107
|
+
j,
|
|
106
108
|
U,
|
|
107
109
|
H,
|
|
108
|
-
|
|
110
|
+
v.length,
|
|
111
|
+
X,
|
|
109
112
|
W,
|
|
110
113
|
Y
|
|
111
|
-
]),
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
]), Z = d(() => {
|
|
115
|
+
R.current ??= window.requestAnimationFrame(() => {
|
|
116
|
+
R.current = null, _e();
|
|
114
117
|
});
|
|
115
|
-
}, [
|
|
116
|
-
|
|
118
|
+
}, [_e]);
|
|
119
|
+
f(() => () => {
|
|
120
|
+
R.current != null && (window.cancelAnimationFrame(R.current), R.current = null), z.current != null && (window.clearTimeout(z.current), z.current = null);
|
|
121
|
+
}, []), p(() => {
|
|
117
122
|
if (!V) return;
|
|
118
|
-
let e =
|
|
119
|
-
e != null && (q ?
|
|
123
|
+
let e = N.current;
|
|
124
|
+
e != null && (q ? L.current = P.current : L.current = ae(e), Z());
|
|
120
125
|
}, [
|
|
121
126
|
q,
|
|
122
127
|
V,
|
|
123
|
-
|
|
128
|
+
Z
|
|
124
129
|
]), f(() => {
|
|
125
130
|
if (!V) return;
|
|
126
|
-
let e =
|
|
127
|
-
|
|
131
|
+
let e = L.current ?? window, t = () => {
|
|
132
|
+
Z();
|
|
128
133
|
};
|
|
129
134
|
return e.addEventListener("scroll", t, { passive: !0 }), window.addEventListener("resize", t), () => {
|
|
130
135
|
e.removeEventListener("scroll", t), window.removeEventListener("resize", t);
|
|
131
136
|
};
|
|
132
|
-
}, [V,
|
|
137
|
+
}, [V, Z]), f(() => {
|
|
133
138
|
if (V || !o({
|
|
134
139
|
enabled: K,
|
|
135
|
-
hasNext:
|
|
136
|
-
isLoading:
|
|
140
|
+
hasNext: A,
|
|
141
|
+
isLoading: j,
|
|
137
142
|
autoLoad: G,
|
|
138
143
|
isCoolingDown: !1
|
|
139
144
|
}) || !J) return;
|
|
140
|
-
let e =
|
|
145
|
+
let e = I.current;
|
|
141
146
|
if (e == null || typeof window > "u" || typeof IntersectionObserver > "u") return;
|
|
142
|
-
let t =
|
|
147
|
+
let t = L.current, n = new IntersectionObserver((e) => {
|
|
143
148
|
let [t] = e;
|
|
144
149
|
t != null && t.isIntersecting && o({
|
|
145
150
|
enabled: K,
|
|
146
|
-
hasNext:
|
|
147
|
-
isLoading:
|
|
151
|
+
hasNext: A,
|
|
152
|
+
isLoading: j,
|
|
148
153
|
autoLoad: G,
|
|
149
154
|
isCoolingDown: B.current
|
|
150
|
-
}) && (
|
|
151
|
-
B.current = !1;
|
|
152
|
-
}, 250));
|
|
155
|
+
}) && (X(), Y());
|
|
153
156
|
}, {
|
|
154
157
|
root: t,
|
|
155
158
|
rootMargin: a({ thresholdPx: W })
|
|
@@ -160,77 +163,78 @@ var v = (e) => {
|
|
|
160
163
|
}, [
|
|
161
164
|
G,
|
|
162
165
|
J,
|
|
163
|
-
|
|
166
|
+
A,
|
|
164
167
|
K,
|
|
165
168
|
V,
|
|
166
|
-
|
|
169
|
+
j,
|
|
170
|
+
X,
|
|
167
171
|
W,
|
|
168
172
|
Y
|
|
169
173
|
]), p(() => {
|
|
170
174
|
if (V) return;
|
|
171
|
-
let e =
|
|
172
|
-
e != null && (q ?
|
|
175
|
+
let e = N.current;
|
|
176
|
+
e != null && (q ? L.current = P.current : L.current = ae(e));
|
|
173
177
|
}, [q, V]);
|
|
174
|
-
let
|
|
175
|
-
if (
|
|
176
|
-
emptyState:
|
|
177
|
-
density:
|
|
178
|
-
classes:
|
|
178
|
+
let Q;
|
|
179
|
+
if (v.length === 0) Q = /* @__PURE__ */ g(t, {
|
|
180
|
+
emptyState: oe,
|
|
181
|
+
density: w,
|
|
182
|
+
classes: E
|
|
179
183
|
});
|
|
180
184
|
else if (V && H != null) {
|
|
181
|
-
let { startIndex: e, endIndex: t } =
|
|
182
|
-
|
|
185
|
+
let { startIndex: e, endIndex: t } = me, n = e * H, r = (v.length - t) * H, i = v.slice(e, t);
|
|
186
|
+
Q = /* @__PURE__ */ _("div", {
|
|
183
187
|
className: s,
|
|
184
|
-
ref:
|
|
188
|
+
ref: F,
|
|
185
189
|
children: [
|
|
186
190
|
/* @__PURE__ */ g("div", {
|
|
187
191
|
className: l,
|
|
188
192
|
style: { height: n }
|
|
189
193
|
}),
|
|
190
|
-
i.map((t, n) =>
|
|
194
|
+
i.map((t, n) => ge(t, e + n, H)),
|
|
191
195
|
/* @__PURE__ */ g("div", {
|
|
192
196
|
className: l,
|
|
193
197
|
style: { height: r }
|
|
194
198
|
})
|
|
195
199
|
]
|
|
196
200
|
});
|
|
197
|
-
} else
|
|
198
|
-
let
|
|
199
|
-
return !V && K && G && (
|
|
200
|
-
ref:
|
|
201
|
+
} else Q = /* @__PURE__ */ g(ie, { children: v.map((e, t) => ge(e, t, null)) });
|
|
202
|
+
let $ = null;
|
|
203
|
+
return !V && K && G && ($ = /* @__PURE__ */ g("div", {
|
|
204
|
+
ref: I,
|
|
201
205
|
className: c
|
|
202
206
|
})), /* @__PURE__ */ _(r, {
|
|
203
|
-
ref:
|
|
204
|
-
className:
|
|
205
|
-
kind:
|
|
206
|
-
bodyScrollMode:
|
|
207
|
-
classes:
|
|
208
|
-
ariaLabel:
|
|
209
|
-
ariaLabelledBy:
|
|
207
|
+
ref: N,
|
|
208
|
+
className: se,
|
|
209
|
+
kind: C,
|
|
210
|
+
bodyScrollMode: D,
|
|
211
|
+
classes: E,
|
|
212
|
+
ariaLabel: fe,
|
|
213
|
+
ariaLabelledBy: pe,
|
|
210
214
|
children: [/* @__PURE__ */ g(n, {
|
|
211
215
|
columns: u,
|
|
212
|
-
kind:
|
|
213
|
-
density:
|
|
214
|
-
headerBehavior:
|
|
215
|
-
headerClassName:
|
|
216
|
-
gridTemplateClassName:
|
|
217
|
-
gridTemplateColumns:
|
|
218
|
-
classes:
|
|
216
|
+
kind: C,
|
|
217
|
+
density: w,
|
|
218
|
+
headerBehavior: ue,
|
|
219
|
+
headerClassName: ce,
|
|
220
|
+
gridTemplateClassName: x,
|
|
221
|
+
gridTemplateColumns: S,
|
|
222
|
+
classes: E
|
|
219
223
|
}), /* @__PURE__ */ _(e, {
|
|
220
|
-
ref:
|
|
221
|
-
className:
|
|
222
|
-
kind:
|
|
223
|
-
bodyScrollMode:
|
|
224
|
-
classes:
|
|
224
|
+
ref: P,
|
|
225
|
+
className: le,
|
|
226
|
+
kind: C,
|
|
227
|
+
bodyScrollMode: D,
|
|
228
|
+
classes: E,
|
|
225
229
|
children: [
|
|
230
|
+
Q,
|
|
226
231
|
$,
|
|
227
|
-
|
|
228
|
-
ue
|
|
232
|
+
de
|
|
229
233
|
]
|
|
230
234
|
})]
|
|
231
235
|
});
|
|
232
236
|
};
|
|
233
237
|
//#endregion
|
|
234
|
-
export {
|
|
238
|
+
export { v as VirtualizedConnectionTable };
|
|
235
239
|
|
|
236
240
|
//# sourceMappingURL=VirtualizedConnectionTable.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualizedConnectionTable.js","names":[],"sources":["../../../../src/components/data-table/VirtualizedConnectionTable.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type JSX,\n type ReactNode,\n} from 'react';\n\nimport {\n DataTableBody,\n DataTableEmptyRow,\n DataTableHeader,\n DataTableRoot,\n DataTableRow,\n type DataTableBodyScrollMode,\n type DataTableColumn,\n type DataTableDensity,\n type DataTableHeaderBehavior,\n type DataTableKind,\n type DataTableRowState,\n type DataTableSlot,\n type GetRowId,\n} from './DataTable.js';\nimport * as styles from './VirtualizedConnectionTable.css.js';\n\nimport {\n clamp,\n computeVirtualWindowBounds,\n isVerticallyScrollable,\n shouldTriggerVirtualizedInfiniteLoad,\n type VirtualWindow,\n} from '../../internal/data-table/virtualization.js';\nimport {\n resolveInfiniteRootMargin,\n shouldTriggerInfiniteLoad,\n} from '../../internal/infinite/infiniteLoad.js';\nimport type { SlotClasses } from '../../styles/slots.js';\n\nexport type VirtualizationConfig = {\n enabled: boolean;\n rowHeightPx: number;\n overscan: number;\n};\n\nexport type InfiniteScrollConfig = {\n enabled: boolean;\n thresholdPx?: number;\n autoLoad?: boolean;\n};\n\nexport type VirtualizedConnectionTableProps<Row> = {\n columns: readonly DataTableColumn<Row>[];\n rows: readonly Row[];\n getRowId: GetRowId<Row>;\n emptyState?: JSX.Element;\n className?: string;\n headerClassName?: string;\n bodyClassName?: string;\n rowClassName?: (row: Row, index: number) => string | null | undefined;\n gridTemplateClassName?: string;\n gridTemplateColumns?: string;\n kind?: DataTableKind;\n density?: DataTableDensity;\n headerBehavior?: DataTableHeaderBehavior;\n rowState?: (row: Row, index: number) => DataTableRowState;\n classes?: SlotClasses<DataTableSlot>;\n bodyScrollMode?: DataTableBodyScrollMode;\n bodyFooterNode?: ReactNode;\n\n virtualization?: VirtualizationConfig;\n\n infiniteScroll?: InfiniteScrollConfig;\n hasNextPage?: boolean;\n isLoadingMore?: boolean;\n onLoadMore?: () => void;\n ariaLabel?: string;\n ariaLabelledBy?: string;\n};\n\nconst findScrollParent = (el: HTMLElement | null): HTMLElement | null => {\n let current: HTMLElement | null = el;\n while (current != null) {\n const style = window.getComputedStyle(current);\n if (\n isVerticallyScrollable({\n overflowY: style.overflowY,\n scrollHeight: current.scrollHeight,\n clientHeight: current.clientHeight,\n })\n ) {\n return current;\n }\n current = current.parentElement;\n }\n return null;\n};\n\nexport const VirtualizedConnectionTable = <Row,>({\n columns,\n rows,\n getRowId,\n emptyState,\n className,\n headerClassName,\n bodyClassName,\n rowClassName,\n gridTemplateClassName,\n gridTemplateColumns,\n kind,\n density,\n headerBehavior,\n rowState,\n classes,\n bodyScrollMode = 'page',\n bodyFooterNode,\n virtualization,\n infiniteScroll,\n hasNextPage = false,\n isLoadingMore = false,\n onLoadMore,\n ariaLabel,\n ariaLabelledBy,\n}: VirtualizedConnectionTableProps<Row>): JSX.Element => {\n const containerRef = useRef<HTMLDivElement>(null);\n const bodyScrollerRef = useRef<HTMLDivElement>(null);\n const bodyRef = useRef<HTMLDivElement>(null);\n const sentinelRef = useRef<HTMLDivElement>(null);\n const scrollParentRef = useRef<HTMLElement | null>(null);\n const rafRef = useRef<number | null>(null);\n const loadMoreCooldownRef = useRef(false);\n\n const isVirtualized = virtualization?.enabled === true;\n const rowHeightPx = useMemo(() => {\n if (!isVirtualized) {\n return null;\n }\n\n const configuredRowHeight = virtualization.rowHeightPx;\n if (\n typeof configuredRowHeight === 'number' &&\n Number.isFinite(configuredRowHeight) &&\n configuredRowHeight > 0\n ) {\n return configuredRowHeight;\n }\n\n return 56;\n }, [isVirtualized, virtualization]);\n\n const overscan = useMemo(() => {\n if (!isVirtualized) {\n return 0;\n }\n\n let nextOverscan = 10;\n const configuredOverscan = virtualization.overscan;\n if (\n typeof configuredOverscan === 'number' &&\n Number.isFinite(configuredOverscan)\n ) {\n nextOverscan = configuredOverscan;\n }\n return Math.max(0, nextOverscan);\n }, [isVirtualized, virtualization]);\n\n const thresholdPx = infiniteScroll?.thresholdPx ?? 800;\n const autoLoad = infiniteScroll?.autoLoad ?? true;\n const infiniteEnabled = infiniteScroll?.enabled === true;\n const hasContainedBodyScroll = bodyScrollMode === 'contained';\n\n const canLoadMore =\n infiniteEnabled && hasNextPage && !isLoadingMore && onLoadMore != null;\n\n const triggerLoadMore = useCallback(() => {\n if (onLoadMore == null) {\n return;\n }\n onLoadMore();\n }, [onLoadMore]);\n\n const [windowState, setWindowState] = useState<VirtualWindow>(() => {\n return { startIndex: 0, endIndex: Math.min(rows.length, 50) };\n });\n\n const renderRow = useCallback(\n (row: Row, index: number, heightPx?: number | null): JSX.Element => {\n const rowStyle: CSSProperties = {};\n if (typeof heightPx === 'number') {\n rowStyle.height = heightPx;\n }\n return (\n <DataTableRow\n key={getRowId(row, index)}\n row={row}\n index={index}\n columns={columns}\n getRowId={getRowId}\n kind={kind}\n density={density}\n rowClassName={rowClassName}\n rowState={rowState}\n gridTemplateClassName={gridTemplateClassName}\n gridTemplateColumns={gridTemplateColumns}\n classes={classes}\n style={rowStyle}\n cellMode=\"singleLine\"\n />\n );\n },\n [\n classes,\n columns,\n density,\n getRowId,\n gridTemplateClassName,\n gridTemplateColumns,\n kind,\n rowClassName,\n rowState,\n ],\n );\n\n const computeVirtualWindow = useCallback(() => {\n if (!isVirtualized) {\n return;\n }\n const height = rowHeightPx;\n if (height == null) {\n return;\n }\n const bodyEl = bodyRef.current;\n if (bodyEl == null) {\n return;\n }\n\n const bodyScroller = bodyScrollerRef.current;\n const scrollParent = scrollParentRef.current;\n let viewportHeight = scrollParent?.clientHeight ?? window.innerHeight;\n let visibleTop = 0;\n if (hasContainedBodyScroll && bodyScroller != null) {\n viewportHeight = bodyScroller.clientHeight;\n visibleTop = bodyScroller.scrollTop;\n } else {\n const parentRectTop = scrollParent?.getBoundingClientRect().top ?? 0;\n const bodyRectTop = bodyEl.getBoundingClientRect().top;\n const relativeTop = bodyRectTop - parentRectTop;\n visibleTop = Math.max(0, -relativeTop);\n }\n const visibleBottom = visibleTop + viewportHeight;\n\n const totalHeight = rows.length * height;\n const clampedBottom = clamp(visibleBottom, 0, totalHeight);\n const { startIndex, endIndex } = computeVirtualWindowBounds({\n rowCount: rows.length,\n rowHeightPx: height,\n overscan,\n visibleTop,\n visibleBottom,\n });\n\n setWindowState((prev) => {\n if (prev.startIndex === startIndex && prev.endIndex === endIndex) {\n return prev;\n }\n return { startIndex, endIndex };\n });\n\n if (\n shouldTriggerInfiniteLoad({\n enabled: infiniteEnabled,\n hasNext: hasNextPage,\n isLoading: isLoadingMore,\n autoLoad,\n isCoolingDown: loadMoreCooldownRef.current,\n }) &&\n canLoadMore &&\n shouldTriggerVirtualizedInfiniteLoad({\n autoLoad,\n canLoadMore,\n totalHeight,\n visibleBottom: clampedBottom,\n thresholdPx,\n isCoolingDown: loadMoreCooldownRef.current,\n })\n ) {\n loadMoreCooldownRef.current = true;\n triggerLoadMore();\n window.setTimeout(() => {\n loadMoreCooldownRef.current = false;\n }, 250);\n }\n }, [\n autoLoad,\n canLoadMore,\n hasNextPage,\n hasContainedBodyScroll,\n isVirtualized,\n infiniteEnabled,\n isLoadingMore,\n overscan,\n rowHeightPx,\n rows.length,\n thresholdPx,\n triggerLoadMore,\n ]);\n\n const scheduleCompute = useCallback(() => {\n if (rafRef.current != null) {\n return;\n }\n rafRef.current = window.requestAnimationFrame(() => {\n rafRef.current = null;\n computeVirtualWindow();\n });\n }, [computeVirtualWindow]);\n\n useLayoutEffect(() => {\n if (!isVirtualized) {\n return;\n }\n const container = containerRef.current;\n if (container == null) {\n return;\n }\n if (hasContainedBodyScroll) {\n scrollParentRef.current = bodyScrollerRef.current;\n } else {\n scrollParentRef.current = findScrollParent(container);\n }\n scheduleCompute();\n }, [hasContainedBodyScroll, isVirtualized, scheduleCompute]);\n\n useEffect(() => {\n if (!isVirtualized) {\n return undefined;\n }\n const scrollParent = scrollParentRef.current;\n const target: HTMLElement | Window = scrollParent ?? window;\n\n const handler = () => {\n scheduleCompute();\n };\n\n target.addEventListener('scroll', handler, { passive: true });\n window.addEventListener('resize', handler);\n\n return () => {\n target.removeEventListener('scroll', handler);\n window.removeEventListener('resize', handler);\n };\n }, [isVirtualized, scheduleCompute]);\n\n useEffect(() => {\n if (isVirtualized) {\n return undefined;\n }\n if (\n !shouldTriggerInfiniteLoad({\n enabled: infiniteEnabled,\n hasNext: hasNextPage,\n isLoading: isLoadingMore,\n autoLoad,\n isCoolingDown: false,\n }) ||\n !canLoadMore\n ) {\n return undefined;\n }\n const sentinel = sentinelRef.current;\n if (sentinel == null) {\n return undefined;\n }\n if (\n typeof window === 'undefined' ||\n typeof IntersectionObserver === 'undefined'\n ) {\n return undefined;\n }\n\n const scrollParent = scrollParentRef.current;\n\n const observer = new IntersectionObserver(\n (entries) => {\n const [entry] = entries;\n if (entry == null) {\n return;\n }\n\n if (\n entry.isIntersecting &&\n shouldTriggerInfiniteLoad({\n enabled: infiniteEnabled,\n hasNext: hasNextPage,\n isLoading: isLoadingMore,\n autoLoad,\n isCoolingDown: loadMoreCooldownRef.current,\n })\n ) {\n loadMoreCooldownRef.current = true;\n triggerLoadMore();\n window.setTimeout(() => {\n loadMoreCooldownRef.current = false;\n }, 250);\n }\n },\n {\n root: scrollParent,\n rootMargin: resolveInfiniteRootMargin({ thresholdPx }),\n },\n );\n\n observer.observe(sentinel);\n return () => {\n observer.disconnect();\n };\n }, [\n autoLoad,\n canLoadMore,\n hasNextPage,\n infiniteEnabled,\n isVirtualized,\n isLoadingMore,\n thresholdPx,\n triggerLoadMore,\n ]);\n\n useLayoutEffect(() => {\n if (isVirtualized) {\n return;\n }\n const container = containerRef.current;\n if (container == null) {\n return;\n }\n if (hasContainedBodyScroll) {\n scrollParentRef.current = bodyScrollerRef.current;\n } else {\n scrollParentRef.current = findScrollParent(container);\n }\n }, [hasContainedBodyScroll, isVirtualized]);\n\n let bodyRows: JSX.Element;\n if (rows.length === 0) {\n bodyRows = (\n <DataTableEmptyRow\n emptyState={emptyState}\n density={density}\n classes={classes}\n />\n );\n } else if (isVirtualized && rowHeightPx != null) {\n const { startIndex, endIndex } = windowState;\n const topSpacerHeight = startIndex * rowHeightPx;\n const bottomSpacerHeight = (rows.length - endIndex) * rowHeightPx;\n const slice = rows.slice(startIndex, endIndex);\n bodyRows = (\n <div className={styles.bodyViewport} ref={bodyRef}>\n <div className={styles.spacer} style={{ height: topSpacerHeight }} />\n {slice.map((row, sliceIndex) => {\n const absoluteIndex = startIndex + sliceIndex;\n return renderRow(row, absoluteIndex, rowHeightPx);\n })}\n <div className={styles.spacer} style={{ height: bottomSpacerHeight }} />\n </div>\n );\n } else {\n bodyRows = (\n <>\n {rows.map((row, index) => {\n return renderRow(row, index, null);\n })}\n </>\n );\n }\n\n let sentinelNode: JSX.Element | null = null;\n if (!isVirtualized && infiniteEnabled && autoLoad) {\n sentinelNode = <div ref={sentinelRef} className={styles.sentinel} />;\n }\n\n return (\n <DataTableRoot\n ref={containerRef}\n className={className}\n kind={kind}\n bodyScrollMode={bodyScrollMode}\n classes={classes}\n ariaLabel={ariaLabel}\n ariaLabelledBy={ariaLabelledBy}\n >\n <DataTableHeader\n columns={columns}\n kind={kind}\n density={density}\n headerBehavior={headerBehavior}\n headerClassName={headerClassName}\n gridTemplateClassName={gridTemplateClassName}\n gridTemplateColumns={gridTemplateColumns}\n classes={classes}\n />\n <DataTableBody\n ref={bodyScrollerRef}\n className={bodyClassName}\n kind={kind}\n bodyScrollMode={bodyScrollMode}\n classes={classes}\n >\n {bodyRows}\n {sentinelNode}\n {bodyFooterNode}\n </DataTableBody>\n </DataTableRoot>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VirtualizedConnectionTable.js","names":[],"sources":["../../../../src/components/data-table/VirtualizedConnectionTable.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type JSX,\n type ReactNode,\n} from 'react';\n\nimport {\n DataTableBody,\n DataTableEmptyRow,\n DataTableHeader,\n DataTableRoot,\n DataTableRow,\n type DataTableBodyScrollMode,\n type DataTableColumn,\n type DataTableDensity,\n type DataTableHeaderBehavior,\n type DataTableKind,\n type DataTableRowState,\n type DataTableSlot,\n type GetRowId,\n} from './DataTable.js';\nimport * as styles from './VirtualizedConnectionTable.css.js';\n\nimport {\n clamp,\n computeVirtualWindowBounds,\n isVerticallyScrollable,\n shouldTriggerVirtualizedInfiniteLoad,\n type VirtualWindow,\n} from '../../internal/data-table/virtualization.js';\nimport {\n resolveInfiniteRootMargin,\n shouldTriggerInfiniteLoad,\n} from '../../internal/infinite/infiniteLoad.js';\nimport type { SlotClasses } from '../../styles/slots.js';\n\nexport type VirtualizationConfig = {\n enabled: boolean;\n rowHeightPx: number;\n overscan: number;\n};\n\nexport type InfiniteScrollConfig = {\n enabled: boolean;\n thresholdPx?: number;\n autoLoad?: boolean;\n};\n\nexport type VirtualizedConnectionTableProps<Row> = {\n columns: readonly DataTableColumn<Row>[];\n rows: readonly Row[];\n getRowId: GetRowId<Row>;\n emptyState?: JSX.Element;\n className?: string;\n headerClassName?: string;\n bodyClassName?: string;\n rowClassName?: (row: Row, index: number) => string | null | undefined;\n gridTemplateClassName?: string;\n gridTemplateColumns?: string;\n kind?: DataTableKind;\n density?: DataTableDensity;\n headerBehavior?: DataTableHeaderBehavior;\n rowState?: (row: Row, index: number) => DataTableRowState;\n classes?: SlotClasses<DataTableSlot>;\n bodyScrollMode?: DataTableBodyScrollMode;\n bodyFooterNode?: ReactNode;\n\n virtualization?: VirtualizationConfig;\n\n infiniteScroll?: InfiniteScrollConfig;\n hasNextPage?: boolean;\n isLoadingMore?: boolean;\n onLoadMore?: () => void;\n ariaLabel?: string;\n ariaLabelledBy?: string;\n};\n\nconst findScrollParent = (el: HTMLElement | null): HTMLElement | null => {\n let current: HTMLElement | null = el;\n while (current != null) {\n const style = window.getComputedStyle(current);\n if (\n isVerticallyScrollable({\n overflowY: style.overflowY,\n scrollHeight: current.scrollHeight,\n clientHeight: current.clientHeight,\n })\n ) {\n return current;\n }\n current = current.parentElement;\n }\n return null;\n};\n\nexport const VirtualizedConnectionTable = <Row,>({\n columns,\n rows,\n getRowId,\n emptyState,\n className,\n headerClassName,\n bodyClassName,\n rowClassName,\n gridTemplateClassName,\n gridTemplateColumns,\n kind,\n density,\n headerBehavior,\n rowState,\n classes,\n bodyScrollMode = 'page',\n bodyFooterNode,\n virtualization,\n infiniteScroll,\n hasNextPage = false,\n isLoadingMore = false,\n onLoadMore,\n ariaLabel,\n ariaLabelledBy,\n}: VirtualizedConnectionTableProps<Row>): JSX.Element => {\n const containerRef = useRef<HTMLDivElement>(null);\n const bodyScrollerRef = useRef<HTMLDivElement>(null);\n const bodyRef = useRef<HTMLDivElement>(null);\n const sentinelRef = useRef<HTMLDivElement>(null);\n const scrollParentRef = useRef<HTMLElement | null>(null);\n const rafRef = useRef<number | null>(null);\n const cooldownTimeoutRef = useRef<number | null>(null);\n const loadMoreCooldownRef = useRef(false);\n\n const isVirtualized = virtualization?.enabled === true;\n const rowHeightPx = useMemo(() => {\n if (!isVirtualized) {\n return null;\n }\n\n const configuredRowHeight = virtualization.rowHeightPx;\n if (\n typeof configuredRowHeight === 'number' &&\n Number.isFinite(configuredRowHeight) &&\n configuredRowHeight > 0\n ) {\n return configuredRowHeight;\n }\n\n return 56;\n }, [isVirtualized, virtualization]);\n\n const overscan = useMemo(() => {\n if (!isVirtualized) {\n return 0;\n }\n\n let nextOverscan = 10;\n const configuredOverscan = virtualization.overscan;\n if (\n typeof configuredOverscan === 'number' &&\n Number.isFinite(configuredOverscan)\n ) {\n nextOverscan = configuredOverscan;\n }\n return Math.max(0, nextOverscan);\n }, [isVirtualized, virtualization]);\n\n const thresholdPx = infiniteScroll?.thresholdPx ?? 800;\n const autoLoad = infiniteScroll?.autoLoad ?? true;\n const infiniteEnabled = infiniteScroll?.enabled === true;\n const hasContainedBodyScroll = bodyScrollMode === 'contained';\n\n const canLoadMore =\n infiniteEnabled && hasNextPage && !isLoadingMore && onLoadMore != null;\n\n const triggerLoadMore = useCallback(() => {\n if (onLoadMore == null) {\n return;\n }\n onLoadMore();\n }, [onLoadMore]);\n\n const startLoadMoreCooldown = useCallback(() => {\n loadMoreCooldownRef.current = true;\n if (cooldownTimeoutRef.current != null) {\n window.clearTimeout(cooldownTimeoutRef.current);\n }\n cooldownTimeoutRef.current = window.setTimeout(() => {\n loadMoreCooldownRef.current = false;\n cooldownTimeoutRef.current = null;\n }, 250);\n }, []);\n\n const [windowState, setWindowState] = useState<VirtualWindow>(() => {\n return { startIndex: 0, endIndex: Math.min(rows.length, 50) };\n });\n\n const renderRow = useCallback(\n (row: Row, index: number, heightPx?: number | null): JSX.Element => {\n const rowStyle: CSSProperties = {};\n if (typeof heightPx === 'number') {\n rowStyle.height = heightPx;\n }\n return (\n <DataTableRow\n key={getRowId(row, index)}\n row={row}\n index={index}\n columns={columns}\n getRowId={getRowId}\n kind={kind}\n density={density}\n rowClassName={rowClassName}\n rowState={rowState}\n gridTemplateClassName={gridTemplateClassName}\n gridTemplateColumns={gridTemplateColumns}\n classes={classes}\n style={rowStyle}\n cellMode=\"singleLine\"\n />\n );\n },\n [\n classes,\n columns,\n density,\n getRowId,\n gridTemplateClassName,\n gridTemplateColumns,\n kind,\n rowClassName,\n rowState,\n ],\n );\n\n const computeVirtualWindow = useCallback(() => {\n if (!isVirtualized) {\n return;\n }\n const height = rowHeightPx;\n if (height == null) {\n return;\n }\n const bodyEl = bodyRef.current;\n if (bodyEl == null) {\n return;\n }\n\n const bodyScroller = bodyScrollerRef.current;\n const scrollParent = scrollParentRef.current;\n let viewportHeight = scrollParent?.clientHeight ?? window.innerHeight;\n let visibleTop = 0;\n if (hasContainedBodyScroll && bodyScroller != null) {\n viewportHeight = bodyScroller.clientHeight;\n visibleTop = bodyScroller.scrollTop;\n } else {\n const parentRectTop = scrollParent?.getBoundingClientRect().top ?? 0;\n const bodyRectTop = bodyEl.getBoundingClientRect().top;\n const relativeTop = bodyRectTop - parentRectTop;\n visibleTop = Math.max(0, -relativeTop);\n }\n const visibleBottom = visibleTop + viewportHeight;\n\n const totalHeight = rows.length * height;\n const clampedBottom = clamp(visibleBottom, 0, totalHeight);\n const { startIndex, endIndex } = computeVirtualWindowBounds({\n rowCount: rows.length,\n rowHeightPx: height,\n overscan,\n visibleTop,\n visibleBottom,\n });\n\n setWindowState((prev) => {\n if (prev.startIndex === startIndex && prev.endIndex === endIndex) {\n return prev;\n }\n return { startIndex, endIndex };\n });\n\n if (\n shouldTriggerInfiniteLoad({\n enabled: infiniteEnabled,\n hasNext: hasNextPage,\n isLoading: isLoadingMore,\n autoLoad,\n isCoolingDown: loadMoreCooldownRef.current,\n }) &&\n canLoadMore &&\n shouldTriggerVirtualizedInfiniteLoad({\n autoLoad,\n canLoadMore,\n totalHeight,\n visibleBottom: clampedBottom,\n thresholdPx,\n isCoolingDown: loadMoreCooldownRef.current,\n })\n ) {\n startLoadMoreCooldown();\n triggerLoadMore();\n }\n }, [\n autoLoad,\n canLoadMore,\n hasNextPage,\n hasContainedBodyScroll,\n isVirtualized,\n infiniteEnabled,\n isLoadingMore,\n overscan,\n rowHeightPx,\n rows.length,\n startLoadMoreCooldown,\n thresholdPx,\n triggerLoadMore,\n ]);\n\n const scheduleCompute = useCallback(() => {\n if (rafRef.current != null) {\n return;\n }\n rafRef.current = window.requestAnimationFrame(() => {\n rafRef.current = null;\n computeVirtualWindow();\n });\n }, [computeVirtualWindow]);\n\n useEffect(() => {\n return () => {\n if (rafRef.current != null) {\n window.cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n if (cooldownTimeoutRef.current != null) {\n window.clearTimeout(cooldownTimeoutRef.current);\n cooldownTimeoutRef.current = null;\n }\n };\n }, []);\n\n useLayoutEffect(() => {\n if (!isVirtualized) {\n return;\n }\n const container = containerRef.current;\n if (container == null) {\n return;\n }\n if (hasContainedBodyScroll) {\n scrollParentRef.current = bodyScrollerRef.current;\n } else {\n scrollParentRef.current = findScrollParent(container);\n }\n scheduleCompute();\n }, [hasContainedBodyScroll, isVirtualized, scheduleCompute]);\n\n useEffect(() => {\n if (!isVirtualized) {\n return undefined;\n }\n const scrollParent = scrollParentRef.current;\n const target: HTMLElement | Window = scrollParent ?? window;\n\n const handler = () => {\n scheduleCompute();\n };\n\n target.addEventListener('scroll', handler, { passive: true });\n window.addEventListener('resize', handler);\n\n return () => {\n target.removeEventListener('scroll', handler);\n window.removeEventListener('resize', handler);\n };\n }, [isVirtualized, scheduleCompute]);\n\n useEffect(() => {\n if (isVirtualized) {\n return undefined;\n }\n if (\n !shouldTriggerInfiniteLoad({\n enabled: infiniteEnabled,\n hasNext: hasNextPage,\n isLoading: isLoadingMore,\n autoLoad,\n isCoolingDown: false,\n }) ||\n !canLoadMore\n ) {\n return undefined;\n }\n const sentinel = sentinelRef.current;\n if (sentinel == null) {\n return undefined;\n }\n if (\n typeof window === 'undefined' ||\n typeof IntersectionObserver === 'undefined'\n ) {\n return undefined;\n }\n\n const scrollParent = scrollParentRef.current;\n\n const observer = new IntersectionObserver(\n (entries) => {\n const [entry] = entries;\n if (entry == null) {\n return;\n }\n\n if (\n entry.isIntersecting &&\n shouldTriggerInfiniteLoad({\n enabled: infiniteEnabled,\n hasNext: hasNextPage,\n isLoading: isLoadingMore,\n autoLoad,\n isCoolingDown: loadMoreCooldownRef.current,\n })\n ) {\n startLoadMoreCooldown();\n triggerLoadMore();\n }\n },\n {\n root: scrollParent,\n rootMargin: resolveInfiniteRootMargin({ thresholdPx }),\n },\n );\n\n observer.observe(sentinel);\n return () => {\n observer.disconnect();\n };\n }, [\n autoLoad,\n canLoadMore,\n hasNextPage,\n infiniteEnabled,\n isVirtualized,\n isLoadingMore,\n startLoadMoreCooldown,\n thresholdPx,\n triggerLoadMore,\n ]);\n\n useLayoutEffect(() => {\n if (isVirtualized) {\n return;\n }\n const container = containerRef.current;\n if (container == null) {\n return;\n }\n if (hasContainedBodyScroll) {\n scrollParentRef.current = bodyScrollerRef.current;\n } else {\n scrollParentRef.current = findScrollParent(container);\n }\n }, [hasContainedBodyScroll, isVirtualized]);\n\n let bodyRows: JSX.Element;\n if (rows.length === 0) {\n bodyRows = (\n <DataTableEmptyRow\n emptyState={emptyState}\n density={density}\n classes={classes}\n />\n );\n } else if (isVirtualized && rowHeightPx != null) {\n const { startIndex, endIndex } = windowState;\n const topSpacerHeight = startIndex * rowHeightPx;\n const bottomSpacerHeight = (rows.length - endIndex) * rowHeightPx;\n const slice = rows.slice(startIndex, endIndex);\n bodyRows = (\n <div className={styles.bodyViewport} ref={bodyRef}>\n <div className={styles.spacer} style={{ height: topSpacerHeight }} />\n {slice.map((row, sliceIndex) => {\n const absoluteIndex = startIndex + sliceIndex;\n return renderRow(row, absoluteIndex, rowHeightPx);\n })}\n <div className={styles.spacer} style={{ height: bottomSpacerHeight }} />\n </div>\n );\n } else {\n bodyRows = (\n <>\n {rows.map((row, index) => {\n return renderRow(row, index, null);\n })}\n </>\n );\n }\n\n let sentinelNode: JSX.Element | null = null;\n if (!isVirtualized && infiniteEnabled && autoLoad) {\n sentinelNode = <div ref={sentinelRef} className={styles.sentinel} />;\n }\n\n return (\n <DataTableRoot\n ref={containerRef}\n className={className}\n kind={kind}\n bodyScrollMode={bodyScrollMode}\n classes={classes}\n ariaLabel={ariaLabel}\n ariaLabelledBy={ariaLabelledBy}\n >\n <DataTableHeader\n columns={columns}\n kind={kind}\n density={density}\n headerBehavior={headerBehavior}\n headerClassName={headerClassName}\n gridTemplateClassName={gridTemplateClassName}\n gridTemplateColumns={gridTemplateColumns}\n classes={classes}\n />\n <DataTableBody\n ref={bodyScrollerRef}\n className={bodyClassName}\n kind={kind}\n bodyScrollMode={bodyScrollMode}\n classes={classes}\n >\n {bodyRows}\n {sentinelNode}\n {bodyFooterNode}\n </DataTableBody>\n </DataTableRoot>\n );\n};\n"],"mappings":";;;;;;;AAmFA,IAAM,MAAoB,MAA+C;CACvE,IAAI,IAA8B;CAClC,OAAO,KAAW,OAAM;EAEtB,IACE,EAAuB;GACrB,WAHU,OAAO,iBAAiB,CAGvB,EAAM;GACjB,cAAc,EAAQ;GACtB,cAAc,EAAQ;EACxB,CAAC,GAED,OAAO;EAET,IAAU,EAAQ;CACpB;CACA,OAAO;AACT,GAEa,KAAoC,EAC/C,YACA,SACA,aACA,gBACA,eACA,qBACA,mBACA,iBACA,0BACA,wBACA,SACA,YACA,oBACA,aACA,YACA,oBAAiB,QACjB,oBACA,mBACA,mBACA,iBAAc,IACd,mBAAgB,IAChB,eACA,eACA,yBACuD;CACvD,IAAM,IAAe,EAAuB,IAAI,GAC1C,IAAkB,EAAuB,IAAI,GAC7C,IAAU,EAAuB,IAAI,GACrC,IAAc,EAAuB,IAAI,GACzC,IAAkB,EAA2B,IAAI,GACjD,IAAS,EAAsB,IAAI,GACnC,IAAqB,EAAsB,IAAI,GAC/C,IAAsB,EAAO,EAAK,GAElC,IAAgB,GAAgB,YAAY,IAC5C,IAAc,QAAc;EAChC,IAAI,CAAC,GACH,OAAO;EAGT,IAAM,IAAsB,EAAe;EAS3C,OAPE,OAAO,KAAwB,YAC/B,OAAO,SAAS,CAAmB,KACnC,IAAsB,IAEf,IAGF;CACT,GAAG,CAAC,GAAe,CAAc,CAAC,GAE5B,IAAW,QAAc;EAC7B,IAAI,CAAC,GACH,OAAO;EAGT,IAAI,IAAe,IACb,IAAqB,EAAe;EAO1C,OALE,OAAO,KAAuB,YAC9B,OAAO,SAAS,CAAkB,MAElC,IAAe,IAEV,KAAK,IAAI,GAAG,CAAY;CACjC,GAAG,CAAC,GAAe,CAAc,CAAC,GAE5B,IAAc,GAAgB,eAAe,KAC7C,IAAW,GAAgB,YAAY,IACvC,IAAkB,GAAgB,YAAY,IAC9C,IAAyB,MAAmB,aAE5C,IACJ,KAAmB,KAAe,CAAC,KAAiB,KAAc,MAE9D,IAAkB,QAAkB;EACpC,IAGO;CACb,GAAG,CAAC,CAAU,CAAC,GAET,IAAwB,QAAkB;EAK9C,AAJA,EAAoB,UAAU,IAC1B,EAAmB,WAAW,QAChC,OAAO,aAAa,EAAmB,OAAO,GAEhD,EAAmB,UAAU,OAAO,iBAAiB;GAEnD,AADA,EAAoB,UAAU,IAC9B,EAAmB,UAAU;EAC/B,GAAG,GAAG;CACR,GAAG,CAAC,CAAC,GAEC,CAAC,IAAa,MAAkB,UAC7B;EAAE,YAAY;EAAG,UAAU,KAAK,IAAI,EAAK,QAAQ,EAAE;CAAE,EAC7D,GAEK,KAAY,GACf,GAAU,GAAe,MAA0C;EAClE,IAAM,IAA0B,CAAC;EAIjC,OAHI,OAAO,KAAa,aACtB,EAAS,SAAS,IAGlB,kBAAC,GAAD;GAEO;GACE;GACE;GACC;GACJ;GACG;GACK;GACJ;GACa;GACF;GACZ;GACT,OAAO;GACP,UAAS;EACV,GAdM,EAAS,GAAK,CAAK,CAczB;CAEL,GACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF,GAEM,KAAuB,QAAkB;EAC7C,IAAI,CAAC,GACH;EAEF,IAAM,IAAS;EACf,IAAI,KAAU,MACZ;EAEF,IAAM,IAAS,EAAQ;EACvB,IAAI,KAAU,MACZ;EAGF,IAAM,IAAe,EAAgB,SAC/B,IAAe,EAAgB,SACjC,IAAiB,GAAc,gBAAgB,OAAO,aACtD,IAAa;EACjB,IAAI,KAA0B,KAAgB,MAE5C,AADA,IAAiB,EAAa,cAC9B,IAAa,EAAa;OACrB;GACL,IAAM,IAAgB,GAAc,sBAAsB,EAAE,OAAO,GAE7D,IADc,EAAO,sBAAsB,EAAE,MACjB;GAClC,IAAa,KAAK,IAAI,GAAG,CAAC,CAAW;EACvC;EACA,IAAM,IAAgB,IAAa,GAE7B,IAAc,EAAK,SAAS,GAC5B,IAAgB,GAAM,GAAe,GAAG,CAAW,GACnD,EAAE,eAAY,gBAAa,GAA2B;GAC1D,UAAU,EAAK;GACf,aAAa;GACb;GACA;GACA;EACF,CAAC;EASD,AAPA,IAAgB,MACV,EAAK,eAAe,KAAc,EAAK,aAAa,IAC/C,IAEF;GAAE;GAAY;EAAS,CAC/B,GAGC,EAA0B;GACxB,SAAS;GACT,SAAS;GACT,WAAW;GACX;GACA,eAAe,EAAoB;EACrC,CAAC,KACD,KACA,GAAqC;GACnC;GACA;GACA;GACA,eAAe;GACf;GACA,eAAe,EAAoB;EACrC,CAAC,MAED,EAAsB,GACtB,EAAgB;CAEpB,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAK;EACL;EACA;EACA;CACF,CAAC,GAEK,IAAkB,QAAkB;EACpC,AAGJ,EAAO,YAAU,OAAO,4BAA4B;GAElD,AADA,EAAO,UAAU,MACjB,GAAqB;EACvB,CAAC;CACH,GAAG,CAAC,EAAoB,CAAC;CA2HzB,AAzHA,cACe;EAKX,AAJI,EAAO,WAAW,SACpB,OAAO,qBAAqB,EAAO,OAAO,GAC1C,EAAO,UAAU,OAEf,EAAmB,WAAW,SAChC,OAAO,aAAa,EAAmB,OAAO,GAC9C,EAAmB,UAAU;CAEjC,GACC,CAAC,CAAC,GAEL,QAAsB;EACpB,IAAI,CAAC,GACH;EAEF,IAAM,IAAY,EAAa;EAC3B,KAAa,SAGb,IACF,EAAgB,UAAU,EAAgB,UAE1C,EAAgB,UAAU,GAAiB,CAAS,GAEtD,EAAgB;CAClB,GAAG;EAAC;EAAwB;EAAe;CAAe,CAAC,GAE3D,QAAgB;EACd,IAAI,CAAC,GACH;EAGF,IAAM,IADe,EAAgB,WACgB,QAE/C,UAAgB;GACpB,EAAgB;EAClB;EAKA,OAHA,EAAO,iBAAiB,UAAU,GAAS,EAAE,SAAS,GAAK,CAAC,GAC5D,OAAO,iBAAiB,UAAU,CAAO,SAE5B;GAEX,AADA,EAAO,oBAAoB,UAAU,CAAO,GAC5C,OAAO,oBAAoB,UAAU,CAAO;EAC9C;CACF,GAAG,CAAC,GAAe,CAAe,CAAC,GAEnC,QAAgB;EAId,IAHI,KAIF,CAAC,EAA0B;GACzB,SAAS;GACT,SAAS;GACT,WAAW;GACX;GACA,eAAe;EACjB,CAAC,KACD,CAAC,GAED;EAEF,IAAM,IAAW,EAAY;EAI7B,IAHI,KAAY,QAId,OAAO,SAAW,OAClB,OAAO,uBAAyB,KAEhC;EAGF,IAAM,IAAe,EAAgB,SAE/B,IAAW,IAAI,sBAClB,MAAY;GACX,IAAM,CAAC,KAAS;GACZ,KAAS,QAKX,EAAM,kBACN,EAA0B;IACxB,SAAS;IACT,SAAS;IACT,WAAW;IACX;IACA,eAAe,EAAoB;GACrC,CAAC,MAED,EAAsB,GACtB,EAAgB;EAEpB,GACA;GACE,MAAM;GACN,YAAY,EAA0B,EAAE,eAAY,CAAC;EACvD,CACF;EAGA,OADA,EAAS,QAAQ,CAAQ,SACZ;GACX,EAAS,WAAW;EACtB;CACF,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,GAED,QAAsB;EACpB,IAAI,GACF;EAEF,IAAM,IAAY,EAAa;EAC3B,KAAa,SAGb,IACF,EAAgB,UAAU,EAAgB,UAE1C,EAAgB,UAAU,GAAiB,CAAS;CAExD,GAAG,CAAC,GAAwB,CAAa,CAAC;CAE1C,IAAI;CACJ,IAAI,EAAK,WAAW,GAClB,IACE,kBAAC,GAAD;EACc;EACH;EACA;CACV,CAAA;MAEE,IAAI,KAAiB,KAAe,MAAM;EAC/C,IAAM,EAAE,eAAY,gBAAa,IAC3B,IAAkB,IAAa,GAC/B,KAAsB,EAAK,SAAS,KAAY,GAChD,IAAQ,EAAK,MAAM,GAAY,CAAQ;EAC7C,IACE,kBAAC,OAAD;GAAK,WAAW;GAAqB,KAAK;aAA1C;IACE,kBAAC,OAAD;KAAK,WAAW;KAAe,OAAO,EAAE,QAAQ,EAAgB;IAAI,CAAA;IACnE,EAAM,KAAK,GAAK,MAER,GAAU,GADK,IAAa,GACE,CAAW,CACjD;IACD,kBAAC,OAAD;KAAK,WAAW;KAAe,OAAO,EAAE,QAAQ,EAAmB;IAAI,CAAA;GACpE;;CAET,OACE,IACE,kBAAA,IAAA,EAAA,UACG,EAAK,KAAK,GAAK,MACP,GAAU,GAAK,GAAO,IAAI,CAClC,EACD,CAAA;CAIN,IAAI,IAAmC;CAKvC,OAJI,CAAC,KAAiB,KAAmB,MACvC,IAAe,kBAAC,OAAD;EAAK,KAAK;EAAa,WAAW;CAAkB,CAAA,IAInE,kBAAC,GAAD;EACE,KAAK;EACM;EACL;EACU;EACP;EACE;EACK;YAPlB,CASE,kBAAC,GAAD;GACW;GACH;GACG;GACO;GACC;GACM;GACF;GACZ;EACV,CAAA,GACD,kBAAC,GAAD;GACE,KAAK;GACL,WAAW;GACL;GACU;GACP;aALX;IAOG;IACA;IACA;GACY;IACF;;AAEnB"}
|