@meridial/react 0.1.0 → 0.1.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.
@@ -9,7 +9,7 @@ import {
9
9
  generateWorkflowName,
10
10
  useElementTracker,
11
11
  workflowSchema
12
- } from "./chunk-QCWLFL7O.js";
12
+ } from "./chunk-PRTYKFO3.js";
13
13
 
14
14
  // src/recorder.tsx
15
15
  import { useRef as useRef7, useState as useState7, useCallback as useCallback6, useEffect as useEffect4 } from "react";
@@ -507,36 +507,6 @@ function useAudioRecorder() {
507
507
 
508
508
  // src/hooks/use-click-capture.ts
509
509
  import { useEffect as useEffect2, useCallback as useCallback2 } from "react";
510
- function getStableElementId(el) {
511
- const meridialId = el.getAttribute("data-meridial-id");
512
- if (meridialId) return `[data-meridial-id="${meridialId}"]`;
513
- if (el.id) return `#${el.id}`;
514
- return getCssPath(el);
515
- }
516
- function getCssPath(el) {
517
- const parts = [];
518
- let current = el;
519
- while (current && current !== document.body) {
520
- let selector = current.tagName.toLowerCase();
521
- if (current.id) {
522
- parts.unshift(`#${current.id}`);
523
- break;
524
- }
525
- const parent = current.parentElement;
526
- if (parent) {
527
- const siblings = Array.from(parent.children).filter(
528
- (child) => child.tagName === current.tagName
529
- );
530
- if (siblings.length > 1) {
531
- const index = siblings.indexOf(current) + 1;
532
- selector += `:nth-of-type(${index})`;
533
- }
534
- }
535
- parts.unshift(selector);
536
- current = current.parentElement;
537
- }
538
- return parts.join(" > ");
539
- }
540
510
  function getElementLabel(el) {
541
511
  const ariaLabel = el.getAttribute("aria-label");
542
512
  if (ariaLabel) return ariaLabel;
@@ -549,19 +519,21 @@ function getElementLabel(el) {
549
519
  }
550
520
  function useClickCapture({
551
521
  enabled,
522
+ attribute,
552
523
  onCapture
553
524
  }) {
554
525
  const handleClick = useCallback2(
555
526
  (e) => {
556
527
  const target = e.target;
557
528
  if (!target || target.closest("[data-meridial-ui]")) return;
558
- const el = target.closest("[data-meridial-id]") ?? target;
559
- const elementId = getStableElementId(el);
529
+ const el = target.closest(`[${attribute}]`);
530
+ if (!el) return;
531
+ const elementId = el.getAttribute(attribute);
560
532
  const elementLabel = getElementLabel(el);
561
533
  const urlPath = window.location.pathname + window.location.search;
562
534
  onCapture({ elementId, elementLabel, urlPath, description: "" });
563
535
  },
564
- [onCapture]
536
+ [attribute, onCapture]
565
537
  );
566
538
  useEffect2(() => {
567
539
  if (!enabled) return;
@@ -1111,7 +1083,7 @@ function DeleteStepButton({
1111
1083
  motion2.div,
1112
1084
  {
1113
1085
  animate: controls,
1114
- className: "absolute top-0 left-0 h-full rounded-tl-lg rounded-bl-lg bg-red-200/40 dark:bg-red-300/40",
1086
+ className: "absolute top-0 left-0 h-full rounded-tl-lg rounded-bl-lg bg-red-400/40 dark:bg-red-300/40",
1115
1087
  initial: { width: "0%" }
1116
1088
  }
1117
1089
  ),
@@ -1489,6 +1461,7 @@ import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-run
1489
1461
  function Recorder({
1490
1462
  baseUrl = "",
1491
1463
  publishableKey,
1464
+ attribute = "data-meridial-id",
1492
1465
  cursor,
1493
1466
  onError
1494
1467
  }) {
@@ -1566,6 +1539,7 @@ function Recorder({
1566
1539
  );
1567
1540
  useClickCapture({
1568
1541
  enabled: isRecording,
1542
+ attribute,
1569
1543
  onCapture: (step) => {
1570
1544
  if (getLastElementId() === step.elementId) return;
1571
1545
  stepsRef.current.push(step);
@@ -1751,4 +1725,4 @@ function Recorder({
1751
1725
  export {
1752
1726
  Recorder
1753
1727
  };
1754
- //# sourceMappingURL=chunk-VDQAVB4N.js.map
1728
+ //# sourceMappingURL=chunk-RJFQIVZM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/recorder.tsx","../../ui/src/components/waveform.tsx","../src/hooks/use-recorder-state.ts","../src/hooks/use-audio-recorder.ts","../src/hooks/use-click-capture.ts","../src/hooks/use-workflows.ts","../src/storage.ts","../src/components/action-button.tsx","../src/components/step-badge.tsx","../src/components/workflow-row.tsx","../src/components/workflow-list-panel.tsx","../src/workflow-editor.tsx","../src/hooks/use-position.ts","../src/components/cursor-guide.tsx","../src/components/delete-step-button.tsx"],"sourcesContent":["\"use client\"\n\nimport { useRef, useState, useCallback, useEffect, type RefObject } from \"react\"\nimport { useDraggable } from \"@neodrag/react\"\nimport { motion, AnimatePresence } from \"motion/react\"\nimport { Waveform } from \"@workspace/ui/components/waveform\"\nimport { Separator } from \"@workspace/ui/components/separator\"\nimport { useRecorderState } from \"./hooks/use-recorder-state.js\"\nimport { useAudioRecorder } from \"./hooks/use-audio-recorder.js\"\nimport { useClickCapture } from \"./hooks/use-click-capture.js\"\nimport { useWorkflows } from \"./hooks/use-workflows.js\"\nimport { generateWorkflowName } from \"./constants.js\"\nimport { DragHandle } from \"./components/drag-handle.js\"\nimport { ActionButton } from \"./components/action-button.js\"\nimport { StepBadge } from \"./components/step-badge.js\"\nimport { WorkflowListPanel } from \"./components/workflow-list-panel.js\"\nimport { WorkflowEditor } from \"./workflow-editor.js\"\nimport { saveAudio, deleteAudio } from \"./storage.js\"\nimport {\n workflowSchema,\n apiWorkflowsResponseSchema,\n type Step,\n type Workflow,\n} from \"./schemas.js\"\n\ninterface RecorderProps {\n baseUrl?: string\n publishableKey?: string\n attribute?: string\n cursor?: React.ReactNode\n onError?: (error: string) => void\n}\n\nexport function Recorder({\n baseUrl = \"\",\n publishableKey,\n attribute = \"data-meridial-id\",\n cursor,\n onError,\n}: RecorderProps) {\n // 1) Setup draggable container for the recorder UI\n const draggableRef = useRef<HTMLDivElement>(null)\n const keylessWarned = useRef(false)\n\n useDraggable(draggableRef as RefObject<HTMLElement>)\n\n // 2) Initialize recorder, audio, and workflow state\n const [state, dispatch] = useRecorderState()\n const audio = useAudioRecorder()\n const wf = useWorkflows()\n\n // 3) Local UI state and refs for capture and remote workflows\n const [showPanel, setShowPanel] = useState(false)\n const [editorWorkflowId, setPlayerWorkflowId] = useState<string | null>(null)\n const stepsRef = useRef<Omit<Step, \"id\">[]>([])\n const streamRef = useRef<MediaStream | null>(null)\n const [serverWorkflows, setServerWorkflows] = useState<Workflow[]>([])\n\n const isRecording = state.status === \"recording\"\n const isPaused = state.status === \"paused\"\n\n // 4) Warn once if no publishable key (local-only mode)\n useEffect(() => {\n if (!publishableKey && !keylessWarned.current) {\n keylessWarned.current = true\n console.warn(\n \"[Meridial] No publishableKey provided. Workflows will only be saved locally.\"\n )\n }\n }, [publishableKey])\n\n // 5) Fetch server workflows when authenticated so the panel can show both local and remote workflows\n useEffect(() => {\n if (!publishableKey) return\n\n fetch(`${baseUrl}/api/workflows`, {\n headers: { Authorization: `Bearer ${publishableKey}` },\n })\n .then(async (res) => {\n const data = await res.json()\n if (!res.ok) {\n const msg =\n (data?.error as string) || `Request failed (${res.status})`\n onError?.(msg)\n return\n }\n if (!data.workflows) return\n const parsed = apiWorkflowsResponseSchema.safeParse(data)\n if (!parsed.success) {\n onError?.(\"Invalid workflows response\")\n return\n }\n if (parsed.data.error) {\n onError?.(parsed.data.error)\n return\n }\n const workflows = parsed.data.workflows ?? []\n const mapped: Workflow[] = []\n for (const w of workflows) {\n const workflow = workflowSchema.safeParse({\n id: w.id,\n name: w.name,\n steps: w.steps,\n configured: true,\n createdAt: new Date().toISOString(),\n })\n if (workflow.success) {\n mapped.push(workflow.data)\n } else {\n console.error(\n \"[Meridial] Invalid workflow shape:\",\n w.id,\n workflow.error\n )\n }\n }\n setServerWorkflows(mapped)\n })\n .catch((err) => {\n const msg = err instanceof Error ? err.message : String(err)\n onError?.(msg)\n })\n }, [publishableKey])\n\n // 6) Track last captured element id to avoid duplicate consecutive steps\n const getLastElementId = useCallback(\n () => stepsRef.current[stepsRef.current.length - 1]?.elementId,\n []\n )\n // 7) While recording, capture user clicks as workflow steps\n useClickCapture({\n enabled: isRecording,\n attribute,\n onCapture: (step) => {\n if (getLastElementId() === step.elementId) return\n stepsRef.current.push(step)\n dispatch({ type: \"STEP_CAPTURED\" })\n },\n })\n\n // 8) When microphone stream is ready, start audio recording\n const handleStreamReady = useCallback(\n (stream: MediaStream) => {\n streamRef.current = stream\n audio.start(stream)\n },\n [audio.start]\n )\n\n // 9) Start a fresh recording session and reset captured steps\n const handleStartRecording = useCallback(() => {\n stepsRef.current = []\n dispatch({ type: \"START_RECORDING\" })\n }, [dispatch])\n\n // 10) Handle main action button: open panel, pause, or resume\n const handleActionClick = useCallback(() => {\n if (state.status === \"idle\") {\n setShowPanel((prev) => !prev)\n } else if (state.status === \"recording\") {\n dispatch({ type: \"PAUSE\" })\n audio.pause()\n } else if (state.status === \"paused\") {\n dispatch({ type: \"RESUME\" })\n audio.resume()\n }\n }, [state.status, dispatch, audio])\n\n // 11) Finalize a paused recording into a local workflow and persist audio\n const handleSave = useCallback(async () => {\n dispatch({ type: \"SAVE\" })\n audio.stop()\n\n // 11.1) Generate workflow and audio identifiers\n const id = crypto.randomUUID()\n const audioKey = `audio-${id}`\n // 11.2) Promote captured click steps into full workflow steps with ids\n const steps: Step[] = stepsRef.current.map((s) => ({\n ...s,\n id: crypto.randomUUID(),\n }))\n\n // 11.3) Store the new workflow locally as unconfigured\n wf.addWorkflow({\n id,\n name: generateWorkflowName(),\n steps,\n audioKey,\n configured: false,\n createdAt: new Date().toISOString(),\n })\n\n // 11.4) Persist audio blob shortly after and mark save as complete\n setTimeout(async () => {\n if (audio.audioBlob) {\n await saveAudio(audioKey, audio.audioBlob).catch(() => {})\n }\n dispatch({ type: \"SAVE_COMPLETE\" })\n }, 200)\n }, [dispatch, audio, wf, publishableKey, baseUrl])\n\n // 12) Handle renaming a workflow in the list\n const handleRename = useCallback(\n (id: string, name: string) => {\n wf.updateWorkflow(id, { name })\n },\n [wf]\n )\n\n // 13) Delete a workflow and its associated audio (if present)\n const handleDelete = useCallback(\n (id: string) => {\n const workflow = wf.getWorkflow(id)\n if (workflow?.audioKey) {\n deleteAudio(workflow.audioKey).catch(() => {})\n }\n wf.deleteWorkflow(id)\n },\n [wf]\n )\n\n // 14) Open the inline editor to configure a given workflow\n const handleConfigure = useCallback((id: string) => {\n setPlayerWorkflowId(id)\n setShowPanel(false)\n }, [])\n\n // 15) Close the editor overlay\n const handleEditorClose = useCallback(() => {\n setPlayerWorkflowId(null)\n }, [])\n\n // 16) Refresh workflows when the editor deletes one remotely\n const handleWorkflowDeleted = useCallback(() => {\n wf.refresh()\n }, [wf])\n\n // 17) Merge local + server workflows for the panel, avoiding duplicates\n const allWorkflows = [\n ...wf.visibleWorkflows,\n ...serverWorkflows.filter(\n (sw) => !wf.visibleWorkflows.some((lw) => lw.id === sw.id)\n ),\n ]\n\n return (\n <>\n <div\n ref={draggableRef}\n data-meridial-ui\n className=\"fixed bottom-4 left-4 z-50 w-64 items-stretch rounded border border-border bg-card shadow-md\"\n >\n <AnimatePresence initial={false}>\n {showPanel && state.status === \"idle\" && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: \"auto\", opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.24, ease: \"easeOut\" }}\n style={{ overflow: \"hidden\" }}\n >\n <WorkflowListPanel\n workflows={allWorkflows}\n hasMore={wf.hasMore}\n remainingCount={wf.remainingCount}\n onLoadMore={wf.loadMore}\n onRename={handleRename}\n onDelete={handleDelete}\n onConfigure={handleConfigure}\n />\n </motion.div>\n )}\n </AnimatePresence>\n <div data-meridial-ui className=\"flex h-12 items-center\">\n <DragHandle className=\"px-2\" />\n <Separator orientation=\"vertical\" className=\"h-full\" />\n {state.status === \"idle\" ? (\n <button\n data-meridial-ui\n onClick={handleStartRecording}\n className=\"w-full cursor-pointer px-4 text-sm tracking-wide text-foreground uppercase\"\n >\n Start Recording\n </button>\n ) : (\n <div className=\"relative h-full w-full\">\n {isRecording && (\n <Waveform\n data-meridial-ui\n active={isRecording}\n height={48}\n mode=\"static\"\n barWidth={3}\n barGap={1}\n barRadius={1.5}\n onStreamReady={handleStreamReady}\n className=\"text-primary\"\n />\n )}\n\n {isPaused && (\n <button\n data-meridial-ui\n onClick={handleSave}\n className=\"absolute inset-0 flex cursor-pointer items-center justify-center text-sm backdrop-blur-[1px]\"\n >\n SAVE WORKFLOW\n </button>\n )}\n {isRecording && state.stepCount > 0 && (\n <StepBadge count={state.stepCount} />\n )}\n </div>\n )}\n <Separator orientation=\"vertical\" className=\"h-full\" />\n <ActionButton\n openPanel={showPanel}\n state={state}\n hasUnconfigured={wf.hasUnconfigured}\n onClick={handleActionClick}\n />\n </div>\n </div>\n\n {editorWorkflowId && (\n <WorkflowEditor\n workflowId={editorWorkflowId}\n workflow={allWorkflows.find((w) => w.id === editorWorkflowId)}\n publishableKey={publishableKey}\n cursor={cursor}\n onClose={handleEditorClose}\n onWorkflowDeleted={handleWorkflowDeleted}\n onError={onError}\n />\n )}\n </>\n )\n}\n","\"use client\"\n\nimport { useEffect, useRef, type HTMLAttributes } from \"react\"\n\nimport { cn } from \"@workspace/ui/lib/utils\"\n\nexport type WaveformProps = HTMLAttributes<HTMLDivElement> & {\n active?: boolean\n processing?: boolean\n deviceId?: string\n barWidth?: number\n barHeight?: number\n barGap?: number\n barRadius?: number\n barColor?: string\n fadeEdges?: boolean\n fadeWidth?: number\n height?: string | number\n sensitivity?: number\n smoothingTimeConstant?: number\n fftSize?: number\n historySize?: number\n updateRate?: number\n mode?: \"scrolling\" | \"static\"\n onError?: (error: Error) => void\n onStreamReady?: (stream: MediaStream) => void\n onStreamEnd?: () => void\n}\n\nexport const Waveform = ({\n active = false,\n processing = false,\n deviceId,\n barWidth = 3,\n barGap = 1,\n barRadius = 1.5,\n barColor,\n fadeEdges = true,\n fadeWidth = 24,\n barHeight: baseBarHeight = 4,\n height = 64,\n sensitivity = 1,\n smoothingTimeConstant = 0.8,\n fftSize = 256,\n historySize = 60,\n updateRate = 30,\n mode = \"static\",\n onError,\n onStreamReady,\n onStreamEnd,\n className,\n ...props\n}: WaveformProps) => {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const historyRef = useRef<number[]>([])\n const analyserRef = useRef<AnalyserNode | null>(null)\n const audioContextRef = useRef<AudioContext | null>(null)\n const streamRef = useRef<MediaStream | null>(null)\n const animationRef = useRef<number>(0)\n const lastUpdateRef = useRef<number>(0)\n const processingAnimationRef = useRef<number | null>(null)\n const lastActiveDataRef = useRef<number[]>([])\n const transitionProgressRef = useRef(0)\n const staticBarsRef = useRef<number[]>([])\n const needsRedrawRef = useRef(true)\n const gradientCacheRef = useRef<CanvasGradient | null>(null)\n const lastWidthRef = useRef(0)\n\n const heightStyle = typeof height === \"number\" ? `${height}px` : height\n\n // Handle canvas resizing\n useEffect(() => {\n const canvas = canvasRef.current\n const container = containerRef.current\n if (!canvas || !container) return\n\n const resizeObserver = new ResizeObserver(() => {\n const rect = container.getBoundingClientRect()\n const dpr = window.devicePixelRatio || 1\n\n canvas.width = rect.width * dpr\n canvas.height = rect.height * dpr\n canvas.style.width = `${rect.width}px`\n canvas.style.height = `${rect.height}px`\n\n const ctx = canvas.getContext(\"2d\")\n if (ctx) {\n ctx.scale(dpr, dpr)\n }\n\n gradientCacheRef.current = null\n lastWidthRef.current = rect.width\n needsRedrawRef.current = true\n })\n\n resizeObserver.observe(container)\n return () => resizeObserver.disconnect()\n }, [])\n\n useEffect(() => {\n if (processing && !active) {\n let time = 0\n transitionProgressRef.current = 0\n\n const animateProcessing = () => {\n time += 0.03\n transitionProgressRef.current = Math.min(\n 1,\n transitionProgressRef.current + 0.02\n )\n\n const processingData = []\n const barCount = Math.floor(\n (containerRef.current?.getBoundingClientRect().width || 200) /\n (barWidth + barGap)\n )\n\n if (mode === \"static\") {\n const halfCount = Math.floor(barCount / 2)\n\n for (let i = 0; i < barCount; i++) {\n const normalizedPosition = (i - halfCount) / halfCount\n const centerWeight = 1 - Math.abs(normalizedPosition) * 0.4\n\n const wave1 = Math.sin(time * 1.5 + normalizedPosition * 3) * 0.25\n const wave2 = Math.sin(time * 0.8 - normalizedPosition * 2) * 0.2\n const wave3 = Math.cos(time * 2 + normalizedPosition) * 0.15\n const combinedWave = wave1 + wave2 + wave3\n const processingValue = (0.2 + combinedWave) * centerWeight\n\n let finalValue = processingValue\n if (\n lastActiveDataRef.current.length > 0 &&\n transitionProgressRef.current < 1\n ) {\n const lastDataIndex = Math.min(\n i,\n lastActiveDataRef.current.length - 1\n )\n const lastValue = lastActiveDataRef.current[lastDataIndex] || 0\n finalValue =\n lastValue * (1 - transitionProgressRef.current) +\n processingValue * transitionProgressRef.current\n }\n\n processingData.push(Math.max(0.05, Math.min(1, finalValue)))\n }\n } else {\n for (let i = 0; i < barCount; i++) {\n const normalizedPosition = (i - barCount / 2) / (barCount / 2)\n const centerWeight = 1 - Math.abs(normalizedPosition) * 0.4\n\n const wave1 = Math.sin(time * 1.5 + i * 0.15) * 0.25\n const wave2 = Math.sin(time * 0.8 - i * 0.1) * 0.2\n const wave3 = Math.cos(time * 2 + i * 0.05) * 0.15\n const combinedWave = wave1 + wave2 + wave3\n const processingValue = (0.2 + combinedWave) * centerWeight\n\n let finalValue = processingValue\n if (\n lastActiveDataRef.current.length > 0 &&\n transitionProgressRef.current < 1\n ) {\n const lastDataIndex = Math.floor(\n (i / barCount) * lastActiveDataRef.current.length\n )\n const lastValue = lastActiveDataRef.current[lastDataIndex] || 0\n finalValue =\n lastValue * (1 - transitionProgressRef.current) +\n processingValue * transitionProgressRef.current\n }\n\n processingData.push(Math.max(0.05, Math.min(1, finalValue)))\n }\n }\n\n if (mode === \"static\") {\n staticBarsRef.current = processingData\n } else {\n historyRef.current = processingData\n }\n\n needsRedrawRef.current = true\n processingAnimationRef.current =\n requestAnimationFrame(animateProcessing)\n }\n\n animateProcessing()\n\n return () => {\n if (processingAnimationRef.current) {\n cancelAnimationFrame(processingAnimationRef.current)\n }\n }\n } else if (!active && !processing) {\n const hasData =\n mode === \"static\"\n ? staticBarsRef.current.length > 0\n : historyRef.current.length > 0\n\n if (hasData) {\n let fadeProgress = 0\n const fadeToIdle = () => {\n fadeProgress += 0.03\n if (fadeProgress < 1) {\n if (mode === \"static\") {\n staticBarsRef.current = staticBarsRef.current.map(\n (value) => value * (1 - fadeProgress)\n )\n } else {\n historyRef.current = historyRef.current.map(\n (value) => value * (1 - fadeProgress)\n )\n }\n needsRedrawRef.current = true\n requestAnimationFrame(fadeToIdle)\n } else {\n if (mode === \"static\") {\n staticBarsRef.current = []\n } else {\n historyRef.current = []\n }\n }\n }\n fadeToIdle()\n }\n }\n }, [processing, active, barWidth, barGap, mode])\n\n // Handle microphone setup and teardown\n useEffect(() => {\n if (!active) {\n if (streamRef.current) {\n streamRef.current.getTracks().forEach((track) => track.stop())\n streamRef.current = null\n onStreamEnd?.()\n }\n if (\n audioContextRef.current &&\n audioContextRef.current.state !== \"closed\"\n ) {\n audioContextRef.current.close()\n audioContextRef.current = null\n }\n if (animationRef.current) {\n cancelAnimationFrame(animationRef.current)\n animationRef.current = 0\n }\n return\n }\n\n const setupMicrophone = async () => {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: deviceId\n ? {\n deviceId: { exact: deviceId },\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n }\n : {\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n },\n })\n streamRef.current = stream\n onStreamReady?.(stream)\n\n const AudioContextConstructor =\n window.AudioContext ||\n (window as unknown as { webkitAudioContext: typeof AudioContext })\n .webkitAudioContext\n const audioContext = new AudioContextConstructor()\n const analyser = audioContext.createAnalyser()\n analyser.fftSize = fftSize\n analyser.smoothingTimeConstant = smoothingTimeConstant\n\n const source = audioContext.createMediaStreamSource(stream)\n source.connect(analyser)\n\n audioContextRef.current = audioContext\n analyserRef.current = analyser\n\n // Clear history when starting\n historyRef.current = []\n } catch (error) {\n onError?.(error as Error)\n }\n }\n\n setupMicrophone()\n\n return () => {\n if (streamRef.current) {\n streamRef.current.getTracks().forEach((track) => track.stop())\n streamRef.current = null\n onStreamEnd?.()\n }\n if (\n audioContextRef.current &&\n audioContextRef.current.state !== \"closed\"\n ) {\n audioContextRef.current.close()\n audioContextRef.current = null\n }\n if (animationRef.current) {\n cancelAnimationFrame(animationRef.current)\n animationRef.current = 0\n }\n }\n }, [\n active,\n deviceId,\n fftSize,\n smoothingTimeConstant,\n onError,\n onStreamReady,\n onStreamEnd,\n ])\n\n // Animation loop\n useEffect(() => {\n const canvas = canvasRef.current\n if (!canvas) return\n\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n let rafId: number\n\n const animate = (currentTime: number) => {\n // Render waveform\n const rect = canvas.getBoundingClientRect()\n\n // Update audio data if active\n if (active && currentTime - lastUpdateRef.current > updateRate) {\n lastUpdateRef.current = currentTime\n\n if (analyserRef.current) {\n const dataArray = new Uint8Array(\n analyserRef.current.frequencyBinCount\n )\n analyserRef.current.getByteFrequencyData(dataArray)\n\n if (mode === \"static\") {\n // For static mode, update bars in place\n const startFreq = Math.floor(dataArray.length * 0.05)\n const endFreq = Math.floor(dataArray.length * 0.4)\n const relevantData = dataArray.slice(startFreq, endFreq)\n\n const barCount = Math.floor(rect.width / (barWidth + barGap))\n const halfCount = Math.floor(barCount / 2)\n const newBars: number[] = []\n\n // Mirror the data for symmetric display\n for (let i = halfCount - 1; i >= 0; i--) {\n const dataIndex = Math.floor(\n (i / halfCount) * relevantData.length\n )\n const source = relevantData[dataIndex] ?? 0\n const value = Math.min(1, (source / 255) * sensitivity)\n newBars.push(Math.max(0.05, value))\n }\n\n for (let i = 0; i < halfCount; i++) {\n const dataIndex = Math.floor(\n (i / halfCount) * relevantData.length\n )\n const source = relevantData[dataIndex] ?? 0\n const value = Math.min(1, (source / 255) * sensitivity)\n newBars.push(Math.max(0.05, value))\n }\n\n staticBarsRef.current = newBars\n lastActiveDataRef.current = newBars\n } else {\n // Scrolling mode - original behavior\n let sum = 0\n const startFreq = Math.floor(dataArray.length * 0.05)\n const endFreq = Math.floor(dataArray.length * 0.4)\n const relevantData = dataArray.slice(startFreq, endFreq)\n\n for (let i = 0; i < relevantData.length; i++) {\n const sample = relevantData[i] ?? 0\n sum += sample\n }\n const average =\n (sum / (relevantData.length || 1) / 255) * sensitivity\n\n // Add to history\n historyRef.current.push(Math.min(1, Math.max(0.05, average)))\n lastActiveDataRef.current = [...historyRef.current]\n\n // Maintain history size\n if (historyRef.current.length > historySize) {\n historyRef.current.shift()\n }\n }\n needsRedrawRef.current = true\n }\n }\n\n // Only redraw if needed\n if (!needsRedrawRef.current && !active) {\n rafId = requestAnimationFrame(animate)\n return\n }\n\n needsRedrawRef.current = active\n ctx.clearRect(0, 0, rect.width, rect.height)\n\n const computedBarColor =\n barColor ||\n (() => {\n const style = getComputedStyle(canvas)\n // Try to get the computed color value directly\n const color = style.color\n return color || \"#000\"\n })()\n\n const step = barWidth + barGap\n const barCount = Math.floor(rect.width / step)\n const centerY = rect.height / 2\n\n // Draw bars based on mode\n if (mode === \"static\") {\n // Static mode - bars in fixed positions\n const dataToRender = processing\n ? staticBarsRef.current\n : active\n ? staticBarsRef.current\n : staticBarsRef.current.length > 0\n ? staticBarsRef.current\n : []\n\n for (let i = 0; i < barCount && i < dataToRender.length; i++) {\n const value = dataToRender[i] || 0.1\n const x = i * step\n const barHeight = Math.max(baseBarHeight, value * rect.height * 0.8)\n const y = centerY - barHeight / 2\n\n ctx.fillStyle = computedBarColor\n ctx.globalAlpha = 0.4 + value * 0.6\n\n if (barRadius > 0) {\n ctx.beginPath()\n ctx.roundRect(x, y, barWidth, barHeight, barRadius)\n ctx.fill()\n } else {\n ctx.fillRect(x, y, barWidth, barHeight)\n }\n }\n } else {\n // Scrolling mode - original behavior\n for (let i = 0; i < barCount && i < historyRef.current.length; i++) {\n const dataIndex = historyRef.current.length - 1 - i\n const value = historyRef.current[dataIndex] || 0.1\n const x = rect.width - (i + 1) * step\n const barHeight = Math.max(baseBarHeight, value * rect.height * 0.8)\n const y = centerY - barHeight / 2\n\n ctx.fillStyle = computedBarColor\n ctx.globalAlpha = 0.4 + value * 0.6\n\n if (barRadius > 0) {\n ctx.beginPath()\n ctx.roundRect(x, y, barWidth, barHeight, barRadius)\n ctx.fill()\n } else {\n ctx.fillRect(x, y, barWidth, barHeight)\n }\n }\n }\n\n // Apply edge fading\n if (fadeEdges && fadeWidth > 0 && rect.width > 0) {\n // Cache gradient if width hasn't changed\n if (!gradientCacheRef.current || lastWidthRef.current !== rect.width) {\n const gradient = ctx.createLinearGradient(0, 0, rect.width, 0)\n const fadePercent = Math.min(0.3, fadeWidth / rect.width)\n\n // destination-out: removes destination where source alpha is high\n // We want: fade edges out, keep center solid\n // Left edge: start opaque (1) = remove, fade to transparent (0) = keep\n gradient.addColorStop(0, \"rgba(255,255,255,1)\")\n gradient.addColorStop(fadePercent, \"rgba(255,255,255,0)\")\n // Center stays transparent = keep everything\n gradient.addColorStop(1 - fadePercent, \"rgba(255,255,255,0)\")\n // Right edge: fade from transparent (0) = keep to opaque (1) = remove\n gradient.addColorStop(1, \"rgba(255,255,255,1)\")\n\n gradientCacheRef.current = gradient\n lastWidthRef.current = rect.width\n }\n\n ctx.globalCompositeOperation = \"destination-out\"\n ctx.fillStyle = gradientCacheRef.current\n ctx.fillRect(0, 0, rect.width, rect.height)\n ctx.globalCompositeOperation = \"source-over\"\n }\n\n ctx.globalAlpha = 1\n\n rafId = requestAnimationFrame(animate)\n }\n\n rafId = requestAnimationFrame(animate)\n\n return () => {\n if (rafId) {\n cancelAnimationFrame(rafId)\n }\n }\n }, [\n active,\n processing,\n sensitivity,\n updateRate,\n historySize,\n barWidth,\n baseBarHeight,\n barGap,\n barRadius,\n barColor,\n fadeEdges,\n fadeWidth,\n mode,\n ])\n\n return (\n <div\n className={cn(\"relative h-full w-full\", className)}\n ref={containerRef}\n style={{ height: heightStyle }}\n aria-label={\n active\n ? \"Live audio waveform\"\n : processing\n ? \"Processing audio\"\n : \"Audio waveform idle\"\n }\n role=\"img\"\n {...props}\n >\n {!active && !processing && (\n <div className=\"absolute top-1/2 right-0 left-0 -translate-y-1/2 border-t-2 border-dotted border-muted-foreground/20\" />\n )}\n <canvas\n className=\"block h-full w-full\"\n ref={canvasRef}\n aria-hidden=\"true\"\n />\n </div>\n )\n}\n","import { useReducer } from \"react\"\n\ntype RecorderState =\n | { status: \"idle\" }\n | { status: \"recording\"; stepCount: number; startTime: number }\n | { status: \"paused\"; stepCount: number }\n | { status: \"saving\" }\n\ntype RecorderAction =\n | { type: \"START_RECORDING\" }\n | { type: \"STEP_CAPTURED\" }\n | { type: \"PAUSE\" }\n | { type: \"RESUME\" }\n | { type: \"SAVE\" }\n | { type: \"SAVE_COMPLETE\" }\n\nfunction recorderReducer(\n state: RecorderState,\n action: RecorderAction\n): RecorderState {\n switch (action.type) {\n case \"START_RECORDING\":\n return { status: \"recording\", stepCount: 0, startTime: Date.now() }\n case \"STEP_CAPTURED\":\n if (state.status === \"recording\") {\n return { ...state, stepCount: state.stepCount + 1 }\n }\n return state\n case \"PAUSE\":\n if (state.status === \"recording\") {\n return { status: \"paused\", stepCount: state.stepCount }\n }\n return state\n case \"RESUME\":\n if (state.status === \"paused\") {\n return {\n status: \"recording\",\n stepCount: state.stepCount,\n startTime: Date.now(),\n }\n }\n return state\n case \"SAVE\":\n if (state.status === \"paused\") {\n return { status: \"saving\" }\n }\n return state\n case \"SAVE_COMPLETE\":\n return { status: \"idle\" }\n default:\n return state\n }\n}\n\nconst initialState: RecorderState = { status: \"idle\" }\n\nexport function useRecorderState() {\n return useReducer(recorderReducer, initialState)\n}\n\nexport type { RecorderState, RecorderAction }\n","import { useRef, useState, useCallback } from \"react\"\n\nexport function useAudioRecorder() {\n const mediaRecorderRef = useRef<MediaRecorder | null>(null)\n const chunksRef = useRef<Blob[]>([])\n const [audioBlob, setAudioBlob] = useState<Blob | null>(null)\n\n const start = useCallback((stream: MediaStream) => {\n chunksRef.current = []\n setAudioBlob(null)\n const recorder = new MediaRecorder(stream)\n recorder.ondataavailable = (e) => {\n if (e.data.size > 0) {\n chunksRef.current.push(e.data)\n }\n }\n recorder.onstop = () => {\n const blob = new Blob(chunksRef.current, { type: \"audio/webm\" })\n setAudioBlob(blob)\n }\n recorder.start()\n mediaRecorderRef.current = recorder\n }, [])\n\n const stop = useCallback(() => {\n if (\n mediaRecorderRef.current &&\n mediaRecorderRef.current.state !== \"inactive\"\n ) {\n mediaRecorderRef.current.stop()\n }\n }, [])\n\n const pause = useCallback(() => {\n if (\n mediaRecorderRef.current &&\n mediaRecorderRef.current.state === \"recording\"\n ) {\n mediaRecorderRef.current.pause()\n }\n }, [])\n\n const resume = useCallback(() => {\n if (\n mediaRecorderRef.current &&\n mediaRecorderRef.current.state === \"paused\"\n ) {\n mediaRecorderRef.current.resume()\n }\n }, [])\n\n return { start, stop, pause, resume, audioBlob } as const\n}\n","import { useEffect, useCallback } from \"react\"\nimport type { Step } from \"../schemas.js\"\n\nfunction getElementLabel(el: HTMLElement): string {\n const ariaLabel = el.getAttribute(\"aria-label\")\n if (ariaLabel) return ariaLabel\n\n const placeholder = el.getAttribute(\"placeholder\")\n if (placeholder) return placeholder\n\n const text = el.innerText?.trim()\n if (text && text.length <= 50) return text\n\n const tag = el.tagName.toLowerCase()\n return el.id ? `${tag}#${el.id}` : tag\n}\n\ninterface UseClickCaptureOptions {\n enabled: boolean\n attribute: string\n onCapture: (step: Omit<Step, \"id\">) => void\n}\n\nexport function useClickCapture({\n enabled,\n attribute,\n onCapture,\n}: UseClickCaptureOptions) {\n const handleClick = useCallback(\n (e: MouseEvent) => {\n const target = e.target as HTMLElement | null\n\n if (!target || target.closest(\"[data-meridial-ui]\")) return\n\n const el = target.closest(`[${attribute}]`) as HTMLElement | null\n if (!el) return // skip — element not stamped by SWC plugin\n\n const elementId = el.getAttribute(attribute)! // bare ID only\n const elementLabel = getElementLabel(el)\n const urlPath = window.location.pathname + window.location.search\n\n onCapture({ elementId, elementLabel, urlPath, description: \"\" })\n },\n [attribute, onCapture]\n )\n\n useEffect(() => {\n if (!enabled) return\n\n document.addEventListener(\"click\", handleClick, true)\n return () => {\n document.removeEventListener(\"click\", handleClick, true)\n }\n }, [enabled, handleClick])\n}\n","import { useState, useCallback, useMemo } from \"react\"\nimport type { Workflow } from \"../schemas.js\"\nimport * as storage from \"../storage.js\"\n\nconst PAGE_SIZE = 5\n\nexport function useWorkflows() {\n const [workflows, setWorkflows] = useState<Workflow[]>(() =>\n storage.loadWorkflows()\n )\n const [visibleCount, setVisibleCount] = useState(PAGE_SIZE)\n\n const sorted = useMemo(() => {\n const unconfigured = workflows.filter((w) => !w.configured)\n const configured = workflows.filter((w) => w.configured)\n return [...unconfigured, ...configured]\n }, [workflows])\n\n const hasUnconfigured = useMemo(\n () => workflows.some((w) => !w.configured),\n [workflows]\n )\n\n const visibleWorkflows = useMemo(\n () => sorted.slice(0, visibleCount),\n [sorted, visibleCount]\n )\n\n const hasMore = sorted.length > visibleCount\n const remainingCount = sorted.length - visibleCount\n\n const loadMore = useCallback(() => {\n setVisibleCount((c) => c + PAGE_SIZE)\n }, [])\n\n const refresh = useCallback(() => {\n setWorkflows(storage.loadWorkflows())\n }, [])\n\n const addWorkflow = useCallback((workflow: Workflow) => {\n storage.addWorkflow(workflow)\n setWorkflows(storage.loadWorkflows())\n }, [])\n\n const updateWorkflow = useCallback(\n (id: string, updates: Partial<Workflow>) => {\n storage.updateWorkflow(id, updates)\n setWorkflows(storage.loadWorkflows())\n },\n []\n )\n\n const deleteWorkflow = useCallback((id: string) => {\n storage.deleteWorkflow(id)\n setWorkflows(storage.loadWorkflows())\n }, [])\n\n const getWorkflow = useCallback((id: string) => {\n return storage.getWorkflow(id)\n }, [])\n\n return {\n workflows,\n hasUnconfigured,\n visibleWorkflows,\n loadMore,\n hasMore,\n remainingCount,\n addWorkflow,\n updateWorkflow,\n deleteWorkflow,\n getWorkflow,\n refresh,\n } as const\n}\n","import { z } from \"zod\"\nimport { STORAGE_KEYS } from \"./constants.js\"\nimport { workflowSchema, type Workflow } from \"./schemas.js\"\n\nconst workflowsArraySchema = z.array(workflowSchema)\n\n// --- localStorage: Workflows ---\n\nconst isBrowser = typeof window !== \"undefined\"\n\nexport function loadWorkflows(): Workflow[] {\n if (!isBrowser) return []\n try {\n const raw = localStorage.getItem(STORAGE_KEYS.workflows)\n if (!raw) return []\n const parsed: unknown = JSON.parse(raw)\n const result = workflowsArraySchema.safeParse(parsed)\n if (!result.success) {\n if (Array.isArray(parsed)) {\n const valid = parsed.filter(\n (item) => workflowSchema.safeParse(item).success\n )\n const validWorkflows = valid.map((item) => workflowSchema.parse(item))\n saveWorkflows(validWorkflows)\n return validWorkflows\n }\n localStorage.removeItem(STORAGE_KEYS.workflows)\n return []\n }\n return result.data\n } catch {\n localStorage.removeItem(STORAGE_KEYS.workflows)\n return []\n }\n}\n\nexport function saveWorkflows(workflows: Workflow[]): void {\n if (!isBrowser) return\n localStorage.setItem(STORAGE_KEYS.workflows, JSON.stringify(workflows))\n}\n\nexport function addWorkflow(workflow: Workflow): void {\n const workflows = loadWorkflows()\n workflows.push(workflow)\n saveWorkflows(workflows)\n}\n\nexport function updateWorkflow(id: string, updates: Partial<Workflow>): void {\n const workflows = loadWorkflows()\n const index = workflows.findIndex((w) => w.id === id)\n if (index !== -1) {\n workflows[index] = { ...workflows[index]!, ...updates }\n saveWorkflows(workflows)\n }\n}\n\nexport function deleteWorkflow(id: string): void {\n const workflows = loadWorkflows().filter((w) => w.id !== id)\n saveWorkflows(workflows)\n}\n\nexport function getWorkflow(id: string): Workflow | undefined {\n return loadWorkflows().find((w) => w.id === id)\n}\n\n// --- IndexedDB: Audio ---\n\nconst DB_NAME = \"meridial\"\nconst AUDIO_STORE = \"audio\"\nconst DB_VERSION = 1\n\nfunction openDB(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION)\n request.onupgradeneeded = () => {\n const db = request.result\n if (!db.objectStoreNames.contains(AUDIO_STORE)) {\n db.createObjectStore(AUDIO_STORE)\n }\n }\n request.onsuccess = () => resolve(request.result)\n request.onerror = () => reject(request.error)\n })\n}\n\nexport async function saveAudio(key: string, blob: Blob): Promise<void> {\n const db = await openDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(AUDIO_STORE, \"readwrite\")\n tx.objectStore(AUDIO_STORE).put(blob, key)\n tx.oncomplete = () => resolve()\n tx.onerror = () => reject(tx.error)\n })\n}\n\nexport async function loadAudio(key: string): Promise<Blob | undefined> {\n const db = await openDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(AUDIO_STORE, \"readonly\")\n const request = tx.objectStore(AUDIO_STORE).get(key)\n request.onsuccess = () => resolve(request.result as Blob | undefined)\n request.onerror = () => reject(request.error)\n })\n}\n\nexport async function deleteAudio(key: string): Promise<void> {\n const db = await openDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(AUDIO_STORE, \"readwrite\")\n tx.objectStore(AUDIO_STORE).delete(key)\n tx.oncomplete = () => resolve()\n tx.onerror = () => reject(tx.error)\n })\n}\n","\"use client\"\n\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport {\n ArrowDown01Icon,\n Alert01Icon,\n StopIcon,\n PlayIcon,\n Loading03Icon,\n} from \"@hugeicons/core-free-icons\"\nimport { cn } from \"@workspace/ui/lib/utils\"\nimport type { RecorderState } from \"../hooks/use-recorder-state.js\"\n\ninterface ActionButtonProps {\n state: RecorderState\n openPanel: boolean\n hasUnconfigured: boolean\n onClick: () => void\n}\n\nexport function ActionButton({\n state,\n openPanel,\n hasUnconfigured,\n onClick,\n}: ActionButtonProps) {\n let icon = ArrowDown01Icon\n let className = \"text-muted-foreground\"\n let spin = false\n\n if (state.status === \"idle\") {\n if (hasUnconfigured) {\n icon = Alert01Icon\n className = \"text-amber-500 fill-amber-500/20\"\n } else {\n icon = ArrowDown01Icon\n className = cn(\n \"fill-none text-muted-foreground transition-transform duration-200\",\n openPanel ? \"rotate-180\" : \"rotate-0\"\n )\n }\n } else if (state.status === \"recording\") {\n icon = StopIcon\n className = \"text-red-500 fill-destructive/50\"\n } else if (state.status === \"paused\") {\n icon = PlayIcon\n className = \"text-emerald-500 fill-emerald-500/20\"\n } else if (state.status === \"saving\") {\n icon = Loading03Icon\n className = \"text-muted-foreground\"\n spin = true\n }\n\n return (\n <button\n data-meridial-ui\n onClick={onClick}\n disabled={state.status === \"saving\"}\n className={cn(\"flex items-center justify-center px-2.5\", className, {\n \"cursor-not-allowed\": state.status === \"saving\",\n \"cursor-pointer hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-50\":\n state.status !== \"saving\",\n })}\n >\n <HugeiconsIcon\n icon={icon}\n size={18}\n className={spin ? \"animate-spin\" : \"\"}\n fill={className}\n />\n </button>\n )\n}\n","\"use client\"\n\ninterface StepBadgeProps {\n count: number\n}\n\nexport function StepBadge({ count }: StepBadgeProps) {\n return (\n <div\n data-meridial-ui\n className=\"absolute right-1 bottom-1 flex h-5 min-w-5 items-center justify-center rounded-full bg-foreground px-1 text-xs font-medium text-background\"\n >\n {count}\n </div>\n )\n}\n","\"use client\"\n\nimport { useState, useRef, useEffect } from \"react\"\nimport { cn } from \"@workspace/ui/lib/utils\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport {\n Alert01Icon,\n CheckmarkCircle02Icon,\n Delete01Icon,\n Settings01Icon,\n} from \"@hugeicons/core-free-icons\"\nimport type { Workflow } from \"../schemas.js\"\n\ninterface WorkflowRowProps {\n workflow: Workflow\n onRename: (id: string, name: string) => void\n onDelete: (id: string) => void\n onConfigure: (id: string) => void\n}\n\nexport function WorkflowRow({\n workflow,\n onRename,\n onDelete,\n onConfigure,\n}: WorkflowRowProps) {\n const [editing, setEditing] = useState(false)\n const [name, setName] = useState(workflow.name)\n const inputRef = useRef<HTMLInputElement>(null)\n\n useEffect(() => {\n if (editing && inputRef.current) {\n inputRef.current.focus()\n inputRef.current.select()\n }\n }, [editing])\n\n const commitRename = () => {\n const trimmed = name.trim()\n if (trimmed && trimmed !== workflow.name) {\n onRename(workflow.id, trimmed)\n } else {\n setName(workflow.name)\n }\n setEditing(false)\n }\n\n return (\n <div\n data-meridial-ui\n className=\"flex items-center gap-2 px-3 py-2 hover:bg-muted/50\"\n >\n <HugeiconsIcon\n icon={workflow.configured ? CheckmarkCircle02Icon : Alert01Icon}\n size={16}\n className={\n workflow.configured\n ? \"shrink-0 fill-green-500/20 text-green-500\"\n : \"shrink-0 fill-amber-500/20 text-amber-500\"\n }\n />\n\n {editing ? (\n <input\n ref={inputRef}\n data-meridial-ui\n value={name}\n onChange={(e) => setName(e.target.value)}\n onBlur={commitRename}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") commitRename()\n if (e.key === \"Escape\") {\n setName(workflow.name)\n setEditing(false)\n }\n }}\n className=\"min-w-0 flex-1 rounded border border-border bg-background px-1.5 py-0.5 text-sm outline-none\"\n />\n ) : (\n <button\n data-meridial-ui\n onClick={() => {\n if (workflow.configured) return\n setEditing(true)\n }}\n className=\"min-w-0 flex-1 cursor-pointer truncate text-left text-sm\"\n >\n {workflow.name}\n </button>\n )}\n\n {/* Only show delete button for unconfigured workflows to delete unconfigured workflows from local storage, workflow deletion is only possible via the dashboard*/}\n {!workflow.configured && (\n <button\n data-meridial-ui\n onClick={() => onDelete(workflow.id)}\n className=\"shrink-0 cursor-pointer p-0.5 text-muted-foreground hover:text-destructive\"\n >\n <HugeiconsIcon icon={Delete01Icon} size={14} />\n </button>\n )}\n\n <button\n data-meridial-ui\n onClick={() => onConfigure(workflow.id)}\n className={cn(\n \"shrink-0 cursor-pointer p-0.5\",\n workflow.configured\n ? \"text-muted-foreground hover:text-foreground\"\n : \"text-amber-500 hover:text-amber-500/80\"\n )}\n >\n <HugeiconsIcon icon={Settings01Icon} size={14} />\n </button>\n </div>\n )\n}\n","\"use client\"\n\nimport type { Workflow } from \"../schemas.js\"\nimport { WorkflowRow } from \"./workflow-row.js\"\n\ninterface WorkflowListPanelProps {\n workflows: Workflow[]\n hasMore: boolean\n remainingCount: number\n onLoadMore: () => void\n onRename: (id: string, name: string) => void\n onDelete: (id: string) => void\n onConfigure: (id: string) => void\n}\n\nexport function WorkflowListPanel({\n workflows,\n hasMore,\n remainingCount,\n onLoadMore,\n onRename,\n onDelete,\n onConfigure,\n}: WorkflowListPanelProps) {\n return (\n <div data-meridial-ui className=\"max-h-60 overflow-y-auto border-b bg-card\">\n {workflows.length === 0 ? (\n <p className=\"px-3 py-4 text-center text-sm text-muted-foreground\">\n No workflow recorded\n </p>\n ) : (\n <>\n {workflows.map((w) => (\n <WorkflowRow\n key={w.id}\n workflow={w}\n onRename={onRename}\n onDelete={onDelete}\n onConfigure={onConfigure}\n />\n ))}\n {hasMore && (\n <button\n data-meridial-ui\n onClick={onLoadMore}\n className=\"w-full cursor-pointer px-3 py-2 text-center text-sm text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n >\n {remainingCount} More…\n </button>\n )}\n </>\n )}\n </div>\n )\n}\n","\"use client\"\n\nimport { useRef, useState, useCallback, type RefObject } from \"react\"\nimport {\n MultiplicationSignIcon,\n Cursor02Icon,\n ArrowLeft01Icon,\n ArrowRight01Icon,\n Loading03Icon,\n Tick01Icon,\n} from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { Button } from \"@workspace/ui/components/button\"\nimport { createPortal } from \"react-dom\"\nimport { useDraggable } from \"@neodrag/react\"\nimport { usePosition } from \"./hooks/use-position.js\"\nimport { STORAGE_KEYS, MIN_DESC_LENGTH } from \"./constants.js\"\nimport { DragHandle } from \"./components/drag-handle.js\"\nimport { CursorGuide } from \"./components/cursor-guide.js\"\nimport { DeleteStepButton } from \"./components/delete-step-button.js\"\nimport type { Workflow, Step } from \"./schemas.js\"\nimport * as storage from \"./storage.js\"\n\ninterface WorkflowEditorProps {\n baseUrl?: string\n workflowId: string\n workflow?: Workflow\n publishableKey?: string\n cursor?: React.ReactNode\n onClose: () => void\n onWorkflowDeleted: (id: string) => void\n onError?: (error: string) => void\n}\n\nexport function WorkflowEditor({\n baseUrl = \"\",\n workflowId,\n workflow: workflowProp,\n publishableKey,\n cursor,\n onClose,\n onWorkflowDeleted,\n onError,\n}: WorkflowEditorProps) {\n const draggableRef = useRef<HTMLDivElement>(null)\n const { position, updatePosition } = usePosition(STORAGE_KEYS.editorPos)\n\n useDraggable(draggableRef as RefObject<HTMLElement>, {\n handle: \"[data-meridial-drag-handle]\",\n defaultPosition: position,\n onDragEnd: ({ offsetX, offsetY }) => {\n updatePosition({ x: offsetX, y: offsetY })\n },\n })\n\n const [workflowState, setWorkflowState] = useState<Workflow | null>(\n () => workflowProp ?? storage.getWorkflow(workflowId) ?? null\n )\n const isConfigured = workflowState?.configured ?? false\n\n const initialDescriptions: Record<string, string> = (() => {\n if (!workflowState) return {}\n const map: Record<string, string> = {}\n for (const step of workflowState.steps) {\n map[step.id] = step.description\n }\n return map\n })()\n\n const originalDescriptions =\n useRef<Record<string, string>>(initialDescriptions)\n\n const [currentIndex, setCurrentIndex] = useState(0)\n const [descriptions, setDescriptions] =\n useState<Record<string, string>>(initialDescriptions)\n const [saving, setSaving] = useState(false)\n const [savingChanges, setSavingChanges] = useState(false)\n\n const steps = workflowState?.steps ?? []\n const currentStep: Step | undefined = steps[currentIndex]\n const currentDesc = currentStep ? (descriptions[currentStep.id] ?? \"\") : \"\"\n\n const completedCount = steps.filter(\n (s) => (descriptions[s.id] ?? \"\").length >= MIN_DESC_LENGTH\n ).length\n\n const hasChanges =\n isConfigured &&\n steps.some(\n (s) =>\n (descriptions[s.id] ?? \"\") !==\n (originalDescriptions.current[s.id] ?? \"\")\n )\n\n const updateDescription = useCallback(\n (value: string) => {\n if (!currentStep) return\n setDescriptions((prev) => ({ ...prev, [currentStep.id]: value }))\n },\n [currentStep]\n )\n\n const handleDeleteStep = useCallback(async () => {\n if (!workflowState || !currentStep) return\n\n if (isConfigured && publishableKey) {\n try {\n const res = await fetch(\n `${baseUrl}/api/workflows/${workflowState.id}`,\n {\n method: \"PATCH\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${publishableKey}`,\n },\n body: JSON.stringify({ deleteStepId: currentStep.id }),\n }\n )\n if (!res.ok) {\n const data = await res.json().catch(() => ({}))\n throw new Error((data?.error as string) || `Failed (${res.status})`)\n }\n const data = await res.json()\n if (data.deleted) {\n onWorkflowDeleted(workflowState.id)\n onClose()\n return\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n onError?.(msg)\n return\n }\n } else {\n if (workflowState.steps.length === 1) {\n storage.deleteWorkflow(workflowState.id)\n if (workflowState.audioKey) {\n storage.deleteAudio(workflowState.audioKey).catch(() => {})\n }\n onWorkflowDeleted(workflowState.id)\n onClose()\n return\n }\n storage.updateWorkflow(workflowState.id, {\n steps: workflowState.steps.filter((s) => s.id !== currentStep.id),\n })\n }\n\n const newSteps = workflowState.steps.filter((s) => s.id !== currentStep.id)\n setWorkflowState({ ...workflowState, steps: newSteps })\n setCurrentIndex((prev) => Math.min(prev, newSteps.length - 1))\n }, [\n workflowState,\n currentStep,\n isConfigured,\n publishableKey,\n onClose,\n onWorkflowDeleted,\n ])\n\n const handleSaveChanges = useCallback(async () => {\n if (!workflowState || !publishableKey || !isConfigured) return\n\n setSavingChanges(true)\n\n try {\n const updatedSteps = steps.map((s) => ({\n ...s,\n description: descriptions[s.id] ?? s.description,\n }))\n\n const res = await fetch(`${baseUrl}/api/workflows/${workflowState.id}`, {\n method: \"PATCH\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${publishableKey}`,\n },\n body: JSON.stringify({ steps: updatedSteps }),\n })\n\n if (!res.ok) {\n const data = await res.json().catch(() => ({}))\n throw new Error((data?.error as string) || `Failed (${res.status})`)\n }\n\n setWorkflowState({ ...workflowState, steps: updatedSteps })\n const newBaseline: Record<string, string> = {}\n for (const s of updatedSteps) {\n newBaseline[s.id] = s.description\n }\n originalDescriptions.current = newBaseline\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n onError?.(msg)\n } finally {\n setSavingChanges(false)\n }\n }, [workflowState, publishableKey, isConfigured, steps, descriptions])\n\n const handleBack = useCallback(() => {\n setCurrentIndex((prev) => Math.max(0, prev - 1))\n }, [])\n\n const uploadAndFinish = useCallback(async () => {\n const wf = workflowState!\n const finalSteps = steps.map((s) => ({\n ...s,\n description: descriptions[s.id] ?? s.description,\n }))\n\n const finish = () => {\n storage.deleteWorkflow(wf.id)\n if (wf.audioKey) {\n storage.deleteAudio(wf.audioKey).catch(() => {})\n }\n onWorkflowDeleted(wf.id)\n setTimeout(() => {\n setSaving(false)\n onClose()\n }, 300)\n }\n\n if (publishableKey && wf.audioKey) {\n try {\n const audioBlob = await storage.loadAudio(wf.audioKey!)\n\n const presignRes = await fetch(`${baseUrl}/api/upload/presigned-url`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${publishableKey}`,\n },\n body: JSON.stringify({ workflowId: wf.id }),\n })\n if (!presignRes.ok) {\n throw new Error(\n `[Meridial] Failed to get presigned URL (status ${presignRes.status})`\n )\n }\n const { uploadUrl } = await presignRes.json()\n\n if (audioBlob) {\n const uploadRes = await fetch(uploadUrl, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"audio/webm\" },\n body: audioBlob,\n })\n if (!uploadRes.ok) {\n throw new Error(\n `[Meridial] Failed to upload audio blob (status ${uploadRes.status})`\n )\n }\n }\n\n await fetch(`${baseUrl}/api/upload/complete`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${publishableKey}`,\n },\n body: JSON.stringify({\n workflowId: wf.id,\n name: wf.name,\n description: \"\",\n steps: finalSteps,\n }),\n })\n finish()\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n onError?.(msg)\n setSaving(false)\n }\n } else {\n finish()\n }\n }, [\n workflowState,\n steps,\n descriptions,\n publishableKey,\n onClose,\n onWorkflowDeleted,\n baseUrl,\n ])\n\n const handleNext = useCallback(() => {\n const isLast = currentIndex === steps.length - 1\n\n if (!isLast) {\n setCurrentIndex((prev) => prev + 1)\n return\n }\n\n if (isConfigured) {\n onClose()\n return\n }\n\n setSaving(true)\n uploadAndFinish()\n }, [isConfigured, currentIndex, steps, uploadAndFinish, onClose])\n\n if (!workflowState || !currentStep) return null\n\n const isLastStep = currentIndex === steps.length - 1\n const canAdvance = currentDesc.length >= MIN_DESC_LENGTH\n const allConfigured = completedCount === steps.length && steps.length > 0\n const isConfiguredSaveMode = isConfigured && hasChanges\n\n const primaryDisabled = isConfiguredSaveMode\n ? savingChanges\n : isLastStep\n ? isConfigured\n ? false\n : !allConfigured || saving\n : !canAdvance\n\n const primaryAction = isConfiguredSaveMode ? handleSaveChanges : handleNext\n\n return createPortal(\n <div\n ref={draggableRef}\n data-meridial-ui\n className=\"group fixed bottom-4 left-1/2 z-[99998] w-[500px] -translate-x-1/2 rounded border border-border bg-card shadow-md\"\n >\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2 p-2\">\n <DragHandle />\n <span className=\"text-sm text-muted-foreground\">\n {currentStep.elementLabel}\n </span>\n </div>\n <Button variant=\"ghost\" size=\"icon\" onClick={onClose}>\n <HugeiconsIcon\n icon={MultiplicationSignIcon}\n strokeWidth={2}\n size={16}\n />\n </Button>\n </div>\n\n <textarea\n data-meridial-ui\n value={currentDesc}\n onChange={(e) => updateDescription(e.target.value)}\n placeholder=\"Add or edit existing step description\"\n rows={3}\n className=\"-mb-2 w-full resize-none border-y bg-muted/50 px-3 py-2 text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n\n <div data-meridial-ui className=\"flex items-center justify-between p-2\">\n <span className=\"text-xs text-muted-foreground\">\n {completedCount} / {steps.length} Steps Completed\n </span>\n <div className=\"flex gap-2\">\n <DeleteStepButton onConfirm={handleDeleteStep} />\n <Button\n variant=\"outline\"\n data-meridial-ui\n onClick={handleBack}\n disabled={currentIndex === 0}\n title=\"Back\"\n >\n <HugeiconsIcon icon={ArrowLeft01Icon} size={16} />\n <span className=\"text-xs\">Back</span>\n </Button>\n <Button\n variant=\"default\"\n data-meridial-ui\n onClick={primaryAction}\n disabled={primaryDisabled}\n >\n {isConfiguredSaveMode ? (\n savingChanges ? (\n <>\n <HugeiconsIcon\n icon={Loading03Icon}\n size={14}\n className=\"animate-spin\"\n />\n Saving Workflow\n </>\n ) : (\n \"Save Workflow\"\n )\n ) : saving ? (\n <HugeiconsIcon\n icon={Loading03Icon}\n size={14}\n className=\"animate-spin\"\n />\n ) : isLastStep ? (\n <>\n Finish\n <HugeiconsIcon icon={Tick01Icon} size={14} />\n </>\n ) : (\n <>\n Next\n <HugeiconsIcon icon={ArrowRight01Icon} size={14} />\n </>\n )}\n </Button>\n </div>\n </div>\n <CursorGuide\n selector={currentStep.elementId}\n urlPath={currentStep.urlPath}\n onError={onError}\n onClick={isConfigured ? primaryAction : undefined}\n >\n {cursor ?? (\n <HugeiconsIcon\n icon={Cursor02Icon}\n strokeWidth={2}\n size={32}\n className=\"fill-primary/80 text-primary\"\n />\n )}\n </CursorGuide>\n </div>,\n document.body\n )\n}\n","import { useState, useCallback } from \"react\"\n\ninterface Position {\n x: number\n y: number\n}\n\nexport function usePosition(\n storageKey: string,\n defaultPos: Position = { x: 0, y: 0 }\n) {\n const [position] = useState<Position>(() => {\n if (typeof window === \"undefined\") return defaultPos\n try {\n const raw = localStorage.getItem(storageKey)\n if (raw) {\n const parsed = JSON.parse(raw) as Position\n if (typeof parsed.x === \"number\" && typeof parsed.y === \"number\") {\n return parsed\n }\n }\n } catch {\n // ignore\n }\n return defaultPos\n })\n\n const updatePosition = useCallback(\n (pos: Position) => {\n try {\n localStorage.setItem(storageKey, JSON.stringify(pos))\n } catch {\n // ignore\n }\n },\n [storageKey]\n )\n\n return { position, updatePosition } as const\n}\n","\"use client\"\n\nimport { useRef, type ReactNode } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport {\n motion,\n useMotionValue,\n useSpring,\n AnimatePresence,\n} from \"motion/react\"\nimport { useElementTracker } from \"../hooks/use-element-tracker.js\"\n\ninterface CursorGuideProps {\n selector: string\n children: ReactNode\n urlPath: string\n onError?: (message: string) => void\n onClick?: () => void\n}\n\nconst SPRING_CONFIG = { stiffness: 120, damping: 20, mass: 0.8 }\nconst OFFSET = -16\n\nexport function CursorGuide({\n selector,\n urlPath,\n children,\n onError,\n onClick,\n}: CursorGuideProps) {\n const { rect } = useElementTracker({\n selector,\n urlPath,\n onError: onError\n ? (msg) => {\n if (msg !== null) onError(msg)\n }\n : undefined,\n onClick,\n })\n const hasAnimated = useRef(false)\n\n const springX = useSpring(useMotionValue(0), SPRING_CONFIG)\n const springY = useSpring(useMotionValue(0), SPRING_CONFIG)\n\n if (rect) {\n const targetX = rect.right + OFFSET\n const targetY = rect.bottom + OFFSET\n\n if (!hasAnimated.current) {\n // Snap immediately — first render or after a path change reset\n springX.jump(targetX)\n springY.jump(targetY)\n hasAnimated.current = true\n } else {\n springX.set(targetX)\n springY.set(targetY)\n }\n } else {\n // rect was cleared (path changed) — reset so the next element snaps in\n hasAnimated.current = false\n }\n\n return createPortal(\n <AnimatePresence>\n {rect && (\n <motion.div\n data-meridial-ui\n className=\"pointer-events-none fixed z-[99999]\"\n style={{ top: springY, left: springX }}\n initial={{ opacity: 0, scale: 0.6 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.6 }}\n transition={{ duration: 0.2 }}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>,\n document.body\n )\n}\n","\"use client\"\n\nimport { useRef, useState } from \"react\"\nimport { motion, useAnimation } from \"motion/react\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { Delete01Icon } from \"@hugeicons/core-free-icons\"\nimport { Button } from \"@workspace/ui/components/button\"\n\ninterface DeleteStepButtonProps {\n holdDuration?: number\n onConfirm: () => void\n}\n\nexport function DeleteStepButton({\n holdDuration = 3000,\n onConfirm,\n}: DeleteStepButtonProps) {\n const [isHolding, setIsHolding] = useState(false)\n const controls = useAnimation()\n const holdingRef = useRef(false)\n\n async function handleHoldStart() {\n holdingRef.current = true\n setIsHolding(true)\n controls.set({ width: \"5%\" })\n\n await controls.start({\n width: \"100%\",\n transition: {\n duration: holdDuration / 1000,\n ease: \"linear\",\n },\n })\n\n if (holdingRef.current) {\n holdingRef.current = false\n setIsHolding(false)\n onConfirm()\n }\n }\n\n function handleHoldEnd() {\n holdingRef.current = false\n setIsHolding(false)\n controls.stop()\n controls.start({\n width: \"0%\",\n transition: { duration: 0.1 },\n })\n }\n\n return (\n <Button\n type=\"button\"\n onMouseDown={handleHoldStart}\n onMouseLeave={handleHoldEnd}\n onMouseUp={handleHoldEnd}\n onTouchCancel={handleHoldEnd}\n onTouchEnd={handleHoldEnd}\n onTouchStart={handleHoldStart}\n variant=\"destructive\"\n className=\"relative w-42\"\n >\n <motion.div\n animate={controls}\n className=\"absolute top-0 left-0 h-full rounded-tl-lg rounded-bl-lg bg-red-400/40 dark:bg-red-300/40\"\n initial={{ width: \"0%\" }}\n />\n <span className=\"relative z-10 flex items-center gap-1\">\n <HugeiconsIcon icon={Delete01Icon} size={14} />\n {isHolding ? \"Release to cancel\" : \"Hold to delete\"}\n </span>\n </Button>\n )\n}\n\nexport default DeleteStepButton\n"],"mappings":";;;;;;;;;;;;;;AAEA,SAAS,UAAAA,SAAQ,YAAAC,WAAU,eAAAC,cAAa,aAAAC,kBAAiC;AACzE,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,UAAAC,SAAQ,mBAAAC,wBAAuB;;;ACFxC,SAAS,WAAW,cAAmC;AAmhBnD,SAeI,KAfJ;AAxfG,IAAM,WAAW,CAAC;AAAA,EACvB,SAAS;AAAA,EACT,aAAa;AAAA,EACb;AAAA,EACA,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAY;AAAA,EACZ;AAAA,EACA,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,WAAW,gBAAgB;AAAA,EAC3B,SAAS;AAAA,EACT,cAAc;AAAA,EACd,wBAAwB;AAAA,EACxB,UAAU;AAAA,EACV,cAAc;AAAA,EACd,aAAa;AAAA,EACb,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAqB;AACnB,QAAM,YAAY,OAA0B,IAAI;AAChD,QAAM,eAAe,OAAuB,IAAI;AAChD,QAAM,aAAa,OAAiB,CAAC,CAAC;AACtC,QAAM,cAAc,OAA4B,IAAI;AACpD,QAAM,kBAAkB,OAA4B,IAAI;AACxD,QAAM,YAAY,OAA2B,IAAI;AACjD,QAAM,eAAe,OAAe,CAAC;AACrC,QAAM,gBAAgB,OAAe,CAAC;AACtC,QAAM,yBAAyB,OAAsB,IAAI;AACzD,QAAM,oBAAoB,OAAiB,CAAC,CAAC;AAC7C,QAAM,wBAAwB,OAAO,CAAC;AACtC,QAAM,gBAAgB,OAAiB,CAAC,CAAC;AACzC,QAAM,iBAAiB,OAAO,IAAI;AAClC,QAAM,mBAAmB,OAA8B,IAAI;AAC3D,QAAM,eAAe,OAAO,CAAC;AAE7B,QAAM,cAAc,OAAO,WAAW,WAAW,GAAG,MAAM,OAAO;AAGjE,YAAU,MAAM;AACd,UAAM,SAAS,UAAU;AACzB,UAAM,YAAY,aAAa;AAC/B,QAAI,CAAC,UAAU,CAAC,UAAW;AAE3B,UAAM,iBAAiB,IAAI,eAAe,MAAM;AAC9C,YAAM,OAAO,UAAU,sBAAsB;AAC7C,YAAM,MAAM,OAAO,oBAAoB;AAEvC,aAAO,QAAQ,KAAK,QAAQ;AAC5B,aAAO,SAAS,KAAK,SAAS;AAC9B,aAAO,MAAM,QAAQ,GAAG,KAAK,KAAK;AAClC,aAAO,MAAM,SAAS,GAAG,KAAK,MAAM;AAEpC,YAAM,MAAM,OAAO,WAAW,IAAI;AAClC,UAAI,KAAK;AACP,YAAI,MAAM,KAAK,GAAG;AAAA,MACpB;AAEA,uBAAiB,UAAU;AAC3B,mBAAa,UAAU,KAAK;AAC5B,qBAAe,UAAU;AAAA,IAC3B,CAAC;AAED,mBAAe,QAAQ,SAAS;AAChC,WAAO,MAAM,eAAe,WAAW;AAAA,EACzC,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,cAAc,CAAC,QAAQ;AACzB,UAAI,OAAO;AACX,4BAAsB,UAAU;AAEhC,YAAM,oBAAoB,MAAM;AAC9B,gBAAQ;AACR,8BAAsB,UAAU,KAAK;AAAA,UACnC;AAAA,UACA,sBAAsB,UAAU;AAAA,QAClC;AAEA,cAAM,iBAAiB,CAAC;AACxB,cAAM,WAAW,KAAK;AAAA,WACnB,aAAa,SAAS,sBAAsB,EAAE,SAAS,QACrD,WAAW;AAAA,QAChB;AAEA,YAAI,SAAS,UAAU;AACrB,gBAAM,YAAY,KAAK,MAAM,WAAW,CAAC;AAEzC,mBAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,kBAAM,sBAAsB,IAAI,aAAa;AAC7C,kBAAM,eAAe,IAAI,KAAK,IAAI,kBAAkB,IAAI;AAExD,kBAAM,QAAQ,KAAK,IAAI,OAAO,MAAM,qBAAqB,CAAC,IAAI;AAC9D,kBAAM,QAAQ,KAAK,IAAI,OAAO,MAAM,qBAAqB,CAAC,IAAI;AAC9D,kBAAM,QAAQ,KAAK,IAAI,OAAO,IAAI,kBAAkB,IAAI;AACxD,kBAAM,eAAe,QAAQ,QAAQ;AACrC,kBAAM,mBAAmB,MAAM,gBAAgB;AAE/C,gBAAI,aAAa;AACjB,gBACE,kBAAkB,QAAQ,SAAS,KACnC,sBAAsB,UAAU,GAChC;AACA,oBAAM,gBAAgB,KAAK;AAAA,gBACzB;AAAA,gBACA,kBAAkB,QAAQ,SAAS;AAAA,cACrC;AACA,oBAAM,YAAY,kBAAkB,QAAQ,aAAa,KAAK;AAC9D,2BACE,aAAa,IAAI,sBAAsB,WACvC,kBAAkB,sBAAsB;AAAA,YAC5C;AAEA,2BAAe,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI,GAAG,UAAU,CAAC,CAAC;AAAA,UAC7D;AAAA,QACF,OAAO;AACL,mBAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,kBAAM,sBAAsB,IAAI,WAAW,MAAM,WAAW;AAC5D,kBAAM,eAAe,IAAI,KAAK,IAAI,kBAAkB,IAAI;AAExD,kBAAM,QAAQ,KAAK,IAAI,OAAO,MAAM,IAAI,IAAI,IAAI;AAChD,kBAAM,QAAQ,KAAK,IAAI,OAAO,MAAM,IAAI,GAAG,IAAI;AAC/C,kBAAM,QAAQ,KAAK,IAAI,OAAO,IAAI,IAAI,IAAI,IAAI;AAC9C,kBAAM,eAAe,QAAQ,QAAQ;AACrC,kBAAM,mBAAmB,MAAM,gBAAgB;AAE/C,gBAAI,aAAa;AACjB,gBACE,kBAAkB,QAAQ,SAAS,KACnC,sBAAsB,UAAU,GAChC;AACA,oBAAM,gBAAgB,KAAK;AAAA,gBACxB,IAAI,WAAY,kBAAkB,QAAQ;AAAA,cAC7C;AACA,oBAAM,YAAY,kBAAkB,QAAQ,aAAa,KAAK;AAC9D,2BACE,aAAa,IAAI,sBAAsB,WACvC,kBAAkB,sBAAsB;AAAA,YAC5C;AAEA,2BAAe,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI,GAAG,UAAU,CAAC,CAAC;AAAA,UAC7D;AAAA,QACF;AAEA,YAAI,SAAS,UAAU;AACrB,wBAAc,UAAU;AAAA,QAC1B,OAAO;AACL,qBAAW,UAAU;AAAA,QACvB;AAEA,uBAAe,UAAU;AACzB,+BAAuB,UACrB,sBAAsB,iBAAiB;AAAA,MAC3C;AAEA,wBAAkB;AAElB,aAAO,MAAM;AACX,YAAI,uBAAuB,SAAS;AAClC,+BAAqB,uBAAuB,OAAO;AAAA,QACrD;AAAA,MACF;AAAA,IACF,WAAW,CAAC,UAAU,CAAC,YAAY;AACjC,YAAM,UACJ,SAAS,WACL,cAAc,QAAQ,SAAS,IAC/B,WAAW,QAAQ,SAAS;AAElC,UAAI,SAAS;AACX,YAAI,eAAe;AACnB,cAAM,aAAa,MAAM;AACvB,0BAAgB;AAChB,cAAI,eAAe,GAAG;AACpB,gBAAI,SAAS,UAAU;AACrB,4BAAc,UAAU,cAAc,QAAQ;AAAA,gBAC5C,CAAC,UAAU,SAAS,IAAI;AAAA,cAC1B;AAAA,YACF,OAAO;AACL,yBAAW,UAAU,WAAW,QAAQ;AAAA,gBACtC,CAAC,UAAU,SAAS,IAAI;AAAA,cAC1B;AAAA,YACF;AACA,2BAAe,UAAU;AACzB,kCAAsB,UAAU;AAAA,UAClC,OAAO;AACL,gBAAI,SAAS,UAAU;AACrB,4BAAc,UAAU,CAAC;AAAA,YAC3B,OAAO;AACL,yBAAW,UAAU,CAAC;AAAA,YACxB;AAAA,UACF;AAAA,QACF;AACA,mBAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,GAAG,CAAC,YAAY,QAAQ,UAAU,QAAQ,IAAI,CAAC;AAG/C,YAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX,UAAI,UAAU,SAAS;AACrB,kBAAU,QAAQ,UAAU,EAAE,QAAQ,CAAC,UAAU,MAAM,KAAK,CAAC;AAC7D,kBAAU,UAAU;AACpB,sBAAc;AAAA,MAChB;AACA,UACE,gBAAgB,WAChB,gBAAgB,QAAQ,UAAU,UAClC;AACA,wBAAgB,QAAQ,MAAM;AAC9B,wBAAgB,UAAU;AAAA,MAC5B;AACA,UAAI,aAAa,SAAS;AACxB,6BAAqB,aAAa,OAAO;AACzC,qBAAa,UAAU;AAAA,MACzB;AACA;AAAA,IACF;AAEA,UAAM,kBAAkB,YAAY;AAClC,UAAI;AACF,cAAM,SAAS,MAAM,UAAU,aAAa,aAAa;AAAA,UACvD,OAAO,WACH;AAAA,YACE,UAAU,EAAE,OAAO,SAAS;AAAA,YAC5B,kBAAkB;AAAA,YAClB,kBAAkB;AAAA,YAClB,iBAAiB;AAAA,UACnB,IACA;AAAA,YACE,kBAAkB;AAAA,YAClB,kBAAkB;AAAA,YAClB,iBAAiB;AAAA,UACnB;AAAA,QACN,CAAC;AACD,kBAAU,UAAU;AACpB,wBAAgB,MAAM;AAEtB,cAAM,0BACJ,OAAO,gBACN,OACE;AACL,cAAM,eAAe,IAAI,wBAAwB;AACjD,cAAM,WAAW,aAAa,eAAe;AAC7C,iBAAS,UAAU;AACnB,iBAAS,wBAAwB;AAEjC,cAAM,SAAS,aAAa,wBAAwB,MAAM;AAC1D,eAAO,QAAQ,QAAQ;AAEvB,wBAAgB,UAAU;AAC1B,oBAAY,UAAU;AAGtB,mBAAW,UAAU,CAAC;AAAA,MACxB,SAAS,OAAO;AACd,kBAAU,KAAc;AAAA,MAC1B;AAAA,IACF;AAEA,oBAAgB;AAEhB,WAAO,MAAM;AACX,UAAI,UAAU,SAAS;AACrB,kBAAU,QAAQ,UAAU,EAAE,QAAQ,CAAC,UAAU,MAAM,KAAK,CAAC;AAC7D,kBAAU,UAAU;AACpB,sBAAc;AAAA,MAChB;AACA,UACE,gBAAgB,WAChB,gBAAgB,QAAQ,UAAU,UAClC;AACA,wBAAgB,QAAQ,MAAM;AAC9B,wBAAgB,UAAU;AAAA,MAC5B;AACA,UAAI,aAAa,SAAS;AACxB,6BAAqB,aAAa,OAAO;AACzC,qBAAa,UAAU;AAAA,MACzB;AAAA,IACF;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAGD,YAAU,MAAM;AACd,UAAM,SAAS,UAAU;AACzB,QAAI,CAAC,OAAQ;AAEb,UAAM,MAAM,OAAO,WAAW,IAAI;AAClC,QAAI,CAAC,IAAK;AAEV,QAAI;AAEJ,UAAM,UAAU,CAAC,gBAAwB;AAEvC,YAAM,OAAO,OAAO,sBAAsB;AAG1C,UAAI,UAAU,cAAc,cAAc,UAAU,YAAY;AAC9D,sBAAc,UAAU;AAExB,YAAI,YAAY,SAAS;AACvB,gBAAM,YAAY,IAAI;AAAA,YACpB,YAAY,QAAQ;AAAA,UACtB;AACA,sBAAY,QAAQ,qBAAqB,SAAS;AAElD,cAAI,SAAS,UAAU;AAErB,kBAAM,YAAY,KAAK,MAAM,UAAU,SAAS,IAAI;AACpD,kBAAM,UAAU,KAAK,MAAM,UAAU,SAAS,GAAG;AACjD,kBAAM,eAAe,UAAU,MAAM,WAAW,OAAO;AAEvD,kBAAMC,YAAW,KAAK,MAAM,KAAK,SAAS,WAAW,OAAO;AAC5D,kBAAM,YAAY,KAAK,MAAMA,YAAW,CAAC;AACzC,kBAAM,UAAoB,CAAC;AAG3B,qBAAS,IAAI,YAAY,GAAG,KAAK,GAAG,KAAK;AACvC,oBAAM,YAAY,KAAK;AAAA,gBACpB,IAAI,YAAa,aAAa;AAAA,cACjC;AACA,oBAAM,SAAS,aAAa,SAAS,KAAK;AAC1C,oBAAM,QAAQ,KAAK,IAAI,GAAI,SAAS,MAAO,WAAW;AACtD,sBAAQ,KAAK,KAAK,IAAI,MAAM,KAAK,CAAC;AAAA,YACpC;AAEA,qBAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,oBAAM,YAAY,KAAK;AAAA,gBACpB,IAAI,YAAa,aAAa;AAAA,cACjC;AACA,oBAAM,SAAS,aAAa,SAAS,KAAK;AAC1C,oBAAM,QAAQ,KAAK,IAAI,GAAI,SAAS,MAAO,WAAW;AACtD,sBAAQ,KAAK,KAAK,IAAI,MAAM,KAAK,CAAC;AAAA,YACpC;AAEA,0BAAc,UAAU;AACxB,8BAAkB,UAAU;AAAA,UAC9B,OAAO;AAEL,gBAAI,MAAM;AACV,kBAAM,YAAY,KAAK,MAAM,UAAU,SAAS,IAAI;AACpD,kBAAM,UAAU,KAAK,MAAM,UAAU,SAAS,GAAG;AACjD,kBAAM,eAAe,UAAU,MAAM,WAAW,OAAO;AAEvD,qBAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,oBAAM,SAAS,aAAa,CAAC,KAAK;AAClC,qBAAO;AAAA,YACT;AACA,kBAAM,UACH,OAAO,aAAa,UAAU,KAAK,MAAO;AAG7C,uBAAW,QAAQ,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,OAAO,CAAC,CAAC;AAC5D,8BAAkB,UAAU,CAAC,GAAG,WAAW,OAAO;AAGlD,gBAAI,WAAW,QAAQ,SAAS,aAAa;AAC3C,yBAAW,QAAQ,MAAM;AAAA,YAC3B;AAAA,UACF;AACA,yBAAe,UAAU;AAAA,QAC3B;AAAA,MACF;AAGA,UAAI,CAAC,eAAe,WAAW,CAAC,QAAQ;AACtC,gBAAQ,sBAAsB,OAAO;AACrC;AAAA,MACF;AAEA,qBAAe,UAAU;AACzB,UAAI,UAAU,GAAG,GAAG,KAAK,OAAO,KAAK,MAAM;AAE3C,YAAM,mBACJ,aACC,MAAM;AACL,cAAM,QAAQ,iBAAiB,MAAM;AAErC,cAAM,QAAQ,MAAM;AACpB,eAAO,SAAS;AAAA,MAClB,GAAG;AAEL,YAAM,OAAO,WAAW;AACxB,YAAM,WAAW,KAAK,MAAM,KAAK,QAAQ,IAAI;AAC7C,YAAM,UAAU,KAAK,SAAS;AAG9B,UAAI,SAAS,UAAU;AAErB,cAAM,eAAe,aACjB,cAAc,UACd,SACE,cAAc,UACd,cAAc,QAAQ,SAAS,IAC7B,cAAc,UACd,CAAC;AAET,iBAAS,IAAI,GAAG,IAAI,YAAY,IAAI,aAAa,QAAQ,KAAK;AAC5D,gBAAM,QAAQ,aAAa,CAAC,KAAK;AACjC,gBAAM,IAAI,IAAI;AACd,gBAAM,YAAY,KAAK,IAAI,eAAe,QAAQ,KAAK,SAAS,GAAG;AACnE,gBAAM,IAAI,UAAU,YAAY;AAEhC,cAAI,YAAY;AAChB,cAAI,cAAc,MAAM,QAAQ;AAEhC,cAAI,YAAY,GAAG;AACjB,gBAAI,UAAU;AACd,gBAAI,UAAU,GAAG,GAAG,UAAU,WAAW,SAAS;AAClD,gBAAI,KAAK;AAAA,UACX,OAAO;AACL,gBAAI,SAAS,GAAG,GAAG,UAAU,SAAS;AAAA,UACxC;AAAA,QACF;AAAA,MACF,OAAO;AAEL,iBAAS,IAAI,GAAG,IAAI,YAAY,IAAI,WAAW,QAAQ,QAAQ,KAAK;AAClE,gBAAM,YAAY,WAAW,QAAQ,SAAS,IAAI;AAClD,gBAAM,QAAQ,WAAW,QAAQ,SAAS,KAAK;AAC/C,gBAAM,IAAI,KAAK,SAAS,IAAI,KAAK;AACjC,gBAAM,YAAY,KAAK,IAAI,eAAe,QAAQ,KAAK,SAAS,GAAG;AACnE,gBAAM,IAAI,UAAU,YAAY;AAEhC,cAAI,YAAY;AAChB,cAAI,cAAc,MAAM,QAAQ;AAEhC,cAAI,YAAY,GAAG;AACjB,gBAAI,UAAU;AACd,gBAAI,UAAU,GAAG,GAAG,UAAU,WAAW,SAAS;AAClD,gBAAI,KAAK;AAAA,UACX,OAAO;AACL,gBAAI,SAAS,GAAG,GAAG,UAAU,SAAS;AAAA,UACxC;AAAA,QACF;AAAA,MACF;AAGA,UAAI,aAAa,YAAY,KAAK,KAAK,QAAQ,GAAG;AAEhD,YAAI,CAAC,iBAAiB,WAAW,aAAa,YAAY,KAAK,OAAO;AACpE,gBAAM,WAAW,IAAI,qBAAqB,GAAG,GAAG,KAAK,OAAO,CAAC;AAC7D,gBAAM,cAAc,KAAK,IAAI,KAAK,YAAY,KAAK,KAAK;AAKxD,mBAAS,aAAa,GAAG,qBAAqB;AAC9C,mBAAS,aAAa,aAAa,qBAAqB;AAExD,mBAAS,aAAa,IAAI,aAAa,qBAAqB;AAE5D,mBAAS,aAAa,GAAG,qBAAqB;AAE9C,2BAAiB,UAAU;AAC3B,uBAAa,UAAU,KAAK;AAAA,QAC9B;AAEA,YAAI,2BAA2B;AAC/B,YAAI,YAAY,iBAAiB;AACjC,YAAI,SAAS,GAAG,GAAG,KAAK,OAAO,KAAK,MAAM;AAC1C,YAAI,2BAA2B;AAAA,MACjC;AAEA,UAAI,cAAc;AAElB,cAAQ,sBAAsB,OAAO;AAAA,IACvC;AAEA,YAAQ,sBAAsB,OAAO;AAErC,WAAO,MAAM;AACX,UAAI,OAAO;AACT,6BAAqB,KAAK;AAAA,MAC5B;AAAA,IACF;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,0BAA0B,SAAS;AAAA,MACjD,KAAK;AAAA,MACL,OAAO,EAAE,QAAQ,YAAY;AAAA,MAC7B,cACE,SACI,wBACA,aACE,qBACA;AAAA,MAER,MAAK;AAAA,MACJ,GAAG;AAAA,MAEH;AAAA,SAAC,UAAU,CAAC,cACX,oBAAC,SAAI,WAAU,wGAAuG;AAAA,QAExH;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,KAAK;AAAA,YACL,eAAY;AAAA;AAAA,QACd;AAAA;AAAA;AAAA,EACF;AAEJ;;;AC7iBA,SAAS,kBAAkB;AAgB3B,SAAS,gBACP,OACA,QACe;AACf,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO,EAAE,QAAQ,aAAa,WAAW,GAAG,WAAW,KAAK,IAAI,EAAE;AAAA,IACpE,KAAK;AACH,UAAI,MAAM,WAAW,aAAa;AAChC,eAAO,EAAE,GAAG,OAAO,WAAW,MAAM,YAAY,EAAE;AAAA,MACpD;AACA,aAAO;AAAA,IACT,KAAK;AACH,UAAI,MAAM,WAAW,aAAa;AAChC,eAAO,EAAE,QAAQ,UAAU,WAAW,MAAM,UAAU;AAAA,MACxD;AACA,aAAO;AAAA,IACT,KAAK;AACH,UAAI,MAAM,WAAW,UAAU;AAC7B,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,WAAW,MAAM;AAAA,UACjB,WAAW,KAAK,IAAI;AAAA,QACtB;AAAA,MACF;AACA,aAAO;AAAA,IACT,KAAK;AACH,UAAI,MAAM,WAAW,UAAU;AAC7B,eAAO,EAAE,QAAQ,SAAS;AAAA,MAC5B;AACA,aAAO;AAAA,IACT,KAAK;AACH,aAAO,EAAE,QAAQ,OAAO;AAAA,IAC1B;AACE,aAAO;AAAA,EACX;AACF;AAEA,IAAM,eAA8B,EAAE,QAAQ,OAAO;AAE9C,SAAS,mBAAmB;AACjC,SAAO,WAAW,iBAAiB,YAAY;AACjD;;;AC1DA,SAAS,UAAAC,SAAQ,UAAU,mBAAmB;AAEvC,SAAS,mBAAmB;AACjC,QAAM,mBAAmBA,QAA6B,IAAI;AAC1D,QAAM,YAAYA,QAAe,CAAC,CAAC;AACnC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAsB,IAAI;AAE5D,QAAM,QAAQ,YAAY,CAAC,WAAwB;AACjD,cAAU,UAAU,CAAC;AACrB,iBAAa,IAAI;AACjB,UAAM,WAAW,IAAI,cAAc,MAAM;AACzC,aAAS,kBAAkB,CAAC,MAAM;AAChC,UAAI,EAAE,KAAK,OAAO,GAAG;AACnB,kBAAU,QAAQ,KAAK,EAAE,IAAI;AAAA,MAC/B;AAAA,IACF;AACA,aAAS,SAAS,MAAM;AACtB,YAAM,OAAO,IAAI,KAAK,UAAU,SAAS,EAAE,MAAM,aAAa,CAAC;AAC/D,mBAAa,IAAI;AAAA,IACnB;AACA,aAAS,MAAM;AACf,qBAAiB,UAAU;AAAA,EAC7B,GAAG,CAAC,CAAC;AAEL,QAAM,OAAO,YAAY,MAAM;AAC7B,QACE,iBAAiB,WACjB,iBAAiB,QAAQ,UAAU,YACnC;AACA,uBAAiB,QAAQ,KAAK;AAAA,IAChC;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ,YAAY,MAAM;AAC9B,QACE,iBAAiB,WACjB,iBAAiB,QAAQ,UAAU,aACnC;AACA,uBAAiB,QAAQ,MAAM;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,SAAS,YAAY,MAAM;AAC/B,QACE,iBAAiB,WACjB,iBAAiB,QAAQ,UAAU,UACnC;AACA,uBAAiB,QAAQ,OAAO;AAAA,IAClC;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,SAAO,EAAE,OAAO,MAAM,OAAO,QAAQ,UAAU;AACjD;;;ACpDA,SAAS,aAAAC,YAAW,eAAAC,oBAAmB;AAGvC,SAAS,gBAAgB,IAAyB;AAChD,QAAM,YAAY,GAAG,aAAa,YAAY;AAC9C,MAAI,UAAW,QAAO;AAEtB,QAAM,cAAc,GAAG,aAAa,aAAa;AACjD,MAAI,YAAa,QAAO;AAExB,QAAM,OAAO,GAAG,WAAW,KAAK;AAChC,MAAI,QAAQ,KAAK,UAAU,GAAI,QAAO;AAEtC,QAAM,MAAM,GAAG,QAAQ,YAAY;AACnC,SAAO,GAAG,KAAK,GAAG,GAAG,IAAI,GAAG,EAAE,KAAK;AACrC;AAQO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,cAAcA;AAAA,IAClB,CAAC,MAAkB;AACjB,YAAM,SAAS,EAAE;AAEjB,UAAI,CAAC,UAAU,OAAO,QAAQ,oBAAoB,EAAG;AAErD,YAAM,KAAK,OAAO,QAAQ,IAAI,SAAS,GAAG;AAC1C,UAAI,CAAC,GAAI;AAET,YAAM,YAAY,GAAG,aAAa,SAAS;AAC3C,YAAM,eAAe,gBAAgB,EAAE;AACvC,YAAM,UAAU,OAAO,SAAS,WAAW,OAAO,SAAS;AAE3D,gBAAU,EAAE,WAAW,cAAc,SAAS,aAAa,GAAG,CAAC;AAAA,IACjE;AAAA,IACA,CAAC,WAAW,SAAS;AAAA,EACvB;AAEA,EAAAD,WAAU,MAAM;AACd,QAAI,CAAC,QAAS;AAEd,aAAS,iBAAiB,SAAS,aAAa,IAAI;AACpD,WAAO,MAAM;AACX,eAAS,oBAAoB,SAAS,aAAa,IAAI;AAAA,IACzD;AAAA,EACF,GAAG,CAAC,SAAS,WAAW,CAAC;AAC3B;;;ACtDA,SAAS,YAAAE,WAAU,eAAAC,cAAa,eAAe;;;ACA/C,SAAS,SAAS;AAIlB,IAAM,uBAAuB,EAAE,MAAM,cAAc;AAInD,IAAM,YAAY,OAAO,WAAW;AAE7B,SAAS,gBAA4B;AAC1C,MAAI,CAAC,UAAW,QAAO,CAAC;AACxB,MAAI;AACF,UAAM,MAAM,aAAa,QAAQ,aAAa,SAAS;AACvD,QAAI,CAAC,IAAK,QAAO,CAAC;AAClB,UAAM,SAAkB,KAAK,MAAM,GAAG;AACtC,UAAM,SAAS,qBAAqB,UAAU,MAAM;AACpD,QAAI,CAAC,OAAO,SAAS;AACnB,UAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,cAAM,QAAQ,OAAO;AAAA,UACnB,CAAC,SAAS,eAAe,UAAU,IAAI,EAAE;AAAA,QAC3C;AACA,cAAM,iBAAiB,MAAM,IAAI,CAAC,SAAS,eAAe,MAAM,IAAI,CAAC;AACrE,sBAAc,cAAc;AAC5B,eAAO;AAAA,MACT;AACA,mBAAa,WAAW,aAAa,SAAS;AAC9C,aAAO,CAAC;AAAA,IACV;AACA,WAAO,OAAO;AAAA,EAChB,QAAQ;AACN,iBAAa,WAAW,aAAa,SAAS;AAC9C,WAAO,CAAC;AAAA,EACV;AACF;AAEO,SAAS,cAAc,WAA6B;AACzD,MAAI,CAAC,UAAW;AAChB,eAAa,QAAQ,aAAa,WAAW,KAAK,UAAU,SAAS,CAAC;AACxE;AAEO,SAAS,YAAY,UAA0B;AACpD,QAAM,YAAY,cAAc;AAChC,YAAU,KAAK,QAAQ;AACvB,gBAAc,SAAS;AACzB;AAEO,SAAS,eAAe,IAAY,SAAkC;AAC3E,QAAM,YAAY,cAAc;AAChC,QAAM,QAAQ,UAAU,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE;AACpD,MAAI,UAAU,IAAI;AAChB,cAAU,KAAK,IAAI,EAAE,GAAG,UAAU,KAAK,GAAI,GAAG,QAAQ;AACtD,kBAAc,SAAS;AAAA,EACzB;AACF;AAEO,SAAS,eAAe,IAAkB;AAC/C,QAAM,YAAY,cAAc,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAC3D,gBAAc,SAAS;AACzB;AAEO,SAAS,YAAY,IAAkC;AAC5D,SAAO,cAAc,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAChD;AAIA,IAAM,UAAU;AAChB,IAAM,cAAc;AACpB,IAAM,aAAa;AAEnB,SAAS,SAA+B;AACtC,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,UAAU,UAAU,KAAK,SAAS,UAAU;AAClD,YAAQ,kBAAkB,MAAM;AAC9B,YAAM,KAAK,QAAQ;AACnB,UAAI,CAAC,GAAG,iBAAiB,SAAS,WAAW,GAAG;AAC9C,WAAG,kBAAkB,WAAW;AAAA,MAClC;AAAA,IACF;AACA,YAAQ,YAAY,MAAM,QAAQ,QAAQ,MAAM;AAChD,YAAQ,UAAU,MAAM,OAAO,QAAQ,KAAK;AAAA,EAC9C,CAAC;AACH;AAEA,eAAsB,UAAU,KAAa,MAA2B;AACtE,QAAM,KAAK,MAAM,OAAO;AACxB,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,KAAK,GAAG,YAAY,aAAa,WAAW;AAClD,OAAG,YAAY,WAAW,EAAE,IAAI,MAAM,GAAG;AACzC,OAAG,aAAa,MAAM,QAAQ;AAC9B,OAAG,UAAU,MAAM,OAAO,GAAG,KAAK;AAAA,EACpC,CAAC;AACH;AAEA,eAAsB,UAAU,KAAwC;AACtE,QAAM,KAAK,MAAM,OAAO;AACxB,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,KAAK,GAAG,YAAY,aAAa,UAAU;AACjD,UAAM,UAAU,GAAG,YAAY,WAAW,EAAE,IAAI,GAAG;AACnD,YAAQ,YAAY,MAAM,QAAQ,QAAQ,MAA0B;AACpE,YAAQ,UAAU,MAAM,OAAO,QAAQ,KAAK;AAAA,EAC9C,CAAC;AACH;AAEA,eAAsB,YAAY,KAA4B;AAC5D,QAAM,KAAK,MAAM,OAAO;AACxB,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,KAAK,GAAG,YAAY,aAAa,WAAW;AAClD,OAAG,YAAY,WAAW,EAAE,OAAO,GAAG;AACtC,OAAG,aAAa,MAAM,QAAQ;AAC9B,OAAG,UAAU,MAAM,OAAO,GAAG,KAAK;AAAA,EACpC,CAAC;AACH;;;AD7GA,IAAM,YAAY;AAEX,SAAS,eAAe;AAC7B,QAAM,CAAC,WAAW,YAAY,IAAIC;AAAA,IAAqB,MAC7C,cAAc;AAAA,EACxB;AACA,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAS,SAAS;AAE1D,QAAM,SAAS,QAAQ,MAAM;AAC3B,UAAM,eAAe,UAAU,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU;AAC1D,UAAM,aAAa,UAAU,OAAO,CAAC,MAAM,EAAE,UAAU;AACvD,WAAO,CAAC,GAAG,cAAc,GAAG,UAAU;AAAA,EACxC,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,kBAAkB;AAAA,IACtB,MAAM,UAAU,KAAK,CAAC,MAAM,CAAC,EAAE,UAAU;AAAA,IACzC,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,mBAAmB;AAAA,IACvB,MAAM,OAAO,MAAM,GAAG,YAAY;AAAA,IAClC,CAAC,QAAQ,YAAY;AAAA,EACvB;AAEA,QAAM,UAAU,OAAO,SAAS;AAChC,QAAM,iBAAiB,OAAO,SAAS;AAEvC,QAAM,WAAWC,aAAY,MAAM;AACjC,oBAAgB,CAAC,MAAM,IAAI,SAAS;AAAA,EACtC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAUA,aAAY,MAAM;AAChC,iBAAqB,cAAc,CAAC;AAAA,EACtC,GAAG,CAAC,CAAC;AAEL,QAAMC,eAAcD,aAAY,CAAC,aAAuB;AACtD,IAAQ,YAAY,QAAQ;AAC5B,iBAAqB,cAAc,CAAC;AAAA,EACtC,GAAG,CAAC,CAAC;AAEL,QAAME,kBAAiBF;AAAA,IACrB,CAAC,IAAY,YAA+B;AAC1C,MAAQ,eAAe,IAAI,OAAO;AAClC,mBAAqB,cAAc,CAAC;AAAA,IACtC;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAMG,kBAAiBH,aAAY,CAAC,OAAe;AACjD,IAAQ,eAAe,EAAE;AACzB,iBAAqB,cAAc,CAAC;AAAA,EACtC,GAAG,CAAC,CAAC;AAEL,QAAMI,eAAcJ,aAAY,CAAC,OAAe;AAC9C,WAAe,YAAY,EAAE;AAAA,EAC/B,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,aAAAC;AAAA,IACA;AAAA,EACF;AACF;;;AExEA,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAuDD,gBAAAC,YAAA;AA5CC,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,MAAI,OAAO;AACX,MAAI,YAAY;AAChB,MAAI,OAAO;AAEX,MAAI,MAAM,WAAW,QAAQ;AAC3B,QAAI,iBAAiB;AACnB,aAAO;AACP,kBAAY;AAAA,IACd,OAAO;AACL,aAAO;AACP,kBAAY;AAAA,QACV;AAAA,QACA,YAAY,eAAe;AAAA,MAC7B;AAAA,IACF;AAAA,EACF,WAAW,MAAM,WAAW,aAAa;AACvC,WAAO;AACP,gBAAY;AAAA,EACd,WAAW,MAAM,WAAW,UAAU;AACpC,WAAO;AACP,gBAAY;AAAA,EACd,WAAW,MAAM,WAAW,UAAU;AACpC,WAAO;AACP,gBAAY;AACZ,WAAO;AAAA,EACT;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,oBAAgB;AAAA,MAChB;AAAA,MACA,UAAU,MAAM,WAAW;AAAA,MAC3B,WAAW,GAAG,2CAA2C,WAAW;AAAA,QAClE,sBAAsB,MAAM,WAAW;AAAA,QACvC,mFACE,MAAM,WAAW;AAAA,MACrB,CAAC;AAAA,MAED,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,MAAM;AAAA,UACN,WAAW,OAAO,iBAAiB;AAAA,UACnC,MAAM;AAAA;AAAA,MACR;AAAA;AAAA,EACF;AAEJ;;;AChEI,gBAAAC,YAAA;AAFG,SAAS,UAAU,EAAE,MAAM,GAAmB;AACnD,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,oBAAgB;AAAA,MAChB,WAAU;AAAA,MAET;AAAA;AAAA,EACH;AAEJ;;;ACbA,SAAS,YAAAC,WAAU,UAAAC,SAAQ,aAAAC,kBAAiB;AAE5C,SAAS,iBAAAC,sBAAqB;AAC9B;AAAA,EACE,eAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAsCH,SAIE,OAAAC,MAJF,QAAAC,aAAA;AA5BG,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,CAAC,SAAS,UAAU,IAAIC,UAAS,KAAK;AAC5C,QAAM,CAAC,MAAM,OAAO,IAAIA,UAAS,SAAS,IAAI;AAC9C,QAAM,WAAWC,QAAyB,IAAI;AAE9C,EAAAC,WAAU,MAAM;AACd,QAAI,WAAW,SAAS,SAAS;AAC/B,eAAS,QAAQ,MAAM;AACvB,eAAS,QAAQ,OAAO;AAAA,IAC1B;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,eAAe,MAAM;AACzB,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,WAAW,YAAY,SAAS,MAAM;AACxC,eAAS,SAAS,IAAI,OAAO;AAAA,IAC/B,OAAO;AACL,cAAQ,SAAS,IAAI;AAAA,IACvB;AACA,eAAW,KAAK;AAAA,EAClB;AAEA,SACE,gBAAAH;AAAA,IAAC;AAAA;AAAA,MACC,oBAAgB;AAAA,MAChB,WAAU;AAAA,MAEV;AAAA,wBAAAD;AAAA,UAACF;AAAA,UAAA;AAAA,YACC,MAAM,SAAS,aAAa,wBAAwBC;AAAA,YACpD,MAAM;AAAA,YACN,WACE,SAAS,aACL,8CACA;AAAA;AAAA,QAER;AAAA,QAEC,UACC,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,oBAAgB;AAAA,YAChB,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,QAAQ,EAAE,OAAO,KAAK;AAAA,YACvC,QAAQ;AAAA,YACR,WAAW,CAAC,MAAM;AAChB,kBAAI,EAAE,QAAQ,QAAS,cAAa;AACpC,kBAAI,EAAE,QAAQ,UAAU;AACtB,wBAAQ,SAAS,IAAI;AACrB,2BAAW,KAAK;AAAA,cAClB;AAAA,YACF;AAAA,YACA,WAAU;AAAA;AAAA,QACZ,IAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,oBAAgB;AAAA,YAChB,SAAS,MAAM;AACb,kBAAI,SAAS,WAAY;AACzB,yBAAW,IAAI;AAAA,YACjB;AAAA,YACA,WAAU;AAAA,YAET,mBAAS;AAAA;AAAA,QACZ;AAAA,QAID,CAAC,SAAS,cACT,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,oBAAgB;AAAA,YAChB,SAAS,MAAM,SAAS,SAAS,EAAE;AAAA,YACnC,WAAU;AAAA,YAEV,0BAAAA,KAACF,gBAAA,EAAc,MAAM,cAAc,MAAM,IAAI;AAAA;AAAA,QAC/C;AAAA,QAGF,gBAAAE;AAAA,UAAC;AAAA;AAAA,YACC,oBAAgB;AAAA,YAChB,SAAS,MAAM,YAAY,SAAS,EAAE;AAAA,YACtC,WAAW;AAAA,cACT;AAAA,cACA,SAAS,aACL,gDACA;AAAA,YACN;AAAA,YAEA,0BAAAA,KAACF,gBAAA,EAAc,MAAM,gBAAgB,MAAM,IAAI;AAAA;AAAA,QACjD;AAAA;AAAA;AAAA,EACF;AAEJ;;;ACzFQ,SAIA,UAJA,OAAAO,MAeI,QAAAC,aAfJ;AAZD,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,SACE,gBAAAD,KAAC,SAAI,oBAAgB,MAAC,WAAU,6CAC7B,oBAAU,WAAW,IACpB,gBAAAA,KAAC,OAAE,WAAU,uDAAsD,kCAEnE,IAEA,gBAAAC,MAAA,YACG;AAAA,cAAU,IAAI,CAAC,MACd,gBAAAD;AAAA,MAAC;AAAA;AAAA,QAEC,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA;AAAA,MAJK,EAAE;AAAA,IAKT,CACD;AAAA,IACA,WACC,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,oBAAgB;AAAA,QAChB,SAAS;AAAA,QACT,WAAU;AAAA,QAET;AAAA;AAAA,UAAe;AAAA;AAAA;AAAA,IAClB;AAAA,KAEJ,GAEJ;AAEJ;;;ACpDA,SAAS,UAAAC,SAAQ,YAAAC,WAAU,eAAAC,oBAAmC;AAC9D;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAAC;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAAC,sBAAqB;AAE9B,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,oBAAoB;;;ACd7B,SAAS,YAAAC,WAAU,eAAAC,oBAAmB;AAO/B,SAAS,YACd,YACA,aAAuB,EAAE,GAAG,GAAG,GAAG,EAAE,GACpC;AACA,QAAM,CAAC,QAAQ,IAAID,UAAmB,MAAM;AAC1C,QAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAI;AACF,YAAM,MAAM,aAAa,QAAQ,UAAU;AAC3C,UAAI,KAAK;AACP,cAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,YAAI,OAAO,OAAO,MAAM,YAAY,OAAO,OAAO,MAAM,UAAU;AAChE,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AACA,WAAO;AAAA,EACT,CAAC;AAED,QAAM,iBAAiBC;AAAA,IACrB,CAAC,QAAkB;AACjB,UAAI;AACF,qBAAa,QAAQ,YAAY,KAAK,UAAU,GAAG,CAAC;AAAA,MACtD,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,IACA,CAAC,UAAU;AAAA,EACb;AAEA,SAAO,EAAE,UAAU,eAAe;AACpC;;;ACrCA,SAAS,UAAAC,eAA8B;AACvC,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAyDC,gBAAAC,YAAA;AA9CR,IAAM,gBAAgB,EAAE,WAAW,KAAK,SAAS,IAAI,MAAM,IAAI;AAC/D,IAAM,SAAS;AAER,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,EAAE,KAAK,IAAI,kBAAkB;AAAA,IACjC;AAAA,IACA;AAAA,IACA,SAAS,UACL,CAAC,QAAQ;AACP,UAAI,QAAQ,KAAM,SAAQ,GAAG;AAAA,IAC/B,IACA;AAAA,IACJ;AAAA,EACF,CAAC;AACD,QAAM,cAAcC,QAAO,KAAK;AAEhC,QAAM,UAAU,UAAU,eAAe,CAAC,GAAG,aAAa;AAC1D,QAAM,UAAU,UAAU,eAAe,CAAC,GAAG,aAAa;AAE1D,MAAI,MAAM;AACR,UAAM,UAAU,KAAK,QAAQ;AAC7B,UAAM,UAAU,KAAK,SAAS;AAE9B,QAAI,CAAC,YAAY,SAAS;AAExB,cAAQ,KAAK,OAAO;AACpB,cAAQ,KAAK,OAAO;AACpB,kBAAY,UAAU;AAAA,IACxB,OAAO;AACL,cAAQ,IAAI,OAAO;AACnB,cAAQ,IAAI,OAAO;AAAA,IACrB;AAAA,EACF,OAAO;AAEL,gBAAY,UAAU;AAAA,EACxB;AAEA,SAAO;AAAA,IACL,gBAAAD,KAAC,mBACE,kBACC,gBAAAA;AAAA,MAAC,OAAO;AAAA,MAAP;AAAA,QACC,oBAAgB;AAAA,QAChB,WAAU;AAAA,QACV,OAAO,EAAE,KAAK,SAAS,MAAM,QAAQ;AAAA,QACrC,SAAS,EAAE,SAAS,GAAG,OAAO,IAAI;AAAA,QAClC,SAAS,EAAE,SAAS,GAAG,OAAO,EAAE;AAAA,QAChC,MAAM,EAAE,SAAS,GAAG,OAAO,IAAI;AAAA,QAC/B,YAAY,EAAE,UAAU,IAAI;AAAA,QAE3B;AAAA;AAAA,IACH,GAEJ;AAAA,IACA,SAAS;AAAA,EACX;AACF;;;AC/EA,SAAS,UAAAE,SAAQ,YAAAC,iBAAgB;AACjC,SAAS,UAAAC,SAAQ,oBAAoB;AACrC,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,gBAAAC,qBAAoB;AA0DvB,gBAAAC,MAKA,QAAAC,aALA;AAlDC,SAAS,iBAAiB;AAAA,EAC/B,eAAe;AAAA,EACf;AACF,GAA0B;AACxB,QAAM,CAAC,WAAW,YAAY,IAAIC,UAAS,KAAK;AAChD,QAAM,WAAW,aAAa;AAC9B,QAAM,aAAaC,QAAO,KAAK;AAE/B,iBAAe,kBAAkB;AAC/B,eAAW,UAAU;AACrB,iBAAa,IAAI;AACjB,aAAS,IAAI,EAAE,OAAO,KAAK,CAAC;AAE5B,UAAM,SAAS,MAAM;AAAA,MACnB,OAAO;AAAA,MACP,YAAY;AAAA,QACV,UAAU,eAAe;AAAA,QACzB,MAAM;AAAA,MACR;AAAA,IACF,CAAC;AAED,QAAI,WAAW,SAAS;AACtB,iBAAW,UAAU;AACrB,mBAAa,KAAK;AAClB,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,WAAS,gBAAgB;AACvB,eAAW,UAAU;AACrB,iBAAa,KAAK;AAClB,aAAS,KAAK;AACd,aAAS,MAAM;AAAA,MACb,OAAO;AAAA,MACP,YAAY,EAAE,UAAU,IAAI;AAAA,IAC9B,CAAC;AAAA,EACH;AAEA,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,aAAa;AAAA,MACb,cAAc;AAAA,MACd,WAAW;AAAA,MACX,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,SAAQ;AAAA,MACR,WAAU;AAAA,MAEV;AAAA,wBAAAD;AAAA,UAACI,QAAO;AAAA,UAAP;AAAA,YACC,SAAS;AAAA,YACT,WAAU;AAAA,YACV,SAAS,EAAE,OAAO,KAAK;AAAA;AAAA,QACzB;AAAA,QACA,gBAAAH,MAAC,UAAK,WAAU,yCACd;AAAA,0BAAAD,KAACK,gBAAA,EAAc,MAAMC,eAAc,MAAM,IAAI;AAAA,UAC5C,YAAY,sBAAsB;AAAA,WACrC;AAAA;AAAA;AAAA,EACF;AAEJ;;;AH6PQ,SAgDQ,YAAAC,WA/CN,OAAAC,MADF,QAAAC,aAAA;AArSD,SAAS,eAAe;AAAA,EAC7B,UAAU;AAAA,EACV;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAwB;AACtB,QAAM,eAAeC,QAAuB,IAAI;AAChD,QAAM,EAAE,UAAU,eAAe,IAAI,YAAY,aAAa,SAAS;AAEvE,eAAa,cAAwC;AAAA,IACnD,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,WAAW,CAAC,EAAE,SAAS,QAAQ,MAAM;AACnC,qBAAe,EAAE,GAAG,SAAS,GAAG,QAAQ,CAAC;AAAA,IAC3C;AAAA,EACF,CAAC;AAED,QAAM,CAAC,eAAe,gBAAgB,IAAIC;AAAA,IACxC,MAAM,gBAAwB,YAAY,UAAU,KAAK;AAAA,EAC3D;AACA,QAAM,eAAe,eAAe,cAAc;AAElD,QAAM,uBAA+C,MAAM;AACzD,QAAI,CAAC,cAAe,QAAO,CAAC;AAC5B,UAAM,MAA8B,CAAC;AACrC,eAAW,QAAQ,cAAc,OAAO;AACtC,UAAI,KAAK,EAAE,IAAI,KAAK;AAAA,IACtB;AACA,WAAO;AAAA,EACT,GAAG;AAEH,QAAM,uBACJD,QAA+B,mBAAmB;AAEpD,QAAM,CAAC,cAAc,eAAe,IAAIC,UAAS,CAAC;AAClD,QAAM,CAAC,cAAc,eAAe,IAClCA,UAAiC,mBAAmB;AACtD,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAS,KAAK;AAC1C,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAS,KAAK;AAExD,QAAM,QAAQ,eAAe,SAAS,CAAC;AACvC,QAAM,cAAgC,MAAM,YAAY;AACxD,QAAM,cAAc,cAAe,aAAa,YAAY,EAAE,KAAK,KAAM;AAEzE,QAAM,iBAAiB,MAAM;AAAA,IAC3B,CAAC,OAAO,aAAa,EAAE,EAAE,KAAK,IAAI,UAAU;AAAA,EAC9C,EAAE;AAEF,QAAM,aACJ,gBACA,MAAM;AAAA,IACJ,CAAC,OACE,aAAa,EAAE,EAAE,KAAK,SACtB,qBAAqB,QAAQ,EAAE,EAAE,KAAK;AAAA,EAC3C;AAEF,QAAM,oBAAoBC;AAAA,IACxB,CAAC,UAAkB;AACjB,UAAI,CAAC,YAAa;AAClB,sBAAgB,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,YAAY,EAAE,GAAG,MAAM,EAAE;AAAA,IAClE;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAEA,QAAM,mBAAmBA,aAAY,YAAY;AAC/C,QAAI,CAAC,iBAAiB,CAAC,YAAa;AAEpC,QAAI,gBAAgB,gBAAgB;AAClC,UAAI;AACF,cAAM,MAAM,MAAM;AAAA,UAChB,GAAG,OAAO,kBAAkB,cAAc,EAAE;AAAA,UAC5C;AAAA,YACE,QAAQ;AAAA,YACR,SAAS;AAAA,cACP,gBAAgB;AAAA,cAChB,eAAe,UAAU,cAAc;AAAA,YACzC;AAAA,YACA,MAAM,KAAK,UAAU,EAAE,cAAc,YAAY,GAAG,CAAC;AAAA,UACvD;AAAA,QACF;AACA,YAAI,CAAC,IAAI,IAAI;AACX,gBAAMC,QAAO,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC9C,gBAAM,IAAI,MAAOA,OAAM,SAAoB,WAAW,IAAI,MAAM,GAAG;AAAA,QACrE;AACA,cAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,YAAI,KAAK,SAAS;AAChB,4BAAkB,cAAc,EAAE;AAClC,kBAAQ;AACR;AAAA,QACF;AAAA,MACF,SAAS,KAAK;AACZ,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,kBAAU,GAAG;AACb;AAAA,MACF;AAAA,IACF,OAAO;AACL,UAAI,cAAc,MAAM,WAAW,GAAG;AACpC,QAAQ,eAAe,cAAc,EAAE;AACvC,YAAI,cAAc,UAAU;AAC1B,UAAQ,YAAY,cAAc,QAAQ,EAAE,MAAM,MAAM;AAAA,UAAC,CAAC;AAAA,QAC5D;AACA,0BAAkB,cAAc,EAAE;AAClC,gBAAQ;AACR;AAAA,MACF;AACA,MAAQ,eAAe,cAAc,IAAI;AAAA,QACvC,OAAO,cAAc,MAAM,OAAO,CAAC,MAAM,EAAE,OAAO,YAAY,EAAE;AAAA,MAClE,CAAC;AAAA,IACH;AAEA,UAAM,WAAW,cAAc,MAAM,OAAO,CAAC,MAAM,EAAE,OAAO,YAAY,EAAE;AAC1E,qBAAiB,EAAE,GAAG,eAAe,OAAO,SAAS,CAAC;AACtD,oBAAgB,CAAC,SAAS,KAAK,IAAI,MAAM,SAAS,SAAS,CAAC,CAAC;AAAA,EAC/D,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,oBAAoBD,aAAY,YAAY;AAChD,QAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,aAAc;AAExD,qBAAiB,IAAI;AAErB,QAAI;AACF,YAAM,eAAe,MAAM,IAAI,CAAC,OAAO;AAAA,QACrC,GAAG;AAAA,QACH,aAAa,aAAa,EAAE,EAAE,KAAK,EAAE;AAAA,MACvC,EAAE;AAEF,YAAM,MAAM,MAAM,MAAM,GAAG,OAAO,kBAAkB,cAAc,EAAE,IAAI;AAAA,QACtE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,eAAe,UAAU,cAAc;AAAA,QACzC;AAAA,QACA,MAAM,KAAK,UAAU,EAAE,OAAO,aAAa,CAAC;AAAA,MAC9C,CAAC;AAED,UAAI,CAAC,IAAI,IAAI;AACX,cAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC9C,cAAM,IAAI,MAAO,MAAM,SAAoB,WAAW,IAAI,MAAM,GAAG;AAAA,MACrE;AAEA,uBAAiB,EAAE,GAAG,eAAe,OAAO,aAAa,CAAC;AAC1D,YAAM,cAAsC,CAAC;AAC7C,iBAAW,KAAK,cAAc;AAC5B,oBAAY,EAAE,EAAE,IAAI,EAAE;AAAA,MACxB;AACA,2BAAqB,UAAU;AAAA,IACjC,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,gBAAU,GAAG;AAAA,IACf,UAAE;AACA,uBAAiB,KAAK;AAAA,IACxB;AAAA,EACF,GAAG,CAAC,eAAe,gBAAgB,cAAc,OAAO,YAAY,CAAC;AAErE,QAAM,aAAaA,aAAY,MAAM;AACnC,oBAAgB,CAAC,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,EACjD,GAAG,CAAC,CAAC;AAEL,QAAM,kBAAkBA,aAAY,YAAY;AAC9C,UAAM,KAAK;AACX,UAAM,aAAa,MAAM,IAAI,CAAC,OAAO;AAAA,MACnC,GAAG;AAAA,MACH,aAAa,aAAa,EAAE,EAAE,KAAK,EAAE;AAAA,IACvC,EAAE;AAEF,UAAM,SAAS,MAAM;AACnB,MAAQ,eAAe,GAAG,EAAE;AAC5B,UAAI,GAAG,UAAU;AACf,QAAQ,YAAY,GAAG,QAAQ,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MACjD;AACA,wBAAkB,GAAG,EAAE;AACvB,iBAAW,MAAM;AACf,kBAAU,KAAK;AACf,gBAAQ;AAAA,MACV,GAAG,GAAG;AAAA,IACR;AAEA,QAAI,kBAAkB,GAAG,UAAU;AACjC,UAAI;AACF,cAAM,YAAY,MAAc,UAAU,GAAG,QAAS;AAEtD,cAAM,aAAa,MAAM,MAAM,GAAG,OAAO,6BAA6B;AAAA,UACpE,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,eAAe,UAAU,cAAc;AAAA,UACzC;AAAA,UACA,MAAM,KAAK,UAAU,EAAE,YAAY,GAAG,GAAG,CAAC;AAAA,QAC5C,CAAC;AACD,YAAI,CAAC,WAAW,IAAI;AAClB,gBAAM,IAAI;AAAA,YACR,kDAAkD,WAAW,MAAM;AAAA,UACrE;AAAA,QACF;AACA,cAAM,EAAE,UAAU,IAAI,MAAM,WAAW,KAAK;AAE5C,YAAI,WAAW;AACb,gBAAM,YAAY,MAAM,MAAM,WAAW;AAAA,YACvC,QAAQ;AAAA,YACR,SAAS,EAAE,gBAAgB,aAAa;AAAA,YACxC,MAAM;AAAA,UACR,CAAC;AACD,cAAI,CAAC,UAAU,IAAI;AACjB,kBAAM,IAAI;AAAA,cACR,kDAAkD,UAAU,MAAM;AAAA,YACpE;AAAA,UACF;AAAA,QACF;AAEA,cAAM,MAAM,GAAG,OAAO,wBAAwB;AAAA,UAC5C,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,eAAe,UAAU,cAAc;AAAA,UACzC;AAAA,UACA,MAAM,KAAK,UAAU;AAAA,YACnB,YAAY,GAAG;AAAA,YACf,MAAM,GAAG;AAAA,YACT,aAAa;AAAA,YACb,OAAO;AAAA,UACT,CAAC;AAAA,QACH,CAAC;AACD,eAAO;AAAA,MACT,SAAS,KAAK;AACZ,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,kBAAU,GAAG;AACb,kBAAU,KAAK;AAAA,MACjB;AAAA,IACF,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,aAAaA,aAAY,MAAM;AACnC,UAAM,SAAS,iBAAiB,MAAM,SAAS;AAE/C,QAAI,CAAC,QAAQ;AACX,sBAAgB,CAAC,SAAS,OAAO,CAAC;AAClC;AAAA,IACF;AAEA,QAAI,cAAc;AAChB,cAAQ;AACR;AAAA,IACF;AAEA,cAAU,IAAI;AACd,oBAAgB;AAAA,EAClB,GAAG,CAAC,cAAc,cAAc,OAAO,iBAAiB,OAAO,CAAC;AAEhE,MAAI,CAAC,iBAAiB,CAAC,YAAa,QAAO;AAE3C,QAAM,aAAa,iBAAiB,MAAM,SAAS;AACnD,QAAM,aAAa,YAAY,UAAU;AACzC,QAAM,gBAAgB,mBAAmB,MAAM,UAAU,MAAM,SAAS;AACxE,QAAM,uBAAuB,gBAAgB;AAE7C,QAAM,kBAAkB,uBACpB,gBACA,aACE,eACE,QACA,CAAC,iBAAiB,SACpB,CAAC;AAEP,QAAM,gBAAgB,uBAAuB,oBAAoB;AAEjE,SAAOE;AAAA,IACL,gBAAAL;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,oBAAgB;AAAA,QAChB,WAAU;AAAA,QAEV;AAAA,0BAAAA,MAAC,SAAI,WAAU,qCACb;AAAA,4BAAAA,MAAC,SAAI,WAAU,+BACb;AAAA,8BAAAD,KAAC,cAAW;AAAA,cACZ,gBAAAA,KAAC,UAAK,WAAU,iCACb,sBAAY,cACf;AAAA,eACF;AAAA,YACA,gBAAAA,KAAC,UAAO,SAAQ,SAAQ,MAAK,QAAO,SAAS,SAC3C,0BAAAA;AAAA,cAACO;AAAA,cAAA;AAAA,gBACC,MAAM;AAAA,gBACN,aAAa;AAAA,gBACb,MAAM;AAAA;AAAA,YACR,GACF;AAAA,aACF;AAAA,UAEA,gBAAAP;AAAA,YAAC;AAAA;AAAA,cACC,oBAAgB;AAAA,cAChB,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,kBAAkB,EAAE,OAAO,KAAK;AAAA,cACjD,aAAY;AAAA,cACZ,MAAM;AAAA,cACN,WAAU;AAAA;AAAA,UACZ;AAAA,UAEA,gBAAAC,MAAC,SAAI,oBAAgB,MAAC,WAAU,yCAC9B;AAAA,4BAAAA,MAAC,UAAK,WAAU,iCACb;AAAA;AAAA,cAAe;AAAA,cAAI,MAAM;AAAA,cAAO;AAAA,eACnC;AAAA,YACA,gBAAAA,MAAC,SAAI,WAAU,cACb;AAAA,8BAAAD,KAAC,oBAAiB,WAAW,kBAAkB;AAAA,cAC/C,gBAAAC;AAAA,gBAAC;AAAA;AAAA,kBACC,SAAQ;AAAA,kBACR,oBAAgB;AAAA,kBAChB,SAAS;AAAA,kBACT,UAAU,iBAAiB;AAAA,kBAC3B,OAAM;AAAA,kBAEN;AAAA,oCAAAD,KAACO,gBAAA,EAAc,MAAM,iBAAiB,MAAM,IAAI;AAAA,oBAChD,gBAAAP,KAAC,UAAK,WAAU,WAAU,kBAAI;AAAA;AAAA;AAAA,cAChC;AAAA,cACA,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,SAAQ;AAAA,kBACR,oBAAgB;AAAA,kBAChB,SAAS;AAAA,kBACT,UAAU;AAAA,kBAET,iCACC,gBACE,gBAAAC,MAAAF,WAAA,EACE;AAAA,oCAAAC;AAAA,sBAACO;AAAA,sBAAA;AAAA,wBACC,MAAMC;AAAA,wBACN,MAAM;AAAA,wBACN,WAAU;AAAA;AAAA,oBACZ;AAAA,oBAAE;AAAA,qBAEJ,IAEA,kBAEA,SACF,gBAAAR;AAAA,oBAACO;AAAA,oBAAA;AAAA,sBACC,MAAMC;AAAA,sBACN,MAAM;AAAA,sBACN,WAAU;AAAA;AAAA,kBACZ,IACE,aACF,gBAAAP,MAAAF,WAAA,EAAE;AAAA;AAAA,oBAEA,gBAAAC,KAACO,gBAAA,EAAc,MAAM,YAAY,MAAM,IAAI;AAAA,qBAC7C,IAEA,gBAAAN,MAAAF,WAAA,EAAE;AAAA;AAAA,oBAEA,gBAAAC,KAACO,gBAAA,EAAc,MAAM,kBAAkB,MAAM,IAAI;AAAA,qBACnD;AAAA;AAAA,cAEJ;AAAA,eACF;AAAA,aACF;AAAA,UACA,gBAAAP;AAAA,YAAC;AAAA;AAAA,cACC,UAAU,YAAY;AAAA,cACtB,SAAS,YAAY;AAAA,cACrB;AAAA,cACA,SAAS,eAAe,gBAAgB;AAAA,cAEvC,oBACC,gBAAAA;AAAA,gBAACO;AAAA,gBAAA;AAAA,kBACC,MAAM;AAAA,kBACN,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,WAAU;AAAA;AAAA,cACZ;AAAA;AAAA,UAEJ;AAAA;AAAA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,EACX;AACF;;;AXlLI,qBAAAE,WAeU,OAAAC,MAwBF,QAAAC,aAvCR;AArNG,SAAS,SAAS;AAAA,EACvB,UAAU;AAAA,EACV;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AACF,GAAkB;AAEhB,QAAM,eAAeC,QAAuB,IAAI;AAChD,QAAM,gBAAgBA,QAAO,KAAK;AAElC,EAAAC,cAAa,YAAsC;AAGnD,QAAM,CAAC,OAAO,QAAQ,IAAI,iBAAiB;AAC3C,QAAM,QAAQ,iBAAiB;AAC/B,QAAM,KAAK,aAAa;AAGxB,QAAM,CAAC,WAAW,YAAY,IAAIC,UAAS,KAAK;AAChD,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA,UAAwB,IAAI;AAC5E,QAAM,WAAWF,QAA2B,CAAC,CAAC;AAC9C,QAAM,YAAYA,QAA2B,IAAI;AACjD,QAAM,CAAC,iBAAiB,kBAAkB,IAAIE,UAAqB,CAAC,CAAC;AAErE,QAAM,cAAc,MAAM,WAAW;AACrC,QAAM,WAAW,MAAM,WAAW;AAGlC,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,kBAAkB,CAAC,cAAc,SAAS;AAC7C,oBAAc,UAAU;AACxB,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,cAAc,CAAC;AAGnB,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,eAAgB;AAErB,UAAM,GAAG,OAAO,kBAAkB;AAAA,MAChC,SAAS,EAAE,eAAe,UAAU,cAAc,GAAG;AAAA,IACvD,CAAC,EACE,KAAK,OAAO,QAAQ;AACnB,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,UAAI,CAAC,IAAI,IAAI;AACX,cAAM,MACH,MAAM,SAAoB,mBAAmB,IAAI,MAAM;AAC1D,kBAAU,GAAG;AACb;AAAA,MACF;AACA,UAAI,CAAC,KAAK,UAAW;AACrB,YAAM,SAAS,2BAA2B,UAAU,IAAI;AACxD,UAAI,CAAC,OAAO,SAAS;AACnB,kBAAU,4BAA4B;AACtC;AAAA,MACF;AACA,UAAI,OAAO,KAAK,OAAO;AACrB,kBAAU,OAAO,KAAK,KAAK;AAC3B;AAAA,MACF;AACA,YAAM,YAAY,OAAO,KAAK,aAAa,CAAC;AAC5C,YAAM,SAAqB,CAAC;AAC5B,iBAAW,KAAK,WAAW;AACzB,cAAM,WAAW,eAAe,UAAU;AAAA,UACxC,IAAI,EAAE;AAAA,UACN,MAAM,EAAE;AAAA,UACR,OAAO,EAAE;AAAA,UACT,YAAY;AAAA,UACZ,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC,CAAC;AACD,YAAI,SAAS,SAAS;AACpB,iBAAO,KAAK,SAAS,IAAI;AAAA,QAC3B,OAAO;AACL,kBAAQ;AAAA,YACN;AAAA,YACA,EAAE;AAAA,YACF,SAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AACA,yBAAmB,MAAM;AAAA,IAC3B,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,gBAAU,GAAG;AAAA,IACf,CAAC;AAAA,EACL,GAAG,CAAC,cAAc,CAAC;AAGnB,QAAM,mBAAmBC;AAAA,IACvB,MAAM,SAAS,QAAQ,SAAS,QAAQ,SAAS,CAAC,GAAG;AAAA,IACrD,CAAC;AAAA,EACH;AAEA,kBAAgB;AAAA,IACd,SAAS;AAAA,IACT;AAAA,IACA,WAAW,CAAC,SAAS;AACnB,UAAI,iBAAiB,MAAM,KAAK,UAAW;AAC3C,eAAS,QAAQ,KAAK,IAAI;AAC1B,eAAS,EAAE,MAAM,gBAAgB,CAAC;AAAA,IACpC;AAAA,EACF,CAAC;AAGD,QAAM,oBAAoBA;AAAA,IACxB,CAAC,WAAwB;AACvB,gBAAU,UAAU;AACpB,YAAM,MAAM,MAAM;AAAA,IACpB;AAAA,IACA,CAAC,MAAM,KAAK;AAAA,EACd;AAGA,QAAM,uBAAuBA,aAAY,MAAM;AAC7C,aAAS,UAAU,CAAC;AACpB,aAAS,EAAE,MAAM,kBAAkB,CAAC;AAAA,EACtC,GAAG,CAAC,QAAQ,CAAC;AAGb,QAAM,oBAAoBA,aAAY,MAAM;AAC1C,QAAI,MAAM,WAAW,QAAQ;AAC3B,mBAAa,CAAC,SAAS,CAAC,IAAI;AAAA,IAC9B,WAAW,MAAM,WAAW,aAAa;AACvC,eAAS,EAAE,MAAM,QAAQ,CAAC;AAC1B,YAAM,MAAM;AAAA,IACd,WAAW,MAAM,WAAW,UAAU;AACpC,eAAS,EAAE,MAAM,SAAS,CAAC;AAC3B,YAAM,OAAO;AAAA,IACf;AAAA,EACF,GAAG,CAAC,MAAM,QAAQ,UAAU,KAAK,CAAC;AAGlC,QAAM,aAAaA,aAAY,YAAY;AACzC,aAAS,EAAE,MAAM,OAAO,CAAC;AACzB,UAAM,KAAK;AAGX,UAAM,KAAK,OAAO,WAAW;AAC7B,UAAM,WAAW,SAAS,EAAE;AAE5B,UAAM,QAAgB,SAAS,QAAQ,IAAI,CAAC,OAAO;AAAA,MACjD,GAAG;AAAA,MACH,IAAI,OAAO,WAAW;AAAA,IACxB,EAAE;AAGF,OAAG,YAAY;AAAA,MACb;AAAA,MACA,MAAM,qBAAqB;AAAA,MAC3B;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,CAAC;AAGD,eAAW,YAAY;AACrB,UAAI,MAAM,WAAW;AACnB,cAAM,UAAU,UAAU,MAAM,SAAS,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MAC3D;AACA,eAAS,EAAE,MAAM,gBAAgB,CAAC;AAAA,IACpC,GAAG,GAAG;AAAA,EACR,GAAG,CAAC,UAAU,OAAO,IAAI,gBAAgB,OAAO,CAAC;AAGjD,QAAM,eAAeA;AAAA,IACnB,CAAC,IAAY,SAAiB;AAC5B,SAAG,eAAe,IAAI,EAAE,KAAK,CAAC;AAAA,IAChC;AAAA,IACA,CAAC,EAAE;AAAA,EACL;AAGA,QAAM,eAAeA;AAAA,IACnB,CAAC,OAAe;AACd,YAAM,WAAW,GAAG,YAAY,EAAE;AAClC,UAAI,UAAU,UAAU;AACtB,oBAAY,SAAS,QAAQ,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MAC/C;AACA,SAAG,eAAe,EAAE;AAAA,IACtB;AAAA,IACA,CAAC,EAAE;AAAA,EACL;AAGA,QAAM,kBAAkBA,aAAY,CAAC,OAAe;AAClD,wBAAoB,EAAE;AACtB,iBAAa,KAAK;AAAA,EACpB,GAAG,CAAC,CAAC;AAGL,QAAM,oBAAoBA,aAAY,MAAM;AAC1C,wBAAoB,IAAI;AAAA,EAC1B,GAAG,CAAC,CAAC;AAGL,QAAM,wBAAwBA,aAAY,MAAM;AAC9C,OAAG,QAAQ;AAAA,EACb,GAAG,CAAC,EAAE,CAAC;AAGP,QAAM,eAAe;AAAA,IACnB,GAAG,GAAG;AAAA,IACN,GAAG,gBAAgB;AAAA,MACjB,CAAC,OAAO,CAAC,GAAG,iBAAiB,KAAK,CAAC,OAAO,GAAG,OAAO,GAAG,EAAE;AAAA,IAC3D;AAAA,EACF;AAEA,SACE,gBAAAL,MAAAF,WAAA,EACE;AAAA,oBAAAE;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,oBAAgB;AAAA,QAChB,WAAU;AAAA,QAEV;AAAA,0BAAAD,KAACO,kBAAA,EAAgB,SAAS,OACvB,uBAAa,MAAM,WAAW,UAC7B,gBAAAP;AAAA,YAACQ,QAAO;AAAA,YAAP;AAAA,cACC,SAAS,EAAE,QAAQ,GAAG,SAAS,EAAE;AAAA,cACjC,SAAS,EAAE,QAAQ,QAAQ,SAAS,EAAE;AAAA,cACtC,MAAM,EAAE,QAAQ,GAAG,SAAS,EAAE;AAAA,cAC9B,YAAY,EAAE,UAAU,MAAM,MAAM,UAAU;AAAA,cAC9C,OAAO,EAAE,UAAU,SAAS;AAAA,cAE5B,0BAAAR;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAW;AAAA,kBACX,SAAS,GAAG;AAAA,kBACZ,gBAAgB,GAAG;AAAA,kBACnB,YAAY,GAAG;AAAA,kBACf,UAAU;AAAA,kBACV,UAAU;AAAA,kBACV,aAAa;AAAA;AAAA,cACf;AAAA;AAAA,UACF,GAEJ;AAAA,UACA,gBAAAC,MAAC,SAAI,oBAAgB,MAAC,WAAU,0BAC9B;AAAA,4BAAAD,KAAC,cAAW,WAAU,QAAO;AAAA,YAC7B,gBAAAA,KAAC,aAAU,aAAY,YAAW,WAAU,UAAS;AAAA,YACpD,MAAM,WAAW,SAChB,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,oBAAgB;AAAA,gBAChB,SAAS;AAAA,gBACT,WAAU;AAAA,gBACX;AAAA;AAAA,YAED,IAEA,gBAAAC,MAAC,SAAI,WAAU,0BACZ;AAAA,6BACC,gBAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,oBAAgB;AAAA,kBAChB,QAAQ;AAAA,kBACR,QAAQ;AAAA,kBACR,MAAK;AAAA,kBACL,UAAU;AAAA,kBACV,QAAQ;AAAA,kBACR,WAAW;AAAA,kBACX,eAAe;AAAA,kBACf,WAAU;AAAA;AAAA,cACZ;AAAA,cAGD,YACC,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,oBAAgB;AAAA,kBAChB,SAAS;AAAA,kBACT,WAAU;AAAA,kBACX;AAAA;AAAA,cAED;AAAA,cAED,eAAe,MAAM,YAAY,KAChC,gBAAAA,KAAC,aAAU,OAAO,MAAM,WAAW;AAAA,eAEvC;AAAA,YAEF,gBAAAA,KAAC,aAAU,aAAY,YAAW,WAAU,UAAS;AAAA,YACrD,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA,gBACX;AAAA,gBACA,iBAAiB,GAAG;AAAA,gBACpB,SAAS;AAAA;AAAA,YACX;AAAA,aACF;AAAA;AAAA;AAAA,IACF;AAAA,IAEC,oBACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,YAAY;AAAA,QACZ,UAAU,aAAa,KAAK,CAAC,MAAM,EAAE,OAAO,gBAAgB;AAAA,QAC5D;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT,mBAAmB;AAAA,QACnB;AAAA;AAAA,IACF;AAAA,KAEJ;AAEJ;","names":["useRef","useState","useCallback","useEffect","useDraggable","motion","AnimatePresence","barCount","useRef","useEffect","useCallback","useState","useCallback","useState","useCallback","addWorkflow","updateWorkflow","deleteWorkflow","getWorkflow","jsx","jsx","useState","useRef","useEffect","HugeiconsIcon","Alert01Icon","jsx","jsxs","useState","useRef","useEffect","jsx","jsxs","useRef","useState","useCallback","Loading03Icon","HugeiconsIcon","createPortal","useState","useCallback","useRef","jsx","useRef","useRef","useState","motion","HugeiconsIcon","Delete01Icon","jsx","jsxs","useState","useRef","motion","HugeiconsIcon","Delete01Icon","Fragment","jsx","jsxs","useRef","useState","useCallback","data","createPortal","HugeiconsIcon","Loading03Icon","Fragment","jsx","jsxs","useRef","useDraggable","useState","useEffect","useCallback","AnimatePresence","motion"]}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { Recorder } from './recorder.js';
2
- export { V as Voicebox, a as VoiceboxTool, b as VoiceboxToolParams, d as defineTool } from './voicebox-DCgECemo.js';
2
+ export { V as Voicebox, a as VoiceboxTool, b as VoiceboxToolParams, d as defineTool } from './voicebox-FiaoHnkf.js';
3
3
  import 'react/jsx-runtime';
4
4
  import 'zod';
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  Recorder
3
- } from "./chunk-VDQAVB4N.js";
3
+ } from "./chunk-RJFQIVZM.js";
4
4
  import {
5
5
  Voicebox
6
- } from "./chunk-WCRZUGN4.js";
7
- import "./chunk-QCWLFL7O.js";
6
+ } from "./chunk-BWBGNRKO.js";
7
+ import "./chunk-PRTYKFO3.js";
8
8
 
9
9
  // src/types/tools.ts
10
10
  function defineTool(tool) {
@@ -3,9 +3,10 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  interface RecorderProps {
4
4
  baseUrl?: string;
5
5
  publishableKey?: string;
6
+ attribute?: string;
6
7
  cursor?: React.ReactNode;
7
8
  onError?: (error: string) => void;
8
9
  }
9
- declare function Recorder({ baseUrl, publishableKey, cursor, onError, }: RecorderProps): react_jsx_runtime.JSX.Element;
10
+ declare function Recorder({ baseUrl, publishableKey, attribute, cursor, onError, }: RecorderProps): react_jsx_runtime.JSX.Element;
10
11
 
11
12
  export { Recorder };
package/dist/recorder.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import {
3
3
  Recorder
4
- } from "./chunk-VDQAVB4N.js";
5
- import "./chunk-QCWLFL7O.js";
4
+ } from "./chunk-RJFQIVZM.js";
5
+ import "./chunk-PRTYKFO3.js";
6
6
  export {
7
7
  Recorder
8
8
  };
package/dist/styles.css CHANGED
@@ -6,9 +6,10 @@
6
6
  --font-sans: var(--font-sans);
7
7
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
8
8
  "Courier New", monospace;
9
- --color-red-200: oklch(88.5% 0.062 18.334);
10
9
  --color-red-300: oklch(80.8% 0.114 19.571);
10
+ --color-red-400: oklch(70.4% 0.191 22.216);
11
11
  --color-red-500: oklch(63.7% 0.237 25.331);
12
+ --color-amber-400: oklch(82.8% 0.189 84.429);
12
13
  --color-amber-500: oklch(76.9% 0.188 70.08);
13
14
  --color-green-500: oklch(72.3% 0.219 149.579);
14
15
  --color-emerald-500: oklch(69.6% 0.17 162.48);
@@ -259,6 +260,9 @@
259
260
  .inset-0 {
260
261
  inset: calc(var(--spacing) * 0);
261
262
  }
263
+ .inset-x-0 {
264
+ inset-inline: calc(var(--spacing) * 0);
265
+ }
262
266
  .inset-y-0 {
263
267
  inset-block: calc(var(--spacing) * 0);
264
268
  }
@@ -289,9 +293,6 @@
289
293
  .top-3\.5 {
290
294
  top: calc(var(--spacing) * 3.5);
291
295
  }
292
- .top-4 {
293
- top: calc(var(--spacing) * 4);
294
- }
295
296
  .top-6 {
296
297
  top: calc(var(--spacing) * 6);
297
298
  }
@@ -316,9 +317,6 @@
316
317
  .right-3 {
317
318
  right: calc(var(--spacing) * 3);
318
319
  }
319
- .right-4 {
320
- right: calc(var(--spacing) * 4);
321
- }
322
320
  .right-6 {
323
321
  right: calc(var(--spacing) * 6);
324
322
  }
@@ -334,6 +332,9 @@
334
332
  .bottom-6 {
335
333
  bottom: calc(var(--spacing) * 6);
336
334
  }
335
+ .bottom-8 {
336
+ bottom: calc(var(--spacing) * 8);
337
+ }
337
338
  .bottom-full {
338
339
  bottom: 100%;
339
340
  }
@@ -436,6 +437,9 @@
436
437
  .my-2 {
437
438
  margin-block: calc(var(--spacing) * 2);
438
439
  }
440
+ .mt-0\.5 {
441
+ margin-top: calc(var(--spacing) * 0.5);
442
+ }
439
443
  .mt-1 {
440
444
  margin-top: calc(var(--spacing) * 1);
441
445
  }
@@ -651,6 +655,9 @@
651
655
  .h-12 {
652
656
  height: calc(var(--spacing) * 12);
653
657
  }
658
+ .h-\[200px\] {
659
+ height: 200px;
660
+ }
654
661
  .h-auto {
655
662
  height: auto;
656
663
  }
@@ -723,9 +730,6 @@
723
730
  .w-42 {
724
731
  width: calc(var(--spacing) * 42);
725
732
  }
726
- .w-56 {
727
- width: calc(var(--spacing) * 56);
728
- }
729
733
  .w-64 {
730
734
  width: calc(var(--spacing) * 64);
731
735
  }
@@ -913,8 +917,8 @@
913
917
  .auto-rows-min {
914
918
  grid-auto-rows: min-content;
915
919
  }
916
- .grid-cols-4 {
917
- grid-template-columns: repeat(4, minmax(0, 1fr));
920
+ .grid-cols-2 {
921
+ grid-template-columns: repeat(2, minmax(0, 1fr));
918
922
  }
919
923
  .grid-rows-\[auto_1fr\] {
920
924
  grid-template-rows: auto 1fr;
@@ -1211,6 +1215,10 @@
1211
1215
  border-bottom-style: var(--tw-border-style);
1212
1216
  border-bottom-width: 1px;
1213
1217
  }
1218
+ .border-b-2 {
1219
+ border-bottom-style: var(--tw-border-style);
1220
+ border-bottom-width: 2px;
1221
+ }
1214
1222
  .border-l {
1215
1223
  border-left-style: var(--tw-border-style);
1216
1224
  border-left-width: 1px;
@@ -1250,6 +1258,9 @@
1250
1258
  border-color: color-mix(in oklab, var(--muted-foreground) 20%, transparent);
1251
1259
  }
1252
1260
  }
1261
+ .border-primary {
1262
+ border-color: var(--primary);
1263
+ }
1253
1264
  .border-sidebar-border {
1254
1265
  border-color: var(--sidebar-border);
1255
1266
  }
@@ -1307,16 +1318,22 @@
1307
1318
  .bg-primary {
1308
1319
  background-color: var(--primary);
1309
1320
  }
1321
+ .bg-primary\/10 {
1322
+ background-color: var(--primary);
1323
+ @supports (color: color-mix(in lab, red, red)) {
1324
+ background-color: color-mix(in oklab, var(--primary) 10%, transparent);
1325
+ }
1326
+ }
1310
1327
  .bg-primary\/20 {
1311
1328
  background-color: var(--primary);
1312
1329
  @supports (color: color-mix(in lab, red, red)) {
1313
1330
  background-color: color-mix(in oklab, var(--primary) 20%, transparent);
1314
1331
  }
1315
1332
  }
1316
- .bg-red-200\/40 {
1317
- background-color: color-mix(in srgb, oklch(88.5% 0.062 18.334) 40%, transparent);
1333
+ .bg-red-400\/40 {
1334
+ background-color: color-mix(in srgb, oklch(70.4% 0.191 22.216) 40%, transparent);
1318
1335
  @supports (color: color-mix(in lab, red, red)) {
1319
- background-color: color-mix(in oklab, var(--color-red-200) 40%, transparent);
1336
+ background-color: color-mix(in oklab, var(--color-red-400) 40%, transparent);
1320
1337
  }
1321
1338
  }
1322
1339
  .bg-secondary {
@@ -1343,6 +1360,9 @@
1343
1360
  .mask-repeat {
1344
1361
  mask-repeat: repeat;
1345
1362
  }
1363
+ .fill-amber-400 {
1364
+ fill: var(--color-amber-400);
1365
+ }
1346
1366
  .fill-amber-500\/20 {
1347
1367
  fill: color-mix(in srgb, oklch(76.9% 0.188 70.08) 20%, transparent);
1348
1368
  @supports (color: color-mix(in lab, red, red)) {
@@ -1579,6 +1599,9 @@
1579
1599
  .whitespace-nowrap {
1580
1600
  white-space: nowrap;
1581
1601
  }
1602
+ .text-amber-400 {
1603
+ color: var(--color-amber-400);
1604
+ }
1582
1605
  .text-amber-500 {
1583
1606
  color: var(--color-amber-500);
1584
1607
  }
@@ -4951,6 +4974,11 @@
4951
4974
  flex: none;
4952
4975
  }
4953
4976
  }
4977
+ .\[\&\:\:-webkit-scrollbar\]\:hidden {
4978
+ &::-webkit-scrollbar {
4979
+ display: none;
4980
+ }
4981
+ }
4954
4982
  .\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0 {
4955
4983
  &:has([role=checkbox]) {
4956
4984
  padding-right: calc(var(--spacing) * 0);
@@ -16,12 +16,13 @@ interface VoiceboxProps {
16
16
  baseUrl?: string;
17
17
  publishableKey?: string;
18
18
  identifier?: string | null;
19
+ attribute?: string;
19
20
  tools?: VoiceboxTool[];
20
21
  triggerIcon?: React.ReactNode;
21
22
  cursor?: React.ReactNode;
22
- metadata?: Record<string, string>;
23
+ metadata?: Record<string, unknown>;
23
24
  onError?: (error: string) => void;
24
25
  }
25
- declare function Voicebox({ baseUrl, publishableKey, identifier, tools, triggerIcon, cursor, firstMessage, instructions, metadata, onError, }: VoiceboxProps): react_jsx_runtime.JSX.Element | null;
26
+ declare function Voicebox({ baseUrl, publishableKey, identifier, attribute, tools, triggerIcon, cursor, firstMessage, instructions, metadata, onError, }: VoiceboxProps): react_jsx_runtime.JSX.Element | null;
26
27
 
27
28
  export { Voicebox as V, type VoiceboxTool as a, type VoiceboxToolParams as b, defineTool as d };
@@ -1,3 +1,3 @@
1
1
  import 'react/jsx-runtime';
2
- export { V as Voicebox, a as VoiceboxTool } from './voicebox-DCgECemo.js';
2
+ export { V as Voicebox, a as VoiceboxTool } from './voicebox-FiaoHnkf.js';
3
3
  import 'zod';
package/dist/voicebox.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import {
3
3
  Voicebox
4
- } from "./chunk-WCRZUGN4.js";
5
- import "./chunk-QCWLFL7O.js";
4
+ } from "./chunk-BWBGNRKO.js";
5
+ import "./chunk-PRTYKFO3.js";
6
6
  export {
7
7
  Voicebox
8
8
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meridial/react",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "description": "React components for embedding the Meridial in-app assistant UI (Voicebox) and workflow recorder UI (Recorder).",
6
6
  "author": "Meridial",
@@ -32,8 +32,8 @@
32
32
  "tailwindcss": "^4.1.18",
33
33
  "tsup": "^8.5.0",
34
34
  "typescript": "^5.9.3",
35
- "@workspace/typescript-config": "0.0.0",
36
- "@workspace/ui": "0.0.0"
35
+ "@workspace/ui": "0.0.0",
36
+ "@workspace/typescript-config": "0.0.0"
37
37
  },
38
38
  "publishConfig": {
39
39
  "access": "public"