@tetrascience-npm/tetrascience-react-ui 0.5.0-beta.64.1 → 0.5.0-beta.66.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -25,9 +25,9 @@ This library provides:
25
25
  ## Compatibility
26
26
 
27
27
  | Library version | React | Node.js | TDP (server utilities) |
28
- | --- | --- | --- | --- |
29
- | v0.5.x | 19+ | 18+ | v4.x+ |
30
- | v0.4.x | 19+ | 18+ | v4.x+ |
28
+ | --------------- | ----- | ------- | ---------------------- |
29
+ | v0.5.x | 19+ | 18+ | v4.x+ |
30
+ | v0.4.x | 19+ | 18+ | v4.x+ |
31
31
 
32
32
  > **Note:** The client-side components have no TDP version dependency.
33
33
  > The `/server` utilities (JWT auth, provider helpers) require a running TDP instance of v4.x or later.
@@ -43,10 +43,10 @@ yarn add @tetrascience-npm/tetrascience-react-ui
43
43
 
44
44
  ```tsx
45
45
  // 1. Import the CSS once at your app root (required)
46
- import '@tetrascience-npm/tetrascience-react-ui/index.css';
46
+ import "@tetrascience-npm/tetrascience-react-ui/index.css";
47
47
 
48
48
  // 2. Import components
49
- import { Button, Card, CardHeader, CardContent } from '@tetrascience-npm/tetrascience-react-ui';
49
+ import { Button, Card, CardHeader, CardContent } from "@tetrascience-npm/tetrascience-react-ui";
50
50
 
51
51
  function App() {
52
52
  return (
@@ -67,9 +67,9 @@ This library uses **Tailwind CSS 4** with design tokens defined as CSS custom pr
67
67
 
68
68
  ### CSS Import Options
69
69
 
70
- | Import path | Use case |
71
- | --- | --- |
72
- | `@tetrascience-npm/tetrascience-react-ui/index.css` | **Pre-built CSS** — use this for most apps. Import once at your app root. |
70
+ | Import path | Use case |
71
+ | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
72
+ | `@tetrascience-npm/tetrascience-react-ui/index.css` | **Pre-built CSS** — use this for most apps. Import once at your app root. |
73
73
  | `@tetrascience-npm/tetrascience-react-ui/index.tailwind.css` | **Tailwind source** — for apps that run their own Tailwind build and want to extend/override tokens. |
74
74
 
75
75
  Most consumers only need `index.css`:
@@ -100,7 +100,58 @@ Accordion, Alert, AlertDialog, AspectRatio, Avatar, Badge, Breadcrumb, Button, B
100
100
 
101
101
  TetraScience-specific compositions built from UI primitives:
102
102
 
103
- AppHeader, AppLayout, AssistantModal, CodeScriptEditorButton, LaunchContent, Main, Navbar, ProtocolConfiguration, ProtocolYamlCard, PythonEditorModal, Sidebar, TdpLink, TdpSearch, TdpUrl
103
+ AppHeader, AppLayout, AssistantModal, CodeScriptEditorButton, LaunchContent, Main, Navbar, ProcessFlow, ProtocolConfiguration, ProtocolYamlCard, PythonEditorModal, Sidebar, TdpLink, TdpSearch, TdpUrl
104
+
105
+ #### ProcessFlow
106
+
107
+ Use `ProcessFlow` to render parent-owned multi-step workflow state such as uploads, validation pipelines, review flows, processing stages, and setup sequences. Import it from the package and keep all workflow transitions and side effects in the consuming app.
108
+
109
+ ```tsx
110
+ import {
111
+ PROCESS_FLOW_STEP_STATUSES,
112
+ ProcessFlow,
113
+ type ProcessFlowStep,
114
+ type ProcessFlowStepStatus,
115
+ } from "@tetrascience-npm/tetrascience-react-ui";
116
+
117
+ const steps: ProcessFlowStep[] = [
118
+ { id: "upload", label: "Upload", description: "Choose source files", status: "completed" },
119
+ { id: "validate", label: "Validate", description: "Check schema and lineage", status: "active" },
120
+ { id: "publish", label: "Publish", description: "Send downstream", status: "pending" },
121
+ ];
122
+
123
+ function WorkflowProgress() {
124
+ return (
125
+ <ProcessFlow
126
+ steps={steps}
127
+ selectedStepId="validate"
128
+ onStepSelect={(step, details) => {
129
+ console.log(step.id, details.status);
130
+ }}
131
+ />
132
+ );
133
+ }
134
+
135
+ const allStatuses: readonly ProcessFlowStepStatus[] = PROCESS_FLOW_STEP_STATUSES;
136
+ ```
137
+
138
+ Expected contract:
139
+
140
+ - `status` is independently controlled per step: `pending`, `active`, `completed`, `error`, or `disabled`.
141
+ - `selectedStepId` means the step the user is viewing or has clicked; it is separate from the `active` workflow state.
142
+ - `onStepSelect` emits user selection only. It does not mean a workflow step completed.
143
+ - Parent workflow code owns completion, error handling, retries, analytics, and other side effects.
144
+ - `description` is shown by default. Pass `showDescriptions={false}` to hide all descriptions.
145
+ - Descriptions auto-hide at narrow container widths (≤40rem) for mobile layouts.
146
+ - The component fills 100% of its container width — size it by controlling the container.
147
+ - Selected completed steps render with a green label; selected active steps render with a blue label.
148
+ - Use `connections` and per-step `position` only for simple branching/configurable flows.
149
+
150
+ For AI-assisted consuming apps, add a short instruction like this to the app's `AGENTS.md` or `CLAUDE.md`:
151
+
152
+ ```md
153
+ Use `ProcessFlow` from `@tetrascience-npm/tetrascience-react-ui` for multi-step workflow visualization. Do not build a custom stepper for upload, validation, review, approval, processing, or setup flows. Parent components own the workflow state and pass `steps: ProcessFlowStep[]`; each step status must be one of `PROCESS_FLOW_STEP_STATUSES`. Use `selectedStepId` only for the viewed/selected step. Keep completion/error side effects in the parent workflow code, not inside `ProcessFlow`.
154
+ ```
104
155
 
105
156
  ### Charts (`charts/`)
106
157
 
@@ -117,7 +168,7 @@ Beyond UI components, this library includes server-side helper functions for bui
117
168
  **JWT Token Manager** - Manages JWT token retrieval for data apps:
118
169
 
119
170
  ```typescript
120
- import { jwtManager } from '@tetrascience-npm/tetrascience-react-ui/server';
171
+ import { jwtManager } from "@tetrascience-npm/tetrascience-react-ui/server";
121
172
 
122
173
  // In Express middleware
123
174
  app.use(async (req, res, next) => {
@@ -146,12 +197,8 @@ TypeScript equivalents of the Python helpers from `ts-lib-ui-kit-streamlit` for
146
197
  **Getting Provider Configurations:**
147
198
 
148
199
  ```typescript
149
- import { TDPClient } from '@tetrascience-npm/ts-connectors-sdk';
150
- import {
151
- getProviderConfigurations,
152
- buildProvider,
153
- jwtManager,
154
- } from '@tetrascience-npm/tetrascience-react-ui/server';
200
+ import { TDPClient } from "@tetrascience-npm/ts-connectors-sdk";
201
+ import { getProviderConfigurations, buildProvider, jwtManager } from "@tetrascience-npm/tetrascience-react-ui/server";
155
202
 
156
203
  // Get user's auth token from request (e.g., in Express middleware)
157
204
  const userToken = await jwtManager.getTokenFromExpressRequest(req);
@@ -160,7 +207,7 @@ const userToken = await jwtManager.getTokenFromExpressRequest(req);
160
207
  // Other fields (tdpEndpoint, connectorId, orgSlug) are read from environment variables
161
208
  const client = new TDPClient({
162
209
  authToken: userToken,
163
- artifactType: 'data-app',
210
+ artifactType: "data-app",
164
211
  });
165
212
  await client.init();
166
213
 
@@ -172,7 +219,7 @@ for (const config of providers) {
172
219
 
173
220
  // Build a database connection from the config
174
221
  const provider = await buildProvider(config);
175
- const results = await provider.query('SELECT * FROM my_table LIMIT 10');
222
+ const results = await provider.query("SELECT * FROM my_table LIMIT 10");
176
223
  await provider.close();
177
224
  }
178
225
  ```
@@ -185,21 +232,21 @@ import {
185
232
  buildDatabricksProvider,
186
233
  getTdpAthenaProvider,
187
234
  type ProviderConfiguration,
188
- } from '@tetrascience-npm/tetrascience-react-ui/server';
235
+ } from "@tetrascience-npm/tetrascience-react-ui/server";
189
236
 
190
237
  // Snowflake
191
238
  const snowflakeProvider = await buildSnowflakeProvider(config);
192
- const data = await snowflakeProvider.query('SELECT * FROM users');
239
+ const data = await snowflakeProvider.query("SELECT * FROM users");
193
240
  await snowflakeProvider.close();
194
241
 
195
242
  // Databricks
196
243
  const databricksProvider = await buildDatabricksProvider(config);
197
- const data = await databricksProvider.query('SELECT * FROM events');
244
+ const data = await databricksProvider.query("SELECT * FROM events");
198
245
  await databricksProvider.close();
199
246
 
200
247
  // TDP Athena (uses environment configuration)
201
248
  const athenaProvider = await getTdpAthenaProvider();
202
- const data = await athenaProvider.query('SELECT * FROM files');
249
+ const data = await athenaProvider.query("SELECT * FROM files");
203
250
  await athenaProvider.close();
204
251
  ```
205
252
 
@@ -211,15 +258,15 @@ import {
211
258
  MissingTableError,
212
259
  ProviderConnectionError,
213
260
  InvalidProviderConfigurationError,
214
- } from '@tetrascience-npm/tetrascience-react-ui/server';
261
+ } from "@tetrascience-npm/tetrascience-react-ui/server";
215
262
 
216
263
  try {
217
- const results = await provider.query('SELECT * FROM missing_table');
264
+ const results = await provider.query("SELECT * FROM missing_table");
218
265
  } catch (error) {
219
266
  if (error instanceof MissingTableError) {
220
- console.error('Table not found:', error.message);
267
+ console.error("Table not found:", error.message);
221
268
  } else if (error instanceof QueryError) {
222
- console.error('Query failed:', error.message);
269
+ console.error("Query failed:", error.message);
223
270
  }
224
271
  }
225
272
  ```
@@ -242,20 +289,20 @@ The TDP connector key/value store lets data apps persist small pieces of state (
242
289
  **Reading and writing values with the user's JWT token:**
243
290
 
244
291
  ```typescript
245
- import { TDPClient } from '@tetrascience-npm/ts-connectors-sdk';
246
- import { jwtManager } from '@tetrascience-npm/tetrascience-react-ui/server';
292
+ import { TDPClient } from "@tetrascience-npm/ts-connectors-sdk";
293
+ import { jwtManager } from "@tetrascience-npm/tetrascience-react-ui/server";
247
294
 
248
295
  // In an Express route handler:
249
- app.get('/api/kv/:key', async (req, res) => {
296
+ app.get("/api/kv/:key", async (req, res) => {
250
297
  // 1. Get the user's JWT from request cookies
251
298
  const userToken = await jwtManager.getTokenFromExpressRequest(req);
252
- if (!userToken) return res.status(401).json({ error: 'Not authenticated' });
299
+ if (!userToken) return res.status(401).json({ error: "Not authenticated" });
253
300
 
254
301
  // 2. Create a TDPClient authenticated as the user
255
302
  // (CONNECTOR_ID, TDP_ENDPOINT, ORG_SLUG are read from env vars)
256
303
  const client = new TDPClient({
257
304
  authToken: userToken,
258
- artifactType: 'data-app',
305
+ artifactType: "data-app",
259
306
  });
260
307
  await client.init();
261
308
 
@@ -264,13 +311,13 @@ app.get('/api/kv/:key', async (req, res) => {
264
311
  res.json({ key: req.params.key, value });
265
312
  });
266
313
 
267
- app.put('/api/kv/:key', async (req, res) => {
314
+ app.put("/api/kv/:key", async (req, res) => {
268
315
  const userToken = await jwtManager.getTokenFromExpressRequest(req);
269
- if (!userToken) return res.status(401).json({ error: 'Not authenticated' });
316
+ if (!userToken) return res.status(401).json({ error: "Not authenticated" });
270
317
 
271
318
  const client = new TDPClient({
272
319
  authToken: userToken,
273
- artifactType: 'data-app',
320
+ artifactType: "data-app",
274
321
  });
275
322
  await client.init();
276
323
 
@@ -283,7 +330,7 @@ app.put('/api/kv/:key', async (req, res) => {
283
330
  **Reading multiple values at once:**
284
331
 
285
332
  ```typescript
286
- const values = await client.getValues(['theme', 'locale', 'last-run']);
333
+ const values = await client.getValues(["theme", "locale", "last-run"]);
287
334
  // values[0] → theme, values[1] → locale, values[2] → last-run
288
335
  ```
289
336
 
@@ -315,8 +362,8 @@ Frontend: use `<TdpSearch columns={...} />` with default `apiEndpoint="/api/sear
315
362
  Full TypeScript support with exported types:
316
363
 
317
364
  ```tsx
318
- import { Button } from '@tetrascience-npm/tetrascience-react-ui';
319
- import type { ButtonProps, BarGraphProps, BarDataSeries } from '@tetrascience-npm/tetrascience-react-ui';
365
+ import { Button } from "@tetrascience-npm/tetrascience-react-ui";
366
+ import type { ButtonProps, BarGraphProps, BarDataSeries } from "@tetrascience-npm/tetrascience-react-ui";
320
367
  ```
321
368
 
322
369
  ## Examples
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),x=require("lucide-react"),m=require("./ProcessFlow.utils.cjs"),f=require("../../../lib/utils.cjs"),H={pending:"text-muted-foreground",active:"text-foreground",completed:"text-foreground",error:"text-destructive",disabled:"text-muted-foreground"},L={pending:"border-border bg-background text-muted-foreground",active:"border-primary bg-primary text-primary-foreground",completed:"border-positive bg-positive text-background",error:"border-destructive bg-destructive text-background",disabled:"border-border bg-muted text-muted-foreground"},q={pending:"stroke-muted-foreground/35",active:"stroke-primary",completed:"stroke-positive",error:"stroke-destructive",disabled:"stroke-border"},A={default:"11rem",compact:"8.5rem"},P={default:"8rem",compact:"7rem"},M={default:"5.5rem",compact:"4.75rem"},O={default:"2.75rem",compact:"2.5rem"},E={default:"7.5rem",compact:"5.75rem"},N={default:"6.5rem",compact:"5rem"},k={default:"4.5rem",compact:"3.75rem"},y={default:"3.5rem",compact:"3rem"},G={default:"1.25rem",compact:"0.75rem"},V={default:"0.875rem",compact:"0.625rem"},U={default:"0.5rem",compact:"0.375rem"},W={default:"0.375rem",compact:"0.25rem"},I={default:"2.5rem",compact:"1.75rem"},j={default:"2rem",compact:"1.5rem"},R={default:"1.5rem",compact:"1.25rem"},T={default:"1.25rem",compact:"1.125rem"};function F(r,a){return r==="completed"?s.jsx(x.CheckIcon,{"aria-hidden":"true"}):r==="error"?s.jsx(x.TriangleAlertIcon,{"aria-hidden":"true"}):r==="disabled"?s.jsx(x.LockIcon,{"aria-hidden":"true"}):r==="active"?s.jsx(x.DotIcon,{"aria-hidden":"true"}):a}function Z(r,a){return{left:`calc(${(r+.5)/a*100}% + (var(--process-flow-marker-size) / 2))`,width:`calc(${1/a*100}% - var(--process-flow-marker-size))`}}function z(r,a){return{height:`calc(${1/a*100}% - var(--process-flow-marker-size))`,top:`calc(${(r+.5)/a*100}% + (var(--process-flow-marker-size) / 2))`}}function K(){const r="calc(((100% / var(--process-flow-count)) / 2) + (var(--process-flow-marker-size) / 2))";return{left:r,right:r}}function Q(){const r="calc(((100% / var(--process-flow-count)) / 2) + (var(--process-flow-marker-size) / 2))";return{bottom:r,top:r}}function $({contentLayout:r,onStepSelect:a,isDisabled:l,size:t,status:n}){return f.cn("flex w-full min-w-0 border-0 bg-transparent p-0 text-sm outline-none transition-all focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50",r==="inline"&&"flex-row items-center gap-3 text-left",r==="stacked"&&"flex-col items-center gap-2 text-center",r==="anchored"&&"relative h-full flex-col items-center justify-center text-center",t==="compact"&&(r==="inline"?"gap-2":"gap-1.5"),a&&!l&&f.cn("cursor-pointer hover:text-foreground",r!=="anchored"&&"hover:-translate-y-px"),a&&l&&"cursor-not-allowed",H[n])}function B({isSelected:r,size:a,status:l}){return f.cn("flex size-[var(--process-flow-marker-size)] shrink-0 items-center justify-center rounded-full border text-xs font-semibold tabular-nums transition-colors [&_svg]:size-4",a==="compact"&&"text-[0.7rem] [&_svg]:size-3","shadow-[0_0_0_0.25rem_var(--background)]",r&&"ring-4 ring-primary/20",L[l])}function J({layout:r,isSelected:a,status:l}){return f.cn("block max-w-full truncate font-medium text-current",r==="linear"&&a&&l==="completed"&&"text-positive",r==="linear"&&a&&l!=="completed"&&l!=="error"&&"text-primary")}function C({item:r,isSelected:a,onStepSelect:l,descriptionVisibility:t,size:n,layout:o,contentLayout:p}){const{step:d,stepIndex:u,status:e}=r,c=e==="disabled"||d.selectable===!1,v=m.getStepAccessibleLabel(d,e,u+1),w=t==="visible"?"visible":"auto",g=$({contentLayout:p,onStepSelect:l,isDisabled:c,size:n,status:e}),h=s.jsx("span",{"aria-hidden":"true",className:B({isSelected:a,size:n,status:e}),"data-slot":"process-flow-marker",children:F(e,u+1)}),_=s.jsxs("span",{"data-slot":"process-flow-text","data-text-visibility":w,className:f.cn("flex min-w-0 flex-col gap-0.5",p==="stacked"&&"w-full items-center",p==="anchored"&&"pointer-events-none absolute left-1/2 top-[calc(50%+var(--process-flow-marker-size)/2+0.375rem)] w-max max-w-[calc(var(--process-flow-step-min-width)-0.5rem)] -translate-x-1/2 items-center px-1"),children:[s.jsx("span",{className:J({layout:o,isSelected:a,status:e}),"data-slot":"process-flow-label",children:d.label}),t!=="hidden"&&d.description?s.jsx("span",{className:"line-clamp-2 text-xs leading-snug text-muted-foreground","data-description-visibility":t,"data-slot":"process-flow-description",children:d.description}):null,s.jsxs("span",{className:"sr-only",children:["Status: ",m.STATUS_LABELS[e]]})]}),b=s.jsxs(s.Fragment,{children:[h,_]});return l?s.jsx("button",{type:"button","aria-current":e==="active"?"step":void 0,"aria-invalid":e==="error"||void 0,"aria-label":v,"aria-pressed":a,className:g,"data-selected":a||void 0,"data-status":e,disabled:c,onClick:S=>l(d,{nativeEvent:S,status:e,stepIndex:u}),children:b}):s.jsx("div",{"aria-current":e==="active"?"step":void 0,"aria-disabled":c||void 0,"aria-invalid":e==="error"||void 0,"aria-label":v,className:g,"data-selected":a||void 0,"data-status":e,children:b})}function X({steps:r,selectedStepId:a,onStepSelect:l,size:t,showDescriptions:n}){const o=r.map((e,c)=>m.positionStep(e,c,"horizontal")),p=m.resolveConnections(o),d=m.getDescriptionVisibility(n),u={"--process-flow-count":r.length,"--process-flow-step-min-width-base":A[t],"--process-flow-step-min-width-responsive":P[t],"--process-flow-step-min-width-squeezed":M[t],"--process-flow-step-min-width-mini":O[t],"--process-flow-row-min-height-base":E[t],"--process-flow-row-min-height-responsive":N[t],"--process-flow-row-min-height-squeezed":k[t],"--process-flow-row-min-height-mini":y[t],"--process-flow-marker-size-base":I[t],"--process-flow-marker-size-responsive":j[t],"--process-flow-marker-size-squeezed":R[t],"--process-flow-marker-size-mini":T[t]};return s.jsx("div",{className:"overflow-hidden px-3 py-4","data-slot":"process-flow-viewport",style:u,children:s.jsxs("ol",{className:"relative grid min-w-0 min-h-[var(--process-flow-row-min-height)] list-none p-0","data-slot":"process-flow-list",style:{gridTemplateColumns:"repeat(var(--process-flow-count), minmax(0, 1fr))"},children:[r.length>1?s.jsx("li",{"aria-hidden":"true",className:"absolute top-[calc(var(--process-flow-marker-size)/2)] h-0.5 -translate-y-1/2 rounded-full bg-muted",style:K()}):null,p.map((e,c)=>s.jsx("li",{"aria-hidden":"true",className:f.cn("absolute top-[calc(var(--process-flow-marker-size)/2)] h-0.5 -translate-y-1/2 rounded-full transition-colors",e.status==="completed"&&"bg-positive",e.status==="active"&&"bg-primary",e.status==="error"&&"bg-destructive",e.status==="pending"&&"bg-muted",e.status==="disabled"&&"bg-border"),style:Z(c,r.length)},e.id)),o.map(e=>s.jsx("li",{className:"relative z-[1] flex min-w-0 items-start justify-center","data-slot":"process-flow-item",children:s.jsx(C,{item:e,contentLayout:"stacked",descriptionVisibility:d,isSelected:a===e.step.id,layout:"linear",onStepSelect:l,size:t})},e.step.id))]})})}function Y({steps:r,selectedStepId:a,onStepSelect:l,size:t,showDescriptions:n}){const o=r.map((e,c)=>m.positionStep(e,c,"vertical")),p=m.resolveConnections(o),d=m.getDescriptionVisibility(n),u={"--process-flow-count":r.length,"--process-flow-row-min-height-base":E[t],"--process-flow-row-min-height-responsive":N[t],"--process-flow-row-min-height-squeezed":k[t],"--process-flow-row-min-height-mini":y[t],"--process-flow-marker-size-base":I[t],"--process-flow-marker-size-responsive":j[t],"--process-flow-marker-size-squeezed":R[t],"--process-flow-marker-size-mini":T[t]};return s.jsx("div",{className:"overflow-x-auto px-3 py-3","data-slot":"process-flow-viewport",style:u,children:s.jsxs("ol",{className:"relative grid min-h-[calc(var(--process-flow-count)*var(--process-flow-row-min-height))] min-w-72 list-none p-0","data-slot":"process-flow-list",style:{gridTemplateRows:"repeat(var(--process-flow-count), minmax(var(--process-flow-row-min-height), auto))"},children:[r.length>1?s.jsx("li",{"aria-hidden":"true",className:"absolute left-[calc(var(--process-flow-marker-size)/2)] w-0.5 -translate-x-1/2 rounded-full bg-muted",style:Q()}):null,p.map((e,c)=>s.jsx("li",{"aria-hidden":"true",className:f.cn("absolute left-[calc(var(--process-flow-marker-size)/2)] w-0.5 -translate-x-1/2 rounded-full transition-colors",e.status==="completed"&&"bg-positive",e.status==="active"&&"bg-primary",e.status==="error"&&"bg-destructive",e.status==="pending"&&"bg-muted",e.status==="disabled"&&"bg-border"),style:z(c,r.length)},e.id)),o.map(e=>s.jsx("li",{className:"relative z-[1] flex min-w-0 items-center","data-slot":"process-flow-item",children:s.jsx(C,{item:e,contentLayout:"inline",descriptionVisibility:d,isSelected:a===e.step.id,layout:"linear",onStepSelect:l,size:t})},e.step.id))]})})}function ee({steps:r,connections:a,selectedStepId:l,onStepSelect:t,orientation:n="horizontal",size:o="default",showDescriptions:p,className:d,style:u,"aria-label":e="Process flow",...c}){if(r.length===0)return null;const v=a||m.hasCustomStepLayout(r)?"branching":"linear";if(v==="linear"&&n==="horizontal")return s.jsx("nav",{"aria-label":e,className:f.cn("w-full min-w-0",d),"data-orientation":n,"data-slot":"process-flow","data-size":o,style:u,...c,children:s.jsx(X,{steps:r,selectedStepId:l,onStepSelect:t,showDescriptions:p,size:o})});if(v==="linear"&&n==="vertical")return s.jsx("nav",{"aria-label":e,className:f.cn("w-full min-w-0",d),"data-orientation":n,"data-slot":"process-flow","data-size":o,style:u,...c,children:s.jsx(Y,{steps:r,selectedStepId:l,onStepSelect:t,showDescriptions:p,size:o})});const w=r.map((i,D)=>m.positionStep(i,D,n)),g=Math.max(...w.map(i=>i.row+1),1),h=Math.max(...w.map(i=>i.column+1),1),_=m.resolveConnections(w,a),b=m.getDescriptionVisibility(p),S={"--process-flow-columns":h,"--process-flow-rows":g,"--process-flow-step-min-width-base":A[o],"--process-flow-step-min-width-responsive":P[o],"--process-flow-step-min-width-squeezed":M[o],"--process-flow-step-min-width-mini":O[o],"--process-flow-row-min-height-base":E[o],"--process-flow-row-min-height-responsive":N[o],"--process-flow-row-min-height-squeezed":k[o],"--process-flow-row-min-height-mini":y[o],"--process-flow-gap-base":G[o],"--process-flow-gap-responsive":V[o],"--process-flow-gap-squeezed":U[o],"--process-flow-gap-mini":W[o],"--process-flow-marker-size-base":I[o],"--process-flow-marker-size-responsive":j[o],"--process-flow-marker-size-squeezed":R[o],"--process-flow-marker-size-mini":T[o]};return s.jsx("nav",{"aria-label":e,className:f.cn("w-full min-w-0",d),"data-orientation":n,"data-slot":"process-flow","data-size":o,style:u,...c,children:s.jsx("div",{className:"overflow-x-auto py-2","data-slot":"process-flow-viewport",style:S,children:s.jsxs("div",{className:"relative min-w-[calc(var(--process-flow-columns)*var(--process-flow-step-min-width))] min-h-[calc(var(--process-flow-rows)*var(--process-flow-row-min-height))]","data-slot":"process-flow-canvas",children:[s.jsx("svg",{"aria-hidden":"true",className:"pointer-events-none absolute inset-0 z-0 size-full overflow-visible",preserveAspectRatio:"none",viewBox:"0 0 100 100",children:_.map(i=>s.jsx("path",{className:f.cn("fill-none stroke-2 transition-colors",q[i.status],i.status==="disabled"&&"opacity-60"),d:m.getConnectionPath(i,g,h),"data-status":i.status,strokeLinecap:"round",vectorEffect:"non-scaling-stroke"},i.id))}),s.jsx("ol",{className:"relative z-[1] grid min-h-[inherit] list-none p-0","data-slot":"process-flow-list",style:{gap:"var(--process-flow-gap)",gridTemplateColumns:"repeat(var(--process-flow-columns), minmax(var(--process-flow-step-min-width), 1fr))",gridTemplateRows:"repeat(var(--process-flow-rows), minmax(var(--process-flow-row-min-height), auto))"},children:w.map(i=>s.jsx("li",{className:"flex min-w-0 items-center justify-center","data-slot":"process-flow-item",style:{gridColumn:i.column+1,gridRow:i.row+1},children:s.jsx(C,{item:i,contentLayout:"anchored",descriptionVisibility:b,isSelected:l===i.step.id,layout:"branching",onStepSelect:t,size:o})},i.step.id))})]})})})}exports.PROCESS_FLOW_STEP_STATUSES=m.PROCESS_FLOW_STEP_STATUSES;exports.ProcessFlow=ee;
2
+ //# sourceMappingURL=ProcessFlow.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProcessFlow.cjs","sources":["../../../../src/components/composed/ProcessFlow/ProcessFlow.tsx"],"sourcesContent":["import { CheckIcon, DotIcon, LockIcon, TriangleAlertIcon } from \"lucide-react\";\n\nimport {\n getConnectionPath,\n getDescriptionVisibility,\n getStepAccessibleLabel,\n hasCustomStepLayout,\n positionStep,\n resolveConnections,\n STATUS_LABELS,\n type PositionedStep,\n type ProcessFlowConnection,\n type ProcessFlowDescriptionVisibility,\n type ProcessFlowOrientation,\n type ProcessFlowSize,\n type ProcessFlowStep,\n type ProcessFlowStepStatus,\n} from \"./ProcessFlow.utils\";\n\nimport type { ComponentPropsWithoutRef, CSSProperties, MouseEvent } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nexport { PROCESS_FLOW_STEP_STATUSES } from \"./ProcessFlow.utils\";\nexport type {\n ProcessFlowConnection,\n ProcessFlowOrientation,\n ProcessFlowSize,\n ProcessFlowStep,\n ProcessFlowStepConfig,\n ProcessFlowStepPosition,\n ProcessFlowStepStatus,\n ProcessStep,\n ProcessStepStatus,\n} from \"./ProcessFlow.utils\";\n\ntype ProcessFlowLayout = \"linear\" | \"branching\";\ntype ProcessFlowStepContentLayout = \"stacked\" | \"inline\" | \"anchored\";\n\nexport interface ProcessFlowStepSelectDetails {\n /** Zero-based index of the selected step in the steps prop. */\n stepIndex: number;\n /** Current visual status of the selected step. */\n status: ProcessFlowStepStatus;\n nativeEvent: MouseEvent<HTMLButtonElement>;\n}\n\n/**\n * Presentational process flow.\n *\n * ProcessFlow is fully controlled by props. It visualizes parent-owned workflow state and emits user selection through\n * onStepSelect. It intentionally does not own status transitions or fire completion/error side effects.\n */\nexport interface ProcessFlowProps extends Omit<ComponentPropsWithoutRef<\"nav\">, \"onSelect\"> {\n /** Ordered list of steps to render. Each step controls its own visual status. */\n steps: ProcessFlowStep[];\n /** Optional explicit connections for branching/configurable flows. */\n connections?: ProcessFlowConnection[];\n /** Selected/viewed step id. This is separate from the active workflow status. */\n selectedStepId?: string;\n /** Called when a selectable step is clicked. Disabled and non-selectable steps do not call this. */\n onStepSelect?: (step: ProcessFlowStep, details: ProcessFlowStepSelectDetails) => void;\n orientation?: ProcessFlowOrientation;\n size?: ProcessFlowSize;\n /** Defaults to true. Set to false to hide step descriptions. */\n showDescriptions?: boolean;\n}\n\ninterface StepControlClassOptions {\n layout: ProcessFlowLayout;\n contentLayout: ProcessFlowStepContentLayout;\n onStepSelect?: ProcessFlowProps[\"onStepSelect\"];\n isDisabled: boolean;\n isSelected: boolean;\n size: ProcessFlowSize;\n status: ProcessFlowStepStatus;\n}\n\nconst LINEAR_STEP_STATUS_CLASSES: Record<ProcessFlowStepStatus, string> = {\n pending: \"text-muted-foreground\",\n active: \"text-foreground\",\n completed: \"text-foreground\",\n error: \"text-destructive\",\n disabled: \"text-muted-foreground\",\n};\n\nconst MARKER_STATUS_CLASSES: Record<ProcessFlowStepStatus, string> = {\n pending: \"border-border bg-background text-muted-foreground\",\n active: \"border-primary bg-primary text-primary-foreground\",\n completed: \"border-positive bg-positive text-background\",\n error: \"border-destructive bg-destructive text-background\",\n disabled: \"border-border bg-muted text-muted-foreground\",\n};\n\nconst CONNECTION_STATUS_CLASSES: Record<ProcessFlowStepStatus, string> = {\n pending: \"stroke-muted-foreground/35\",\n active: \"stroke-primary\",\n completed: \"stroke-positive\",\n error: \"stroke-destructive\",\n disabled: \"stroke-border\",\n};\n\nconst STEP_MIN_WIDTH: Record<ProcessFlowSize, string> = {\n default: \"11rem\",\n compact: \"8.5rem\",\n};\n\nconst RESPONSIVE_STEP_MIN_WIDTH: Record<ProcessFlowSize, string> = {\n default: \"8rem\",\n compact: \"7rem\",\n};\n\nconst SQUEEZED_STEP_MIN_WIDTH: Record<ProcessFlowSize, string> = {\n default: \"5.5rem\",\n compact: \"4.75rem\",\n};\n\nconst MINI_STEP_MIN_WIDTH: Record<ProcessFlowSize, string> = {\n default: \"2.75rem\",\n compact: \"2.5rem\",\n};\n\nconst ROW_MIN_HEIGHT: Record<ProcessFlowSize, string> = {\n default: \"7.5rem\",\n compact: \"5.75rem\",\n};\n\nconst RESPONSIVE_ROW_MIN_HEIGHT: Record<ProcessFlowSize, string> = {\n default: \"6.5rem\",\n compact: \"5rem\",\n};\n\nconst SQUEEZED_ROW_MIN_HEIGHT: Record<ProcessFlowSize, string> = {\n default: \"4.5rem\",\n compact: \"3.75rem\",\n};\n\nconst MINI_ROW_MIN_HEIGHT: Record<ProcessFlowSize, string> = {\n default: \"3.5rem\",\n compact: \"3rem\",\n};\n\nconst GRID_GAP: Record<ProcessFlowSize, string> = {\n default: \"1.25rem\",\n compact: \"0.75rem\",\n};\n\nconst RESPONSIVE_GRID_GAP: Record<ProcessFlowSize, string> = {\n default: \"0.875rem\",\n compact: \"0.625rem\",\n};\n\nconst SQUEEZED_GRID_GAP: Record<ProcessFlowSize, string> = {\n default: \"0.5rem\",\n compact: \"0.375rem\",\n};\n\nconst MINI_GRID_GAP: Record<ProcessFlowSize, string> = {\n default: \"0.375rem\",\n compact: \"0.25rem\",\n};\n\nconst LINEAR_MARKER_SIZE: Record<ProcessFlowSize, string> = {\n default: \"2.5rem\",\n compact: \"1.75rem\",\n};\n\nconst RESPONSIVE_LINEAR_MARKER_SIZE: Record<ProcessFlowSize, string> = {\n default: \"2rem\",\n compact: \"1.5rem\",\n};\n\nconst SQUEEZED_LINEAR_MARKER_SIZE: Record<ProcessFlowSize, string> = {\n default: \"1.5rem\",\n compact: \"1.25rem\",\n};\n\nconst MINI_LINEAR_MARKER_SIZE: Record<ProcessFlowSize, string> = {\n default: \"1.25rem\",\n compact: \"1.125rem\",\n};\n\nfunction getMarkerContent(status: ProcessFlowStepStatus, stepNumber: number) {\n if (status === \"completed\") {\n return <CheckIcon aria-hidden=\"true\" />;\n }\n\n if (status === \"error\") {\n return <TriangleAlertIcon aria-hidden=\"true\" />;\n }\n\n if (status === \"disabled\") {\n return <LockIcon aria-hidden=\"true\" />;\n }\n\n if (status === \"active\") {\n return <DotIcon aria-hidden=\"true\" />;\n }\n\n return stepNumber;\n}\n\nfunction getLinearSegmentStyle(index: number, count: number): CSSProperties {\n return {\n left: `calc(${((index + 0.5) / count) * 100}% + (var(--process-flow-marker-size) / 2))`,\n width: `calc(${(1 / count) * 100}% - var(--process-flow-marker-size))`,\n };\n}\n\nfunction getVerticalSegmentStyle(index: number, count: number): CSSProperties {\n return {\n height: `calc(${(1 / count) * 100}% - var(--process-flow-marker-size))`,\n top: `calc(${((index + 0.5) / count) * 100}% + (var(--process-flow-marker-size) / 2))`,\n };\n}\n\nfunction getHorizontalRailStyle(): CSSProperties {\n const inset = \"calc(((100% / var(--process-flow-count)) / 2) + (var(--process-flow-marker-size) / 2))\";\n\n return {\n left: inset,\n right: inset,\n };\n}\n\nfunction getVerticalRailStyle(): CSSProperties {\n const inset = \"calc(((100% / var(--process-flow-count)) / 2) + (var(--process-flow-marker-size) / 2))\";\n\n return {\n bottom: inset,\n top: inset,\n };\n}\n\nfunction getStepControlClassName({ contentLayout, onStepSelect, isDisabled, size, status }: StepControlClassOptions) {\n return cn(\n \"flex w-full min-w-0 border-0 bg-transparent p-0 text-sm outline-none transition-all focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50\",\n contentLayout === \"inline\" && \"flex-row items-center gap-3 text-left\",\n contentLayout === \"stacked\" && \"flex-col items-center gap-2 text-center\",\n contentLayout === \"anchored\" && \"relative h-full flex-col items-center justify-center text-center\",\n size === \"compact\" && (contentLayout === \"inline\" ? \"gap-2\" : \"gap-1.5\"),\n onStepSelect &&\n !isDisabled &&\n cn(\"cursor-pointer hover:text-foreground\", contentLayout !== \"anchored\" && \"hover:-translate-y-px\"),\n onStepSelect && isDisabled && \"cursor-not-allowed\",\n LINEAR_STEP_STATUS_CLASSES[status],\n );\n}\n\nfunction getMarkerClassName({\n isSelected,\n size,\n status,\n}: Pick<StepControlClassOptions, \"isSelected\" | \"size\" | \"status\">) {\n return cn(\n \"flex size-[var(--process-flow-marker-size)] shrink-0 items-center justify-center rounded-full border text-xs font-semibold tabular-nums transition-colors [&_svg]:size-4\",\n size === \"compact\" && \"text-[0.7rem] [&_svg]:size-3\",\n \"shadow-[0_0_0_0.25rem_var(--background)]\",\n isSelected && \"ring-4 ring-primary/20\",\n MARKER_STATUS_CLASSES[status],\n );\n}\n\nfunction getLabelClassName({\n layout,\n isSelected,\n status,\n}: Pick<StepControlClassOptions, \"layout\" | \"isSelected\" | \"status\">) {\n return cn(\n \"block max-w-full truncate font-medium text-current\",\n layout === \"linear\" && isSelected && status === \"completed\" && \"text-positive\",\n layout === \"linear\" && isSelected && status !== \"completed\" && status !== \"error\" && \"text-primary\",\n );\n}\n\nfunction ProcessFlowStepControl({\n item,\n isSelected,\n onStepSelect,\n descriptionVisibility,\n size,\n layout,\n contentLayout,\n}: {\n item: PositionedStep;\n isSelected: boolean;\n onStepSelect?: ProcessFlowProps[\"onStepSelect\"];\n descriptionVisibility: ProcessFlowDescriptionVisibility;\n size: ProcessFlowSize;\n layout: ProcessFlowLayout;\n contentLayout: ProcessFlowStepContentLayout;\n}) {\n const { step, stepIndex, status } = item;\n const isDisabled = status === \"disabled\" || step.selectable === false;\n const accessibleLabel = getStepAccessibleLabel(step, status, stepIndex + 1);\n const textVisibility = descriptionVisibility === \"visible\" ? \"visible\" : \"auto\";\n const controlClassName = getStepControlClassName({\n layout,\n contentLayout,\n onStepSelect,\n isDisabled,\n isSelected,\n size,\n status,\n });\n const markerContent = (\n <span\n aria-hidden=\"true\"\n className={getMarkerClassName({\n isSelected,\n size,\n status,\n })}\n data-slot=\"process-flow-marker\"\n >\n {getMarkerContent(status, stepIndex + 1)}\n </span>\n );\n const textContent = (\n <span\n data-slot=\"process-flow-text\"\n data-text-visibility={textVisibility}\n className={cn(\n \"flex min-w-0 flex-col gap-0.5\",\n contentLayout === \"stacked\" && \"w-full items-center\",\n contentLayout === \"anchored\" &&\n \"pointer-events-none absolute left-1/2 top-[calc(50%+var(--process-flow-marker-size)/2+0.375rem)] w-max max-w-[calc(var(--process-flow-step-min-width)-0.5rem)] -translate-x-1/2 items-center px-1\",\n )}\n >\n <span className={getLabelClassName({ layout, isSelected, status })} data-slot=\"process-flow-label\">\n {step.label}\n </span>\n {descriptionVisibility !== \"hidden\" && step.description ? (\n <span\n className=\"line-clamp-2 text-xs leading-snug text-muted-foreground\"\n data-description-visibility={descriptionVisibility}\n data-slot=\"process-flow-description\"\n >\n {step.description}\n </span>\n ) : null}\n <span className=\"sr-only\">Status: {STATUS_LABELS[status]}</span>\n </span>\n );\n const content = (\n <>\n {markerContent}\n {textContent}\n </>\n );\n\n if (!onStepSelect) {\n return (\n <div\n aria-current={status === \"active\" ? \"step\" : undefined}\n aria-disabled={isDisabled || undefined}\n aria-invalid={status === \"error\" || undefined}\n aria-label={accessibleLabel}\n className={controlClassName}\n data-selected={isSelected || undefined}\n data-status={status}\n >\n {content}\n </div>\n );\n }\n\n return (\n <button\n type=\"button\"\n aria-current={status === \"active\" ? \"step\" : undefined}\n aria-invalid={status === \"error\" || undefined}\n aria-label={accessibleLabel}\n aria-pressed={isSelected}\n className={controlClassName}\n data-selected={isSelected || undefined}\n data-status={status}\n disabled={isDisabled}\n onClick={(nativeEvent) =>\n onStepSelect(step, {\n nativeEvent,\n status,\n stepIndex,\n })\n }\n >\n {content}\n </button>\n );\n}\n\nfunction HorizontalProcessFlow({\n steps,\n selectedStepId,\n onStepSelect,\n size,\n showDescriptions,\n}: Pick<ProcessFlowProps, \"steps\" | \"selectedStepId\" | \"onStepSelect\" | \"showDescriptions\"> & {\n size: ProcessFlowSize;\n}) {\n const positionedSteps = steps.map((step, index) => positionStep(step, index, \"horizontal\"));\n const resolvedConnections = resolveConnections(positionedSteps);\n const descriptionVisibility = getDescriptionVisibility(showDescriptions);\n const flowStyle = {\n \"--process-flow-count\": steps.length,\n \"--process-flow-step-min-width-base\": STEP_MIN_WIDTH[size],\n \"--process-flow-step-min-width-responsive\": RESPONSIVE_STEP_MIN_WIDTH[size],\n \"--process-flow-step-min-width-squeezed\": SQUEEZED_STEP_MIN_WIDTH[size],\n \"--process-flow-step-min-width-mini\": MINI_STEP_MIN_WIDTH[size],\n \"--process-flow-row-min-height-base\": ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-responsive\": RESPONSIVE_ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-squeezed\": SQUEEZED_ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-mini\": MINI_ROW_MIN_HEIGHT[size],\n \"--process-flow-marker-size-base\": LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-responsive\": RESPONSIVE_LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-squeezed\": SQUEEZED_LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-mini\": MINI_LINEAR_MARKER_SIZE[size],\n } as CSSProperties;\n\n return (\n <div className=\"overflow-hidden px-3 py-4\" data-slot=\"process-flow-viewport\" style={flowStyle}>\n <ol\n className=\"relative grid min-w-0 min-h-[var(--process-flow-row-min-height)] list-none p-0\"\n data-slot=\"process-flow-list\"\n style={{\n gridTemplateColumns: \"repeat(var(--process-flow-count), minmax(0, 1fr))\",\n }}\n >\n {steps.length > 1 ? (\n <li\n aria-hidden=\"true\"\n className=\"absolute top-[calc(var(--process-flow-marker-size)/2)] h-0.5 -translate-y-1/2 rounded-full bg-muted\"\n style={getHorizontalRailStyle()}\n />\n ) : null}\n {resolvedConnections.map((connection, index) => (\n <li\n key={connection.id}\n aria-hidden=\"true\"\n className={cn(\n \"absolute top-[calc(var(--process-flow-marker-size)/2)] h-0.5 -translate-y-1/2 rounded-full transition-colors\",\n connection.status === \"completed\" && \"bg-positive\",\n connection.status === \"active\" && \"bg-primary\",\n connection.status === \"error\" && \"bg-destructive\",\n connection.status === \"pending\" && \"bg-muted\",\n connection.status === \"disabled\" && \"bg-border\",\n )}\n style={getLinearSegmentStyle(index, steps.length)}\n />\n ))}\n {positionedSteps.map((item) => (\n <li\n key={item.step.id}\n className=\"relative z-[1] flex min-w-0 items-start justify-center\"\n data-slot=\"process-flow-item\"\n >\n <ProcessFlowStepControl\n item={item}\n contentLayout=\"stacked\"\n descriptionVisibility={descriptionVisibility}\n isSelected={selectedStepId === item.step.id}\n layout=\"linear\"\n onStepSelect={onStepSelect}\n size={size}\n />\n </li>\n ))}\n </ol>\n </div>\n );\n}\n\nfunction VerticalProcessFlow({\n steps,\n selectedStepId,\n onStepSelect,\n size,\n showDescriptions,\n}: Pick<ProcessFlowProps, \"steps\" | \"selectedStepId\" | \"onStepSelect\" | \"showDescriptions\"> & {\n size: ProcessFlowSize;\n}) {\n const positionedSteps = steps.map((step, index) => positionStep(step, index, \"vertical\"));\n const resolvedConnections = resolveConnections(positionedSteps);\n const descriptionVisibility = getDescriptionVisibility(showDescriptions);\n const flowStyle = {\n \"--process-flow-count\": steps.length,\n \"--process-flow-row-min-height-base\": ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-responsive\": RESPONSIVE_ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-squeezed\": SQUEEZED_ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-mini\": MINI_ROW_MIN_HEIGHT[size],\n \"--process-flow-marker-size-base\": LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-responsive\": RESPONSIVE_LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-squeezed\": SQUEEZED_LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-mini\": MINI_LINEAR_MARKER_SIZE[size],\n } as CSSProperties;\n\n return (\n <div className=\"overflow-x-auto px-3 py-3\" data-slot=\"process-flow-viewport\" style={flowStyle}>\n <ol\n className=\"relative grid min-h-[calc(var(--process-flow-count)*var(--process-flow-row-min-height))] min-w-72 list-none p-0\"\n data-slot=\"process-flow-list\"\n style={{\n gridTemplateRows: \"repeat(var(--process-flow-count), minmax(var(--process-flow-row-min-height), auto))\",\n }}\n >\n {steps.length > 1 ? (\n <li\n aria-hidden=\"true\"\n className=\"absolute left-[calc(var(--process-flow-marker-size)/2)] w-0.5 -translate-x-1/2 rounded-full bg-muted\"\n style={getVerticalRailStyle()}\n />\n ) : null}\n {resolvedConnections.map((connection, index) => (\n <li\n key={connection.id}\n aria-hidden=\"true\"\n className={cn(\n \"absolute left-[calc(var(--process-flow-marker-size)/2)] w-0.5 -translate-x-1/2 rounded-full transition-colors\",\n connection.status === \"completed\" && \"bg-positive\",\n connection.status === \"active\" && \"bg-primary\",\n connection.status === \"error\" && \"bg-destructive\",\n connection.status === \"pending\" && \"bg-muted\",\n connection.status === \"disabled\" && \"bg-border\",\n )}\n style={getVerticalSegmentStyle(index, steps.length)}\n />\n ))}\n {positionedSteps.map((item) => (\n <li key={item.step.id} className=\"relative z-[1] flex min-w-0 items-center\" data-slot=\"process-flow-item\">\n <ProcessFlowStepControl\n item={item}\n contentLayout=\"inline\"\n descriptionVisibility={descriptionVisibility}\n isSelected={selectedStepId === item.step.id}\n layout=\"linear\"\n onStepSelect={onStepSelect}\n size={size}\n />\n </li>\n ))}\n </ol>\n </div>\n );\n}\n\nexport function ProcessFlow({\n steps,\n connections,\n selectedStepId,\n onStepSelect,\n orientation = \"horizontal\",\n size = \"default\",\n showDescriptions,\n className,\n style,\n \"aria-label\": ariaLabel = \"Process flow\",\n ...props\n}: ProcessFlowProps) {\n if (steps.length === 0) {\n return null;\n }\n\n const layout: ProcessFlowLayout = connections || hasCustomStepLayout(steps) ? \"branching\" : \"linear\";\n\n if (layout === \"linear\" && orientation === \"horizontal\") {\n return (\n <nav\n aria-label={ariaLabel}\n className={cn(\"w-full min-w-0\", className)}\n data-orientation={orientation}\n data-slot=\"process-flow\"\n data-size={size}\n style={style}\n {...props}\n >\n <HorizontalProcessFlow\n steps={steps}\n selectedStepId={selectedStepId}\n onStepSelect={onStepSelect}\n showDescriptions={showDescriptions}\n size={size}\n />\n </nav>\n );\n }\n\n if (layout === \"linear\" && orientation === \"vertical\") {\n return (\n <nav\n aria-label={ariaLabel}\n className={cn(\"w-full min-w-0\", className)}\n data-orientation={orientation}\n data-slot=\"process-flow\"\n data-size={size}\n style={style}\n {...props}\n >\n <VerticalProcessFlow\n steps={steps}\n selectedStepId={selectedStepId}\n onStepSelect={onStepSelect}\n showDescriptions={showDescriptions}\n size={size}\n />\n </nav>\n );\n }\n\n const positionedSteps = steps.map((step, index) => positionStep(step, index, orientation));\n const rowCount = Math.max(...positionedSteps.map((step) => step.row + 1), 1);\n const columnCount = Math.max(...positionedSteps.map((step) => step.column + 1), 1);\n const resolvedConnections = resolveConnections(positionedSteps, connections);\n const descriptionVisibility = getDescriptionVisibility(showDescriptions);\n const flowStyle = {\n \"--process-flow-columns\": columnCount,\n \"--process-flow-rows\": rowCount,\n \"--process-flow-step-min-width-base\": STEP_MIN_WIDTH[size],\n \"--process-flow-step-min-width-responsive\": RESPONSIVE_STEP_MIN_WIDTH[size],\n \"--process-flow-step-min-width-squeezed\": SQUEEZED_STEP_MIN_WIDTH[size],\n \"--process-flow-step-min-width-mini\": MINI_STEP_MIN_WIDTH[size],\n \"--process-flow-row-min-height-base\": ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-responsive\": RESPONSIVE_ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-squeezed\": SQUEEZED_ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-mini\": MINI_ROW_MIN_HEIGHT[size],\n \"--process-flow-gap-base\": GRID_GAP[size],\n \"--process-flow-gap-responsive\": RESPONSIVE_GRID_GAP[size],\n \"--process-flow-gap-squeezed\": SQUEEZED_GRID_GAP[size],\n \"--process-flow-gap-mini\": MINI_GRID_GAP[size],\n \"--process-flow-marker-size-base\": LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-responsive\": RESPONSIVE_LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-squeezed\": SQUEEZED_LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-mini\": MINI_LINEAR_MARKER_SIZE[size],\n } as CSSProperties;\n\n return (\n <nav\n aria-label={ariaLabel}\n className={cn(\"w-full min-w-0\", className)}\n data-orientation={orientation}\n data-slot=\"process-flow\"\n data-size={size}\n style={style}\n {...props}\n >\n <div className=\"overflow-x-auto py-2\" data-slot=\"process-flow-viewport\" style={flowStyle}>\n <div\n className=\"relative min-w-[calc(var(--process-flow-columns)*var(--process-flow-step-min-width))] min-h-[calc(var(--process-flow-rows)*var(--process-flow-row-min-height))]\"\n data-slot=\"process-flow-canvas\"\n >\n <svg\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 z-0 size-full overflow-visible\"\n preserveAspectRatio=\"none\"\n viewBox=\"0 0 100 100\"\n >\n {resolvedConnections.map((connection) => (\n <path\n key={connection.id}\n className={cn(\n \"fill-none stroke-2 transition-colors\",\n CONNECTION_STATUS_CLASSES[connection.status],\n connection.status === \"disabled\" && \"opacity-60\",\n )}\n d={getConnectionPath(connection, rowCount, columnCount)}\n data-status={connection.status}\n strokeLinecap=\"round\"\n vectorEffect=\"non-scaling-stroke\"\n />\n ))}\n </svg>\n\n <ol\n className=\"relative z-[1] grid min-h-[inherit] list-none p-0\"\n data-slot=\"process-flow-list\"\n style={{\n gap: \"var(--process-flow-gap)\",\n gridTemplateColumns:\n \"repeat(var(--process-flow-columns), minmax(var(--process-flow-step-min-width), 1fr))\",\n gridTemplateRows: \"repeat(var(--process-flow-rows), minmax(var(--process-flow-row-min-height), auto))\",\n }}\n >\n {positionedSteps.map((item) => (\n <li\n key={item.step.id}\n className=\"flex min-w-0 items-center justify-center\"\n data-slot=\"process-flow-item\"\n style={{\n gridColumn: item.column + 1,\n gridRow: item.row + 1,\n }}\n >\n <ProcessFlowStepControl\n item={item}\n contentLayout=\"anchored\"\n descriptionVisibility={descriptionVisibility}\n isSelected={selectedStepId === item.step.id}\n layout=\"branching\"\n onStepSelect={onStepSelect}\n size={size}\n />\n </li>\n ))}\n </ol>\n </div>\n </div>\n </nav>\n );\n}\n"],"names":["LINEAR_STEP_STATUS_CLASSES","MARKER_STATUS_CLASSES","CONNECTION_STATUS_CLASSES","STEP_MIN_WIDTH","RESPONSIVE_STEP_MIN_WIDTH","SQUEEZED_STEP_MIN_WIDTH","MINI_STEP_MIN_WIDTH","ROW_MIN_HEIGHT","RESPONSIVE_ROW_MIN_HEIGHT","SQUEEZED_ROW_MIN_HEIGHT","MINI_ROW_MIN_HEIGHT","GRID_GAP","RESPONSIVE_GRID_GAP","SQUEEZED_GRID_GAP","MINI_GRID_GAP","LINEAR_MARKER_SIZE","RESPONSIVE_LINEAR_MARKER_SIZE","SQUEEZED_LINEAR_MARKER_SIZE","MINI_LINEAR_MARKER_SIZE","getMarkerContent","status","stepNumber","jsx","CheckIcon","TriangleAlertIcon","LockIcon","DotIcon","getLinearSegmentStyle","index","count","getVerticalSegmentStyle","getHorizontalRailStyle","inset","getVerticalRailStyle","getStepControlClassName","contentLayout","onStepSelect","isDisabled","size","cn","getMarkerClassName","isSelected","getLabelClassName","layout","ProcessFlowStepControl","item","descriptionVisibility","step","stepIndex","accessibleLabel","getStepAccessibleLabel","textVisibility","controlClassName","markerContent","textContent","jsxs","STATUS_LABELS","content","Fragment","nativeEvent","HorizontalProcessFlow","steps","selectedStepId","showDescriptions","positionedSteps","positionStep","resolvedConnections","resolveConnections","getDescriptionVisibility","flowStyle","connection","VerticalProcessFlow","ProcessFlow","connections","orientation","className","style","ariaLabel","props","hasCustomStepLayout","rowCount","columnCount","getConnectionPath"],"mappings":"wNA8EMA,EAAoE,CACxE,QAAS,wBACT,OAAQ,kBACR,UAAW,kBACX,MAAO,mBACP,SAAU,uBACZ,EAEMC,EAA+D,CACnE,QAAS,oDACT,OAAQ,oDACR,UAAW,8CACX,MAAO,oDACP,SAAU,8CACZ,EAEMC,EAAmE,CACvE,QAAS,6BACT,OAAQ,iBACR,UAAW,kBACX,MAAO,qBACP,SAAU,eACZ,EAEMC,EAAkD,CACtD,QAAS,QACT,QAAS,QACX,EAEMC,EAA6D,CACjE,QAAS,OACT,QAAS,MACX,EAEMC,EAA2D,CAC/D,QAAS,SACT,QAAS,SACX,EAEMC,EAAuD,CAC3D,QAAS,UACT,QAAS,QACX,EAEMC,EAAkD,CACtD,QAAS,SACT,QAAS,SACX,EAEMC,EAA6D,CACjE,QAAS,SACT,QAAS,MACX,EAEMC,EAA2D,CAC/D,QAAS,SACT,QAAS,SACX,EAEMC,EAAuD,CAC3D,QAAS,SACT,QAAS,MACX,EAEMC,EAA4C,CAChD,QAAS,UACT,QAAS,SACX,EAEMC,EAAuD,CAC3D,QAAS,WACT,QAAS,UACX,EAEMC,EAAqD,CACzD,QAAS,SACT,QAAS,UACX,EAEMC,EAAiD,CACrD,QAAS,WACT,QAAS,SACX,EAEMC,EAAsD,CAC1D,QAAS,SACT,QAAS,SACX,EAEMC,EAAiE,CACrE,QAAS,OACT,QAAS,QACX,EAEMC,EAA+D,CACnE,QAAS,SACT,QAAS,SACX,EAEMC,EAA2D,CAC/D,QAAS,UACT,QAAS,UACX,EAEA,SAASC,EAAiBC,EAA+BC,EAAoB,CAC3E,OAAID,IAAW,YACNE,EAAAA,IAACC,EAAAA,UAAA,CAAU,cAAY,MAAA,CAAO,EAGnCH,IAAW,QACNE,EAAAA,IAACE,EAAAA,kBAAA,CAAkB,cAAY,MAAA,CAAO,EAG3CJ,IAAW,WACNE,EAAAA,IAACG,EAAAA,SAAA,CAAS,cAAY,MAAA,CAAO,EAGlCL,IAAW,SACNE,EAAAA,IAACI,EAAAA,QAAA,CAAQ,cAAY,MAAA,CAAO,EAG9BL,CACT,CAEA,SAASM,EAAsBC,EAAeC,EAA8B,CAC1E,MAAO,CACL,KAAM,SAAUD,EAAQ,IAAOC,EAAS,GAAG,6CAC3C,MAAO,QAAS,EAAIA,EAAS,GAAG,sCAAA,CAEpC,CAEA,SAASC,EAAwBF,EAAeC,EAA8B,CAC5E,MAAO,CACL,OAAQ,QAAS,EAAIA,EAAS,GAAG,uCACjC,IAAK,SAAUD,EAAQ,IAAOC,EAAS,GAAG,4CAAA,CAE9C,CAEA,SAASE,GAAwC,CAC/C,MAAMC,EAAQ,yFAEd,MAAO,CACL,KAAMA,EACN,MAAOA,CAAA,CAEX,CAEA,SAASC,GAAsC,CAC7C,MAAMD,EAAQ,yFAEd,MAAO,CACL,OAAQA,EACR,IAAKA,CAAA,CAET,CAEA,SAASE,EAAwB,CAAE,cAAAC,EAAe,aAAAC,EAAc,WAAAC,EAAY,KAAAC,EAAM,OAAAlB,GAAmC,CACnH,OAAOmB,EAAAA,GACL,gKACAJ,IAAkB,UAAY,wCAC9BA,IAAkB,WAAa,0CAC/BA,IAAkB,YAAc,mEAChCG,IAAS,YAAcH,IAAkB,SAAW,QAAU,WAC9DC,GACE,CAACC,GACDE,EAAAA,GAAG,uCAAwCJ,IAAkB,YAAc,uBAAuB,EACpGC,GAAgBC,GAAc,qBAC9BrC,EAA2BoB,CAAM,CAAA,CAErC,CAEA,SAASoB,EAAmB,CAC1B,WAAAC,EACA,KAAAH,EACA,OAAAlB,CACF,EAAoE,CAClE,OAAOmB,EAAAA,GACL,2KACAD,IAAS,WAAa,+BACtB,2CACAG,GAAc,yBACdxC,EAAsBmB,CAAM,CAAA,CAEhC,CAEA,SAASsB,EAAkB,CACzB,OAAAC,EACA,WAAAF,EACA,OAAArB,CACF,EAAsE,CACpE,OAAOmB,EAAAA,GACL,qDACAI,IAAW,UAAYF,GAAcrB,IAAW,aAAe,gBAC/DuB,IAAW,UAAYF,GAAcrB,IAAW,aAAeA,IAAW,SAAW,cAAA,CAEzF,CAEA,SAASwB,EAAuB,CAC9B,KAAAC,EACA,WAAAJ,EACA,aAAAL,EACA,sBAAAU,EACA,KAAAR,EACA,OAAAK,EACA,cAAAR,CACF,EAQG,CACD,KAAM,CAAE,KAAAY,EAAM,UAAAC,EAAW,OAAA5B,CAAA,EAAWyB,EAC9BR,EAAajB,IAAW,YAAc2B,EAAK,aAAe,GAC1DE,EAAkBC,EAAAA,uBAAuBH,EAAM3B,EAAQ4B,EAAY,CAAC,EACpEG,EAAiBL,IAA0B,UAAY,UAAY,OACnEM,EAAmBlB,EAAwB,CAE/C,cAAAC,EACA,aAAAC,EACA,WAAAC,EAEA,KAAAC,EACA,OAAAlB,CAAA,CACD,EACKiC,EACJ/B,EAAAA,IAAC,OAAA,CACC,cAAY,OACZ,UAAWkB,EAAmB,CAC5B,WAAAC,EACA,KAAAH,EACA,OAAAlB,CAAA,CACD,EACD,YAAU,sBAET,SAAAD,EAAiBC,EAAQ4B,EAAY,CAAC,CAAA,CAAA,EAGrCM,EACJC,EAAAA,KAAC,OAAA,CACC,YAAU,oBACV,uBAAsBJ,EACtB,UAAWZ,EAAAA,GACT,gCACAJ,IAAkB,WAAa,sBAC/BA,IAAkB,YAChB,mMAAA,EAGJ,SAAA,CAAAb,EAAAA,IAAC,OAAA,CAAK,UAAWoB,EAAkB,CAAE,OAAAC,EAAQ,WAAAF,EAAY,OAAArB,CAAA,CAAQ,EAAG,YAAU,qBAC3E,SAAA2B,EAAK,KAAA,CACR,EACCD,IAA0B,UAAYC,EAAK,YAC1CzB,EAAAA,IAAC,OAAA,CACC,UAAU,0DACV,8BAA6BwB,EAC7B,YAAU,2BAET,SAAAC,EAAK,WAAA,CAAA,EAEN,KACJQ,EAAAA,KAAC,OAAA,CAAK,UAAU,UAAU,SAAA,CAAA,WAASC,EAAAA,cAAcpC,CAAM,CAAA,CAAA,CAAE,CAAA,CAAA,CAAA,EAGvDqC,EACJF,EAAAA,KAAAG,EAAAA,SAAA,CACG,SAAA,CAAAL,EACAC,CAAA,EACH,EAGF,OAAKlB,EAiBHd,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,eAAcF,IAAW,SAAW,OAAS,OAC7C,eAAcA,IAAW,SAAW,OACpC,aAAY6B,EACZ,eAAcR,EACd,UAAWW,EACX,gBAAeX,GAAc,OAC7B,cAAarB,EACb,SAAUiB,EACV,QAAUsB,GACRvB,EAAaW,EAAM,CACjB,YAAAY,EACA,OAAAvC,EACA,UAAA4B,CAAA,CACD,EAGF,SAAAS,CAAA,CAAA,EAjCDnC,EAAAA,IAAC,MAAA,CACC,eAAcF,IAAW,SAAW,OAAS,OAC7C,gBAAeiB,GAAc,OAC7B,eAAcjB,IAAW,SAAW,OACpC,aAAY6B,EACZ,UAAWG,EACX,gBAAeX,GAAc,OAC7B,cAAarB,EAEZ,SAAAqC,CAAA,CAAA,CA2BT,CAEA,SAASG,EAAsB,CAC7B,MAAAC,EACA,eAAAC,EACA,aAAA1B,EACA,KAAAE,EACA,iBAAAyB,CACF,EAEG,CACD,MAAMC,EAAkBH,EAAM,IAAI,CAACd,EAAMnB,IAAUqC,EAAAA,aAAalB,EAAMnB,EAAO,YAAY,CAAC,EACpFsC,EAAsBC,EAAAA,mBAAmBH,CAAe,EACxDlB,EAAwBsB,EAAAA,yBAAyBL,CAAgB,EACjEM,EAAY,CAChB,uBAAwBR,EAAM,OAC9B,qCAAsC1D,EAAemC,CAAI,EACzD,2CAA4ClC,EAA0BkC,CAAI,EAC1E,yCAA0CjC,EAAwBiC,CAAI,EACtE,qCAAsChC,EAAoBgC,CAAI,EAC9D,qCAAsC/B,EAAe+B,CAAI,EACzD,2CAA4C9B,EAA0B8B,CAAI,EAC1E,yCAA0C7B,EAAwB6B,CAAI,EACtE,qCAAsC5B,EAAoB4B,CAAI,EAC9D,kCAAmCvB,EAAmBuB,CAAI,EAC1D,wCAAyCtB,EAA8BsB,CAAI,EAC3E,sCAAuCrB,EAA4BqB,CAAI,EACvE,kCAAmCpB,EAAwBoB,CAAI,CAAA,EAGjE,aACG,MAAA,CAAI,UAAU,4BAA4B,YAAU,wBAAwB,MAAO+B,EAClF,SAAAd,EAAAA,KAAC,KAAA,CACC,UAAU,iFACV,YAAU,oBACV,MAAO,CACL,oBAAqB,mDAAA,EAGtB,SAAA,CAAAM,EAAM,OAAS,EACdvC,EAAAA,IAAC,KAAA,CACC,cAAY,OACZ,UAAU,sGACV,MAAOS,EAAA,CAAuB,CAAA,EAE9B,KACHmC,EAAoB,IAAI,CAACI,EAAY1C,IACpCN,EAAAA,IAAC,KAAA,CAEC,cAAY,OACZ,UAAWiB,EAAAA,GACT,+GACA+B,EAAW,SAAW,aAAe,cACrCA,EAAW,SAAW,UAAY,aAClCA,EAAW,SAAW,SAAW,iBACjCA,EAAW,SAAW,WAAa,WACnCA,EAAW,SAAW,YAAc,WAAA,EAEtC,MAAO3C,EAAsBC,EAAOiC,EAAM,MAAM,CAAA,EAV3CS,EAAW,EAAA,CAYnB,EACAN,EAAgB,IAAKnB,GACpBvB,EAAAA,IAAC,KAAA,CAEC,UAAU,yDACV,YAAU,oBAEV,SAAAA,EAAAA,IAACsB,EAAA,CACC,KAAAC,EACA,cAAc,UACd,sBAAAC,EACA,WAAYgB,IAAmBjB,EAAK,KAAK,GACzC,OAAO,SACP,aAAAT,EACA,KAAAE,CAAA,CAAA,CACF,EAZKO,EAAK,KAAK,EAAA,CAclB,CAAA,CAAA,CAAA,EAEL,CAEJ,CAEA,SAAS0B,EAAoB,CAC3B,MAAAV,EACA,eAAAC,EACA,aAAA1B,EACA,KAAAE,EACA,iBAAAyB,CACF,EAEG,CACD,MAAMC,EAAkBH,EAAM,IAAI,CAACd,EAAMnB,IAAUqC,EAAAA,aAAalB,EAAMnB,EAAO,UAAU,CAAC,EAClFsC,EAAsBC,EAAAA,mBAAmBH,CAAe,EACxDlB,EAAwBsB,EAAAA,yBAAyBL,CAAgB,EACjEM,EAAY,CAChB,uBAAwBR,EAAM,OAC9B,qCAAsCtD,EAAe+B,CAAI,EACzD,2CAA4C9B,EAA0B8B,CAAI,EAC1E,yCAA0C7B,EAAwB6B,CAAI,EACtE,qCAAsC5B,EAAoB4B,CAAI,EAC9D,kCAAmCvB,EAAmBuB,CAAI,EAC1D,wCAAyCtB,EAA8BsB,CAAI,EAC3E,sCAAuCrB,EAA4BqB,CAAI,EACvE,kCAAmCpB,EAAwBoB,CAAI,CAAA,EAGjE,aACG,MAAA,CAAI,UAAU,4BAA4B,YAAU,wBAAwB,MAAO+B,EAClF,SAAAd,EAAAA,KAAC,KAAA,CACC,UAAU,kHACV,YAAU,oBACV,MAAO,CACL,iBAAkB,qFAAA,EAGnB,SAAA,CAAAM,EAAM,OAAS,EACdvC,EAAAA,IAAC,KAAA,CACC,cAAY,OACZ,UAAU,uGACV,MAAOW,EAAA,CAAqB,CAAA,EAE5B,KACHiC,EAAoB,IAAI,CAACI,EAAY1C,IACpCN,EAAAA,IAAC,KAAA,CAEC,cAAY,OACZ,UAAWiB,EAAAA,GACT,gHACA+B,EAAW,SAAW,aAAe,cACrCA,EAAW,SAAW,UAAY,aAClCA,EAAW,SAAW,SAAW,iBACjCA,EAAW,SAAW,WAAa,WACnCA,EAAW,SAAW,YAAc,WAAA,EAEtC,MAAOxC,EAAwBF,EAAOiC,EAAM,MAAM,CAAA,EAV7CS,EAAW,EAAA,CAYnB,EACAN,EAAgB,IAAKnB,SACnB,KAAA,CAAsB,UAAU,2CAA2C,YAAU,oBACpF,SAAAvB,EAAAA,IAACsB,EAAA,CACC,KAAAC,EACA,cAAc,SACd,sBAAAC,EACA,WAAYgB,IAAmBjB,EAAK,KAAK,GACzC,OAAO,SACP,aAAAT,EACA,KAAAE,CAAA,CAAA,GARKO,EAAK,KAAK,EAUnB,CACD,CAAA,CAAA,CAAA,EAEL,CAEJ,CAEO,SAAS2B,GAAY,CAC1B,MAAAX,EACA,YAAAY,EACA,eAAAX,EACA,aAAA1B,EACA,YAAAsC,EAAc,aACd,KAAApC,EAAO,UACP,iBAAAyB,EACA,UAAAY,EACA,MAAAC,EACA,aAAcC,EAAY,eAC1B,GAAGC,CACL,EAAqB,CACnB,GAAIjB,EAAM,SAAW,EACnB,OAAO,KAGT,MAAMlB,EAA4B8B,GAAeM,EAAAA,oBAAoBlB,CAAK,EAAI,YAAc,SAE5F,GAAIlB,IAAW,UAAY+B,IAAgB,aACzC,OACEpD,EAAAA,IAAC,MAAA,CACC,aAAYuD,EACZ,UAAWtC,EAAAA,GAAG,iBAAkBoC,CAAS,EACzC,mBAAkBD,EAClB,YAAU,eACV,YAAWpC,EACX,MAAAsC,EACC,GAAGE,EAEJ,SAAAxD,EAAAA,IAACsC,EAAA,CACC,MAAAC,EACA,eAAAC,EACA,aAAA1B,EACA,iBAAA2B,EACA,KAAAzB,CAAA,CAAA,CACF,CAAA,EAKN,GAAIK,IAAW,UAAY+B,IAAgB,WACzC,OACEpD,EAAAA,IAAC,MAAA,CACC,aAAYuD,EACZ,UAAWtC,EAAAA,GAAG,iBAAkBoC,CAAS,EACzC,mBAAkBD,EAClB,YAAU,eACV,YAAWpC,EACX,MAAAsC,EACC,GAAGE,EAEJ,SAAAxD,EAAAA,IAACiD,EAAA,CACC,MAAAV,EACA,eAAAC,EACA,aAAA1B,EACA,iBAAA2B,EACA,KAAAzB,CAAA,CAAA,CACF,CAAA,EAKN,MAAM0B,EAAkBH,EAAM,IAAI,CAACd,EAAMnB,IAAUqC,EAAAA,aAAalB,EAAMnB,EAAO8C,CAAW,CAAC,EACnFM,EAAW,KAAK,IAAI,GAAGhB,EAAgB,IAAKjB,GAASA,EAAK,IAAM,CAAC,EAAG,CAAC,EACrEkC,EAAc,KAAK,IAAI,GAAGjB,EAAgB,IAAKjB,GAASA,EAAK,OAAS,CAAC,EAAG,CAAC,EAC3EmB,EAAsBC,EAAAA,mBAAmBH,EAAiBS,CAAW,EACrE3B,EAAwBsB,EAAAA,yBAAyBL,CAAgB,EACjEM,EAAY,CAChB,yBAA0BY,EAC1B,sBAAuBD,EACvB,qCAAsC7E,EAAemC,CAAI,EACzD,2CAA4ClC,EAA0BkC,CAAI,EAC1E,yCAA0CjC,EAAwBiC,CAAI,EACtE,qCAAsChC,EAAoBgC,CAAI,EAC9D,qCAAsC/B,EAAe+B,CAAI,EACzD,2CAA4C9B,EAA0B8B,CAAI,EAC1E,yCAA0C7B,EAAwB6B,CAAI,EACtE,qCAAsC5B,EAAoB4B,CAAI,EAC9D,0BAA2B3B,EAAS2B,CAAI,EACxC,gCAAiC1B,EAAoB0B,CAAI,EACzD,8BAA+BzB,EAAkByB,CAAI,EACrD,0BAA2BxB,EAAcwB,CAAI,EAC7C,kCAAmCvB,EAAmBuB,CAAI,EAC1D,wCAAyCtB,EAA8BsB,CAAI,EAC3E,sCAAuCrB,EAA4BqB,CAAI,EACvE,kCAAmCpB,EAAwBoB,CAAI,CAAA,EAGjE,OACEhB,EAAAA,IAAC,MAAA,CACC,aAAYuD,EACZ,UAAWtC,EAAAA,GAAG,iBAAkBoC,CAAS,EACzC,mBAAkBD,EAClB,YAAU,eACV,YAAWpC,EACX,MAAAsC,EACC,GAAGE,EAEJ,eAAC,MAAA,CAAI,UAAU,uBAAuB,YAAU,wBAAwB,MAAOT,EAC7E,SAAAd,EAAAA,KAAC,MAAA,CACC,UAAU,kKACV,YAAU,sBAEV,SAAA,CAAAjC,EAAAA,IAAC,MAAA,CACC,cAAY,OACZ,UAAU,sEACV,oBAAoB,OACpB,QAAQ,cAEP,SAAA4C,EAAoB,IAAKI,GACxBhD,EAAAA,IAAC,OAAA,CAEC,UAAWiB,EAAAA,GACT,uCACArC,EAA0BoE,EAAW,MAAM,EAC3CA,EAAW,SAAW,YAAc,YAAA,EAEtC,EAAGY,EAAAA,kBAAkBZ,EAAYU,EAAUC,CAAW,EACtD,cAAaX,EAAW,OACxB,cAAc,QACd,aAAa,oBAAA,EATRA,EAAW,EAAA,CAWnB,CAAA,CAAA,EAGHhD,EAAAA,IAAC,KAAA,CACC,UAAU,oDACV,YAAU,oBACV,MAAO,CACL,IAAK,0BACL,oBACE,uFACF,iBAAkB,oFAAA,EAGnB,SAAA0C,EAAgB,IAAKnB,GACpBvB,EAAAA,IAAC,KAAA,CAEC,UAAU,2CACV,YAAU,oBACV,MAAO,CACL,WAAYuB,EAAK,OAAS,EAC1B,QAASA,EAAK,IAAM,CAAA,EAGtB,SAAAvB,EAAAA,IAACsB,EAAA,CACC,KAAAC,EACA,cAAc,WACd,sBAAAC,EACA,WAAYgB,IAAmBjB,EAAK,KAAK,GACzC,OAAO,YACP,aAAAT,EACA,KAAAE,CAAA,CAAA,CACF,EAhBKO,EAAK,KAAK,EAAA,CAkBlB,CAAA,CAAA,CACH,CAAA,CAAA,CACF,CACF,CAAA,CAAA,CAGN"}