@cartanova/qgrid-cli 1.1.5 → 1.2.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 (50) hide show
  1. package/bundle/dist/application/sonamu.generated.js +10 -5
  2. package/bundle/dist/application/sonamu.generated.sso.js +3 -2
  3. package/bundle/dist/application/token/token.model.js +21 -3
  4. package/bundle/dist/application/token/token.types.js +3 -2
  5. package/bundle/dist/i18n/sd.generated.js +3 -1
  6. package/bundle/dist/migrations/20260415113716_alter_tokens_add_ord.js +16 -0
  7. package/bundle/dist/migrations/20260415134649_alter_request_logs_alter1.js +14 -0
  8. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980 → vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496}/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +2 -2
  9. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980 → vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496}/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +2 -2
  10. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980 → vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496}/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +2 -2
  11. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980 → vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496}/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +2 -2
  12. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980 → vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496}/node_modules/vitest/dist/chunks/index.DOa3dzoN.js +2 -2
  13. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980 → vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496}/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +2 -2
  14. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980 → vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496}/node_modules/vitest/dist/chunks/test.p_J6dB8a.js +2 -2
  15. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980 → vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496}/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +2 -2
  16. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980 → vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496}/node_modules/vitest/dist/index.js +1 -1
  17. package/bundle/dist/sonamu.config.js +9 -9
  18. package/bundle/dist/testing/setup-mocks.js +2 -2
  19. package/bundle/src/application/request-log/request-log.entity.json +9 -3
  20. package/bundle/src/application/sonamu.generated.http +13 -1
  21. package/bundle/src/application/sonamu.generated.sso.ts +1 -0
  22. package/bundle/src/application/sonamu.generated.ts +5 -2
  23. package/bundle/src/application/token/token.entity.json +5 -3
  24. package/bundle/src/application/token/token.model.ts +15 -1
  25. package/bundle/src/application/token/token.types.ts +1 -0
  26. package/bundle/src/i18n/sd.generated.ts +2 -0
  27. package/bundle/src/migrations/20260415113716_alter_tokens_add_ord.ts +13 -0
  28. package/bundle/src/migrations/20260415134649_alter_request_logs_alter1.ts +13 -0
  29. package/bundle/src/sonamu.config.ts +8 -8
  30. package/bundle/web-dist/client/assets/index-BP0XRvKL.css +1 -0
  31. package/bundle/web-dist/client/assets/{index-Dyn67Y0R.js → index-BowrnLVe.js} +3 -3
  32. package/bundle/web-dist/client/assets/routes-DRU2rj_p.js +5 -0
  33. package/bundle/web-dist/client/assets/{sd.generated-BrQoQXvv.js → sd.generated-CkJCx4Bp.js} +1 -1
  34. package/bundle/web-dist/client/assets/services.generated-CAJQk7Wk.js +1 -0
  35. package/bundle/web-dist/client/assets/{show-DIzwg78k.js → show-DjQUOob1.js} +1 -1
  36. package/bundle/web-dist/client/assets/tokens-B6y-rxlU.js +1 -0
  37. package/bundle/web-dist/client/index.html +3 -3
  38. package/bundle/web-dist/server/assets/routes-CQY28Uq3.js +2855 -0
  39. package/bundle/web-dist/server/assets/{sd.generated-BnonqqKr.js → sd.generated-BeEKgSOs.js} +336 -1
  40. package/bundle/web-dist/server/assets/{services.generated-D5ABD5fr.js → services.generated-DjxCLdMu.js} +10 -1
  41. package/bundle/web-dist/server/assets/{show-C9pcdSxc.js → show-BEFi1cKV.js} +2 -2
  42. package/bundle/web-dist/server/assets/{tokens-ARL5AOAh.js → tokens-Dyi6qMmP.js} +9 -6
  43. package/bundle/web-dist/server/entry-server.generated.js +18 -19
  44. package/package.json +1 -1
  45. package/bundle/web-dist/client/assets/index-p3clzhWX.css +0 -1
  46. package/bundle/web-dist/client/assets/routes-ytPY-kr9.js +0 -1
  47. package/bundle/web-dist/client/assets/services.generated-BspO2L0j.js +0 -1
  48. package/bundle/web-dist/client/assets/tokens-CiU_LVOp.js +0 -1
  49. package/bundle/web-dist/server/assets/react-dom-CGIzOSuj.js +0 -335
  50. package/bundle/web-dist/server/assets/routes-BQmURFK9.js +0 -492
@@ -0,0 +1,2855 @@
1
+ import { S as require_react, b as useQueryClient, nt as __toESM, v as require_react_dom, x as require_jsx_runtime } from "./sd.generated-BeEKgSOs.js";
2
+ import { n as RequestLogService, r as TokenService, t as QgridService } from "./services.generated-DjxCLdMu.js";
3
+ import { i as lucideKeyRound, o as useNavigate } from "../entry-server.generated.js";
4
+ //#region ~icons/lucide/activity.jsx
5
+ var import_react = /* @__PURE__ */ __toESM(require_react());
6
+ var import_jsx_runtime = require_jsx_runtime();
7
+ var lucideActivity = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
8
+ viewBox: "0 0 24 24",
9
+ width: "1.2em",
10
+ height: "1.2em",
11
+ ...props,
12
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
13
+ fill: "none",
14
+ stroke: "currentColor",
15
+ strokeLinecap: "round",
16
+ strokeLinejoin: "round",
17
+ strokeWidth: 2,
18
+ d: "M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2"
19
+ })
20
+ });
21
+ //#endregion
22
+ //#region ~icons/lucide/cpu.jsx
23
+ var lucideCpu = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
24
+ viewBox: "0 0 24 24",
25
+ width: "1.2em",
26
+ height: "1.2em",
27
+ ...props,
28
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", {
29
+ fill: "none",
30
+ stroke: "currentColor",
31
+ strokeLinecap: "round",
32
+ strokeLinejoin: "round",
33
+ strokeWidth: 2,
34
+ children: [
35
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 20v2m0-20v2m5 16v2m0-20v2M2 12h2m-2 5h2M2 7h2m16 5h2m-2 5h2M20 7h2M7 20v2M7 2v2" }),
36
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", {
37
+ width: 16,
38
+ height: 16,
39
+ x: 4,
40
+ y: 4,
41
+ rx: 2
42
+ }),
43
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", {
44
+ width: 8,
45
+ height: 8,
46
+ x: 8,
47
+ y: 8,
48
+ rx: 1
49
+ })
50
+ ]
51
+ })
52
+ });
53
+ //#endregion
54
+ //#region src/components/qgrid/HealthCard.tsx
55
+ function MetricCard({ label, icon: Icon, children }) {
56
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
57
+ className: "rounded-lg bg-sand-50 px-5 py-4",
58
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
59
+ className: "flex items-center justify-between mb-2",
60
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
61
+ className: "text-[10px] uppercase tracking-wider text-sand-400 font-medium",
62
+ children: label
63
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: "size-4 text-sand-400" })]
64
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children })]
65
+ });
66
+ }
67
+ function HealthCard({ data, isLoading, isError }) {
68
+ if (isLoading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
69
+ className: "grid grid-cols-1 sm:grid-cols-3 gap-4",
70
+ children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
71
+ className: "rounded-lg bg-sand-50 px-5 py-4 animate-pulse",
72
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-3 w-16 bg-sand-200 rounded mb-3" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-6 w-12 bg-sand-200 rounded" })]
73
+ }, `skeleton-${i}`))
74
+ });
75
+ const isOnline = (isError ? "offline" : data?.status ?? "unknown") === "ok";
76
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
77
+ className: "grid grid-cols-1 sm:grid-cols-3 gap-4",
78
+ children: [
79
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MetricCard, {
80
+ label: "Status",
81
+ icon: lucideActivity,
82
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
83
+ className: "flex items-center gap-2",
84
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `size-2 rounded-full ${isOnline ? "bg-sage-400" : "bg-red-400"}` }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
85
+ className: "text-base font-semibold text-sand-800",
86
+ children: isOnline ? "Online" : "Offline"
87
+ })]
88
+ })
89
+ }),
90
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MetricCard, {
91
+ label: "Workers",
92
+ icon: lucideCpu,
93
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
94
+ className: "text-base font-semibold text-sand-800",
95
+ children: data?.workers ?? 0
96
+ })
97
+ }),
98
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MetricCard, {
99
+ label: "Active Tokens",
100
+ icon: lucideKeyRound,
101
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
102
+ className: "text-base font-semibold text-sand-800",
103
+ children: data?.activeTokens ?? 0
104
+ })
105
+ })
106
+ ]
107
+ });
108
+ }
109
+ //#endregion
110
+ //#region ~icons/lucide/chevron-left.jsx
111
+ var lucideChevronLeft = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
112
+ viewBox: "0 0 24 24",
113
+ width: "1.2em",
114
+ height: "1.2em",
115
+ ...props,
116
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
117
+ fill: "none",
118
+ stroke: "currentColor",
119
+ strokeLinecap: "round",
120
+ strokeLinejoin: "round",
121
+ strokeWidth: 2,
122
+ d: "m15 18l-6-6l6-6"
123
+ })
124
+ });
125
+ //#endregion
126
+ //#region ~icons/lucide/chevron-right.jsx
127
+ var lucideChevronRight = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
128
+ viewBox: "0 0 24 24",
129
+ width: "1.2em",
130
+ height: "1.2em",
131
+ ...props,
132
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
133
+ fill: "none",
134
+ stroke: "currentColor",
135
+ strokeLinecap: "round",
136
+ strokeLinejoin: "round",
137
+ strokeWidth: 2,
138
+ d: "m9 18l6-6l-6-6"
139
+ })
140
+ });
141
+ //#endregion
142
+ //#region src/components/qgrid/RequestLogTable.tsx
143
+ var PAGE_SIZE$1 = 50;
144
+ function formatDateTime(iso) {
145
+ const d = new Date(iso);
146
+ return `${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")} ${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
147
+ }
148
+ function formatNum(n) {
149
+ return n.toLocaleString();
150
+ }
151
+ function calcCacheHitRate(row) {
152
+ const denom = row.input_tokens + row.cache_read_tokens + row.cache_creation_tokens;
153
+ if (denom === 0) return "—";
154
+ return `${Math.round(row.cache_read_tokens / denom * 100)}%`;
155
+ }
156
+ function trimQuery(q, maxLen = 30) {
157
+ return q.length > maxLen ? `${q.slice(0, maxLen)}...` : q;
158
+ }
159
+ function RequestLogTable() {
160
+ const navigate = useNavigate();
161
+ const [page, setPage] = (0, import_react.useState)(1);
162
+ const [tokenFilter, setTokenFilter] = (0, import_react.useState)("");
163
+ const { data: statsData } = QgridService.useStats();
164
+ const tokenNames = (statsData ?? []).map((t) => t.name).filter(Boolean);
165
+ const { data, isLoading } = RequestLogService.useRequestLogs("A", {
166
+ num: PAGE_SIZE$1,
167
+ page,
168
+ orderBy: "id-desc",
169
+ ...tokenFilter ? { token_name: tokenFilter } : {}
170
+ });
171
+ const rows = data?.rows ?? [];
172
+ const total = data?.total ?? 0;
173
+ const totalPages = Math.ceil(total / PAGE_SIZE$1);
174
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
175
+ className: "flex items-center gap-2 mb-3 flex-wrap",
176
+ children: [tokenNames.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
177
+ value: tokenFilter,
178
+ onChange: (e) => {
179
+ setTokenFilter(e.target.value);
180
+ setPage(1);
181
+ },
182
+ className: "border border-sand-200 rounded-md px-2 py-1 text-xs text-sand-700 bg-white focus:outline-none focus:border-sienna-300",
183
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
184
+ value: "",
185
+ children: "All Tokens"
186
+ }), tokenNames.map((name) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
187
+ value: name,
188
+ children: name
189
+ }, name))]
190
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
191
+ className: "text-[11px] text-sand-400",
192
+ children: [total, " results"]
193
+ })]
194
+ }), isLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
195
+ className: "space-y-2",
196
+ children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-8 bg-sand-100 rounded animate-pulse" }, `skel-${i}`))
197
+ }) : rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
198
+ className: "text-sand-400 text-center py-12 text-sm",
199
+ children: "No requests yet."
200
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
201
+ className: "rounded-lg bg-sand-50 overflow-hidden",
202
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", {
203
+ className: "w-full text-sm",
204
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", {
205
+ className: "border-b border-sand-200",
206
+ children: [
207
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
208
+ className: "text-left px-3 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium",
209
+ children: "Date"
210
+ }),
211
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
212
+ className: "text-left px-3 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium",
213
+ children: "Token"
214
+ }),
215
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
216
+ className: "text-left px-3 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium",
217
+ children: "Query"
218
+ }),
219
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
220
+ className: "text-right px-3 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium",
221
+ children: "In"
222
+ }),
223
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
224
+ className: "text-right px-3 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium",
225
+ children: "Out"
226
+ }),
227
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
228
+ className: "text-right px-3 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium",
229
+ children: "C.Read"
230
+ }),
231
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
232
+ className: "text-right px-3 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium",
233
+ children: "C.Write"
234
+ }),
235
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
236
+ className: "text-right px-3 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium",
237
+ children: "Hit"
238
+ }),
239
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "w-8 px-2 py-2.5" })
240
+ ]
241
+ }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", {
242
+ className: "divide-y divide-sand-200/60",
243
+ children: rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", {
244
+ className: "transition-colors duration-150 hover:bg-sand-100/60 cursor-pointer",
245
+ onClick: () => navigate({
246
+ to: "/requests/show",
247
+ search: { id: row.id }
248
+ }),
249
+ children: [
250
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
251
+ className: "px-3 py-2.5",
252
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
253
+ className: "text-[10px] text-sand-400 tabular-nums whitespace-nowrap",
254
+ children: formatDateTime(row.created_at)
255
+ })
256
+ }),
257
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
258
+ className: "px-3 py-2.5",
259
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
260
+ className: "text-xs text-sand-500",
261
+ children: row.token_name
262
+ })
263
+ }),
264
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
265
+ className: "px-3 py-2.5",
266
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
267
+ className: "text-sand-800 truncate max-w-48",
268
+ title: row.query,
269
+ children: trimQuery(row.query)
270
+ })
271
+ }),
272
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
273
+ className: "px-3 py-2.5 text-right tabular-nums text-sand-700",
274
+ children: formatNum(row.input_tokens)
275
+ }),
276
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
277
+ className: "px-3 py-2.5 text-right tabular-nums text-sand-700",
278
+ children: formatNum(row.output_tokens)
279
+ }),
280
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
281
+ className: "px-3 py-2.5 text-right tabular-nums text-sand-700",
282
+ children: formatNum(row.cache_read_tokens)
283
+ }),
284
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
285
+ className: "px-3 py-2.5 text-right tabular-nums text-sand-700",
286
+ children: formatNum(row.cache_creation_tokens)
287
+ }),
288
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
289
+ className: "px-3 py-2.5 text-right tabular-nums text-sand-700",
290
+ children: calcCacheHitRate(row)
291
+ }),
292
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
293
+ className: "px-2 py-2.5",
294
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(lucideChevronRight, { className: "size-4 text-sand-400" })
295
+ })
296
+ ]
297
+ }, row.id))
298
+ })]
299
+ })
300
+ }), totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
301
+ className: "flex items-center justify-center gap-3 mt-3",
302
+ children: [
303
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
304
+ type: "button",
305
+ className: "p-1 rounded text-sand-400 hover:text-sand-600 disabled:opacity-30 transition-colors",
306
+ disabled: page === 1,
307
+ onClick: () => setPage((p) => p - 1),
308
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(lucideChevronLeft, { className: "size-4" })
309
+ }),
310
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
311
+ className: "text-[11px] text-sand-400 tabular-nums",
312
+ children: [
313
+ page,
314
+ " / ",
315
+ totalPages
316
+ ]
317
+ }),
318
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
319
+ type: "button",
320
+ className: "p-1 rounded text-sand-400 hover:text-sand-600 disabled:opacity-30 transition-colors",
321
+ disabled: page === totalPages,
322
+ onClick: () => setPage((p) => p + 1),
323
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(lucideChevronRight, { className: "size-4" })
324
+ })
325
+ ]
326
+ })] })] });
327
+ }
328
+ //#endregion
329
+ //#region ../../node_modules/.pnpm/@dnd-kit+utilities@3.2.2_react@19.2.4/node_modules/@dnd-kit/utilities/dist/utilities.esm.js
330
+ var import_react_dom = /* @__PURE__ */ __toESM(require_react_dom());
331
+ function useCombinedRefs() {
332
+ for (var _len = arguments.length, refs = new Array(_len), _key = 0; _key < _len; _key++) refs[_key] = arguments[_key];
333
+ return (0, import_react.useMemo)(() => (node) => {
334
+ refs.forEach((ref) => ref(node));
335
+ }, refs);
336
+ }
337
+ var canUseDOM = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
338
+ function isWindow(element) {
339
+ const elementString = Object.prototype.toString.call(element);
340
+ return elementString === "[object Window]" || elementString === "[object global]";
341
+ }
342
+ function isNode(node) {
343
+ return "nodeType" in node;
344
+ }
345
+ function getWindow(target) {
346
+ var _target$ownerDocument, _target$ownerDocument2;
347
+ if (!target) return window;
348
+ if (isWindow(target)) return target;
349
+ if (!isNode(target)) return window;
350
+ return (_target$ownerDocument = (_target$ownerDocument2 = target.ownerDocument) == null ? void 0 : _target$ownerDocument2.defaultView) != null ? _target$ownerDocument : window;
351
+ }
352
+ function isDocument(node) {
353
+ const { Document } = getWindow(node);
354
+ return node instanceof Document;
355
+ }
356
+ function isHTMLElement(node) {
357
+ if (isWindow(node)) return false;
358
+ return node instanceof getWindow(node).HTMLElement;
359
+ }
360
+ function isSVGElement(node) {
361
+ return node instanceof getWindow(node).SVGElement;
362
+ }
363
+ function getOwnerDocument(target) {
364
+ if (!target) return document;
365
+ if (isWindow(target)) return target.document;
366
+ if (!isNode(target)) return document;
367
+ if (isDocument(target)) return target;
368
+ if (isHTMLElement(target) || isSVGElement(target)) return target.ownerDocument;
369
+ return document;
370
+ }
371
+ /**
372
+ * A hook that resolves to useEffect on the server and useLayoutEffect on the client
373
+ * @param callback {function} Callback function that is invoked when the dependencies of the hook change
374
+ */
375
+ var useIsomorphicLayoutEffect = canUseDOM ? import_react.useLayoutEffect : import_react.useEffect;
376
+ function useEvent(handler) {
377
+ const handlerRef = (0, import_react.useRef)(handler);
378
+ useIsomorphicLayoutEffect(() => {
379
+ handlerRef.current = handler;
380
+ });
381
+ return (0, import_react.useCallback)(function() {
382
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) args[_key] = arguments[_key];
383
+ return handlerRef.current == null ? void 0 : handlerRef.current(...args);
384
+ }, []);
385
+ }
386
+ function useInterval() {
387
+ const intervalRef = (0, import_react.useRef)(null);
388
+ return [(0, import_react.useCallback)((listener, duration) => {
389
+ intervalRef.current = setInterval(listener, duration);
390
+ }, []), (0, import_react.useCallback)(() => {
391
+ if (intervalRef.current !== null) {
392
+ clearInterval(intervalRef.current);
393
+ intervalRef.current = null;
394
+ }
395
+ }, [])];
396
+ }
397
+ function useLazyMemo(callback, dependencies) {
398
+ const valueRef = (0, import_react.useRef)();
399
+ return (0, import_react.useMemo)(() => {
400
+ const newValue = callback(valueRef.current);
401
+ valueRef.current = newValue;
402
+ return newValue;
403
+ }, [...dependencies]);
404
+ }
405
+ function useNodeRef(onChange) {
406
+ const onChangeHandler = useEvent(onChange);
407
+ const node = (0, import_react.useRef)(null);
408
+ return [node, (0, import_react.useCallback)((element) => {
409
+ if (element !== node.current) onChangeHandler?.(element, node.current);
410
+ node.current = element;
411
+ }, [])];
412
+ }
413
+ var ids = {};
414
+ function useUniqueId(prefix, value) {
415
+ return (0, import_react.useMemo)(() => {
416
+ if (value) return value;
417
+ const id = ids[prefix] == null ? 0 : ids[prefix] + 1;
418
+ ids[prefix] = id;
419
+ return prefix + "-" + id;
420
+ }, [prefix, value]);
421
+ }
422
+ function createAdjustmentFn(modifier) {
423
+ return function(object) {
424
+ for (var _len = arguments.length, adjustments = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) adjustments[_key - 1] = arguments[_key];
425
+ return adjustments.reduce((accumulator, adjustment) => {
426
+ const entries = Object.entries(adjustment);
427
+ for (const [key, valueAdjustment] of entries) {
428
+ const value = accumulator[key];
429
+ if (value != null) accumulator[key] = value + modifier * valueAdjustment;
430
+ }
431
+ return accumulator;
432
+ }, { ...object });
433
+ };
434
+ }
435
+ var add = /* @__PURE__ */ createAdjustmentFn(1);
436
+ var subtract = /* @__PURE__ */ createAdjustmentFn(-1);
437
+ function hasViewportRelativeCoordinates(event) {
438
+ return "clientX" in event && "clientY" in event;
439
+ }
440
+ function isKeyboardEvent(event) {
441
+ if (!event) return false;
442
+ const { KeyboardEvent } = getWindow(event.target);
443
+ return KeyboardEvent && event instanceof KeyboardEvent;
444
+ }
445
+ function isTouchEvent(event) {
446
+ if (!event) return false;
447
+ const { TouchEvent } = getWindow(event.target);
448
+ return TouchEvent && event instanceof TouchEvent;
449
+ }
450
+ /**
451
+ * Returns the normalized x and y coordinates for mouse and touch events.
452
+ */
453
+ function getEventCoordinates(event) {
454
+ if (isTouchEvent(event)) {
455
+ if (event.touches && event.touches.length) {
456
+ const { clientX: x, clientY: y } = event.touches[0];
457
+ return {
458
+ x,
459
+ y
460
+ };
461
+ } else if (event.changedTouches && event.changedTouches.length) {
462
+ const { clientX: x, clientY: y } = event.changedTouches[0];
463
+ return {
464
+ x,
465
+ y
466
+ };
467
+ }
468
+ }
469
+ if (hasViewportRelativeCoordinates(event)) return {
470
+ x: event.clientX,
471
+ y: event.clientY
472
+ };
473
+ return null;
474
+ }
475
+ var CSS = /* @__PURE__ */ Object.freeze({
476
+ Translate: { toString(transform) {
477
+ if (!transform) return;
478
+ const { x, y } = transform;
479
+ return "translate3d(" + (x ? Math.round(x) : 0) + "px, " + (y ? Math.round(y) : 0) + "px, 0)";
480
+ } },
481
+ Scale: { toString(transform) {
482
+ if (!transform) return;
483
+ const { scaleX, scaleY } = transform;
484
+ return "scaleX(" + scaleX + ") scaleY(" + scaleY + ")";
485
+ } },
486
+ Transform: { toString(transform) {
487
+ if (!transform) return;
488
+ return [CSS.Translate.toString(transform), CSS.Scale.toString(transform)].join(" ");
489
+ } },
490
+ Transition: { toString(_ref) {
491
+ let { property, duration, easing } = _ref;
492
+ return property + " " + duration + "ms " + easing;
493
+ } }
494
+ });
495
+ //#endregion
496
+ //#region ../../node_modules/.pnpm/@dnd-kit+accessibility@3.1.1_react@19.2.4/node_modules/@dnd-kit/accessibility/dist/accessibility.esm.js
497
+ var hiddenStyles = { display: "none" };
498
+ function HiddenText(_ref) {
499
+ let { id, value } = _ref;
500
+ return import_react.createElement("div", {
501
+ id,
502
+ style: hiddenStyles
503
+ }, value);
504
+ }
505
+ function LiveRegion(_ref) {
506
+ let { id, announcement, ariaLiveType = "assertive" } = _ref;
507
+ return import_react.createElement("div", {
508
+ id,
509
+ style: {
510
+ position: "fixed",
511
+ top: 0,
512
+ left: 0,
513
+ width: 1,
514
+ height: 1,
515
+ margin: -1,
516
+ border: 0,
517
+ padding: 0,
518
+ overflow: "hidden",
519
+ clip: "rect(0 0 0 0)",
520
+ clipPath: "inset(100%)",
521
+ whiteSpace: "nowrap"
522
+ },
523
+ role: "status",
524
+ "aria-live": ariaLiveType,
525
+ "aria-atomic": true
526
+ }, announcement);
527
+ }
528
+ function useAnnouncement() {
529
+ const [announcement, setAnnouncement] = (0, import_react.useState)("");
530
+ return {
531
+ announce: (0, import_react.useCallback)((value) => {
532
+ if (value != null) setAnnouncement(value);
533
+ }, []),
534
+ announcement
535
+ };
536
+ }
537
+ //#endregion
538
+ //#region ../../node_modules/.pnpm/@dnd-kit+core@4.0.3_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@dnd-kit/core/dist/core.esm.js
539
+ var screenReaderInstructions = { draggable: `
540
+ To pick up a draggable item, press the space bar.
541
+ While dragging, use the arrow keys to move the item.
542
+ Press space again to drop the item in its new position, or press escape to cancel.
543
+ ` };
544
+ var defaultAnnouncements = {
545
+ onDragStart(id) {
546
+ return `Picked up draggable item ${id}.`;
547
+ },
548
+ onDragOver(id, overId) {
549
+ if (overId) return `Draggable item ${id} was moved over droppable area ${overId}.`;
550
+ return `Draggable item ${id} is no longer over a droppable area.`;
551
+ },
552
+ onDragEnd(id, overId) {
553
+ if (overId) return `Draggable item ${id} was dropped over droppable area ${overId}`;
554
+ return `Draggable item ${id} was dropped.`;
555
+ },
556
+ onDragCancel(id) {
557
+ return `Dragging was cancelled. Draggable item ${id} was dropped.`;
558
+ }
559
+ };
560
+ var Action;
561
+ (function(Action) {
562
+ Action["DragStart"] = "dragStart";
563
+ Action["DragMove"] = "dragMove";
564
+ Action["DragEnd"] = "dragEnd";
565
+ Action["DragCancel"] = "dragCancel";
566
+ Action["DragOver"] = "dragOver";
567
+ Action["RegisterDroppable"] = "registerDroppable";
568
+ Action["SetDroppableDisabled"] = "setDroppableDisabled";
569
+ Action["UnregisterDroppable"] = "unregisterDroppable";
570
+ })(Action || (Action = {}));
571
+ function noop(..._args) {}
572
+ var DroppableContainersMap = class extends Map {
573
+ get(id) {
574
+ var _super$get;
575
+ return id != null ? (_super$get = super.get(id)) != null ? _super$get : void 0 : void 0;
576
+ }
577
+ toArray() {
578
+ return Array.from(this.values());
579
+ }
580
+ getEnabled() {
581
+ return this.toArray().filter(({ disabled }) => !disabled);
582
+ }
583
+ getNodeFor(id) {
584
+ var _this$get$node$curren, _this$get;
585
+ return (_this$get$node$curren = (_this$get = this.get(id)) == null ? void 0 : _this$get.node.current) != null ? _this$get$node$curren : void 0;
586
+ }
587
+ };
588
+ var Context$1 = /* @__PURE__ */ (0, import_react.createContext)({
589
+ activatorEvent: null,
590
+ active: null,
591
+ activeNode: null,
592
+ activeNodeRect: null,
593
+ activeNodeClientRect: null,
594
+ activators: [],
595
+ ariaDescribedById: { draggable: "" },
596
+ containerNodeRect: null,
597
+ dispatch: noop,
598
+ draggableNodes: {},
599
+ droppableRects: /* @__PURE__ */ new Map(),
600
+ droppableContainers: /* @__PURE__ */ new DroppableContainersMap(),
601
+ over: null,
602
+ dragOverlay: {
603
+ nodeRef: { current: null },
604
+ rect: null,
605
+ setRef: noop
606
+ },
607
+ scrollableAncestors: [],
608
+ scrollableAncestorRects: [],
609
+ recomputeLayouts: noop,
610
+ windowRect: null,
611
+ willRecomputeLayouts: false
612
+ });
613
+ function getInitialState() {
614
+ return {
615
+ draggable: {
616
+ active: null,
617
+ initialCoordinates: {
618
+ x: 0,
619
+ y: 0
620
+ },
621
+ nodes: {},
622
+ translate: {
623
+ x: 0,
624
+ y: 0
625
+ }
626
+ },
627
+ droppable: { containers: new DroppableContainersMap() }
628
+ };
629
+ }
630
+ function reducer(state, action) {
631
+ switch (action.type) {
632
+ case Action.DragStart: return {
633
+ ...state,
634
+ draggable: {
635
+ ...state.draggable,
636
+ initialCoordinates: action.initialCoordinates,
637
+ active: action.active
638
+ }
639
+ };
640
+ case Action.DragMove:
641
+ if (!state.draggable.active) return state;
642
+ return {
643
+ ...state,
644
+ draggable: {
645
+ ...state.draggable,
646
+ translate: {
647
+ x: action.coordinates.x - state.draggable.initialCoordinates.x,
648
+ y: action.coordinates.y - state.draggable.initialCoordinates.y
649
+ }
650
+ }
651
+ };
652
+ case Action.DragEnd:
653
+ case Action.DragCancel: return {
654
+ ...state,
655
+ draggable: {
656
+ ...state.draggable,
657
+ active: null,
658
+ initialCoordinates: {
659
+ x: 0,
660
+ y: 0
661
+ },
662
+ translate: {
663
+ x: 0,
664
+ y: 0
665
+ }
666
+ }
667
+ };
668
+ case Action.RegisterDroppable: {
669
+ const { element } = action;
670
+ const { id } = element;
671
+ const containers = new DroppableContainersMap(state.droppable.containers);
672
+ containers.set(id, element);
673
+ return {
674
+ ...state,
675
+ droppable: {
676
+ ...state.droppable,
677
+ containers
678
+ }
679
+ };
680
+ }
681
+ case Action.SetDroppableDisabled: {
682
+ const { id, key, disabled } = action;
683
+ const element = state.droppable.containers.get(id);
684
+ if (!element || key !== element.key) return state;
685
+ const containers = new DroppableContainersMap(state.droppable.containers);
686
+ containers.set(id, {
687
+ ...element,
688
+ disabled
689
+ });
690
+ return {
691
+ ...state,
692
+ droppable: {
693
+ ...state.droppable,
694
+ containers
695
+ }
696
+ };
697
+ }
698
+ case Action.UnregisterDroppable: {
699
+ const { id, key } = action;
700
+ const element = state.droppable.containers.get(id);
701
+ if (!element || key !== element.key) return state;
702
+ const containers = new DroppableContainersMap(state.droppable.containers);
703
+ containers.delete(id);
704
+ return {
705
+ ...state,
706
+ droppable: {
707
+ ...state.droppable,
708
+ containers
709
+ }
710
+ };
711
+ }
712
+ default: return state;
713
+ }
714
+ }
715
+ var DndMonitorContext = /* @__PURE__ */ (0, import_react.createContext)({
716
+ type: null,
717
+ event: null
718
+ });
719
+ function useDndMonitor({ onDragStart, onDragMove, onDragOver, onDragEnd, onDragCancel }) {
720
+ const monitorState = (0, import_react.useContext)(DndMonitorContext);
721
+ const previousMonitorState = (0, import_react.useRef)(monitorState);
722
+ (0, import_react.useEffect)(() => {
723
+ if (monitorState !== previousMonitorState.current) {
724
+ const { type, event } = monitorState;
725
+ switch (type) {
726
+ case Action.DragStart:
727
+ onDragStart?.(event);
728
+ break;
729
+ case Action.DragMove:
730
+ onDragMove?.(event);
731
+ break;
732
+ case Action.DragOver:
733
+ onDragOver?.(event);
734
+ break;
735
+ case Action.DragCancel:
736
+ onDragCancel?.(event);
737
+ break;
738
+ case Action.DragEnd:
739
+ onDragEnd?.(event);
740
+ break;
741
+ }
742
+ previousMonitorState.current = monitorState;
743
+ }
744
+ }, [
745
+ monitorState,
746
+ onDragStart,
747
+ onDragMove,
748
+ onDragOver,
749
+ onDragEnd,
750
+ onDragCancel
751
+ ]);
752
+ }
753
+ function Accessibility({ announcements = defaultAnnouncements, hiddenTextDescribedById, screenReaderInstructions }) {
754
+ const { announce, announcement } = useAnnouncement();
755
+ const liveRegionId = useUniqueId(`DndLiveRegion`);
756
+ const [mounted, setMounted] = (0, import_react.useState)(false);
757
+ (0, import_react.useEffect)(() => {
758
+ setMounted(true);
759
+ }, []);
760
+ useDndMonitor((0, import_react.useMemo)(() => ({
761
+ onDragStart({ active }) {
762
+ announce(announcements.onDragStart(active.id));
763
+ },
764
+ onDragMove({ active, over }) {
765
+ if (announcements.onDragMove) announce(announcements.onDragMove(active.id, over == null ? void 0 : over.id));
766
+ },
767
+ onDragOver({ active, over }) {
768
+ announce(announcements.onDragOver(active.id, over == null ? void 0 : over.id));
769
+ },
770
+ onDragEnd({ active, over }) {
771
+ announce(announcements.onDragEnd(active.id, over == null ? void 0 : over.id));
772
+ },
773
+ onDragCancel({ active }) {
774
+ announce(announcements.onDragCancel(active.id));
775
+ }
776
+ }), [announce, announcements]));
777
+ return mounted ? (0, import_react_dom.createPortal)(import_react.createElement(import_react.Fragment, null, import_react.createElement(HiddenText, {
778
+ id: hiddenTextDescribedById,
779
+ value: screenReaderInstructions.draggable
780
+ }), import_react.createElement(LiveRegion, {
781
+ id: liveRegionId,
782
+ announcement
783
+ })), document.body) : null;
784
+ }
785
+ var defaultCoordinates = /* @__PURE__ */ Object.freeze({
786
+ x: 0,
787
+ y: 0
788
+ });
789
+ /**
790
+ * Returns the distance between two points
791
+ */
792
+ function distanceBetween(p1, p2) {
793
+ return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
794
+ }
795
+ /**
796
+ * Returns the coordinates of the center of a given ClientRect
797
+ */
798
+ function centerOfRectangle(rect, left = rect.offsetLeft, top = rect.offsetTop) {
799
+ return {
800
+ x: left + rect.width * .5,
801
+ y: top + rect.height * .5
802
+ };
803
+ }
804
+ /**
805
+ * Returns the closest rectangle from an array of rectangles to the center of a given
806
+ * rectangle.
807
+ */
808
+ var closestCenter = ({ collisionRect, droppableContainers }) => {
809
+ const centerRect = centerOfRectangle(collisionRect, collisionRect.left, collisionRect.top);
810
+ let minDistanceToCenter = Infinity;
811
+ let minDroppableContainer = null;
812
+ for (const droppableContainer of droppableContainers) {
813
+ const { rect: { current: rect } } = droppableContainer;
814
+ if (rect) {
815
+ const distBetween = distanceBetween(centerOfRectangle(rect), centerRect);
816
+ if (distBetween < minDistanceToCenter) {
817
+ minDistanceToCenter = distBetween;
818
+ minDroppableContainer = droppableContainer.id;
819
+ }
820
+ }
821
+ }
822
+ return minDroppableContainer;
823
+ };
824
+ function adjustScale(transform, rect1, rect2) {
825
+ return {
826
+ ...transform,
827
+ scaleX: rect1 && rect2 ? rect1.width / rect2.width : 1,
828
+ scaleY: rect1 && rect2 ? rect1.height / rect2.height : 1
829
+ };
830
+ }
831
+ function getRectDelta(rect1, rect2) {
832
+ return rect1 && rect2 ? {
833
+ x: rect1.left - rect2.left,
834
+ y: rect1.top - rect2.top
835
+ } : defaultCoordinates;
836
+ }
837
+ function createRectAdjustmentFn(modifier) {
838
+ return function adjustViewRect(viewRect, ...adjustments) {
839
+ return adjustments.reduce((acc, adjustment) => ({
840
+ ...acc,
841
+ top: acc.top + modifier * adjustment.y,
842
+ bottom: acc.bottom + modifier * adjustment.y,
843
+ left: acc.left + modifier * adjustment.x,
844
+ right: acc.right + modifier * adjustment.x,
845
+ offsetLeft: acc.offsetLeft + modifier * adjustment.x,
846
+ offsetTop: acc.offsetTop + modifier * adjustment.y
847
+ }), { ...viewRect });
848
+ };
849
+ }
850
+ var getAdjustedRect = /* @__PURE__ */ createRectAdjustmentFn(1);
851
+ function isFixed(node, computedStyle = window.getComputedStyle(node)) {
852
+ return computedStyle.position === "fixed";
853
+ }
854
+ function isScrollable(node, computedStyle = window.getComputedStyle(node)) {
855
+ const overflowRegex = /(auto|scroll|overlay)/;
856
+ return [
857
+ "overflow",
858
+ "overflowX",
859
+ "overflowY"
860
+ ].find((property) => {
861
+ const value = computedStyle[property];
862
+ return typeof value === "string" ? overflowRegex.test(value) : false;
863
+ }) != null;
864
+ }
865
+ function getScrollableAncestors(element) {
866
+ const scrollParents = [];
867
+ function findScrollableAncestors(node) {
868
+ if (!node) return scrollParents;
869
+ if (isDocument(node) && node.scrollingElement != null && !scrollParents.includes(node.scrollingElement)) {
870
+ scrollParents.push(node.scrollingElement);
871
+ return scrollParents;
872
+ }
873
+ if (!isHTMLElement(node) || isSVGElement(node)) return scrollParents;
874
+ if (scrollParents.includes(node)) return scrollParents;
875
+ const computedStyle = window.getComputedStyle(node);
876
+ if (isScrollable(node, computedStyle)) scrollParents.push(node);
877
+ if (isFixed(node, computedStyle)) return scrollParents;
878
+ return findScrollableAncestors(node.parentNode);
879
+ }
880
+ return element ? findScrollableAncestors(element.parentNode) : scrollParents;
881
+ }
882
+ function getScrollableElement(element) {
883
+ if (!canUseDOM || !element) return null;
884
+ if (isWindow(element)) return element;
885
+ if (!isNode(element)) return null;
886
+ if (isDocument(element) || element === getOwnerDocument(element).scrollingElement) return window;
887
+ if (isHTMLElement(element)) return element;
888
+ return null;
889
+ }
890
+ function getScrollCoordinates(element) {
891
+ if (isWindow(element)) return {
892
+ x: element.scrollX,
893
+ y: element.scrollY
894
+ };
895
+ return {
896
+ x: element.scrollLeft,
897
+ y: element.scrollTop
898
+ };
899
+ }
900
+ var Direction;
901
+ (function(Direction) {
902
+ Direction[Direction["Forward"] = 1] = "Forward";
903
+ Direction[Direction["Backward"] = -1] = "Backward";
904
+ })(Direction || (Direction = {}));
905
+ function getScrollPosition(scrollingContainer) {
906
+ const minScroll = {
907
+ x: 0,
908
+ y: 0
909
+ };
910
+ const maxScroll = {
911
+ x: scrollingContainer.scrollWidth - scrollingContainer.clientWidth,
912
+ y: scrollingContainer.scrollHeight - scrollingContainer.clientHeight
913
+ };
914
+ return {
915
+ isTop: scrollingContainer.scrollTop <= minScroll.y,
916
+ isLeft: scrollingContainer.scrollLeft <= minScroll.x,
917
+ isBottom: scrollingContainer.scrollTop >= maxScroll.y,
918
+ isRight: scrollingContainer.scrollLeft >= maxScroll.x,
919
+ maxScroll,
920
+ minScroll
921
+ };
922
+ }
923
+ function isDocumentScrollingElement(element) {
924
+ if (!canUseDOM || !element) return false;
925
+ return element === document.scrollingElement;
926
+ }
927
+ var defaultThreshold = {
928
+ x: .2,
929
+ y: .2
930
+ };
931
+ function getScrollDirectionAndSpeed(scrollContainer, scrollContainerRect, { top, left, right, bottom }, acceleration = 10, thresholdPercentage = defaultThreshold) {
932
+ const { clientHeight, clientWidth } = scrollContainer;
933
+ const finalScrollContainerRect = isDocumentScrollingElement(scrollContainer) ? {
934
+ top: 0,
935
+ left: 0,
936
+ right: clientWidth,
937
+ bottom: clientHeight,
938
+ width: clientWidth,
939
+ height: clientHeight
940
+ } : scrollContainerRect;
941
+ const { isTop, isBottom, isLeft, isRight } = getScrollPosition(scrollContainer);
942
+ const direction = {
943
+ x: 0,
944
+ y: 0
945
+ };
946
+ const speed = {
947
+ x: 0,
948
+ y: 0
949
+ };
950
+ const threshold = {
951
+ height: finalScrollContainerRect.height * thresholdPercentage.y,
952
+ width: finalScrollContainerRect.width * thresholdPercentage.x
953
+ };
954
+ if (!isTop && top <= finalScrollContainerRect.top + threshold.height) {
955
+ direction.y = Direction.Backward;
956
+ speed.y = acceleration * Math.abs((finalScrollContainerRect.top + threshold.height - top) / threshold.height);
957
+ } else if (!isBottom && bottom >= finalScrollContainerRect.bottom - threshold.height) {
958
+ direction.y = Direction.Forward;
959
+ speed.y = acceleration * Math.abs((finalScrollContainerRect.bottom - threshold.height - bottom) / threshold.height);
960
+ }
961
+ if (!isRight && right >= finalScrollContainerRect.right - threshold.width) {
962
+ direction.x = Direction.Forward;
963
+ speed.x = acceleration * Math.abs((finalScrollContainerRect.right - threshold.width - right) / threshold.width);
964
+ } else if (!isLeft && left <= finalScrollContainerRect.left + threshold.width) {
965
+ direction.x = Direction.Backward;
966
+ speed.x = acceleration * Math.abs((finalScrollContainerRect.left + threshold.width - left) / threshold.width);
967
+ }
968
+ return {
969
+ direction,
970
+ speed
971
+ };
972
+ }
973
+ function getScrollElementRect(element) {
974
+ if (element === document.scrollingElement) {
975
+ const { innerWidth, innerHeight } = window;
976
+ return {
977
+ top: 0,
978
+ left: 0,
979
+ right: innerWidth,
980
+ bottom: innerHeight,
981
+ width: innerWidth,
982
+ height: innerHeight
983
+ };
984
+ }
985
+ const { top, left, right, bottom } = element.getBoundingClientRect();
986
+ return {
987
+ top,
988
+ left,
989
+ right,
990
+ bottom,
991
+ width: element.clientWidth,
992
+ height: element.clientHeight
993
+ };
994
+ }
995
+ function getScrollOffsets(scrollableAncestors) {
996
+ return scrollableAncestors.reduce((acc, node) => {
997
+ return add(acc, getScrollCoordinates(node));
998
+ }, defaultCoordinates);
999
+ }
1000
+ function getEdgeOffset(node, parent, offset = defaultCoordinates) {
1001
+ if (!node || !isHTMLElement(node)) return offset;
1002
+ const nodeOffset = {
1003
+ x: offset.x + node.offsetLeft,
1004
+ y: offset.y + node.offsetTop
1005
+ };
1006
+ if (node.offsetParent === parent) return nodeOffset;
1007
+ return getEdgeOffset(node.offsetParent, parent, nodeOffset);
1008
+ }
1009
+ function getLayoutRect(element) {
1010
+ const { offsetWidth: width, offsetHeight: height } = element;
1011
+ const { x: offsetLeft, y: offsetTop } = getEdgeOffset(element, null);
1012
+ return {
1013
+ width,
1014
+ height,
1015
+ offsetTop,
1016
+ offsetLeft
1017
+ };
1018
+ }
1019
+ function getBoundingClientRect(element) {
1020
+ if (isWindow(element)) {
1021
+ const width = window.innerWidth;
1022
+ const height = window.innerHeight;
1023
+ return {
1024
+ top: 0,
1025
+ left: 0,
1026
+ right: width,
1027
+ bottom: height,
1028
+ width,
1029
+ height,
1030
+ offsetTop: 0,
1031
+ offsetLeft: 0
1032
+ };
1033
+ }
1034
+ const { offsetTop, offsetLeft } = getLayoutRect(element);
1035
+ const { width, height, top, bottom, left, right } = element.getBoundingClientRect();
1036
+ return {
1037
+ width,
1038
+ height,
1039
+ top,
1040
+ bottom,
1041
+ right,
1042
+ left,
1043
+ offsetTop,
1044
+ offsetLeft
1045
+ };
1046
+ }
1047
+ function getViewRect(element) {
1048
+ const { width, height, offsetTop, offsetLeft } = getLayoutRect(element);
1049
+ const scrollOffsets = getScrollOffsets(getScrollableAncestors(element));
1050
+ const top = offsetTop - scrollOffsets.y;
1051
+ const left = offsetLeft - scrollOffsets.x;
1052
+ return {
1053
+ width,
1054
+ height,
1055
+ top,
1056
+ bottom: top + height,
1057
+ right: left + width,
1058
+ left,
1059
+ offsetTop,
1060
+ offsetLeft
1061
+ };
1062
+ }
1063
+ /**
1064
+ * Returns the intersecting rectangle area between two rectangles
1065
+ */
1066
+ function getIntersectionRatio(entry, target) {
1067
+ const top = Math.max(target.top, entry.offsetTop);
1068
+ const left = Math.max(target.left, entry.offsetLeft);
1069
+ const right = Math.min(target.left + target.width, entry.offsetLeft + entry.width);
1070
+ const bottom = Math.min(target.top + target.height, entry.offsetTop + entry.height);
1071
+ const width = right - left;
1072
+ const height = bottom - top;
1073
+ if (left < right && top < bottom) {
1074
+ const targetArea = target.width * target.height;
1075
+ const entryArea = entry.width * entry.height;
1076
+ const intersectionArea = width * height;
1077
+ const intersectionRatio = intersectionArea / (targetArea + entryArea - intersectionArea);
1078
+ return Number(intersectionRatio.toFixed(4));
1079
+ }
1080
+ return 0;
1081
+ }
1082
+ /**
1083
+ * Returns the rectangle that has the greatest intersection area with a given
1084
+ * rectangle in an array of rectangles.
1085
+ */
1086
+ var rectIntersection = ({ collisionRect, droppableContainers }) => {
1087
+ let maxIntersectionRatio = 0;
1088
+ let maxIntersectingDroppableContainer = null;
1089
+ for (const droppableContainer of droppableContainers) {
1090
+ const { rect: { current: rect } } = droppableContainer;
1091
+ if (rect) {
1092
+ const intersectionRatio = getIntersectionRatio(rect, collisionRect);
1093
+ if (intersectionRatio > maxIntersectionRatio) {
1094
+ maxIntersectionRatio = intersectionRatio;
1095
+ maxIntersectingDroppableContainer = droppableContainer.id;
1096
+ }
1097
+ }
1098
+ }
1099
+ return maxIntersectingDroppableContainer;
1100
+ };
1101
+ var AutoScrollActivator;
1102
+ (function(AutoScrollActivator) {
1103
+ AutoScrollActivator[AutoScrollActivator["Pointer"] = 0] = "Pointer";
1104
+ AutoScrollActivator[AutoScrollActivator["DraggableRect"] = 1] = "DraggableRect";
1105
+ })(AutoScrollActivator || (AutoScrollActivator = {}));
1106
+ var TraversalOrder;
1107
+ (function(TraversalOrder) {
1108
+ TraversalOrder[TraversalOrder["TreeOrder"] = 0] = "TreeOrder";
1109
+ TraversalOrder[TraversalOrder["ReversedTreeOrder"] = 1] = "ReversedTreeOrder";
1110
+ })(TraversalOrder || (TraversalOrder = {}));
1111
+ function useAutoScroller({ acceleration, activator = AutoScrollActivator.Pointer, canScroll, draggingRect, enabled, interval = 5, order = TraversalOrder.TreeOrder, pointerCoordinates, scrollableAncestors, scrollableAncestorRects, threshold }) {
1112
+ const [setAutoScrollInterval, clearAutoScrollInterval] = useInterval();
1113
+ const scrollSpeed = (0, import_react.useRef)({
1114
+ x: 1,
1115
+ y: 1
1116
+ });
1117
+ const rect = (0, import_react.useMemo)(() => {
1118
+ switch (activator) {
1119
+ case AutoScrollActivator.Pointer: return pointerCoordinates ? {
1120
+ top: pointerCoordinates.y,
1121
+ bottom: pointerCoordinates.y,
1122
+ left: pointerCoordinates.x,
1123
+ right: pointerCoordinates.x
1124
+ } : null;
1125
+ case AutoScrollActivator.DraggableRect: return draggingRect;
1126
+ }
1127
+ return null;
1128
+ }, [
1129
+ activator,
1130
+ draggingRect,
1131
+ pointerCoordinates
1132
+ ]);
1133
+ const scrollDirection = (0, import_react.useRef)(defaultCoordinates);
1134
+ const scrollContainerRef = (0, import_react.useRef)(null);
1135
+ const autoScroll = (0, import_react.useCallback)(() => {
1136
+ const scrollContainer = scrollContainerRef.current;
1137
+ if (!scrollContainer) return;
1138
+ const scrollLeft = scrollSpeed.current.x * scrollDirection.current.x;
1139
+ const scrollTop = scrollSpeed.current.y * scrollDirection.current.y;
1140
+ scrollContainer.scrollBy(scrollLeft, scrollTop);
1141
+ }, []);
1142
+ const sortedScrollableAncestors = (0, import_react.useMemo)(() => order === TraversalOrder.TreeOrder ? [...scrollableAncestors].reverse() : scrollableAncestors, [order, scrollableAncestors]);
1143
+ (0, import_react.useEffect)(() => {
1144
+ if (!enabled || !scrollableAncestors.length || !rect) {
1145
+ clearAutoScrollInterval();
1146
+ return;
1147
+ }
1148
+ for (const scrollContainer of sortedScrollableAncestors) {
1149
+ if ((canScroll == null ? void 0 : canScroll(scrollContainer)) === false) continue;
1150
+ const scrolllContainerRect = scrollableAncestorRects[scrollableAncestors.indexOf(scrollContainer)];
1151
+ if (!scrolllContainerRect) continue;
1152
+ const { direction, speed } = getScrollDirectionAndSpeed(scrollContainer, scrolllContainerRect, rect, acceleration, threshold);
1153
+ if (speed.x > 0 || speed.y > 0) {
1154
+ clearAutoScrollInterval();
1155
+ scrollContainerRef.current = scrollContainer;
1156
+ setAutoScrollInterval(autoScroll, interval);
1157
+ scrollSpeed.current = speed;
1158
+ scrollDirection.current = direction;
1159
+ return;
1160
+ }
1161
+ }
1162
+ scrollSpeed.current = {
1163
+ x: 0,
1164
+ y: 0
1165
+ };
1166
+ scrollDirection.current = {
1167
+ x: 0,
1168
+ y: 0
1169
+ };
1170
+ clearAutoScrollInterval();
1171
+ }, [
1172
+ acceleration,
1173
+ autoScroll,
1174
+ canScroll,
1175
+ clearAutoScrollInterval,
1176
+ enabled,
1177
+ interval,
1178
+ JSON.stringify(rect),
1179
+ setAutoScrollInterval,
1180
+ scrollableAncestors,
1181
+ sortedScrollableAncestors,
1182
+ scrollableAncestorRects,
1183
+ JSON.stringify(threshold)
1184
+ ]);
1185
+ }
1186
+ function useCachedNode(draggableNodes, id) {
1187
+ const draggableNode = id !== null ? draggableNodes[id] : void 0;
1188
+ const node = draggableNode ? draggableNode.node.current : null;
1189
+ return useLazyMemo((cachedNode) => {
1190
+ var _ref;
1191
+ if (id === null) return null;
1192
+ return (_ref = node != null ? node : cachedNode) != null ? _ref : null;
1193
+ }, [node, id]);
1194
+ }
1195
+ function useCombineActivators(sensors, getSyntheticHandler) {
1196
+ return (0, import_react.useMemo)(() => sensors.reduce((accumulator, sensor) => {
1197
+ const { sensor: Sensor } = sensor;
1198
+ const sensorActivators = Sensor.activators.map((activator) => ({
1199
+ eventName: activator.eventName,
1200
+ handler: getSyntheticHandler(activator.handler, sensor)
1201
+ }));
1202
+ return [...accumulator, ...sensorActivators];
1203
+ }, []), [sensors, getSyntheticHandler]);
1204
+ }
1205
+ function useData(data) {
1206
+ const dataRef = (0, import_react.useRef)(data);
1207
+ useIsomorphicLayoutEffect(() => {
1208
+ if (dataRef.current !== data) dataRef.current = data;
1209
+ }, [data]);
1210
+ return dataRef;
1211
+ }
1212
+ var MeasuringStrategy;
1213
+ (function(MeasuringStrategy) {
1214
+ MeasuringStrategy[MeasuringStrategy["Always"] = 0] = "Always";
1215
+ MeasuringStrategy[MeasuringStrategy["BeforeDragging"] = 1] = "BeforeDragging";
1216
+ MeasuringStrategy[MeasuringStrategy["WhileDragging"] = 2] = "WhileDragging";
1217
+ })(MeasuringStrategy || (MeasuringStrategy = {}));
1218
+ var MeasuringFrequency;
1219
+ (function(MeasuringFrequency) {
1220
+ MeasuringFrequency["Optimized"] = "optimized";
1221
+ })(MeasuringFrequency || (MeasuringFrequency = {}));
1222
+ var defaultValue = /* @__PURE__ */ new Map();
1223
+ var defaultConfig = {
1224
+ measure: getLayoutRect,
1225
+ strategy: MeasuringStrategy.WhileDragging,
1226
+ frequency: MeasuringFrequency.Optimized
1227
+ };
1228
+ function useDroppableMeasuring(containers, { dragging, dependencies, config }) {
1229
+ const [willRecomputeLayouts, setWillRecomputeLayouts] = (0, import_react.useState)(false);
1230
+ const { frequency, measure, strategy } = {
1231
+ ...defaultConfig,
1232
+ ...config
1233
+ };
1234
+ const containersRef = (0, import_react.useRef)(containers);
1235
+ const recomputeLayouts = (0, import_react.useCallback)(() => setWillRecomputeLayouts(true), []);
1236
+ const recomputeLayoutsTimeoutId = (0, import_react.useRef)(null);
1237
+ const disabled = isDisabled();
1238
+ const layoutRectMap = useLazyMemo((previousValue) => {
1239
+ if (disabled && !dragging) return defaultValue;
1240
+ if (!previousValue || previousValue === defaultValue || containersRef.current !== containers || willRecomputeLayouts) {
1241
+ for (let container of containers) {
1242
+ if (!container) continue;
1243
+ container.rect.current = container.node.current ? measure(container.node.current) : null;
1244
+ }
1245
+ return createLayoutRectMap(containers);
1246
+ }
1247
+ return previousValue;
1248
+ }, [
1249
+ containers,
1250
+ dragging,
1251
+ disabled,
1252
+ measure,
1253
+ willRecomputeLayouts
1254
+ ]);
1255
+ (0, import_react.useEffect)(() => {
1256
+ containersRef.current = containers;
1257
+ }, [containers]);
1258
+ (0, import_react.useEffect)(() => {
1259
+ if (willRecomputeLayouts) setWillRecomputeLayouts(false);
1260
+ }, [willRecomputeLayouts]);
1261
+ (0, import_react.useEffect)(function recompute() {
1262
+ if (disabled) return;
1263
+ requestAnimationFrame(recomputeLayouts);
1264
+ }, [dragging, disabled]);
1265
+ (0, import_react.useEffect)(function forceRecomputeLayouts() {
1266
+ if (disabled || typeof frequency !== "number" || recomputeLayoutsTimeoutId.current !== null) return;
1267
+ recomputeLayoutsTimeoutId.current = setTimeout(() => {
1268
+ recomputeLayouts();
1269
+ recomputeLayoutsTimeoutId.current = null;
1270
+ }, frequency);
1271
+ }, [
1272
+ frequency,
1273
+ disabled,
1274
+ recomputeLayouts,
1275
+ ...dependencies
1276
+ ]);
1277
+ return {
1278
+ layoutRectMap,
1279
+ recomputeLayouts,
1280
+ willRecomputeLayouts
1281
+ };
1282
+ function isDisabled() {
1283
+ switch (strategy) {
1284
+ case MeasuringStrategy.Always: return false;
1285
+ case MeasuringStrategy.BeforeDragging: return dragging;
1286
+ default: return !dragging;
1287
+ }
1288
+ }
1289
+ }
1290
+ function createLayoutRectMap(containers) {
1291
+ const layoutRectMap = /* @__PURE__ */ new Map();
1292
+ if (containers) for (const container of containers) {
1293
+ if (!container) continue;
1294
+ const { id, rect } = container;
1295
+ if (rect.current == null) continue;
1296
+ layoutRectMap.set(id, rect.current);
1297
+ }
1298
+ return layoutRectMap;
1299
+ }
1300
+ function useScrollOffsets(elements) {
1301
+ const [scrollCoordinates, setScrollCoordinates] = (0, import_react.useState)(null);
1302
+ const prevElements = (0, import_react.useRef)(elements);
1303
+ const handleScroll = (0, import_react.useCallback)((event) => {
1304
+ const scrollingElement = getScrollableElement(event.target);
1305
+ if (!scrollingElement) return;
1306
+ setScrollCoordinates((scrollCoordinates) => {
1307
+ if (!scrollCoordinates) return null;
1308
+ scrollCoordinates.set(scrollingElement, getScrollCoordinates(scrollingElement));
1309
+ return new Map(scrollCoordinates);
1310
+ });
1311
+ }, []);
1312
+ (0, import_react.useEffect)(() => {
1313
+ const previousElements = prevElements.current;
1314
+ if (elements !== previousElements) {
1315
+ cleanup(previousElements);
1316
+ const entries = elements.map((element) => {
1317
+ const scrollableElement = getScrollableElement(element);
1318
+ if (scrollableElement) {
1319
+ scrollableElement.addEventListener("scroll", handleScroll, { passive: true });
1320
+ return [scrollableElement, getScrollCoordinates(scrollableElement)];
1321
+ }
1322
+ return null;
1323
+ }).filter((entry) => entry != null);
1324
+ setScrollCoordinates(entries.length ? new Map(entries) : null);
1325
+ prevElements.current = elements;
1326
+ }
1327
+ return () => {
1328
+ cleanup(elements);
1329
+ cleanup(previousElements);
1330
+ };
1331
+ function cleanup(elements) {
1332
+ elements.forEach((element) => {
1333
+ getScrollableElement(element)?.removeEventListener("scroll", handleScroll);
1334
+ });
1335
+ }
1336
+ }, [handleScroll, elements]);
1337
+ return (0, import_react.useMemo)(() => {
1338
+ if (elements.length) return scrollCoordinates ? Array.from(scrollCoordinates.values()).reduce((acc, coordinates) => add(acc, coordinates), defaultCoordinates) : getScrollOffsets(elements);
1339
+ return defaultCoordinates;
1340
+ }, [elements, scrollCoordinates]);
1341
+ }
1342
+ var defaultValue$1 = [];
1343
+ function useScrollableAncestors(node) {
1344
+ const previousNode = (0, import_react.useRef)(node);
1345
+ const ancestors = useLazyMemo((previousValue) => {
1346
+ if (!node) return defaultValue$1;
1347
+ if (previousValue && node && previousNode.current && node.parentNode === previousNode.current.parentNode) return previousValue;
1348
+ return getScrollableAncestors(node);
1349
+ }, [node]);
1350
+ (0, import_react.useEffect)(() => {
1351
+ previousNode.current = node;
1352
+ }, [node]);
1353
+ return ancestors;
1354
+ }
1355
+ function useSensorSetup(sensors) {
1356
+ (0, import_react.useEffect)(() => {
1357
+ if (!canUseDOM) return;
1358
+ const teardownFns = sensors.map(({ sensor }) => sensor.setup == null ? void 0 : sensor.setup());
1359
+ return () => {
1360
+ for (const teardown of teardownFns) teardown?.();
1361
+ };
1362
+ }, sensors.map(({ sensor }) => sensor));
1363
+ }
1364
+ function useSyntheticListeners(listeners, id) {
1365
+ return (0, import_react.useMemo)(() => {
1366
+ return listeners.reduce((acc, { eventName, handler }) => {
1367
+ acc[eventName] = (event) => {
1368
+ handler(event, id);
1369
+ };
1370
+ return acc;
1371
+ }, {});
1372
+ }, [listeners, id]);
1373
+ }
1374
+ var useClientRect = /* @__PURE__ */ createUseRectFn(getBoundingClientRect);
1375
+ var useClientRects = /* @__PURE__ */ createUseRectsFn(getBoundingClientRect);
1376
+ function useRect(element, getRect, forceRecompute) {
1377
+ const previousElement = (0, import_react.useRef)(element);
1378
+ return useLazyMemo((previousValue) => {
1379
+ if (!element) return null;
1380
+ if (forceRecompute || !previousValue && element || element !== previousElement.current) {
1381
+ if (isHTMLElement(element) && element.parentNode == null) return null;
1382
+ return getRect(element);
1383
+ }
1384
+ return previousValue != null ? previousValue : null;
1385
+ }, [
1386
+ element,
1387
+ forceRecompute,
1388
+ getRect
1389
+ ]);
1390
+ }
1391
+ function createUseRectFn(getRect) {
1392
+ return (element, forceRecompute) => useRect(element, getRect, forceRecompute);
1393
+ }
1394
+ function createUseRectsFn(getRect) {
1395
+ const defaultValue = [];
1396
+ return function useRects(elements, forceRecompute) {
1397
+ const previousElements = (0, import_react.useRef)(elements);
1398
+ return useLazyMemo((previousValue) => {
1399
+ if (!elements.length) return defaultValue;
1400
+ if (forceRecompute || !previousValue && elements.length || elements !== previousElements.current) return elements.map((element) => getRect(element));
1401
+ return previousValue != null ? previousValue : defaultValue;
1402
+ }, [elements, forceRecompute]);
1403
+ };
1404
+ }
1405
+ function getMeasurableNode(node) {
1406
+ if (!node) return null;
1407
+ if (node.children.length > 1) return node;
1408
+ const firstChild = node.children[0];
1409
+ return isHTMLElement(firstChild) ? firstChild : node;
1410
+ }
1411
+ function getDragOverlayRect(element) {
1412
+ const { width, height, offsetLeft, offsetTop } = getLayoutRect(element);
1413
+ return {
1414
+ top: offsetTop,
1415
+ bottom: offsetTop + height,
1416
+ left: offsetLeft,
1417
+ right: offsetLeft + width,
1418
+ width,
1419
+ height,
1420
+ offsetTop,
1421
+ offsetLeft
1422
+ };
1423
+ }
1424
+ var useDragOverlayRect = /* @__PURE__ */ createUseRectFn(getDragOverlayRect);
1425
+ function useDragOverlayMeasuring({ disabled, forceRecompute }) {
1426
+ const [nodeRef, setRef] = useNodeRef();
1427
+ const rect = useDragOverlayRect(disabled ? null : getMeasurableNode(nodeRef.current), forceRecompute);
1428
+ return (0, import_react.useMemo)(() => ({
1429
+ nodeRef,
1430
+ rect,
1431
+ setRef
1432
+ }), [
1433
+ rect,
1434
+ nodeRef,
1435
+ setRef
1436
+ ]);
1437
+ }
1438
+ function useSensor(sensor, options) {
1439
+ return (0, import_react.useMemo)(() => ({
1440
+ sensor,
1441
+ options: options != null ? options : {}
1442
+ }), [sensor, options]);
1443
+ }
1444
+ function useSensors(...sensors) {
1445
+ return (0, import_react.useMemo)(() => [...sensors].filter((sensor) => sensor != null), [...sensors]);
1446
+ }
1447
+ var Listeners = class {
1448
+ constructor(target) {
1449
+ this.target = target;
1450
+ this.listeners = [];
1451
+ this.removeAll = () => {
1452
+ this.listeners.forEach((listener) => {
1453
+ var _this$target;
1454
+ return (_this$target = this.target) == null ? void 0 : _this$target.removeEventListener(...listener);
1455
+ });
1456
+ };
1457
+ }
1458
+ add(eventName, handler, options) {
1459
+ var _this$target2;
1460
+ (_this$target2 = this.target) == null || _this$target2.addEventListener(eventName, handler, options);
1461
+ this.listeners.push([
1462
+ eventName,
1463
+ handler,
1464
+ options
1465
+ ]);
1466
+ }
1467
+ };
1468
+ function getEventListenerTarget(target) {
1469
+ const { EventTarget } = getWindow(target);
1470
+ return target instanceof EventTarget ? target : getOwnerDocument(target);
1471
+ }
1472
+ function hasExceededDistance(delta, measurement) {
1473
+ const dx = Math.abs(delta.x);
1474
+ const dy = Math.abs(delta.y);
1475
+ if (typeof measurement === "number") return Math.sqrt(dx ** 2 + dy ** 2) > measurement;
1476
+ if ("x" in measurement && "y" in measurement) return dx > measurement.x && dy > measurement.y;
1477
+ if ("x" in measurement) return dx > measurement.x;
1478
+ if ("y" in measurement) return dy > measurement.y;
1479
+ return false;
1480
+ }
1481
+ var EventName;
1482
+ (function(EventName) {
1483
+ EventName["Click"] = "click";
1484
+ EventName["DragStart"] = "dragstart";
1485
+ EventName["Keydown"] = "keydown";
1486
+ EventName["ContextMenu"] = "contextmenu";
1487
+ EventName["Resize"] = "resize";
1488
+ EventName["SelectionChange"] = "selectionchange";
1489
+ EventName["VisibilityChange"] = "visibilitychange";
1490
+ })(EventName || (EventName = {}));
1491
+ function preventDefault(event) {
1492
+ event.preventDefault();
1493
+ }
1494
+ function stopPropagation(event) {
1495
+ event.stopPropagation();
1496
+ }
1497
+ var KeyboardCode;
1498
+ (function(KeyboardCode) {
1499
+ KeyboardCode["Space"] = "Space";
1500
+ KeyboardCode["Down"] = "ArrowDown";
1501
+ KeyboardCode["Right"] = "ArrowRight";
1502
+ KeyboardCode["Left"] = "ArrowLeft";
1503
+ KeyboardCode["Up"] = "ArrowUp";
1504
+ KeyboardCode["Esc"] = "Escape";
1505
+ KeyboardCode["Enter"] = "Enter";
1506
+ })(KeyboardCode || (KeyboardCode = {}));
1507
+ var defaultKeyboardCodes = {
1508
+ start: [KeyboardCode.Space, KeyboardCode.Enter],
1509
+ cancel: [KeyboardCode.Esc],
1510
+ end: [KeyboardCode.Space, KeyboardCode.Enter]
1511
+ };
1512
+ var defaultKeyboardCoordinateGetter = (event, { currentCoordinates }) => {
1513
+ switch (event.code) {
1514
+ case KeyboardCode.Right: return {
1515
+ ...currentCoordinates,
1516
+ x: currentCoordinates.x + 25
1517
+ };
1518
+ case KeyboardCode.Left: return {
1519
+ ...currentCoordinates,
1520
+ x: currentCoordinates.x - 25
1521
+ };
1522
+ case KeyboardCode.Down: return {
1523
+ ...currentCoordinates,
1524
+ y: currentCoordinates.y + 25
1525
+ };
1526
+ case KeyboardCode.Up: return {
1527
+ ...currentCoordinates,
1528
+ y: currentCoordinates.y - 25
1529
+ };
1530
+ }
1531
+ };
1532
+ var KeyboardSensor = class {
1533
+ constructor(props) {
1534
+ this.props = props;
1535
+ this.autoScrollEnabled = false;
1536
+ this.coordinates = defaultCoordinates;
1537
+ const { event: { target } } = props;
1538
+ this.props = props;
1539
+ this.listeners = new Listeners(getOwnerDocument(target));
1540
+ this.windowListeners = new Listeners(getWindow(target));
1541
+ this.handleKeyDown = this.handleKeyDown.bind(this);
1542
+ this.handleCancel = this.handleCancel.bind(this);
1543
+ this.attach();
1544
+ }
1545
+ attach() {
1546
+ this.handleStart();
1547
+ this.windowListeners.add(EventName.Resize, this.handleCancel);
1548
+ this.windowListeners.add(EventName.VisibilityChange, this.handleCancel);
1549
+ setTimeout(() => this.listeners.add(EventName.Keydown, this.handleKeyDown));
1550
+ }
1551
+ handleStart() {
1552
+ const { activeNode, onStart } = this.props;
1553
+ if (!activeNode.node.current) throw new Error("Active draggable node is undefined");
1554
+ const activeNodeRect = getBoundingClientRect(activeNode.node.current);
1555
+ const coordinates = {
1556
+ x: activeNodeRect.left,
1557
+ y: activeNodeRect.top
1558
+ };
1559
+ this.coordinates = coordinates;
1560
+ onStart(coordinates);
1561
+ }
1562
+ handleKeyDown(event) {
1563
+ if (isKeyboardEvent(event)) {
1564
+ const { coordinates } = this;
1565
+ const { active, context, options } = this.props;
1566
+ const { keyboardCodes = defaultKeyboardCodes, coordinateGetter = defaultKeyboardCoordinateGetter, scrollBehavior = "smooth" } = options;
1567
+ const { code } = event;
1568
+ if (keyboardCodes.end.includes(code)) {
1569
+ this.handleEnd(event);
1570
+ return;
1571
+ }
1572
+ if (keyboardCodes.cancel.includes(code)) {
1573
+ this.handleCancel(event);
1574
+ return;
1575
+ }
1576
+ const newCoordinates = coordinateGetter(event, {
1577
+ active,
1578
+ context: context.current,
1579
+ currentCoordinates: coordinates
1580
+ });
1581
+ if (newCoordinates) {
1582
+ const scrollDelta = {
1583
+ x: 0,
1584
+ y: 0
1585
+ };
1586
+ const { scrollableAncestors } = context.current;
1587
+ for (const scrollContainer of scrollableAncestors) {
1588
+ const direction = event.code;
1589
+ const coordinatesDelta = subtract(newCoordinates, coordinates);
1590
+ const { isTop, isRight, isLeft, isBottom, maxScroll, minScroll } = getScrollPosition(scrollContainer);
1591
+ const scrollElementRect = getScrollElementRect(scrollContainer);
1592
+ const clampedCoordinates = {
1593
+ x: Math.min(direction === KeyboardCode.Right ? scrollElementRect.right - scrollElementRect.width / 2 : scrollElementRect.right, Math.max(direction === KeyboardCode.Right ? scrollElementRect.left : scrollElementRect.left + scrollElementRect.width / 2, newCoordinates.x)),
1594
+ y: Math.min(direction === KeyboardCode.Down ? scrollElementRect.bottom - scrollElementRect.height / 2 : scrollElementRect.bottom, Math.max(direction === KeyboardCode.Down ? scrollElementRect.top : scrollElementRect.top + scrollElementRect.height / 2, newCoordinates.y))
1595
+ };
1596
+ const canScrollX = direction === KeyboardCode.Right && !isRight || direction === KeyboardCode.Left && !isLeft;
1597
+ const canScrollY = direction === KeyboardCode.Down && !isBottom || direction === KeyboardCode.Up && !isTop;
1598
+ if (canScrollX && clampedCoordinates.x !== newCoordinates.x) {
1599
+ if (direction === KeyboardCode.Right && scrollContainer.scrollLeft + coordinatesDelta.x <= maxScroll.x || direction === KeyboardCode.Left && scrollContainer.scrollLeft + coordinatesDelta.x >= minScroll.x) {
1600
+ scrollContainer.scrollBy({
1601
+ left: coordinatesDelta.x,
1602
+ behavior: scrollBehavior
1603
+ });
1604
+ return;
1605
+ }
1606
+ scrollDelta.x = direction === KeyboardCode.Right ? scrollContainer.scrollLeft - maxScroll.x : scrollContainer.scrollLeft - minScroll.x;
1607
+ scrollContainer.scrollBy({
1608
+ left: -scrollDelta.x,
1609
+ behavior: scrollBehavior
1610
+ });
1611
+ break;
1612
+ } else if (canScrollY && clampedCoordinates.y !== newCoordinates.y) {
1613
+ if (direction === KeyboardCode.Down && scrollContainer.scrollTop + coordinatesDelta.y <= maxScroll.y || direction === KeyboardCode.Up && scrollContainer.scrollTop + coordinatesDelta.y >= minScroll.y) {
1614
+ scrollContainer.scrollBy({
1615
+ top: coordinatesDelta.y,
1616
+ behavior: scrollBehavior
1617
+ });
1618
+ return;
1619
+ }
1620
+ scrollDelta.y = direction === KeyboardCode.Down ? scrollContainer.scrollTop - maxScroll.y : scrollContainer.scrollTop - minScroll.y;
1621
+ scrollContainer.scrollBy({
1622
+ top: -scrollDelta.y,
1623
+ behavior: scrollBehavior
1624
+ });
1625
+ break;
1626
+ }
1627
+ }
1628
+ this.handleMove(event, add(newCoordinates, scrollDelta));
1629
+ }
1630
+ }
1631
+ }
1632
+ handleMove(event, coordinates) {
1633
+ const { onMove } = this.props;
1634
+ event.preventDefault();
1635
+ onMove(coordinates);
1636
+ this.coordinates = coordinates;
1637
+ }
1638
+ handleEnd(event) {
1639
+ const { onEnd } = this.props;
1640
+ event.preventDefault();
1641
+ this.detach();
1642
+ onEnd();
1643
+ }
1644
+ handleCancel(event) {
1645
+ const { onCancel } = this.props;
1646
+ event.preventDefault();
1647
+ this.detach();
1648
+ onCancel();
1649
+ }
1650
+ detach() {
1651
+ this.listeners.removeAll();
1652
+ this.windowListeners.removeAll();
1653
+ }
1654
+ };
1655
+ KeyboardSensor.activators = [{
1656
+ eventName: "onKeyDown",
1657
+ handler: (event, { keyboardCodes = defaultKeyboardCodes, onActivation }) => {
1658
+ const { code } = event.nativeEvent;
1659
+ if (keyboardCodes.start.includes(code)) {
1660
+ event.preventDefault();
1661
+ onActivation?.({ event: event.nativeEvent });
1662
+ return true;
1663
+ }
1664
+ return false;
1665
+ }
1666
+ }];
1667
+ function isDistanceConstraint(constraint) {
1668
+ return Boolean(constraint && "distance" in constraint);
1669
+ }
1670
+ function isDelayConstraint(constraint) {
1671
+ return Boolean(constraint && "delay" in constraint);
1672
+ }
1673
+ var AbstractPointerSensor = class {
1674
+ constructor(props, events, listenerTarget = getEventListenerTarget(props.event.target)) {
1675
+ this.props = props;
1676
+ this.events = events;
1677
+ this.autoScrollEnabled = true;
1678
+ this.activated = false;
1679
+ this.timeoutId = null;
1680
+ const { event } = props;
1681
+ const { target } = event;
1682
+ this.props = props;
1683
+ this.events = events;
1684
+ this.document = getOwnerDocument(target);
1685
+ this.documentListeners = new Listeners(this.document);
1686
+ this.listeners = new Listeners(listenerTarget);
1687
+ this.windowListeners = new Listeners(getWindow(target));
1688
+ this.initialCoordinates = getEventCoordinates(event);
1689
+ this.handleStart = this.handleStart.bind(this);
1690
+ this.handleMove = this.handleMove.bind(this);
1691
+ this.handleEnd = this.handleEnd.bind(this);
1692
+ this.handleCancel = this.handleCancel.bind(this);
1693
+ this.handleKeydown = this.handleKeydown.bind(this);
1694
+ this.removeTextSelection = this.removeTextSelection.bind(this);
1695
+ this.attach();
1696
+ }
1697
+ attach() {
1698
+ const { events, props: { options: { activationConstraint } } } = this;
1699
+ this.listeners.add(events.move.name, this.handleMove, { passive: false });
1700
+ this.listeners.add(events.end.name, this.handleEnd);
1701
+ this.windowListeners.add(EventName.Resize, this.handleCancel);
1702
+ this.windowListeners.add(EventName.DragStart, preventDefault);
1703
+ this.windowListeners.add(EventName.VisibilityChange, this.handleCancel);
1704
+ this.windowListeners.add(EventName.ContextMenu, preventDefault);
1705
+ this.documentListeners.add(EventName.Keydown, this.handleKeydown);
1706
+ if (activationConstraint) {
1707
+ if (isDistanceConstraint(activationConstraint)) return;
1708
+ if (isDelayConstraint(activationConstraint)) {
1709
+ this.timeoutId = setTimeout(this.handleStart, activationConstraint.delay);
1710
+ return;
1711
+ }
1712
+ }
1713
+ this.handleStart();
1714
+ }
1715
+ detach() {
1716
+ this.listeners.removeAll();
1717
+ this.windowListeners.removeAll();
1718
+ setTimeout(this.documentListeners.removeAll, 50);
1719
+ if (this.timeoutId !== null) {
1720
+ clearTimeout(this.timeoutId);
1721
+ this.timeoutId = null;
1722
+ }
1723
+ }
1724
+ handleStart() {
1725
+ const { initialCoordinates } = this;
1726
+ const { onStart } = this.props;
1727
+ if (initialCoordinates) {
1728
+ this.activated = true;
1729
+ this.documentListeners.add(EventName.Click, stopPropagation, { capture: true });
1730
+ this.removeTextSelection();
1731
+ this.documentListeners.add(EventName.SelectionChange, this.removeTextSelection);
1732
+ onStart(initialCoordinates);
1733
+ }
1734
+ }
1735
+ handleMove(event) {
1736
+ const { activated, initialCoordinates, props } = this;
1737
+ const { onMove, options: { activationConstraint } } = props;
1738
+ if (!initialCoordinates) return;
1739
+ const coordinates = getEventCoordinates(event);
1740
+ const delta = subtract(initialCoordinates, coordinates);
1741
+ if (!activated && activationConstraint) {
1742
+ if (isDelayConstraint(activationConstraint)) {
1743
+ if (hasExceededDistance(delta, activationConstraint.tolerance)) return this.handleCancel();
1744
+ return;
1745
+ }
1746
+ if (isDistanceConstraint(activationConstraint)) {
1747
+ if (activationConstraint.tolerance != null && hasExceededDistance(delta, activationConstraint.tolerance)) return this.handleCancel();
1748
+ if (hasExceededDistance(delta, activationConstraint.distance)) return this.handleStart();
1749
+ return;
1750
+ }
1751
+ }
1752
+ if (event.cancelable) event.preventDefault();
1753
+ onMove(coordinates);
1754
+ }
1755
+ handleEnd() {
1756
+ const { onEnd } = this.props;
1757
+ this.detach();
1758
+ onEnd();
1759
+ }
1760
+ handleCancel() {
1761
+ const { onCancel } = this.props;
1762
+ this.detach();
1763
+ onCancel();
1764
+ }
1765
+ handleKeydown(event) {
1766
+ if (event.code === KeyboardCode.Esc) this.handleCancel();
1767
+ }
1768
+ removeTextSelection() {
1769
+ var _this$document$getSel;
1770
+ (_this$document$getSel = this.document.getSelection()) == null || _this$document$getSel.removeAllRanges();
1771
+ }
1772
+ };
1773
+ var events = {
1774
+ move: { name: "pointermove" },
1775
+ end: { name: "pointerup" }
1776
+ };
1777
+ var PointerSensor = class extends AbstractPointerSensor {
1778
+ constructor(props) {
1779
+ const { event } = props;
1780
+ const listenerTarget = getOwnerDocument(event.target);
1781
+ super(props, events, listenerTarget);
1782
+ }
1783
+ };
1784
+ PointerSensor.activators = [{
1785
+ eventName: "onPointerDown",
1786
+ handler: ({ nativeEvent: event }, { onActivation }) => {
1787
+ if (!event.isPrimary || event.button !== 0) return false;
1788
+ onActivation?.({ event });
1789
+ return true;
1790
+ }
1791
+ }];
1792
+ var events$1 = {
1793
+ move: { name: "mousemove" },
1794
+ end: { name: "mouseup" }
1795
+ };
1796
+ var MouseButton;
1797
+ (function(MouseButton) {
1798
+ MouseButton[MouseButton["RightClick"] = 2] = "RightClick";
1799
+ })(MouseButton || (MouseButton = {}));
1800
+ var MouseSensor = class extends AbstractPointerSensor {
1801
+ constructor(props) {
1802
+ super(props, events$1, getOwnerDocument(props.event.target));
1803
+ }
1804
+ };
1805
+ MouseSensor.activators = [{
1806
+ eventName: "onMouseDown",
1807
+ handler: ({ nativeEvent: event }, { onActivation }) => {
1808
+ if (event.button === MouseButton.RightClick) return false;
1809
+ onActivation?.({ event });
1810
+ return true;
1811
+ }
1812
+ }];
1813
+ var events$2 = {
1814
+ move: { name: "touchmove" },
1815
+ end: { name: "touchend" }
1816
+ };
1817
+ var TouchSensor = class extends AbstractPointerSensor {
1818
+ constructor(props) {
1819
+ super(props, events$2);
1820
+ }
1821
+ static setup() {
1822
+ window.addEventListener(events$2.move.name, noop, {
1823
+ capture: false,
1824
+ passive: false
1825
+ });
1826
+ return function teardown() {
1827
+ window.removeEventListener(events$2.move.name, noop);
1828
+ };
1829
+ function noop() {}
1830
+ }
1831
+ };
1832
+ TouchSensor.activators = [{
1833
+ eventName: "onTouchStart",
1834
+ handler: ({ nativeEvent: event }, { onActivation }) => {
1835
+ const { touches } = event;
1836
+ if (touches.length > 1) return false;
1837
+ onActivation?.({ event });
1838
+ return true;
1839
+ }
1840
+ }];
1841
+ function applyModifiers(modifiers, { transform, ...args }) {
1842
+ return (modifiers == null ? void 0 : modifiers.length) ? modifiers.reduce((accumulator, modifier) => {
1843
+ return modifier({
1844
+ transform: accumulator,
1845
+ ...args
1846
+ });
1847
+ }, transform) : transform;
1848
+ }
1849
+ var defaultSensors = [{
1850
+ sensor: PointerSensor,
1851
+ options: {}
1852
+ }, {
1853
+ sensor: KeyboardSensor,
1854
+ options: {}
1855
+ }];
1856
+ var defaultData = { current: {} };
1857
+ var ActiveDraggableContext = /* @__PURE__ */ (0, import_react.createContext)({
1858
+ ...defaultCoordinates,
1859
+ scaleX: 1,
1860
+ scaleY: 1
1861
+ });
1862
+ var DndContext = /* @__PURE__ */ (0, import_react.memo)(function DndContext({ id, autoScroll = true, announcements, children, sensors = defaultSensors, collisionDetection = rectIntersection, measuring, modifiers, screenReaderInstructions: screenReaderInstructions$1 = screenReaderInstructions, ...props }) {
1863
+ var _measuring$draggable$, _measuring$draggable, _sensorContext$curren, _dragOverlay$rect, _over$rect;
1864
+ const [state, dispatch] = (0, import_react.useReducer)(reducer, void 0, getInitialState);
1865
+ const [monitorState, setMonitorState] = (0, import_react.useState)(() => ({
1866
+ type: null,
1867
+ event: null
1868
+ }));
1869
+ const [isDragging, setIsDragging] = (0, import_react.useState)(false);
1870
+ const { draggable: { active: activeId, nodes: draggableNodes, translate }, droppable: { containers: droppableContainers } } = state;
1871
+ const node = activeId ? draggableNodes[activeId] : null;
1872
+ const activeRects = (0, import_react.useRef)({
1873
+ initial: null,
1874
+ translated: null
1875
+ });
1876
+ const active = (0, import_react.useMemo)(() => {
1877
+ var _node$data;
1878
+ return activeId != null ? {
1879
+ id: activeId,
1880
+ data: (_node$data = node == null ? void 0 : node.data) != null ? _node$data : defaultData,
1881
+ rect: activeRects
1882
+ } : null;
1883
+ }, [activeId, node]);
1884
+ const activeRef = (0, import_react.useRef)(null);
1885
+ const [activeSensor, setActiveSensor] = (0, import_react.useState)(null);
1886
+ const [activatorEvent, setActivatorEvent] = (0, import_react.useState)(null);
1887
+ const latestProps = (0, import_react.useRef)(props);
1888
+ const draggableDescribedById = useUniqueId(`DndDescribedBy`, id);
1889
+ const enabledDroppableContainers = (0, import_react.useMemo)(() => {
1890
+ return droppableContainers.getEnabled();
1891
+ }, [droppableContainers]);
1892
+ const { layoutRectMap: droppableRects, recomputeLayouts, willRecomputeLayouts } = useDroppableMeasuring(enabledDroppableContainers, {
1893
+ dragging: isDragging,
1894
+ dependencies: [translate.x, translate.y],
1895
+ config: measuring == null ? void 0 : measuring.droppable
1896
+ });
1897
+ const activeNode = useCachedNode(draggableNodes, activeId);
1898
+ const activationCoordinates = activatorEvent ? getEventCoordinates(activatorEvent) : null;
1899
+ const activeNodeRect = useRect(activeNode, (_measuring$draggable$ = measuring == null ? void 0 : (_measuring$draggable = measuring.draggable) == null ? void 0 : _measuring$draggable.measure) != null ? _measuring$draggable$ : getViewRect);
1900
+ const activeNodeClientRect = useClientRect(activeNode);
1901
+ const initialActiveNodeRectRef = (0, import_react.useRef)(null);
1902
+ const initialActiveNodeRect = initialActiveNodeRectRef.current;
1903
+ const sensorContext = (0, import_react.useRef)({
1904
+ active: null,
1905
+ activeNode,
1906
+ collisionRect: null,
1907
+ droppableRects,
1908
+ draggableNodes,
1909
+ draggingNodeRect: null,
1910
+ droppableContainers,
1911
+ over: null,
1912
+ scrollableAncestors: [],
1913
+ scrollAdjustedTranslate: null,
1914
+ translatedRect: null
1915
+ });
1916
+ const overNode = droppableContainers.getNodeFor((_sensorContext$curren = sensorContext.current.over) == null ? void 0 : _sensorContext$curren.id);
1917
+ const windowRect = useClientRect(activeNode ? activeNode.ownerDocument.defaultView : null);
1918
+ const containerNodeRect = useClientRect(activeNode ? activeNode.parentElement : null);
1919
+ const scrollableAncestors = useScrollableAncestors(activeId ? overNode != null ? overNode : activeNode : null);
1920
+ const scrollableAncestorRects = useClientRects(scrollableAncestors);
1921
+ const dragOverlay = useDragOverlayMeasuring({
1922
+ disabled: activeId == null,
1923
+ forceRecompute: willRecomputeLayouts
1924
+ });
1925
+ const draggingNodeRect = (_dragOverlay$rect = dragOverlay.rect) != null ? _dragOverlay$rect : activeNodeRect;
1926
+ const nodeRectDelta = draggingNodeRect === activeNodeRect ? getRectDelta(activeNodeRect, initialActiveNodeRect) : defaultCoordinates;
1927
+ const modifiedTranslate = applyModifiers(modifiers, {
1928
+ transform: {
1929
+ x: translate.x - nodeRectDelta.x,
1930
+ y: translate.y - nodeRectDelta.y,
1931
+ scaleX: 1,
1932
+ scaleY: 1
1933
+ },
1934
+ activatorEvent,
1935
+ active,
1936
+ activeNodeRect: activeNodeClientRect,
1937
+ containerNodeRect,
1938
+ draggingNodeRect,
1939
+ over: sensorContext.current.over,
1940
+ overlayNodeRect: dragOverlay.rect,
1941
+ scrollableAncestors,
1942
+ scrollableAncestorRects,
1943
+ windowRect
1944
+ });
1945
+ const pointerCoordinates = activationCoordinates ? add(activationCoordinates, translate) : null;
1946
+ const scrollAdjustment = useScrollOffsets(scrollableAncestors);
1947
+ const scrollAdjustedTranslate = add(modifiedTranslate, scrollAdjustment);
1948
+ const translatedRect = draggingNodeRect ? getAdjustedRect(draggingNodeRect, modifiedTranslate) : null;
1949
+ const collisionRect = translatedRect ? getAdjustedRect(translatedRect, scrollAdjustment) : null;
1950
+ const overId = active && collisionRect ? collisionDetection({
1951
+ active,
1952
+ collisionRect,
1953
+ droppableContainers: enabledDroppableContainers
1954
+ }) : null;
1955
+ const [over, setOver] = (0, import_react.useState)(null);
1956
+ const transform = adjustScale(modifiedTranslate, (_over$rect = over == null ? void 0 : over.rect) != null ? _over$rect : null, activeNodeRect);
1957
+ const instantiateSensor = (0, import_react.useCallback)((event, { sensor: Sensor, options }) => {
1958
+ if (!activeRef.current) return;
1959
+ const activeNode = draggableNodes[activeRef.current];
1960
+ if (!activeNode) return;
1961
+ const sensorInstance = new Sensor({
1962
+ active: activeRef.current,
1963
+ activeNode,
1964
+ event: event.nativeEvent,
1965
+ options,
1966
+ context: sensorContext,
1967
+ onStart(initialCoordinates) {
1968
+ const id = activeRef.current;
1969
+ if (!id) return;
1970
+ const node = draggableNodes[id];
1971
+ if (!node) return;
1972
+ const { onDragStart } = latestProps.current;
1973
+ const event = { active: {
1974
+ id,
1975
+ data: node.data,
1976
+ rect: activeRects
1977
+ } };
1978
+ (0, import_react_dom.unstable_batchedUpdates)(() => {
1979
+ dispatch({
1980
+ type: Action.DragStart,
1981
+ initialCoordinates,
1982
+ active: id
1983
+ });
1984
+ setMonitorState({
1985
+ type: Action.DragStart,
1986
+ event
1987
+ });
1988
+ });
1989
+ onDragStart?.(event);
1990
+ },
1991
+ onMove(coordinates) {
1992
+ dispatch({
1993
+ type: Action.DragMove,
1994
+ coordinates
1995
+ });
1996
+ },
1997
+ onEnd: createHandler(Action.DragEnd),
1998
+ onCancel: createHandler(Action.DragCancel)
1999
+ });
2000
+ (0, import_react_dom.unstable_batchedUpdates)(() => {
2001
+ setActiveSensor(sensorInstance);
2002
+ setActivatorEvent(event.nativeEvent);
2003
+ });
2004
+ function createHandler(type) {
2005
+ return async function handler() {
2006
+ const { active, over, scrollAdjustedTranslate } = sensorContext.current;
2007
+ let event = null;
2008
+ if (active && scrollAdjustedTranslate) {
2009
+ const { cancelDrop } = latestProps.current;
2010
+ event = {
2011
+ active,
2012
+ delta: scrollAdjustedTranslate,
2013
+ over
2014
+ };
2015
+ if (type === Action.DragEnd && typeof cancelDrop === "function") {
2016
+ if (await Promise.resolve(cancelDrop(event))) type = Action.DragCancel;
2017
+ }
2018
+ }
2019
+ activeRef.current = null;
2020
+ (0, import_react_dom.unstable_batchedUpdates)(() => {
2021
+ dispatch({ type });
2022
+ setOver(null);
2023
+ setIsDragging(false);
2024
+ setActiveSensor(null);
2025
+ setActivatorEvent(null);
2026
+ if (event) setMonitorState({
2027
+ type,
2028
+ event
2029
+ });
2030
+ });
2031
+ if (event) {
2032
+ const { onDragCancel, onDragEnd } = latestProps.current;
2033
+ (type === Action.DragEnd ? onDragEnd : onDragCancel)?.(event);
2034
+ }
2035
+ };
2036
+ }
2037
+ }, [dispatch, draggableNodes]);
2038
+ const activators = useCombineActivators(sensors, (0, import_react.useCallback)((handler, sensor) => {
2039
+ return (event, active) => {
2040
+ const nativeEvent = event.nativeEvent;
2041
+ if (activeRef.current !== null || nativeEvent.dndKit || nativeEvent.defaultPrevented) return;
2042
+ if (handler(event, sensor.options) === true) {
2043
+ nativeEvent.dndKit = { capturedBy: sensor.sensor };
2044
+ activeRef.current = active;
2045
+ instantiateSensor(event, sensor);
2046
+ }
2047
+ };
2048
+ }, [instantiateSensor]));
2049
+ useSensorSetup(sensors);
2050
+ useIsomorphicLayoutEffect(() => {
2051
+ latestProps.current = props;
2052
+ }, Object.values(props));
2053
+ (0, import_react.useEffect)(() => {
2054
+ if (activeId != null) setIsDragging(true);
2055
+ }, [activeId]);
2056
+ (0, import_react.useEffect)(() => {
2057
+ if (!active) initialActiveNodeRectRef.current = null;
2058
+ if (active && activeNodeRect && !initialActiveNodeRectRef.current) initialActiveNodeRectRef.current = activeNodeRect;
2059
+ }, [activeNodeRect, active]);
2060
+ (0, import_react.useEffect)(() => {
2061
+ const { onDragMove } = latestProps.current;
2062
+ const { active, over } = sensorContext.current;
2063
+ if (!active) return;
2064
+ const event = {
2065
+ active,
2066
+ delta: {
2067
+ x: scrollAdjustedTranslate.x,
2068
+ y: scrollAdjustedTranslate.y
2069
+ },
2070
+ over
2071
+ };
2072
+ setMonitorState({
2073
+ type: Action.DragMove,
2074
+ event
2075
+ });
2076
+ onDragMove?.(event);
2077
+ }, [scrollAdjustedTranslate.x, scrollAdjustedTranslate.y]);
2078
+ (0, import_react.useEffect)(() => {
2079
+ const { active, droppableContainers, scrollAdjustedTranslate } = sensorContext.current;
2080
+ if (!active || !activeRef.current || !scrollAdjustedTranslate) return;
2081
+ const { onDragOver } = latestProps.current;
2082
+ const overContainer = droppableContainers.get(overId);
2083
+ const over = overContainer && overContainer.rect.current ? {
2084
+ id: overContainer.id,
2085
+ rect: overContainer.rect.current,
2086
+ data: overContainer.data,
2087
+ disabled: overContainer.disabled
2088
+ } : null;
2089
+ const event = {
2090
+ active,
2091
+ delta: {
2092
+ x: scrollAdjustedTranslate.x,
2093
+ y: scrollAdjustedTranslate.y
2094
+ },
2095
+ over
2096
+ };
2097
+ (0, import_react_dom.unstable_batchedUpdates)(() => {
2098
+ setOver(over);
2099
+ setMonitorState({
2100
+ type: Action.DragOver,
2101
+ event
2102
+ });
2103
+ onDragOver?.(event);
2104
+ });
2105
+ }, [overId]);
2106
+ useIsomorphicLayoutEffect(() => {
2107
+ sensorContext.current = {
2108
+ active,
2109
+ activeNode,
2110
+ collisionRect,
2111
+ droppableRects,
2112
+ draggableNodes,
2113
+ draggingNodeRect,
2114
+ droppableContainers,
2115
+ over,
2116
+ scrollableAncestors,
2117
+ scrollAdjustedTranslate,
2118
+ translatedRect
2119
+ };
2120
+ activeRects.current = {
2121
+ initial: draggingNodeRect,
2122
+ translated: translatedRect
2123
+ };
2124
+ }, [
2125
+ active,
2126
+ activeNode,
2127
+ collisionRect,
2128
+ draggableNodes,
2129
+ draggingNodeRect,
2130
+ droppableRects,
2131
+ droppableContainers,
2132
+ over,
2133
+ scrollableAncestors,
2134
+ scrollAdjustedTranslate,
2135
+ translatedRect
2136
+ ]);
2137
+ useAutoScroller({
2138
+ ...getAutoScrollerOptions(),
2139
+ draggingRect: translatedRect,
2140
+ pointerCoordinates,
2141
+ scrollableAncestors,
2142
+ scrollableAncestorRects
2143
+ });
2144
+ const contextValue = (0, import_react.useMemo)(() => {
2145
+ return {
2146
+ active,
2147
+ activeNode,
2148
+ activeNodeRect,
2149
+ activeNodeClientRect,
2150
+ activatorEvent,
2151
+ activators,
2152
+ ariaDescribedById: { draggable: draggableDescribedById },
2153
+ containerNodeRect,
2154
+ dispatch,
2155
+ dragOverlay,
2156
+ draggableNodes,
2157
+ droppableContainers,
2158
+ droppableRects,
2159
+ over,
2160
+ recomputeLayouts,
2161
+ scrollableAncestors,
2162
+ scrollableAncestorRects,
2163
+ willRecomputeLayouts,
2164
+ windowRect
2165
+ };
2166
+ }, [
2167
+ active,
2168
+ activeNode,
2169
+ activeNodeClientRect,
2170
+ activeNodeRect,
2171
+ activatorEvent,
2172
+ activators,
2173
+ containerNodeRect,
2174
+ dragOverlay,
2175
+ dispatch,
2176
+ draggableNodes,
2177
+ draggableDescribedById,
2178
+ droppableContainers,
2179
+ droppableRects,
2180
+ over,
2181
+ recomputeLayouts,
2182
+ scrollableAncestors,
2183
+ scrollableAncestorRects,
2184
+ willRecomputeLayouts,
2185
+ windowRect
2186
+ ]);
2187
+ return import_react.createElement(DndMonitorContext.Provider, { value: monitorState }, import_react.createElement(Context$1.Provider, { value: contextValue }, import_react.createElement(ActiveDraggableContext.Provider, { value: transform }, children)), import_react.createElement(Accessibility, {
2188
+ announcements,
2189
+ hiddenTextDescribedById: draggableDescribedById,
2190
+ screenReaderInstructions: screenReaderInstructions$1
2191
+ }));
2192
+ function getAutoScrollerOptions() {
2193
+ const activeSensorDisablesAutoscroll = (activeSensor == null ? void 0 : activeSensor.autoScrollEnabled) === false;
2194
+ const autoScrollGloballyDisabled = typeof autoScroll === "object" ? autoScroll.enabled === false : autoScroll === false;
2195
+ const enabled = !activeSensorDisablesAutoscroll && !autoScrollGloballyDisabled;
2196
+ if (typeof autoScroll === "object") return {
2197
+ ...autoScroll,
2198
+ enabled
2199
+ };
2200
+ return { enabled };
2201
+ }
2202
+ });
2203
+ var NullContext = /* @__PURE__ */ (0, import_react.createContext)(null);
2204
+ var defaultRole = "button";
2205
+ var ID_PREFIX$1 = "Droppable";
2206
+ function useDraggable({ id, data, disabled = false, attributes }) {
2207
+ const key = useUniqueId(ID_PREFIX$1);
2208
+ const { active, activeNodeRect, activatorEvent, ariaDescribedById, draggableNodes, droppableRects, activators, over } = (0, import_react.useContext)(Context$1);
2209
+ const { role = defaultRole, roleDescription = "draggable", tabIndex = 0 } = attributes != null ? attributes : {};
2210
+ const isDragging = (active == null ? void 0 : active.id) === id;
2211
+ const transform = (0, import_react.useContext)(isDragging ? ActiveDraggableContext : NullContext);
2212
+ const [node, setNodeRef] = useNodeRef();
2213
+ const listeners = useSyntheticListeners(activators, id);
2214
+ const dataRef = useData(data);
2215
+ (0, import_react.useEffect)(() => {
2216
+ draggableNodes[id] = {
2217
+ id,
2218
+ key,
2219
+ node,
2220
+ data: dataRef
2221
+ };
2222
+ return () => {
2223
+ const node = draggableNodes[id];
2224
+ if (node && node.key === key) delete draggableNodes[id];
2225
+ };
2226
+ }, [draggableNodes, id]);
2227
+ return {
2228
+ active,
2229
+ activeNodeRect,
2230
+ activatorEvent,
2231
+ attributes: (0, import_react.useMemo)(() => ({
2232
+ role,
2233
+ tabIndex,
2234
+ "aria-pressed": isDragging && role === defaultRole ? true : void 0,
2235
+ "aria-roledescription": roleDescription,
2236
+ "aria-describedby": ariaDescribedById.draggable
2237
+ }), [
2238
+ role,
2239
+ tabIndex,
2240
+ isDragging,
2241
+ roleDescription,
2242
+ ariaDescribedById.draggable
2243
+ ]),
2244
+ droppableRects,
2245
+ isDragging,
2246
+ listeners: disabled ? void 0 : listeners,
2247
+ node,
2248
+ over,
2249
+ setNodeRef,
2250
+ transform
2251
+ };
2252
+ }
2253
+ function useDndContext() {
2254
+ return (0, import_react.useContext)(Context$1);
2255
+ }
2256
+ var ID_PREFIX$1$1 = "Droppable";
2257
+ function useDroppable({ data, disabled = false, id }) {
2258
+ const key = useUniqueId(ID_PREFIX$1$1);
2259
+ const { active, dispatch, over } = (0, import_react.useContext)(Context$1);
2260
+ const rect = (0, import_react.useRef)(null);
2261
+ const [nodeRef, setNodeRef] = useNodeRef();
2262
+ const dataRef = useData(data);
2263
+ useIsomorphicLayoutEffect(() => {
2264
+ dispatch({
2265
+ type: Action.RegisterDroppable,
2266
+ element: {
2267
+ id,
2268
+ key,
2269
+ disabled,
2270
+ node: nodeRef,
2271
+ rect,
2272
+ data: dataRef
2273
+ }
2274
+ });
2275
+ return () => dispatch({
2276
+ type: Action.UnregisterDroppable,
2277
+ key,
2278
+ id
2279
+ });
2280
+ }, [id]);
2281
+ (0, import_react.useEffect)(() => {
2282
+ dispatch({
2283
+ type: Action.SetDroppableDisabled,
2284
+ id,
2285
+ key,
2286
+ disabled
2287
+ });
2288
+ }, [disabled]);
2289
+ return {
2290
+ active,
2291
+ rect,
2292
+ isOver: (over == null ? void 0 : over.id) === id,
2293
+ node: nodeRef,
2294
+ over,
2295
+ setNodeRef
2296
+ };
2297
+ }
2298
+ //#endregion
2299
+ //#region ../../node_modules/.pnpm/@dnd-kit+sortable@5.1.0_@dnd-kit+core@4.0.3_react-dom@19.2.4_react@19.2.4__react@19.2.4__react@19.2.4/node_modules/@dnd-kit/sortable/dist/sortable.esm.js
2300
+ /**
2301
+ * Move an array item to a different position. Returns a new array with the item moved to the new position.
2302
+ */
2303
+ function arrayMove(array, from, to) {
2304
+ const newArray = array.slice();
2305
+ newArray.splice(to < 0 ? newArray.length + to : to, 0, newArray.splice(from, 1)[0]);
2306
+ return newArray;
2307
+ }
2308
+ function getSortedRects(items, layoutRects) {
2309
+ return items.reduce((accumulator, id, index) => {
2310
+ const layoutRect = layoutRects.get(id);
2311
+ if (layoutRect) accumulator[index] = layoutRect;
2312
+ return accumulator;
2313
+ }, Array(items.length));
2314
+ }
2315
+ function isValidIndex(index) {
2316
+ return index !== null && index >= 0;
2317
+ }
2318
+ var rectSortingStrategy = ({ layoutRects, activeIndex, overIndex, index }) => {
2319
+ const newRects = arrayMove(layoutRects, overIndex, activeIndex);
2320
+ const oldRect = layoutRects[index];
2321
+ const newRect = newRects[index];
2322
+ if (!newRect || !oldRect) return null;
2323
+ return {
2324
+ x: newRect.offsetLeft - oldRect.offsetLeft,
2325
+ y: newRect.offsetTop - oldRect.offsetTop,
2326
+ scaleX: newRect.width / oldRect.width,
2327
+ scaleY: newRect.height / oldRect.height
2328
+ };
2329
+ };
2330
+ var ID_PREFIX = "Sortable";
2331
+ var Context = /* @__PURE__ */ import_react.createContext({
2332
+ activeIndex: -1,
2333
+ containerId: ID_PREFIX,
2334
+ disableTransforms: false,
2335
+ items: [],
2336
+ overIndex: -1,
2337
+ useDragOverlay: false,
2338
+ sortedRects: [],
2339
+ strategy: rectSortingStrategy,
2340
+ wasDragging: { current: false }
2341
+ });
2342
+ function SortableContext({ children, id, items: userDefinedItems, strategy = rectSortingStrategy }) {
2343
+ const { active, dragOverlay, droppableRects, over, recomputeLayouts, willRecomputeLayouts } = useDndContext();
2344
+ const containerId = useUniqueId(ID_PREFIX, id);
2345
+ const useDragOverlay = Boolean(dragOverlay.rect !== null);
2346
+ const items = (0, import_react.useMemo)(() => userDefinedItems.map((item) => typeof item === "string" ? item : item.id), [userDefinedItems]);
2347
+ const isDragging = active != null;
2348
+ const wasDragging = (0, import_react.useRef)(false);
2349
+ const activeIndex = active ? items.indexOf(active.id) : -1;
2350
+ const isSorting = activeIndex !== -1;
2351
+ const overIndex = over ? items.indexOf(over.id) : -1;
2352
+ const previousItemsRef = (0, import_react.useRef)(items);
2353
+ const sortedRects = getSortedRects(items, droppableRects);
2354
+ const itemsHaveChanged = !isEqual(items, previousItemsRef.current);
2355
+ const disableTransforms = overIndex !== -1 && activeIndex === -1 || itemsHaveChanged;
2356
+ useIsomorphicLayoutEffect(() => {
2357
+ if (itemsHaveChanged && isSorting && !willRecomputeLayouts) recomputeLayouts();
2358
+ }, [
2359
+ itemsHaveChanged,
2360
+ isSorting,
2361
+ recomputeLayouts,
2362
+ willRecomputeLayouts
2363
+ ]);
2364
+ (0, import_react.useEffect)(() => {
2365
+ previousItemsRef.current = items;
2366
+ }, [items]);
2367
+ (0, import_react.useEffect)(() => {
2368
+ const timeoutId = setTimeout(() => {
2369
+ wasDragging.current = isDragging;
2370
+ }, 100);
2371
+ return () => clearTimeout(timeoutId);
2372
+ }, [isDragging]);
2373
+ const contextValue = (0, import_react.useMemo)(() => ({
2374
+ activeIndex,
2375
+ containerId,
2376
+ disableTransforms,
2377
+ items,
2378
+ overIndex,
2379
+ useDragOverlay,
2380
+ sortedRects,
2381
+ strategy,
2382
+ wasDragging
2383
+ }), [
2384
+ activeIndex,
2385
+ containerId,
2386
+ disableTransforms,
2387
+ items,
2388
+ overIndex,
2389
+ sortedRects,
2390
+ useDragOverlay,
2391
+ strategy,
2392
+ wasDragging
2393
+ ]);
2394
+ return import_react.createElement(Context.Provider, { value: contextValue }, children);
2395
+ }
2396
+ function isEqual(arr1, arr2) {
2397
+ return arr1.join() === arr2.join();
2398
+ }
2399
+ var defaultNewIndexGetter = ({ id, items, activeIndex, overIndex }) => arrayMove(items, activeIndex, overIndex).indexOf(id);
2400
+ var defaultAnimateLayoutChanges = ({ containerId, isSorting, wasDragging, index, items, newIndex, previousItems, previousContainerId, transition }) => {
2401
+ if (!transition || !wasDragging) return false;
2402
+ if (previousItems !== items && index === newIndex) return false;
2403
+ if (isSorting) return true;
2404
+ return newIndex !== index && containerId === previousContainerId;
2405
+ };
2406
+ var defaultTransition = {
2407
+ duration: 200,
2408
+ easing: "ease"
2409
+ };
2410
+ var transitionProperty = "transform";
2411
+ var disabledTransition = /* @__PURE__ */ CSS.Transition.toString({
2412
+ property: transitionProperty,
2413
+ duration: 0,
2414
+ easing: "linear"
2415
+ });
2416
+ var defaultAttributes = { roleDescription: "sortable" };
2417
+ function useDerivedTransform({ disabled, index, node, rect }) {
2418
+ const [derivedTransform, setDerivedtransform] = (0, import_react.useState)(null);
2419
+ const previousIndex = (0, import_react.useRef)(index);
2420
+ useIsomorphicLayoutEffect(() => {
2421
+ if (!disabled && index !== previousIndex.current && node.current) {
2422
+ const initial = rect.current;
2423
+ if (initial) {
2424
+ const current = getBoundingClientRect(node.current);
2425
+ const delta = {
2426
+ x: initial.offsetLeft - current.offsetLeft,
2427
+ y: initial.offsetTop - current.offsetTop,
2428
+ scaleX: initial.width / current.width,
2429
+ scaleY: initial.height / current.height
2430
+ };
2431
+ if (delta.x || delta.y) setDerivedtransform(delta);
2432
+ }
2433
+ }
2434
+ if (index !== previousIndex.current) previousIndex.current = index;
2435
+ }, [
2436
+ disabled,
2437
+ index,
2438
+ node,
2439
+ rect
2440
+ ]);
2441
+ (0, import_react.useEffect)(() => {
2442
+ if (derivedTransform) requestAnimationFrame(() => {
2443
+ setDerivedtransform(null);
2444
+ });
2445
+ }, [derivedTransform]);
2446
+ return derivedTransform;
2447
+ }
2448
+ function useSortable({ animateLayoutChanges = defaultAnimateLayoutChanges, attributes: userDefinedAttributes, disabled, data: customData, getNewIndex = defaultNewIndexGetter, id, strategy: localStrategy, transition = defaultTransition }) {
2449
+ const { items, containerId, activeIndex, disableTransforms, sortedRects, overIndex, useDragOverlay, strategy: globalStrategy, wasDragging } = (0, import_react.useContext)(Context);
2450
+ const index = items.indexOf(id);
2451
+ const data = (0, import_react.useMemo)(() => ({
2452
+ sortable: {
2453
+ containerId,
2454
+ index,
2455
+ items
2456
+ },
2457
+ ...customData
2458
+ }), [
2459
+ containerId,
2460
+ customData,
2461
+ index,
2462
+ items
2463
+ ]);
2464
+ const { rect, node, setNodeRef: setDroppableNodeRef } = useDroppable({
2465
+ id,
2466
+ data
2467
+ });
2468
+ const { active, activeNodeRect, activatorEvent, attributes, setNodeRef: setDraggableNodeRef, listeners, isDragging, over, transform } = useDraggable({
2469
+ id,
2470
+ data,
2471
+ attributes: {
2472
+ ...defaultAttributes,
2473
+ ...userDefinedAttributes
2474
+ },
2475
+ disabled
2476
+ });
2477
+ const setNodeRef = useCombinedRefs(setDroppableNodeRef, setDraggableNodeRef);
2478
+ const isSorting = Boolean(active);
2479
+ const displaceItem = isSorting && wasDragging.current && !disableTransforms && isValidIndex(activeIndex) && isValidIndex(overIndex);
2480
+ const shouldDisplaceDragSource = !useDragOverlay && isDragging;
2481
+ const dragSourceDisplacement = shouldDisplaceDragSource && displaceItem ? transform : null;
2482
+ const finalTransform = displaceItem ? dragSourceDisplacement != null ? dragSourceDisplacement : (localStrategy != null ? localStrategy : globalStrategy)({
2483
+ layoutRects: sortedRects,
2484
+ activeNodeRect,
2485
+ activeIndex,
2486
+ overIndex,
2487
+ index
2488
+ }) : null;
2489
+ const newIndex = isValidIndex(activeIndex) && isValidIndex(overIndex) ? getNewIndex({
2490
+ id,
2491
+ items,
2492
+ activeIndex,
2493
+ overIndex
2494
+ }) : index;
2495
+ const prevItems = (0, import_react.useRef)(items);
2496
+ const itemsHaveChanged = items !== prevItems.current;
2497
+ const prevNewIndex = (0, import_react.useRef)(newIndex);
2498
+ const previousContainerId = (0, import_react.useRef)(containerId);
2499
+ const shouldAnimateLayoutChanges = animateLayoutChanges({
2500
+ active,
2501
+ containerId,
2502
+ isDragging,
2503
+ isSorting,
2504
+ id,
2505
+ index,
2506
+ items,
2507
+ newIndex: prevNewIndex.current,
2508
+ previousItems: prevItems.current,
2509
+ previousContainerId: previousContainerId.current,
2510
+ transition,
2511
+ wasDragging: wasDragging.current
2512
+ });
2513
+ const derivedTransform = useDerivedTransform({
2514
+ disabled: !shouldAnimateLayoutChanges,
2515
+ index,
2516
+ node,
2517
+ rect
2518
+ });
2519
+ (0, import_react.useEffect)(() => {
2520
+ if (isSorting && prevNewIndex.current !== newIndex) prevNewIndex.current = newIndex;
2521
+ if (containerId !== previousContainerId.current) previousContainerId.current = containerId;
2522
+ if (items !== prevItems.current) prevItems.current = items;
2523
+ }, [
2524
+ isSorting,
2525
+ newIndex,
2526
+ containerId,
2527
+ items
2528
+ ]);
2529
+ return {
2530
+ active,
2531
+ attributes,
2532
+ activatorEvent,
2533
+ rect,
2534
+ index,
2535
+ isSorting,
2536
+ isDragging,
2537
+ listeners,
2538
+ node,
2539
+ overIndex,
2540
+ over,
2541
+ setNodeRef,
2542
+ setDroppableNodeRef,
2543
+ setDraggableNodeRef,
2544
+ transform: derivedTransform != null ? derivedTransform : finalTransform,
2545
+ transition: getTransition()
2546
+ };
2547
+ function getTransition() {
2548
+ if (derivedTransform || itemsHaveChanged && prevNewIndex.current === index) return disabledTransition;
2549
+ if (shouldDisplaceDragSource || !transition) return;
2550
+ if (isSorting || shouldAnimateLayoutChanges) return CSS.Transition.toString({
2551
+ ...transition,
2552
+ property: transitionProperty
2553
+ });
2554
+ }
2555
+ }
2556
+ KeyboardCode.Down, KeyboardCode.Right, KeyboardCode.Up, KeyboardCode.Left;
2557
+ //#endregion
2558
+ //#region ~icons/lucide/grip-vertical.jsx
2559
+ var lucideGripVertical = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
2560
+ viewBox: "0 0 24 24",
2561
+ width: "1.2em",
2562
+ height: "1.2em",
2563
+ ...props,
2564
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", {
2565
+ fill: "none",
2566
+ stroke: "currentColor",
2567
+ strokeLinecap: "round",
2568
+ strokeLinejoin: "round",
2569
+ strokeWidth: 2,
2570
+ children: [
2571
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
2572
+ cx: 9,
2573
+ cy: 12,
2574
+ r: 1
2575
+ }),
2576
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
2577
+ cx: 9,
2578
+ cy: 5,
2579
+ r: 1
2580
+ }),
2581
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
2582
+ cx: 9,
2583
+ cy: 19,
2584
+ r: 1
2585
+ }),
2586
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
2587
+ cx: 15,
2588
+ cy: 12,
2589
+ r: 1
2590
+ }),
2591
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
2592
+ cx: 15,
2593
+ cy: 5,
2594
+ r: 1
2595
+ }),
2596
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
2597
+ cx: 15,
2598
+ cy: 19,
2599
+ r: 1
2600
+ })
2601
+ ]
2602
+ })
2603
+ });
2604
+ //#endregion
2605
+ //#region src/components/qgrid/UsageCard.tsx
2606
+ function barColor(pct) {
2607
+ if (pct >= 95) return "bg-red-500";
2608
+ if (pct >= 80) return "bg-amber-400";
2609
+ return "bg-sienna-400";
2610
+ }
2611
+ function formatResets(iso) {
2612
+ if (!iso) return "";
2613
+ const diff = new Date(iso).getTime() - Date.now();
2614
+ if (diff <= 0) return "resetting...";
2615
+ const h = Math.floor(diff / 36e5);
2616
+ const m = Math.floor(diff % 36e5 / 6e4);
2617
+ return h > 0 ? `resets ${h}h ${m}m` : `resets ${m}m`;
2618
+ }
2619
+ function UsageRow({ label, utilization, resetsAt }) {
2620
+ const pct = utilization ?? 0;
2621
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2622
+ className: "flex items-center gap-3",
2623
+ children: [
2624
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2625
+ className: "text-xs text-sand-600 w-20 shrink-0",
2626
+ children: label
2627
+ }),
2628
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2629
+ className: "flex-1 h-2 bg-sand-200 rounded-full overflow-hidden",
2630
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2631
+ className: `h-full rounded-full transition-all duration-300 ${barColor(pct)}`,
2632
+ style: { width: `${Math.min(pct, 100)}%` }
2633
+ })
2634
+ }),
2635
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
2636
+ className: "text-xs tabular-nums text-sand-700 w-10 text-right",
2637
+ children: [pct, "%"]
2638
+ }),
2639
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2640
+ className: "text-[10px] text-sand-400 w-24 text-right",
2641
+ children: formatResets(resetsAt)
2642
+ })
2643
+ ]
2644
+ });
2645
+ }
2646
+ function TokenUsage({ token }) {
2647
+ const { data, isLoading } = QgridService.useUsage(token.name);
2648
+ if (isLoading) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2649
+ className: "animate-pulse space-y-2 py-2",
2650
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-2 w-full bg-sand-200 rounded-full" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-2 w-3/4 bg-sand-200 rounded-full" })]
2651
+ });
2652
+ if (data?.error) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2653
+ className: "py-1",
2654
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
2655
+ className: "text-[11px] text-amber-600",
2656
+ children: "Session expired"
2657
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
2658
+ className: "text-[10px] text-sand-400 mt-0.5",
2659
+ children: "Please re-login via OAuth or update your token"
2660
+ })]
2661
+ });
2662
+ if (!data?.five_hour) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
2663
+ className: "text-[11px] text-sand-400 py-1",
2664
+ children: "No usage data"
2665
+ });
2666
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2667
+ className: "space-y-1.5 py-1",
2668
+ children: [
2669
+ data.five_hour && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UsageRow, {
2670
+ label: "5h",
2671
+ utilization: data.five_hour.utilization,
2672
+ resetsAt: data.five_hour.resets_at
2673
+ }),
2674
+ data.seven_day && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UsageRow, {
2675
+ label: "7d All",
2676
+ utilization: data.seven_day.utilization,
2677
+ resetsAt: data.seven_day.resets_at
2678
+ }),
2679
+ data.seven_day_sonnet && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UsageRow, {
2680
+ label: "7d Sonnet",
2681
+ utilization: data.seven_day_sonnet.utilization,
2682
+ resetsAt: data.seven_day_sonnet.resets_at
2683
+ }),
2684
+ data.seven_day_opus && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UsageRow, {
2685
+ label: "7d Opus",
2686
+ utilization: data.seven_day_opus.utilization,
2687
+ resetsAt: data.seven_day_opus.resets_at
2688
+ })
2689
+ ]
2690
+ });
2691
+ }
2692
+ function SortableTokenCard({ token }) {
2693
+ const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
2694
+ id: String(token.id),
2695
+ transition: {
2696
+ duration: 200,
2697
+ easing: "ease"
2698
+ }
2699
+ });
2700
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2701
+ ref: setNodeRef,
2702
+ style: {
2703
+ transform: CSS.Translate.toString(transform),
2704
+ transition,
2705
+ opacity: isDragging ? .5 : 1,
2706
+ zIndex: isDragging ? 10 : void 0
2707
+ },
2708
+ ...attributes,
2709
+ ...listeners,
2710
+ className: "rounded-lg bg-sand-50 px-4 py-3 select-none cursor-grab active:cursor-grabbing touch-none",
2711
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2712
+ className: "flex items-center gap-2 mb-2",
2713
+ children: [
2714
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(lucideGripVertical, { className: "size-3.5 text-sand-300 shrink-0" }),
2715
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2716
+ className: "text-sm font-medium text-sand-800 truncate",
2717
+ children: token.name ?? "Unnamed"
2718
+ }),
2719
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2720
+ className: `text-[10px] px-1.5 py-0.5 rounded-full shrink-0 ${token.active ? "bg-sage-100 text-sage-600" : "bg-sand-200 text-sand-500"}`,
2721
+ children: token.active ? "Active" : "Inactive"
2722
+ })
2723
+ ]
2724
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TokenUsage, { token })]
2725
+ });
2726
+ }
2727
+ var PAGE_SIZE = 8;
2728
+ function UsageCard() {
2729
+ const [page, setPage] = (0, import_react.useState)(0);
2730
+ const { data, isLoading } = TokenService.useTokens("A", { orderBy: "ord-asc" });
2731
+ const queryClient = useQueryClient();
2732
+ const reorderMutation = TokenService.useReorderMutation();
2733
+ const [localTokens, setLocalTokens] = (0, import_react.useState)([]);
2734
+ (0, import_react.useEffect)(() => {
2735
+ if (data?.rows) setLocalTokens(data.rows);
2736
+ }, [data?.rows]);
2737
+ const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 5 } }));
2738
+ const handleDragEnd = (event) => {
2739
+ const { active, over } = event;
2740
+ if (!over || active.id === over.id) return;
2741
+ const activeId = Number(active.id);
2742
+ const overId = Number(over.id);
2743
+ const oldIndex = localTokens.findIndex((t) => t.id === activeId);
2744
+ const newIndex = localTokens.findIndex((t) => t.id === overId);
2745
+ if (oldIndex === -1 || newIndex === -1) return;
2746
+ const reordered = arrayMove(localTokens, oldIndex, newIndex);
2747
+ setLocalTokens(reordered);
2748
+ const queryKey = TokenService.getTokensQueryOptions("A", { orderBy: "ord-asc" }).queryKey;
2749
+ const prev = queryClient.getQueryData(queryKey);
2750
+ queryClient.setQueryData(queryKey, (old) => old ? {
2751
+ ...old,
2752
+ rows: reordered
2753
+ } : old);
2754
+ reorderMutation.mutate({ ids: reordered.map((t) => t.id) }, {
2755
+ onError: () => {
2756
+ queryClient.setQueryData(queryKey, prev);
2757
+ if (data?.rows) setLocalTokens(data.rows);
2758
+ },
2759
+ onSettled: () => {
2760
+ Promise.all([queryClient.invalidateQueries({ queryKey: ["Token"] }), queryClient.invalidateQueries({ queryKey: ["Qgrid"] })]);
2761
+ }
2762
+ });
2763
+ };
2764
+ if (isLoading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2765
+ className: "grid grid-cols-2 gap-3",
2766
+ children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2767
+ className: "rounded-lg bg-sand-50 px-4 py-3 animate-pulse",
2768
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-3 w-16 bg-sand-200 rounded mb-3" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-2 w-full bg-sand-200 rounded-full" })]
2769
+ }, `skel-${i}`))
2770
+ });
2771
+ if (localTokens.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2772
+ className: "rounded-lg bg-sand-50 px-5 py-4",
2773
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
2774
+ className: "text-sand-400 text-sm",
2775
+ children: "No tokens registered"
2776
+ })
2777
+ });
2778
+ const totalPages = Math.ceil(localTokens.length / PAGE_SIZE);
2779
+ const safePage = Math.min(page, totalPages - 1);
2780
+ const pageTokens = localTokens.slice(safePage * PAGE_SIZE, (safePage + 1) * PAGE_SIZE);
2781
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DndContext, {
2782
+ sensors,
2783
+ collisionDetection: closestCenter,
2784
+ onDragEnd: handleDragEnd,
2785
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SortableContext, {
2786
+ items: pageTokens.map((t) => String(t.id)),
2787
+ strategy: rectSortingStrategy,
2788
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2789
+ className: "grid grid-cols-2 gap-3",
2790
+ children: pageTokens.map((token) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SortableTokenCard, { token }, token.id))
2791
+ })
2792
+ })
2793
+ }), totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2794
+ className: "flex items-center justify-center gap-2 mt-3",
2795
+ children: [
2796
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
2797
+ type: "button",
2798
+ className: "p-0.5 rounded text-sand-400 hover:text-sand-600 disabled:opacity-30 transition-colors",
2799
+ disabled: safePage === 0,
2800
+ onClick: () => setPage(safePage - 1),
2801
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(lucideChevronLeft, { className: "size-4" })
2802
+ }),
2803
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
2804
+ className: "text-[10px] text-sand-400 tabular-nums",
2805
+ children: [
2806
+ safePage + 1,
2807
+ " / ",
2808
+ totalPages
2809
+ ]
2810
+ }),
2811
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
2812
+ type: "button",
2813
+ className: "p-0.5 rounded text-sand-400 hover:text-sand-600 disabled:opacity-30 transition-colors",
2814
+ disabled: safePage === totalPages - 1,
2815
+ onClick: () => setPage(safePage + 1),
2816
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(lucideChevronRight, { className: "size-4" })
2817
+ })
2818
+ ]
2819
+ })] });
2820
+ }
2821
+ //#endregion
2822
+ //#region src/routes/index.tsx?tsr-split=component
2823
+ function Dashboard() {
2824
+ const { data: healthData, isLoading: healthLoading, isError: healthError } = QgridService.useHealth();
2825
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2826
+ className: "space-y-5 max-w-300 mx-auto -translate-x-4",
2827
+ children: [
2828
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
2829
+ className: "text-xl font-medium text-sand-900 tracking-tight",
2830
+ children: "Dashboard"
2831
+ }),
2832
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HealthCard, {
2833
+ data: healthData,
2834
+ isLoading: healthLoading,
2835
+ isError: healthError
2836
+ }),
2837
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2838
+ className: "text-[10px] uppercase tracking-wider text-sand-500 font-medium",
2839
+ children: "Usage"
2840
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2841
+ className: "mt-2",
2842
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UsageCard, {})
2843
+ })] }),
2844
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2845
+ className: "text-[10px] uppercase tracking-wider text-sand-500 font-medium",
2846
+ children: "Request Log"
2847
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2848
+ className: "mt-2",
2849
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RequestLogTable, {})
2850
+ })] })
2851
+ ]
2852
+ });
2853
+ }
2854
+ //#endregion
2855
+ export { Dashboard as component };