@declarion/react 0.1.31 → 0.1.33

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/lib/utils.ts","../src/types/api.ts","../src/api/client.ts","../src/api/schema.ts","../src/hooks/useSchema.ts","../src/stores/tabs.ts","../src/hooks/useTabNavigate.ts","../src/components/shared/DynamicIcon.tsx","../src/types/schema.ts","../src/components/layout/Sidebar.tsx","../src/api/auth.ts","../src/stores/auth.ts","../src/hooks/useAuth.ts","../src/components/ui/dropdown-menu.tsx","../src/components/ui/button.tsx","../src/components/layout/TopBar.tsx","../src/components/layout/TabBar.tsx","../src/api/events.ts","../src/hooks/useChildrenData.ts","../src/hooks/useSSE.ts","../src/components/layout/Layout.tsx","../src/components/ui/input.tsx","../src/components/ui/label.tsx","../src/components/ui/card.tsx","../src/components/pages/LoginPage.tsx","../src/components/pages/SignupPage.tsx","../src/components/pages/SSOCallbackPage.tsx","../src/components/pages/NotFoundPage.tsx","../src/components/shared/PageHeader.tsx","../src/components/ui/badge.tsx","../src/components/pages/AdminCatalogPage.tsx","../src/api/data.ts","../src/hooks/useEntityData.ts","../src/hooks/useMutations.ts","../src/hooks/useDebounce.ts","../src/components/shared/CopyButton.tsx","../src/components/fields/StringField.tsx","../src/components/ui/textarea.tsx","../src/components/fields/TextField.tsx","../src/components/ui/select.tsx","../src/components/fields/EnumField.tsx","../src/components/fields/EmailField.tsx","../src/components/fields/UrlField.tsx","../src/components/fields/TimestampField.tsx","../src/components/fields/BoolField.tsx","../src/components/fields/NumberField.tsx","../src/hooks/useEntity.ts","../src/components/fields/RefField.tsx","../src/components/fields/JsonField.tsx","../src/components/fields/MultilangField.tsx","../src/components/fields/MultilangTextField.tsx","../src/components/fields/StructureField.tsx","../src/components/fields/SecretField.tsx","../src/components/fields/PasswordField.tsx","../src/components/fields/StringArrayField.tsx","../src/components/fields/IntArrayField.tsx","../src/components/fields/index.tsx","../src/components/shared/EmptyState.tsx","../src/components/ui/skeleton.tsx","../src/components/shared/LoadingSkeleton.tsx","../src/components/ui/alert-dialog.tsx","../src/components/shared/ConfirmDialog.tsx","../src/components/ui/dialog.tsx","../src/components/shared/ActionDialog.tsx","../src/components/shared/ActionConfirmDialog.tsx","../src/components/shared/ActionResultDialog.tsx","../src/lib/actions.ts","../src/lib/field-regions.ts","../src/lib/ui-actions.ts","../src/components/shared/ActionButton.tsx","../src/components/shared/RowActionItem.tsx","../src/components/shared/BatchActionProgress.tsx","../src/lib/filters.ts","../src/hooks/useFilters.ts","../src/components/filters/FilterChips.tsx","../src/components/filters/FilterDrawer.tsx","../src/components/columns/ColumnPicker.tsx","../src/components/views/ViewSwitcher.tsx","../src/hooks/useScreen.ts","../src/hooks/useViews.ts","../src/components/pages/SmartListPage.tsx","../src/lib/timestamp.ts","../src/hooks/useEntityItem.ts","../src/components/shared/AssociationTabs.tsx","../src/lib/size-value.ts","../src/components/detail-layout/LayoutRow.tsx","../src/components/detail-layout/LayoutColumn.tsx","../src/components/detail-layout/LayoutTabs.tsx","../src/components/detail-layout/SectionBlock.tsx","../src/lib/child-config.ts","../src/lib/quick-add.ts","../src/components/detail-layout/useQuickAdd.ts","../src/components/detail-layout/QuickAddForm.tsx","../src/components/detail-layout/ChildrenTable.tsx","../src/components/detail-layout/ChildrenList.tsx","../src/components/detail-layout/ChildrenCards.tsx","../src/components/detail-layout/TimelineComposer.tsx","../src/components/detail-layout/ChildrenTimeline.tsx","../src/components/detail-layout/EditableChildrenTable.tsx","../src/components/detail-layout/DraggableChildrenTable.tsx","../src/components/detail-layout/ChildrenBlock.tsx","../src/hooks/useAssociatedData.ts","../src/components/detail-layout/AssociatedToolbar.tsx","../src/components/detail-layout/AssociatedBlock.tsx","../src/components/detail-layout/FieldsBlock.tsx","../src/components/detail-layout/PropertiesBlock.tsx","../src/components/shared/StatusGroupsDisplay.tsx","../src/components/detail-layout/StatusesBlock.tsx","../src/components/detail-layout/LayoutRenderer.tsx","../src/lib/children-validation.ts","../src/components/pages/SmartDetailPage.tsx","../src/api/status.ts","../src/hooks/useObjectStatus.ts","../src/api/properties.ts","../src/hooks/useProperties.ts","../src/components/pages/SmartRecordListPage.tsx","../src/components/shared/ErrorBoundary.tsx","../src/lib/theme-utils.ts","../src/stores/theme.ts","../src/stores/screen-registry.ts","../src/app.tsx","../src/api/entities.ts","../src/api/params.ts","../src/hooks/useParams.ts","../src/hooks/useColumns.ts"],"sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import type { LocalizedString } from \"./schema\";\n\nexport interface ListMeta {\n total: number;\n page: number;\n per_page: number;\n total_pages: number;\n}\n\nexport interface ListResponse<T = Record<string, unknown>> {\n data: T[];\n meta: ListMeta;\n $refs?: Record<string, Record<string, Record<string, unknown>>>;\n}\n\nexport interface DataResponse<T = Record<string, unknown>> {\n data: T;\n}\n\nexport interface ApiErrorBody {\n error: {\n message: string;\n code: string;\n field?: string;\n };\n /** Bulk operation item index (present on validation errors for array requests). */\n index?: number;\n}\n\nexport class ApiError extends Error {\n status: number;\n code: string;\n /** Bulk operation item index (present on validation errors for array requests). */\n index?: number;\n\n constructor(status: number, message: string, code: string, index?: number) {\n super(message);\n this.name = \"ApiError\";\n this.status = status;\n this.code = code;\n this.index = index;\n }\n}\n\nexport interface Tenant {\n id: string;\n code: string;\n name: string;\n role: string;\n}\n\nexport interface AuthUser {\n id: string;\n email: string;\n display_name: string;\n is_active: boolean;\n roles: string[];\n permissions?: string[];\n tenant?: Tenant;\n created_at: string;\n updated_at: string;\n}\n\nexport interface LoginResponse {\n expires_at: string;\n user: AuthUser;\n tenant?: Tenant;\n}\n\nexport interface CheckSetupResponse {\n needs_setup: boolean;\n}\n\nexport interface StatusInfo {\n group_code: string;\n status_code: string;\n status_name: LocalizedString;\n color?: string;\n set_by?: string;\n set_at: string;\n note?: string;\n}\n\nexport interface PropertyValue {\n property_code: string;\n name: LocalizedString;\n type: string;\n value: unknown;\n}\n\nexport interface PublicParam {\n code: string;\n name: LocalizedString;\n type: string;\n category: string;\n description?: LocalizedString;\n value: unknown;\n}\n\nexport interface ResolvedParam {\n code: string;\n name: LocalizedString;\n type: string;\n category?: string;\n description?: LocalizedString;\n value: unknown;\n source: \"object\" | \"user\" | \"role\" | \"tenant\" | \"env\" | \"yaml\" | \"none\";\n}\n\nexport interface ParamOverride {\n param_code: string;\n value: unknown;\n}\n\nexport interface SSOProvider {\n name: string;\n slug: string;\n}\n\nexport interface ListParams {\n page?: number;\n per_page?: number;\n sort?: string;\n search?: string;\n /** JSON filter nodes (recursive AND/OR tree). */\n filters?: FilterNodeParam[];\n include_deleted?: boolean;\n expand?: string[];\n screen?: string;\n}\n\n/** Minimal filter node type for API params (matches backend FilterNode). */\nexport interface FilterNodeParam {\n field?: string;\n op?: string;\n value?: unknown;\n or?: FilterNodeParam[][];\n and?: FilterNodeParam[];\n}\n\n// ---------------------------------------------------------------------------\n// v2 API types - bulk operations, cursor pagination, sub-resource shapes\n// ---------------------------------------------------------------------------\n\n/** Cursor-based pagination metadata returned by v2 List. */\nexport interface V2Meta {\n total: number;\n limit: number;\n has_more: boolean;\n cursor?: string;\n}\n\n/**\n * Refs map: keyed by entity code (or $-prefixed virtual entity code),\n * then by record ID, then field values.\n * Example: { company: { \"uuid-1\": { id: \"uuid-1\", name: \"Acme\" } } }\n */\nexport type Refs = Record<string, Record<string, Record<string, unknown>>>;\n\n/** Per-row status instance. */\nexport interface V2StatusInstance {\n group_code: string;\n status_code: string;\n status_name?: Record<string, string>;\n color?: string;\n set_at?: string;\n set_by?: string;\n note?: string;\n}\n\n/** Per-row property instance. */\nexport interface V2PropertyInstance {\n property_code: string;\n value: unknown;\n updated_at?: string;\n updated_by?: string;\n}\n\n/** Per-row parameter override. */\nexport interface V2ParamInstance {\n param_code: string;\n value: unknown;\n}\n\n/** v2 List response with cursor pagination and response-level $refs. */\nexport interface V2ListResponse<T = Record<string, unknown>> {\n data: T[];\n meta: V2Meta;\n $refs?: Refs;\n}\n\n/** v2 List query parameters. */\nexport interface V2ListParams {\n select?: string[];\n expand?: string[];\n sort?: string;\n search?: string;\n filters?: FilterNodeParam[];\n limit?: number;\n after?: string;\n include_deleted?: boolean;\n}\n\n/** Per-field resolved display unit codes. */\nexport type Units = Record<string, string>;\n\n/** A row enriched with $-prefixed sub-resources (as returned by Get or write responses). */\nexport interface EnrichedRow extends Record<string, unknown> {\n $refs?: Refs;\n $statuses?: V2StatusInstance[];\n $properties?: V2PropertyInstance[];\n $params?: V2ParamInstance[];\n $children?: Record<string, Record<string, unknown>[]>;\n $units?: Units;\n}\n","import { ApiError, type ApiErrorBody } from \"@/types/api\";\n\n// The access and refresh tokens live in httpOnly cookies managed entirely by\n// the backend (__Host-declarion-access-token, __Host-declarion-refresh-token).\n// The browser attaches them automatically on every request when\n// credentials: \"include\" is set. JavaScript cannot read these cookies, which\n// is the whole point - an XSS cannot exfiltrate the session.\n//\n// The backend collapsed every auth/SSO/api-key endpoint into the generic\n// handler dispatcher at POST /api/actions/{code}. `callHandler` below is\n// the single entry point from the frontend; every wrapper in api/auth.ts\n// etc. uses it. `apiFetch` is kept for the handful of platform endpoints\n// that still live at named URLs (schema, data CRUD, params, etc.).\n\n// POST /api/actions/{code} bodies are flat: the handler's params sit at\n// the top level. Global handlers (auth.*, etc.) pass their args as-is.\nconst flatActionBody = (args: unknown) =>\n JSON.stringify(args ?? {});\n\nlet refreshPromise: Promise<void> | null = null;\n\n// refreshAccessToken stays on raw fetch (NOT apiFetch / callHandler) to\n// avoid recursion: apiFetch's 401 retry path waits on refreshPromise, so\n// if the refresh call itself went through apiFetch it would deadlock.\nasync function refreshAccessToken(): Promise<void> {\n const init: RequestInit = {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"Content-Type\": \"application/json\" },\n body: flatActionBody({}),\n };\n const res = await fetch(\"/api/actions/auth.refresh\", init);\n\n // Grace-period replay: backend says retry shortly.\n if (res.status === 429) {\n const retryAfter = parseInt(res.headers.get(\"Retry-After\") || \"1\", 10);\n await new Promise((r) => setTimeout(r, retryAfter * 1000));\n const retryRes = await fetch(\"/api/actions/auth.refresh\", init);\n if (!retryRes.ok) {\n throw new Error(\"refresh failed after retry\");\n }\n return;\n }\n\n if (!res.ok) {\n throw new Error(\"refresh failed\");\n }\n}\n\nexport async function ensureRefresh(): Promise<void> {\n if (refreshPromise) return refreshPromise;\n refreshPromise = refreshAccessToken().finally(() => {\n refreshPromise = null;\n });\n return refreshPromise;\n}\n\n// Handler invoked when a persistent 401 requires sending the user back to\n// the login flow. Injected (not hardcoded) so tests can substitute a spy\n// and non-browser consumers (e.g. a worker) can route the signal their own\n// way. Default implementation assigns window.location.href — same behavior\n// as before this was extracted.\ntype PersistentAuthFailureHandler = () => void;\n\nconst defaultPersistentAuthFailureHandler: PersistentAuthFailureHandler = () => {\n if (typeof window === \"undefined\") return;\n if (\n window.location.pathname.startsWith(\"/login\") ||\n window.location.pathname.startsWith(\"/signup\")\n ) {\n return;\n }\n window.location.href = \"/login\";\n};\n\nlet onPersistentAuthFailure: PersistentAuthFailureHandler =\n defaultPersistentAuthFailureHandler;\n\n/** Replace the handler invoked on persistent 401. Intended for tests\n * and non-browser consumers. Returns the previous handler so callers\n * can restore it if needed. */\nexport function setPersistentAuthFailureHandler(\n h: PersistentAuthFailureHandler,\n): PersistentAuthFailureHandler {\n const prev = onPersistentAuthFailure;\n onPersistentAuthFailure = h;\n return prev;\n}\n\nexport async function apiFetch<T>(\n path: string,\n options: RequestInit = {},\n): Promise<T> {\n const headers = new Headers(options.headers);\n\n if (!headers.has(\"Content-Type\") && options.body) {\n headers.set(\"Content-Type\", \"application/json\");\n }\n\n const res = await fetch(path, { ...options, headers, credentials: \"include\" });\n\n if (res.status === 204) {\n return undefined as T;\n }\n\n if (!res.ok) {\n let message = \"Request failed\";\n let code = \"UNKNOWN\";\n let index: number | undefined;\n\n try {\n const body = (await res.json()) as ApiErrorBody;\n message = body.error.message;\n code = body.error.code;\n if (body.index != null) index = body.index;\n } catch {\n // Ignore JSON parse errors\n }\n\n // 401 with a refresh hint: attempt exactly one silent refresh + retry.\n if (res.status === 401 && (code === \"TOKEN_REFRESH_NEEDED\" || code === \"UNAUTHORIZED\")) {\n try {\n await ensureRefresh();\n const retryHeaders = new Headers(options.headers);\n if (!retryHeaders.has(\"Content-Type\") && options.body) {\n retryHeaders.set(\"Content-Type\", \"application/json\");\n }\n const retryRes = await fetch(path, {\n ...options,\n headers: retryHeaders,\n credentials: \"include\",\n });\n if (retryRes.status === 204) {\n return undefined as T;\n }\n if (!retryRes.ok) {\n onPersistentAuthFailure();\n const retryBody = (await retryRes\n .json()\n .catch(() => ({ error: { message: \"Request failed\", code: \"UNKNOWN\" } }))) as ApiErrorBody;\n throw new ApiError(retryRes.status, retryBody.error.message, retryBody.error.code, retryBody.index);\n }\n return retryRes.json() as Promise<T>;\n } catch (refreshErr) {\n if (refreshErr instanceof ApiError) {\n throw refreshErr;\n }\n onPersistentAuthFailure();\n throw new ApiError(401, message, code, index);\n }\n }\n\n // Session revoked or other 401 - redirect to login.\n if (res.status === 401) {\n onPersistentAuthFailure();\n }\n\n console.error(`[API ${res.status}] ${code}: ${message}`);\n throw new ApiError(res.status, message, code, index);\n }\n\n return res.json() as Promise<T>;\n}\n\n// Action endpoint response envelope. The actions dispatcher always wraps\n// successful handler results as { status: \"success\", result: <data>, ... }.\ninterface ActionEnvelope<R> {\n status: string;\n result: R;\n audit_operation_id?: string;\n object_count?: number;\n}\n\n// callHandler is the single entry point for every auth/SSO/api-key\n// operation. It POSTs to /api/actions/{code} with a flat body (handler\n// params at the top level) and unwraps the result envelope, so callers\n// see the handler's return type directly.\n//\n// Cookie side effects (login/signup/refresh/switch_tenant) are set by the\n// backend via the HTTPCustomizer interface on *auth.LoginResult; the\n// browser stores them automatically because `credentials: \"include\"` is\n// already set by apiFetch. Frontend does not need any special handling.\nexport async function callHandler<R = unknown>(\n code: string,\n args: unknown = {},\n): Promise<R> {\n const env = await apiFetch<ActionEnvelope<R>>(\n `/api/actions/${encodeURIComponent(code)}`,\n {\n method: \"POST\",\n body: flatActionBody(args),\n },\n );\n return env.result;\n}\n","import { apiFetch } from \"./client\";\nimport type { Schema } from \"@/types/schema\";\n\nexport async function fetchSchema(): Promise<Schema> {\n return apiFetch<Schema>(\"/api/schema\");\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { fetchSchema } from \"@/api/schema\";\n\nexport function useSchema() {\n return useQuery({\n queryKey: [\"schema\"],\n queryFn: fetchSchema,\n staleTime: Infinity,\n });\n}\n","import { create } from \"zustand\";\n\nexport interface TabItem {\n id: string;\n pathname: string;\n search: string;\n title: string;\n icon?: string;\n closable: boolean;\n}\n\ninterface TabState {\n tabs: TabItem[];\n activeTabId: string | null;\n\n openTab: (tab: Omit<TabItem, \"id\">) => string;\n closeTab: (id: string) => void;\n switchTab: (id: string) => void;\n reorderTabs: (activeId: string, overId: string) => void;\n findTabByPathname: (pathname: string) => TabItem | undefined;\n updateTabTitle: (id: string, title: string) => void;\n updateTabSearch: (id: string, search: string) => void;\n}\n\n// Routes that should not create tabs.\nconst EXCLUDED_ROUTES = [\"/login\", \"/signup\"];\n\nexport const useTabStore = create<TabState>((set, get) => ({\n tabs: [],\n activeTabId: null,\n\n openTab: (tab) => {\n if (EXCLUDED_ROUTES.includes(tab.pathname)) {\n return \"\";\n }\n\n const state = get();\n // If a tab with the same pathname already exists, switch to it.\n const existing = state.tabs.find((t) => t.pathname === tab.pathname);\n if (existing) {\n set({ activeTabId: existing.id });\n return existing.id;\n }\n\n const id = crypto.randomUUID();\n const newTab: TabItem = { ...tab, id };\n set((s) => ({\n tabs: [...s.tabs, newTab],\n activeTabId: id,\n }));\n return id;\n },\n\n closeTab: (id) => {\n const state = get();\n const idx = state.tabs.findIndex((t) => t.id === id);\n if (idx === -1) return;\n\n const tab = state.tabs[idx];\n if (!tab.closable) return;\n\n // Prevent closing the very last tab — always keep at least one.\n if (state.tabs.length === 1) return;\n\n const remaining = state.tabs.filter((t) => t.id !== id);\n let nextActive = state.activeTabId;\n\n if (state.activeTabId === id) {\n if (remaining.length === 0) {\n nextActive = null;\n } else if (idx < remaining.length) {\n // Switch to the tab at the same index (right neighbor).\n nextActive = remaining[idx].id;\n } else {\n // Switch to the last tab (left neighbor).\n nextActive = remaining[remaining.length - 1].id;\n }\n }\n\n set({ tabs: remaining, activeTabId: nextActive });\n },\n\n switchTab: (id) => {\n set({ activeTabId: id });\n },\n\n reorderTabs: (activeId, overId) => {\n set((s) => {\n const oldIdx = s.tabs.findIndex((t) => t.id === activeId);\n const newIdx = s.tabs.findIndex((t) => t.id === overId);\n if (oldIdx === -1 || newIdx === -1 || oldIdx === newIdx) return s;\n const tabs = [...s.tabs];\n const [moved] = tabs.splice(oldIdx, 1);\n tabs.splice(newIdx, 0, moved);\n return { tabs };\n });\n },\n\n findTabByPathname: (pathname) => {\n return get().tabs.find((t) => t.pathname === pathname);\n },\n\n updateTabTitle: (id, title) => {\n set((s) => ({\n tabs: s.tabs.map((t) => (t.id === id ? { ...t, title } : t)),\n }));\n },\n\n updateTabSearch: (id, search) => {\n set((s) => ({\n tabs: s.tabs.map((t) => (t.id === id ? { ...t, search } : t)),\n }));\n },\n}));\n","import { useCallback } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { useTabStore } from \"@/stores/tabs\";\n\ninterface TabNavigateOptions {\n title?: string;\n icon?: string;\n search?: string;\n replace?: boolean;\n}\n\nexport function useTabNavigate() {\n const navigate = useNavigate();\n const { openTab, switchTab, findTabByPathname } = useTabStore();\n\n const tabNavigate = useCallback(\n (pathname: string, opts?: TabNavigateOptions) => {\n // Check if tab exists for this pathname.\n const existing = findTabByPathname(pathname);\n if (existing) {\n switchTab(existing.id);\n navigate(\n { pathname, search: opts?.search },\n { replace: opts?.replace },\n );\n return;\n }\n\n // Open new tab.\n openTab({\n pathname,\n search: opts?.search ?? \"\",\n title: opts?.title ?? pathname,\n icon: opts?.icon,\n closable: true,\n });\n navigate(\n { pathname, search: opts?.search },\n { replace: opts?.replace },\n );\n },\n [navigate, openTab, switchTab, findTabByPathname],\n );\n\n return tabNavigate;\n}\n","import { lazy, Suspense, useMemo } from \"react\";\nimport type { LucideProps } from \"lucide-react\";\nimport dynamicIconImports from \"lucide-react/dynamicIconImports\";\n\ntype IconName = keyof typeof dynamicIconImports;\n\nconst iconCache = new Map<\n string,\n React.LazyExoticComponent<React.ComponentType<LucideProps>>\n>();\n\nfunction loadIcon(name: string) {\n const cached = iconCache.get(name);\n if (cached) return cached;\n\n const importFn = dynamicIconImports[name as IconName];\n if (!importFn) return null;\n\n const LazyIcon = lazy(importFn) as React.LazyExoticComponent<\n React.ComponentType<LucideProps>\n >;\n iconCache.set(name, LazyIcon);\n return LazyIcon;\n}\n\ninterface DynamicIconProps extends LucideProps {\n name: string;\n}\n\nexport function DynamicIcon({ name, ...props }: DynamicIconProps) {\n const Icon = useMemo(() => loadIcon(name), [name]);\n\n if (!Icon) return null;\n\n return (\n <Suspense fallback={<div className=\"w-4 h-4\" />}>\n <Icon {...props} />\n </Suspense>\n );\n}\n","export type LocalizedString = Record<string, string>;\n\n/**\n * Reserved sentinel value for Screen.detail_screen (list screens). Disables\n * row-click navigation even when the entity declares a canonical detail. Paired\n * with Go's engine.DetailScreenNone - keep the literal \"none\" in sync.\n */\nexport const DETAIL_SCREEN_NONE = \"none\";\n\nexport function loc(ls: LocalizedString | undefined, lang = \"en\"): string {\n if (!ls) return \"\";\n return ls[lang] ?? Object.values(ls)[0] ?? \"\";\n}\n\n// fieldDisplayName resolves a field's display label.\n// For ref fields without an explicit display.name, falls back to the\n// referenced entity's singular name (e.g. organization_id → \"Organization\").\nexport function fieldDisplayName(\n field: EntityField,\n fieldName: string,\n entities?: Record<string, Entity>,\n): string {\n const explicit = loc(field.display?.name);\n if (explicit) return explicit;\n if (field.type === \"ref\" && field.ref?.entity && entities) {\n const refEntity = entities[field.ref.entity];\n if (refEntity) {\n const entityName = loc(refEntity.display?.name);\n if (entityName) return entityName;\n }\n }\n return fieldName;\n}\n\nexport interface RefDisplay {\n field: string;\n}\n\nexport interface RefConfig {\n entity: string;\n field?: string; // lookup column on target entity (default: primary key)\n display?: RefDisplay;\n fields?: string[];\n}\n\nexport interface UnitConfig {\n storage: string;\n display?: string;\n}\n\nexport interface EntityField {\n type: string;\n required?: boolean;\n primary?: boolean;\n auto?: boolean;\n timezone?: string;\n precision?: number;\n scale?: number;\n unit?: UnitConfig;\n default?: unknown;\n display?: {\n name: LocalizedString;\n width?: number;\n widget?: string;\n is_listable?: boolean;\n is_filterable?: boolean;\n ref_display_field?: string;\n span?: number | \"full\";\n };\n values?: Array<{ code: string; name: LocalizedString; description?: LocalizedString; color?: string }>;\n enum?: string;\n ref?: RefConfig;\n structure?: string;\n array?: boolean;\n // copyable exposes a plain copy-to-clipboard icon next to the value in display mode.\n // Dumb by design: copies the field value as-is, no side effects.\n copyable?: boolean;\n}\n\nexport interface StructureDef {\n name: LocalizedString;\n description?: LocalizedString;\n fields: Record<string, EntityField>;\n field_order: string[];\n}\n\nexport type ChildDisplayMode = \"table\" | \"timeline\" | \"list\" | \"cards\";\n\nexport interface TimelineConfig {\n type_field?: string;\n time_field?: string;\n summary_field?: string;\n content_field?: string;\n author_field?: string;\n direction_field?: string;\n intent_field?: string;\n scroll?: boolean;\n auto_scroll?: \"none\" | \"bottom\" | \"top\";\n}\n\nexport interface CardsConfig {\n columns_count?: number;\n header_field?: string;\n badge_field?: string;\n}\n\nexport interface ChildQuickAdd {\n fields: string[];\n defaults?: Record<string, unknown>;\n placeholder?: LocalizedString;\n}\n\nexport interface ChildDisplay {\n name: LocalizedString;\n icon?: string;\n mode?: ChildDisplayMode;\n columns?: string[];\n sort?: string;\n limit?: number;\n timeline?: TimelineConfig;\n cards?: CardsConfig;\n editable?: boolean;\n searchable?: boolean;\n filters?: string[];\n position_field?: string;\n}\n\nexport interface ChildRelation {\n entity: string;\n foreign_key: string | string[];\n display?: ChildDisplay;\n quick_add?: ChildQuickAdd;\n}\n\nexport interface StatusDef {\n code: string;\n name: LocalizedString;\n description?: LocalizedString;\n color?: string;\n is_final?: boolean;\n}\n\nexport interface StatusGroupDef {\n name: LocalizedString;\n description?: LocalizedString;\n is_main?: boolean;\n initial: string;\n statuses: StatusDef[];\n transitions?: Record<string, string[]>;\n}\n\nexport interface PropertyDef {\n name: LocalizedString;\n description?: LocalizedString;\n type: string;\n display?: EntityField[\"display\"];\n values?: EntityField[\"values\"];\n enum?: string;\n ref?: RefConfig;\n structure?: string;\n readonly?: boolean;\n}\n\n// propertyToField converts a PropertyDef to an EntityField for use with renderField().\n// Merges prop.name as fallback display name; prop.display.name wins if set.\nexport function propertyToField(prop: PropertyDef): EntityField {\n const baseName = prop.name;\n const display = prop.display\n ? { ...prop.display, name: prop.display.name ?? baseName }\n : { name: baseName };\n return {\n type: prop.type,\n display,\n values: prop.values,\n ref: prop.ref,\n structure: prop.structure,\n };\n}\n\nexport interface EnumDef {\n name: LocalizedString;\n description?: LocalizedString;\n values: Array<{ code: string; name: LocalizedString; description?: LocalizedString; color?: string }>;\n}\n\nexport interface ParameterDef {\n name: LocalizedString;\n description?: LocalizedString;\n type: string;\n default?: unknown;\n is_public?: boolean;\n category?: string;\n}\n\nexport interface AssociationDisplay {\n name?: LocalizedString;\n icon?: string;\n}\n\nexport interface AssociationDef {\n target: string;\n display?: AssociationDisplay;\n source: string;\n code: string;\n}\n\nexport interface Entity {\n table: string;\n primary_key?: string[];\n virtual?: boolean;\n readonly?: boolean;\n default_timezone?: string;\n display: {\n name: LocalizedString;\n name_plural: LocalizedString;\n description?: LocalizedString;\n icon: string;\n display_field?: string;\n };\n fields: Record<string, EntityField>;\n field_order: string[];\n soft_delete?: string;\n tenant_key?: string;\n children?: ChildRelation[];\n status_groups?: Record<string, StatusGroupDef>;\n properties?: Record<string, PropertyDef>;\n search_fields?: string[];\n actions?: Record<string, Action>;\n handlers?: Record<string, HandlerDef>;\n associations?: Record<string, AssociationDef>;\n detail_screen?: string; // Canonical detail screen for records of this entity. Required when any detail screen targets the entity.\n}\n\n// getPrimaryKeyFields returns the ordered list of primary key field names.\n// Checks entity.primary_key first (composite PK), falls back to scanning\n// fields for field.primary (single PK), defaults to [\"id\"].\nexport function getPrimaryKeyFields(entity: Entity): string[] {\n if (entity.primary_key && entity.primary_key.length > 0) {\n return entity.primary_key;\n }\n for (const name of entity.field_order) {\n if (entity.fields[name]?.primary) return [name];\n }\n return [\"id\"];\n}\n\n// PkValues is a map of PK field names to their string values.\nexport type PkValues = Record<string, string>;\n\n// extractPkValues extracts PK field values from a record.\nexport function extractPkValues(entity: Entity, record: Record<string, unknown>): PkValues {\n const fields = getPrimaryKeyFields(entity);\n const values: PkValues = {};\n for (const f of fields) {\n values[f] = String(record[f] ?? \"\");\n }\n return values;\n}\n\n// pkValuesToId converts PK values to a single string identifier for use as\n// cache keys, React keys, etc. For single PK returns the value directly.\n// For composite PK joins with \"|\".\nexport function pkValuesToId(pkValues: PkValues): string {\n const vals = Object.values(pkValues);\n if (vals.length === 1) return vals[0];\n return vals.join(\"|\");\n}\n\n// isCompositePk returns true if the entity has more than one PK field.\nexport function isCompositePk(entity: Entity): boolean {\n return getPrimaryKeyFields(entity).length > 1;\n}\n\nexport type SizeValue = string; // integer weight (as string), \"<n>px\", \"auto\", \"fill\"\n\nexport interface SectionNode {\n name: LocalizedString;\n items: LayoutNode[];\n collapsed?: boolean;\n columns?: number; // 1 or 2 (default: 2)\n}\n\nexport interface RowConfig {\n items: LayoutNode[];\n gap?: number;\n resizable?: boolean;\n stack_below?: number | \"never\";\n width?: SizeValue;\n height?: SizeValue;\n}\n\nexport interface ColumnConfig {\n items: LayoutNode[];\n gap?: number;\n width?: SizeValue;\n height?: SizeValue;\n}\n\nexport interface TabsConfig {\n items: LayoutNode[];\n}\n\n// LayoutField is one entry in a screen's `fields:` layout block, carrying\n// the field name and any screen-scoped overrides (e.g. inline action buttons).\n// YAML also accepts a bare string, which the server normalizes to { name }.\nexport interface LayoutField {\n name: string;\n actions?: Action[];\n}\n\nexport interface LayoutNode {\n // Container kinds (exactly one, or none if leaf).\n row?: RowConfig;\n column?: ColumnConfig;\n tabs?: TabsConfig;\n\n section?: SectionNode;\n\n // Leaf kinds.\n children?: string;\n associated?: string; // associated entity code (independent entity with FK back)\n properties?: true | string[];\n statuses?: true | string[];\n fields?: LayoutField[];\n\n // Sizing (valid when nested inside row or column).\n width?: SizeValue;\n height?: SizeValue;\n min_width?: string;\n max_width?: string;\n\n // Child-override keys (only valid when children is set).\n label?: LocalizedString;\n icon?: string;\n mode?: ChildDisplayMode;\n columns?: string[];\n sort?: string;\n limit?: number;\n quick_add?: ChildQuickAdd;\n timeline?: TimelineConfig;\n cards?: CardsConfig;\n editable?: boolean;\n searchable?: boolean;\n filters?: string[];\n position_field?: string;\n}\n\nexport interface Screen {\n type: \"list\" | \"detail\" | \"custom\" | \"record_list\";\n entity?: string;\n route: string;\n component?: string;\n display?: {\n name: LocalizedString;\n icon: string;\n };\n columns?: string[];\n default_columns?: string[]; // Subset visible initially. Omit = all visible.\n filters?: string[];\n default_filters?: string[]; // Subset shown initially in filter panel. Omit = empty.\n search_fields?: string[];\n sort_default?: string;\n actions?: string[];\n row_actions?: string[];\n items?: LayoutNode[];\n sidebar?: LayoutNode[]; // right sidebar layout (always visible, independent of tabs)\n sidebar_width?: string; // sidebar CSS width (default: \"380px\")\n self?: boolean;\n list_width?: string; // record_list: CSS width of the left list panel (e.g. \"50%\", \"400px\")\n list_resizable?: boolean; // record_list: enable drag-to-resize the list panel\n // list only: tri-valued.\n // absent -> inherit entity.detail_screen\n // \"none\" -> explicit opt-out (row-click disabled)\n // any code -> override with that detail screen\n detail_screen?: string;\n fixed_filters?: Record<string, unknown>; // backend-injected WHERE clauses\n views?: ViewDefinition[]; // System views (presets) from DSL, read-only\n}\n\n/** System view (preset) defined in screen YAML. Read-only. */\nexport interface ViewDefinition {\n code: string;\n name: LocalizedString;\n icon?: string;\n filters?: Array<{ field: string; op: string; value?: unknown }>;\n columns?: string[];\n sort?: string;\n}\n\nexport interface NavNode {\n screen?: string;\n name?: LocalizedString;\n icon?: string;\n items?: NavNode[];\n}\n\nexport interface HandlerParamDisplay {\n name?: LocalizedString;\n description?: LocalizedString;\n widget?: string;\n}\n\nexport interface HandlerParam {\n type?: string;\n required?: boolean;\n default?: unknown;\n hidden?: boolean;\n enum?: string;\n values?: Array<{ code: string; name: LocalizedString; description?: LocalizedString; color?: string }>;\n ref?: string;\n display?: HandlerParamDisplay;\n}\n\nexport interface ActionCondition {\n status?: string[];\n field?: string;\n op?: string;\n value?: unknown;\n}\n\nexport interface UISetFieldStep {\n target: string;\n value: string;\n}\n\nexport interface UIShowToastStep {\n kind?: \"success\" | \"error\" | \"info\";\n message: string;\n}\n\n// UIStep is a tagged union - exactly one variant field is set per step.\nexport interface UIStep {\n copy_to_clipboard?: string;\n set_field?: UISetFieldStep;\n focus_field?: string;\n show_toast?: UIShowToastStep;\n}\n\nexport interface Action {\n handler?: string;\n type?: string;\n association?: string;\n scope?: string;\n batch_mode?: string;\n entity?: string;\n display: {\n name: LocalizedString;\n icon: string;\n };\n visibility?: string[];\n confirmation?: LocalizedString;\n conditions?: ActionCondition[];\n resolved_params?: Record<string, HandlerParam>;\n resolved_param_order?: string[];\n ui_steps?: UIStep[];\n}\n\nexport interface LanguageDef {\n code: string;\n name: LocalizedString;\n}\n\nexport interface HandlerDef {\n code: string;\n type: string;\n entity?: string;\n display?: {\n name?: LocalizedString;\n icon?: string;\n };\n params?: Record<string, HandlerParam>;\n param_order?: string[];\n success_event?: string;\n}\n\nexport interface Branding {\n app_name?: string;\n app_logo?: string;\n app_initial?: string;\n accent_color?: string;\n}\n\nexport interface ThemeDef {\n extends?: string;\n background?: string;\n foreground?: string;\n card?: string;\n card_foreground?: string;\n popover?: string;\n popover_foreground?: string;\n primary?: string;\n primary_foreground?: string;\n secondary?: string;\n secondary_foreground?: string;\n muted?: string;\n muted_foreground?: string;\n accent?: string;\n accent_foreground?: string;\n destructive?: string;\n destructive_foreground?: string;\n border?: string;\n input?: string;\n ring?: string;\n sidebar?: string;\n sidebar_foreground?: string;\n sidebar_border?: string;\n sidebar_accent?: string;\n sidebar_muted?: string;\n radius?: string;\n}\n\nexport interface Schema {\n languages: LanguageDef[];\n structures: Record<string, StructureDef>;\n entities: Record<string, Entity>;\n screens: Record<string, Screen>;\n navigation: NavNode[];\n actions: Record<string, Action>;\n handlers?: Record<string, HandlerDef>;\n enums: Record<string, EnumDef>;\n parameters: Record<string, ParameterDef>;\n branding?: Branding;\n themes?: Record<string, ThemeDef>;\n}\n","import { useState } from \"react\";\nimport { useLocation } from \"react-router-dom\";\nimport { ChevronLeft, ChevronRight, ChevronDown } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { useTabNavigate } from \"@/hooks/useTabNavigate\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\nimport { loc, type NavNode } from \"@/types/schema\";\n\nexport function Sidebar() {\n const [collapsed, setCollapsed] = useState(false);\n const [collapsedSections, setCollapsedSections] = useState<Record<number, boolean>>({});\n const location = useLocation();\n const { data: schema } = useSchema();\n const tabNavigate = useTabNavigate();\n\n const nodes = schema?.navigation ?? [];\n const branding = schema?.branding;\n const appName = branding?.app_name || \"Declarion\";\n const appInitial = branding?.app_initial || appName.charAt(0);\n const accentColor = branding?.accent_color || \"#4f46e5\";\n\n function findFirstLeaf(items: NavNode[]): NavNode | undefined {\n for (const node of items) {\n if (node.screen) return node;\n if (node.items) {\n const found = findFirstLeaf(node.items);\n if (found) return found;\n }\n }\n return undefined;\n }\n\n function toggleSection(idx: number) {\n setCollapsedSections((prev) => ({ ...prev, [idx]: !prev[idx] }));\n }\n\n function isActive(route: string) {\n return location.pathname === route || location.pathname.startsWith(route + \"/\");\n }\n\n return (\n <aside\n className={cn(\n \"flex flex-col bg-[var(--sidebar)] text-[var(--sidebar-foreground)] border-r border-[var(--sidebar-border)] transition-all duration-200\",\n collapsed ? \"w-16\" : \"w-60\",\n )}\n >\n {/* Brand */}\n <div className=\"flex items-center h-14 px-4 border-b border-[var(--sidebar-border)]\">\n <button\n onClick={() => {\n const first = findFirstLeaf(nodes);\n const screen = first?.screen ? schema?.screens[first.screen] : undefined;\n if (screen && first) {\n tabNavigate(screen.route, {\n title: loc(first.name),\n icon: first.icon,\n });\n }\n }}\n className=\"flex items-center gap-2 overflow-hidden\"\n >\n {branding?.app_logo ? (\n <img src={branding.app_logo} alt={appName} className=\"w-8 h-8 rounded-lg shrink-0\" />\n ) : (\n <div className=\"w-8 h-8 rounded-lg flex items-center justify-center shrink-0\" style={{ backgroundColor: accentColor }}>\n <span className=\"text-white font-bold text-sm\">{appInitial}</span>\n </div>\n )}\n {!collapsed && (\n <span className=\"font-semibold text-sm whitespace-nowrap\">\n {appName}\n </span>\n )}\n </button>\n </div>\n\n {/* Navigation */}\n <nav className=\"flex-1 py-4 px-2 space-y-4 overflow-y-auto\">\n {nodes.map((node, idx) =>\n node.items ? (\n // Branch node — collapsible section\n <div key={idx}>\n {!collapsed && (\n <button\n onClick={() => toggleSection(idx)}\n className=\"flex items-center justify-between w-full px-3 mb-1 text-[10px] font-semibold uppercase tracking-wider text-[var(--sidebar-muted)] hover:text-[var(--sidebar-foreground)] transition-colors\"\n >\n <span>{loc(node.name)}</span>\n <ChevronDown\n className={cn(\n \"w-3 h-3 transition-transform\",\n collapsedSections[idx] && \"-rotate-90\",\n )}\n />\n </button>\n )}\n {!collapsedSections[idx] && (\n <div className=\"space-y-0.5\">\n {node.items.map((item) => {\n if (!item.screen) return null;\n const screen = schema?.screens[item.screen];\n if (!screen) return null;\n const route = screen.route;\n const active = isActive(route);\n\n return (\n <button\n key={item.screen}\n onClick={() =>\n tabNavigate(route, {\n title: loc(item.name),\n icon: item.icon,\n })\n }\n className={cn(\n \"flex items-center gap-3 px-3 py-2 rounded-md text-sm transition-colors w-full text-left\",\n active\n ? \"bg-[var(--sidebar-accent)] text-[var(--sidebar-foreground)]\"\n : \"text-[var(--sidebar-muted)] hover:bg-[var(--sidebar-accent)]/50 hover:text-[var(--sidebar-foreground)]\",\n )}\n title={collapsed ? loc(item.name) : undefined}\n >\n {item.icon && <DynamicIcon name={item.icon} className=\"w-4 h-4 shrink-0\" />}\n {!collapsed && <span>{loc(item.name)}</span>}\n </button>\n );\n })}\n </div>\n )}\n </div>\n ) : node.screen ? (\n // Top-level leaf node (screen without section)\n (() => {\n const screen = schema?.screens[node.screen];\n if (!screen) return null;\n const route = screen.route;\n const active = isActive(route);\n return (\n <button\n key={node.screen}\n onClick={() =>\n tabNavigate(route, {\n title: loc(node.name),\n icon: node.icon,\n })\n }\n className={cn(\n \"flex items-center gap-3 px-3 py-2 rounded-md text-sm transition-colors w-full text-left\",\n active\n ? \"bg-[var(--sidebar-accent)] text-[var(--sidebar-foreground)]\"\n : \"text-[var(--sidebar-muted)] hover:bg-[var(--sidebar-accent)]/50 hover:text-[var(--sidebar-foreground)]\",\n )}\n title={collapsed ? loc(node.name) : undefined}\n >\n {node.icon && <DynamicIcon name={node.icon} className=\"w-4 h-4 shrink-0\" />}\n {!collapsed && <span>{loc(node.name)}</span>}\n </button>\n );\n })()\n ) : null,\n )}\n </nav>\n\n {/* Collapse toggle */}\n <button\n onClick={() => setCollapsed(!collapsed)}\n className=\"flex items-center justify-center h-10 border-t border-[var(--sidebar-border)] text-[var(--sidebar-muted)] hover:text-[var(--sidebar-foreground)] transition-colors\"\n >\n {collapsed ? (\n <ChevronRight className=\"w-4 h-4\" />\n ) : (\n <ChevronLeft className=\"w-4 h-4\" />\n )}\n </button>\n </aside>\n );\n}\n","import { callHandler } from \"./client\";\nimport type {\n CheckSetupResponse,\n LoginResponse,\n AuthUser,\n Tenant,\n SSOProvider,\n} from \"@/types/api\";\n\n// Every auth endpoint now dispatches through POST /api/actions/{code}.\n// The shared callHandler helper in client.ts wraps the envelope and\n// returns the typed handler result directly. Cookies are set by the\n// backend via the HTTPCustomizer interface on *auth.LoginResult, so the\n// client-side wrappers never see tokens - they return user + tenant only.\n\nexport async function checkSetup(): Promise<CheckSetupResponse> {\n return callHandler<CheckSetupResponse>(\"auth.check_setup\");\n}\n\nexport async function login(\n email: string,\n password: string,\n): Promise<LoginResponse> {\n return callHandler<LoginResponse>(\"auth.login\", { email, password });\n}\n\nexport async function signup(\n email: string,\n password: string,\n displayName: string,\n): Promise<LoginResponse> {\n return callHandler<LoginResponse>(\"auth.signup\", {\n email,\n password,\n display_name: displayName,\n });\n}\n\n// auth.me returns { ...user, tenant? } per MeResult. The AuthUser type\n// on the frontend already reflects that shape.\nexport async function getMe(): Promise<AuthUser> {\n return callHandler<AuthUser>(\"auth.me\");\n}\n\n// auth.list_tenants returns { tenants: [...] } from ListTenantsResult.\nexport async function listTenants(): Promise<Tenant[]> {\n const result = await callHandler<{ tenants: Tenant[] }>(\"auth.list_tenants\");\n return result.tenants;\n}\n\nexport async function switchTenant(tenantId: string): Promise<LoginResponse> {\n return callHandler<LoginResponse>(\"auth.switch_tenant\", {\n tenant_id: tenantId,\n });\n}\n\nexport async function createTenant(code: string, name: string): Promise<Tenant> {\n return callHandler<Tenant>(\"auth.create_tenant\", { code, name });\n}\n\nexport async function logout(): Promise<void> {\n await callHandler(\"auth.logout\");\n}\n\n// sso_provider.list is a global handler with AllowUnauthenticated - used\n// on the login page before the user has a session.\nexport async function listSSOProviders(tenantCode?: string): Promise<SSOProvider[]> {\n const result = await callHandler<{ providers: SSOProvider[] }>(\n \"sso_provider.list\",\n tenantCode ? { tenant_code: tenantCode } : {},\n );\n return result.providers;\n}\n\nexport function ssoAuthorizeUrl(\n slug: string,\n tenantCode?: string,\n redirect?: string,\n): string {\n const params = new URLSearchParams();\n if (tenantCode) params.set(\"tenant\", tenantCode);\n if (redirect) params.set(\"redirect\", redirect);\n const qs = params.toString();\n return `/api/auth/sso/authorize/${encodeURIComponent(slug)}${qs ? `?${qs}` : \"\"}`;\n}\n","import { create } from \"zustand\";\nimport type { AuthUser, Tenant } from \"@/types/api\";\nimport { getMe, listTenants, logout as logoutApi } from \"@/api/auth\";\n\ninterface AuthState {\n user: AuthUser | null;\n isAuthenticated: boolean;\n isLoading: boolean;\n activeTenant: Tenant | null;\n tenants: Tenant[];\n initialize: () => Promise<void>;\n setUser: (user: AuthUser, tenant?: Tenant) => void;\n setTenants: (tenants: Tenant[]) => void;\n setActiveTenant: (tenant: Tenant) => void;\n logout: () => Promise<void>;\n}\n\nexport const useAuthStore = create<AuthState>((set) => ({\n user: null,\n isAuthenticated: false,\n isLoading: true,\n activeTenant: null,\n tenants: [],\n\n initialize: async () => {\n // Session lives in httpOnly cookies the JS cannot see. Probe auth.me\n // (dispatched via POST /api/actions/auth.me) with the cookie attached;\n // 401 means unauthenticated.\n try {\n const user = await getMe();\n const tenant = user.tenant ?? null;\n\n let tenants: Tenant[] = [];\n try {\n tenants = await listTenants();\n } catch {\n // Non-critical - user may only have one tenant.\n }\n\n set({\n user,\n isAuthenticated: true,\n isLoading: false,\n activeTenant: tenant,\n tenants,\n });\n } catch {\n set({ user: null, isAuthenticated: false, isLoading: false });\n }\n },\n\n setUser: (user: AuthUser, tenant?: Tenant) => {\n set({\n user,\n isAuthenticated: true,\n isLoading: false,\n activeTenant: tenant ?? null,\n });\n },\n\n setTenants: (tenants: Tenant[]) => {\n set({ tenants });\n },\n\n setActiveTenant: (tenant: Tenant) => {\n set({ activeTenant: tenant });\n },\n\n logout: async () => {\n try {\n await logoutApi();\n } catch {\n // Best-effort - clear local state regardless.\n }\n set({\n user: null,\n isAuthenticated: false,\n activeTenant: null,\n tenants: [],\n });\n },\n}));\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useNavigate } from \"react-router-dom\";\nimport { toast } from \"sonner\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport * as authApi from \"@/api/auth\";\n\nexport function useAuth() {\n const {\n user,\n isAuthenticated,\n isLoading,\n activeTenant,\n tenants,\n setUser,\n setTenants,\n logout: storeLogout,\n } = useAuthStore();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n\n const loginMutation = useMutation({\n mutationFn: ({ email, password }: { email: string; password: string }) =>\n authApi.login(email, password),\n onSuccess: (result) => {\n setUser(result.user, result.tenant);\n // Fetch tenants in background after login.\n authApi.listTenants().then(setTenants).catch(() => {});\n navigate(\"/\");\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n\n const signupMutation = useMutation({\n mutationFn: ({\n email,\n password,\n displayName,\n }: {\n email: string;\n password: string;\n displayName: string;\n }) => authApi.signup(email, password, displayName),\n onSuccess: (result) => {\n setUser(result.user, result.tenant);\n authApi.listTenants().then(setTenants).catch(() => {});\n navigate(\"/\");\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n\n const switchTenantMutation = useMutation({\n mutationFn: (tenantId: string) => authApi.switchTenant(tenantId),\n onSuccess: (result) => {\n // Update user (roles may differ per tenant) + tenant. The new access\n // cookie is set by the backend; the browser picks it up on the next request.\n setUser(result.user, result.tenant);\n // Invalidate all queries - tenant context changed (data, statuses, properties, etc.).\n queryClient.invalidateQueries();\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n\n const logout = async () => {\n await storeLogout();\n queryClient.clear();\n navigate(\"/login\");\n };\n\n return {\n user,\n isAuthenticated,\n isLoading,\n activeTenant,\n tenants,\n login: loginMutation.mutate,\n signup: signupMutation.mutate,\n switchTenant: switchTenantMutation.mutate,\n logout,\n isLoginPending: loginMutation.isPending,\n isSignupPending: signupMutation.isPending,\n isSwitchingTenant: switchTenantMutation.isPending,\n };\n}\n","import * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { Check, ChevronRight, Circle } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\nconst DropdownMenu = DropdownMenuPrimitive.Root;\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group;\nconst DropdownMenuPortal = DropdownMenuPrimitive.Portal;\nconst DropdownMenuSub = DropdownMenuPrimitive.Sub;\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;\n\nconst DropdownMenuSubTrigger = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n }\n>(({ className, inset, children, ...props }, ref) => (\n <DropdownMenuPrimitive.SubTrigger\n ref={ref}\n className={cn(\n \"flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-[var(--accent)] data-[state=open]:bg-[var(--accent)] [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n inset && \"pl-8\",\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRight className=\"ml-auto\" />\n </DropdownMenuPrimitive.SubTrigger>\n));\nDropdownMenuSubTrigger.displayName =\n DropdownMenuPrimitive.SubTrigger.displayName;\n\nconst DropdownMenuSubContent = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.SubContent\n ref={ref}\n className={cn(\n \"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-[var(--popover)] p-1 text-[var(--popover-foreground)] shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className,\n )}\n {...props}\n />\n));\nDropdownMenuSubContent.displayName =\n DropdownMenuPrimitive.SubContent.displayName;\n\nconst DropdownMenuContent = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-[var(--popover)] p-1 text-[var(--popover-foreground)] shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n));\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;\n\nconst DropdownMenuItem = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-[var(--accent)] focus:text-[var(--accent-foreground)] data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0\",\n inset && \"pl-8\",\n className,\n )}\n {...props}\n />\n));\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;\n\nconst DropdownMenuCheckboxItem = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n <DropdownMenuPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n \"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-[var(--accent)] focus:text-[var(--accent-foreground)] data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n));\nDropdownMenuCheckboxItem.displayName =\n DropdownMenuPrimitive.CheckboxItem.displayName;\n\nconst DropdownMenuRadioItem = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n <DropdownMenuPrimitive.RadioItem\n ref={ref}\n className={cn(\n \"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-[var(--accent)] focus:text-[var(--accent-foreground)] data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Circle className=\"h-2 w-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n));\nDropdownMenuRadioItem.displayName =\n DropdownMenuPrimitive.RadioItem.displayName;\n\nconst DropdownMenuLabel = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Label\n ref={ref}\n className={cn(\n \"px-2 py-1.5 text-sm font-semibold\",\n inset && \"pl-8\",\n className,\n )}\n {...props}\n />\n));\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;\n\nconst DropdownMenuSeparator = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-[var(--muted)]\", className)}\n {...props}\n />\n));\nDropdownMenuSeparator.displayName =\n DropdownMenuPrimitive.Separator.displayName;\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) {\n return (\n <span\n className={cn(\"ml-auto text-xs tracking-widest opacity-60\", className)}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuGroup,\n DropdownMenuPortal,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuRadioGroup,\n};\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/utils\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default:\n \"bg-[var(--primary)] text-[var(--primary-foreground)] hover:bg-[var(--primary)]/90\",\n destructive:\n \"bg-[var(--destructive)] text-[var(--destructive-foreground)] hover:bg-[var(--destructive)]/90\",\n outline:\n \"border border-[var(--input)] bg-[var(--background)] hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]\",\n secondary:\n \"bg-[var(--secondary)] text-[var(--secondary-foreground)] hover:bg-[var(--secondary)]/80\",\n ghost:\n \"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]\",\n link: \"text-[var(--primary)] underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"h-9 w-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n","import { LogOut, ChevronsUpDown } from \"lucide-react\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport { useAuth } from \"@/hooks/useAuth\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { Button } from \"@/components/ui/button\";\n\nexport function TopBar() {\n const user = useAuthStore((s) => s.user);\n const { logout, activeTenant, tenants, switchTenant, isSwitchingTenant } =\n useAuth();\n\n const initials = user?.display_name\n ? user.display_name\n .split(\" \")\n .map((n) => n[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2)\n : user?.email?.[0]?.toUpperCase() ?? \"U\";\n\n const canSwitch = tenants.length > 1;\n\n return (\n <header className=\"flex items-center justify-between h-14 px-6 border-b border-[var(--border)] bg-[var(--background)]\">\n <div className=\"flex items-center gap-3\">\n {activeTenant && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n disabled={!canSwitch || isSwitchingTenant}\n >\n {activeTenant.name}\n {canSwitch && (\n <ChevronsUpDown className=\"w-3.5 h-3.5 opacity-50\" />\n )}\n </Button>\n </DropdownMenuTrigger>\n {canSwitch && (\n <DropdownMenuContent align=\"start\">\n {tenants.map((t) => (\n <DropdownMenuItem\n key={t.id}\n onClick={() => switchTenant(t.id)}\n className={\n t.id === activeTenant?.id ? \"font-medium\" : undefined\n }\n >\n {t.name}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n )}\n </DropdownMenu>\n )}\n </div>\n <div className=\"flex items-center gap-3\">\n {user && (\n <>\n <span className=\"text-sm text-[var(--muted-foreground)] hidden sm:inline\">\n {user.email}\n </span>\n <div className=\"w-8 h-8 rounded-full bg-[var(--muted)] flex items-center justify-center\">\n <span className=\"text-xs font-medium text-[var(--muted-foreground)]\">\n {initials}\n </span>\n </div>\n <button\n onClick={logout}\n className=\"p-2 rounded-md text-[var(--muted-foreground)] hover:text-[var(--foreground)] transition-colors\"\n title=\"Sign out\"\n >\n <LogOut className=\"w-4 h-4\" />\n </button>\n </>\n )}\n </div>\n </header>\n );\n}\n","import { useCallback, useMemo } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport {\n DndContext,\n closestCenter,\n PointerSensor,\n useSensor,\n useSensors,\n type DragEndEvent,\n} from \"@dnd-kit/core\";\nimport {\n SortableContext,\n horizontalListSortingStrategy,\n useSortable,\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { X } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { useTabStore, type TabItem } from \"@/stores/tabs\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\n\nfunction SortableTab({\n tab,\n isActive,\n isOnly,\n onSwitch,\n onClose,\n}: {\n tab: TabItem;\n isActive: boolean;\n isOnly: boolean;\n onSwitch: (id: string, pathname: string, search: string) => void;\n onClose: (e: React.MouseEvent, id: string) => void;\n}) {\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: tab.id });\n\n const style = {\n transform: CSS.Translate.toString(transform),\n transition,\n zIndex: isDragging ? 10 : undefined,\n opacity: isDragging ? 0.5 : undefined,\n };\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n {...attributes}\n {...listeners}\n onClick={() => onSwitch(tab.id, tab.pathname, tab.search)}\n className={cn(\n \"flex items-center gap-1.5 px-3 h-7 rounded text-xs whitespace-nowrap max-w-[180px] select-none\",\n isActive\n ? \"bg-[var(--muted)] text-[var(--foreground)]\"\n : \"text-[var(--muted-foreground)] hover:bg-[var(--muted)]/50 hover:text-[var(--foreground)]\",\n )}\n >\n {tab.icon && (\n <DynamicIcon name={tab.icon} className=\"w-3 h-3 shrink-0\" />\n )}\n <span className=\"truncate\">{tab.title}</span>\n {tab.closable && !isOnly && (\n <span\n role=\"button\"\n onPointerDown={(e) => e.stopPropagation()}\n onClick={(e) => {\n e.stopPropagation();\n onClose(e, tab.id);\n }}\n className=\"ml-1 p-0.5 rounded hover:bg-[var(--border)] shrink-0\"\n >\n <X className=\"w-3 h-3\" />\n </span>\n )}\n </div>\n );\n}\n\nexport function TabBar() {\n const navigate = useNavigate();\n const { tabs, activeTabId, switchTab, closeTab, reorderTabs } =\n useTabStore();\n\n // distance: 5 separates click (< 5px) from drag (>= 5px).\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),\n );\n\n const tabIds = useMemo(() => tabs.map((t) => t.id), [tabs]);\n\n const handleSwitch = useCallback(\n (id: string, pathname: string, search: string) => {\n switchTab(id);\n navigate({ pathname, search: search || undefined });\n },\n [switchTab, navigate],\n );\n\n const handleClose = useCallback(\n (_e: React.MouseEvent, id: string) => {\n const state = useTabStore.getState();\n const idx = state.tabs.findIndex((t) => t.id === id);\n const isActive = state.activeTabId === id;\n\n closeTab(id);\n\n if (isActive) {\n const remaining = state.tabs.filter((t) => t.id !== id);\n if (remaining.length > 0) {\n const nextIdx = idx < remaining.length ? idx : remaining.length - 1;\n const next = remaining[nextIdx];\n navigate({\n pathname: next.pathname,\n search: next.search || undefined,\n });\n }\n }\n },\n [closeTab, navigate],\n );\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n const { active, over } = event;\n if (over && active.id !== over.id) {\n reorderTabs(String(active.id), String(over.id));\n }\n },\n [reorderTabs],\n );\n\n if (tabs.length === 0) return null;\n\n const isOnly = tabs.length === 1;\n\n return (\n <div className=\"flex items-center gap-0.5 h-9 px-2 border-t border-[var(--border)] bg-[var(--background)] overflow-x-auto shrink-0\">\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleDragEnd}\n >\n <SortableContext\n items={tabIds}\n strategy={horizontalListSortingStrategy}\n >\n {tabs.map((tab) => (\n <SortableTab\n key={tab.id}\n tab={tab}\n isActive={tab.id === activeTabId}\n isOnly={isOnly}\n onSwitch={handleSwitch}\n onClose={handleClose}\n />\n ))}\n </SortableContext>\n </DndContext>\n </div>\n );\n}\n","export type SSEEvent =\n | {\n type: \"entity_changed\";\n entity: string;\n ids: string[];\n action: \"created\" | \"updated\" | \"deleted\" | \"restored\";\n }\n | { type: \"session_refresh\" };\n\nexport async function* streamEvents(\n signal?: AbortSignal,\n): AsyncGenerator<SSEEvent> {\n const res = await fetch(\"/api/events\", { credentials: \"include\", signal });\n\n if (!res.ok || !res.body) {\n throw new Error(`SSE connection failed: ${res.status}`);\n }\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let currentEvent = \"\";\n let currentData = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"event: \")) {\n currentEvent = line.slice(7);\n } else if (line.startsWith(\"data: \")) {\n currentData = line.slice(6);\n } else if (line === \"\" && currentEvent) {\n try {\n if (currentEvent === \"session_refresh\") {\n yield { type: \"session_refresh\" };\n } else if (currentEvent === \"entity_changed\" && currentData) {\n const parsed = JSON.parse(currentData) as {\n entity: string;\n ids: string[];\n action: \"created\" | \"updated\" | \"deleted\" | \"restored\";\n };\n yield {\n type: \"entity_changed\",\n entity: parsed.entity,\n ids: parsed.ids,\n action: parsed.action,\n };\n }\n } catch {\n // Ignore parse errors\n }\n currentEvent = \"\";\n currentData = \"\";\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { apiFetch } from \"@/api/client\";\nimport type { ListResponse } from \"@/types/api\";\n\n// ENTITY_CHILDREN_KEY is the single source of truth for the query key prefix\n// used by all child entity queries. useSSE, QuickAddForm, TimelineComposer,\n// and SmartDetailPage must all use this constant to stay in sync.\nexport const ENTITY_CHILDREN_KEY = \"entity-children\" as const;\n\n// useChildrenData fetches child entity records for a parent record.\n// Extracted as a shared hook so all child display components can reuse it.\n// Uses the standard list endpoint with a filter on the foreign key field(s).\nexport function useChildrenData(\n parentEntity: string,\n parentId: string,\n childCode: string,\n foreignKey: string | string[],\n sort?: string,\n limit?: number,\n) {\n return useQuery({\n queryKey: [ENTITY_CHILDREN_KEY, parentEntity, parentId, childCode, sort, limit],\n queryFn: () => {\n const params = new URLSearchParams();\n // Build filters: single FK uses parentId directly, composite FK splits parentId by \"|\".\n const fkArr = Array.isArray(foreignKey) ? foreignKey : [foreignKey];\n const idArr = fkArr.length > 1 ? parentId.split(\"|\") : [parentId];\n const filters = fkArr.map((fk, i) => ({ field: fk, op: \"eq\", value: idArr[i] }));\n params.set(\"filters\", JSON.stringify(filters));\n if (sort) params.set(\"sort\", sort);\n if (limit) params.set(\"limit\", String(limit));\n return apiFetch<ListResponse>(\n `/api/data/${childCode}?${params.toString()}`,\n );\n },\n enabled: !!parentEntity && !!parentId && !!childCode && !!foreignKey,\n });\n}\n","import { useEffect, useRef } from \"react\";\nimport { useQueryClient, type QueryClient } from \"@tanstack/react-query\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport { streamEvents } from \"@/api/events\";\nimport { ensureRefresh } from \"@/api/client\";\nimport { ENTITY_CHILDREN_KEY } from \"@/hooks/useChildrenData\";\n\nconst MAX_RECONNECT_DELAY = 30000;\nconst BASE_DELAY = 1000;\n\n// COALESCE_WINDOW_MS groups entity_changed events into a single invalidation\n// per entity-per-window. A bulk upsert of 1000 rows produces ~2000 SSE events\n// server-side (audit_change + audit_operation per write); without coalescing,\n// React Query refires one HTTP fetch per event, saturating the UI and the\n// server's rate limiter. 50ms is short enough to feel real-time and long\n// enough to absorb a typical bulk-write burst.\nconst COALESCE_WINDOW_MS = 50;\n\ntype EntityAction = \"created\" | \"updated\" | \"deleted\" | \"restored\";\n\ninterface EntityChangedEvent {\n entity: string;\n action: EntityAction;\n}\n\n// invalidateForEntityChanges deduplicates a batch of entity_changed events\n// and fires the minimum set of React Query invalidations. Per entity:\n// - always invalidate the list query and matching child queries;\n// - additionally invalidate cached detail views if any event for that\n// entity is a mutation (update/delete/restore) — create events don't\n// need detail invalidation because a new row has no cached detail yet.\n// Exported so useSSE can call it and tests can exercise it directly.\nexport function invalidateForEntityChanges(\n queryClient: QueryClient,\n events: EntityChangedEvent[],\n): void {\n if (events.length === 0) return;\n\n const entities = new Map<string, { mutated: boolean }>();\n for (const ev of events) {\n const prev = entities.get(ev.entity);\n const mutated =\n ev.action === \"updated\" ||\n ev.action === \"deleted\" ||\n ev.action === \"restored\";\n entities.set(ev.entity, { mutated: (prev?.mutated ?? false) || mutated });\n }\n\n for (const [entity, state] of entities) {\n queryClient.invalidateQueries({ queryKey: [\"entity-data\", entity] });\n\n queryClient.invalidateQueries({\n predicate: (query) => {\n const key = query.queryKey;\n return key[0] === ENTITY_CHILDREN_KEY && key[3] === entity;\n },\n });\n\n if (state.mutated) {\n queryClient.invalidateQueries({ queryKey: [\"entity-item\", entity] });\n }\n }\n}\n\nexport function useSSE() {\n const isAuthenticated = useAuthStore((s) => s.isAuthenticated);\n const queryClient = useQueryClient();\n const abortRef = useRef<AbortController | null>(null);\n\n useEffect(() => {\n if (!isAuthenticated) return;\n\n let mounted = true;\n let attempt = 0;\n\n const pending: EntityChangedEvent[] = [];\n let flushTimer: ReturnType<typeof setTimeout> | null = null;\n\n const flush = () => {\n flushTimer = null;\n if (pending.length === 0) return;\n const batch = pending.splice(0, pending.length);\n invalidateForEntityChanges(queryClient, batch);\n };\n\n const scheduleFlush = () => {\n if (flushTimer !== null) return;\n flushTimer = setTimeout(flush, COALESCE_WINDOW_MS);\n };\n\n async function connect() {\n while (mounted) {\n const controller = new AbortController();\n abortRef.current = controller;\n\n try {\n for await (const event of streamEvents(controller.signal)) {\n if (!mounted) break;\n\n // Reset backoff on successful event.\n attempt = 0;\n\n if (event.type === \"session_refresh\") {\n // Permissions changed - refresh token and reconnect.\n try {\n await ensureRefresh();\n } catch {\n // Refresh failed - reconnect will use new token or fail.\n }\n break; // Break to reconnect with new token.\n }\n\n if (event.type === \"entity_changed\") {\n pending.push({ entity: event.entity, action: event.action });\n scheduleFlush();\n }\n }\n } catch (err) {\n if (!mounted) break;\n if (err instanceof DOMException && err.name === \"AbortError\") break;\n }\n\n // Exponential backoff with 50% jitter.\n if (mounted) {\n const delay = Math.min(BASE_DELAY * Math.pow(2, attempt), MAX_RECONNECT_DELAY);\n const jitter = delay * 0.5 * Math.random();\n await new Promise((r) => setTimeout(r, delay + jitter));\n attempt++;\n }\n }\n }\n\n connect();\n\n return () => {\n mounted = false;\n abortRef.current?.abort();\n if (flushTimer !== null) {\n clearTimeout(flushTimer);\n flushTimer = null;\n }\n if (pending.length > 0) {\n invalidateForEntityChanges(queryClient, pending.splice(0, pending.length));\n }\n };\n }, [isAuthenticated, queryClient]);\n}\n","import { useEffect } from \"react\";\nimport { Outlet, useNavigate, useLocation } from \"react-router-dom\";\nimport { Sidebar } from \"./Sidebar\";\nimport { TopBar } from \"./TopBar\";\nimport { TabBar } from \"./TabBar\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport { useSSE } from \"@/hooks/useSSE\";\n\nexport function Layout() {\n const { isAuthenticated, isLoading } = useAuthStore();\n const navigate = useNavigate();\n const location = useLocation();\n\n // SSE connection for real-time updates\n useSSE();\n\n useEffect(() => {\n if (!isLoading && !isAuthenticated) {\n // Preserve the intended URL so we can redirect back after login.\n const intended = location.pathname + location.search;\n const redirectParam = intended && intended !== \"/\" ? `?redirect=${encodeURIComponent(intended)}` : \"\";\n navigate(`/login${redirectParam}`, { replace: true });\n }\n }, [isLoading, isAuthenticated, navigate, location.pathname, location.search]);\n\n if (isLoading) {\n return (\n <div className=\"flex h-screen items-center justify-center bg-[var(--background)]\">\n <div className=\"text-[var(--muted-foreground)]\">Loading...</div>\n </div>\n );\n }\n\n if (!isAuthenticated) {\n return null;\n }\n\n return (\n <div className=\"flex h-screen overflow-hidden bg-[var(--background)]\">\n <Sidebar />\n <div className=\"flex flex-col flex-1 overflow-hidden\">\n <TopBar />\n <main className=\"flex-1 overflow-auto\">\n <Outlet />\n </main>\n <TabBar />\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nconst Input = React.forwardRef<\n HTMLInputElement,\n React.InputHTMLAttributes<HTMLInputElement>\n>(({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-9 w-full rounded-md border border-[var(--input)] bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-[var(--foreground)] placeholder:text-[var(--muted-foreground)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[var(--ring)] disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n});\nInput.displayName = \"Input\";\n\nexport { Input };\n","import * as React from \"react\";\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/utils\";\n\nconst labelVariants = cva(\n \"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\",\n);\n\nconst Label = React.forwardRef<\n React.ComponentRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &\n VariantProps<typeof labelVariants>\n>(({ className, ...props }, ref) => (\n <LabelPrimitive.Root\n ref={ref}\n className={cn(labelVariants(), className)}\n {...props}\n />\n));\nLabel.displayName = LabelPrimitive.Root.displayName;\n\nexport { Label };\n","import * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nconst Card = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n \"rounded-xl border bg-[var(--card)] text-[var(--card-foreground)] shadow-sm\",\n className,\n )}\n {...props}\n />\n));\nCard.displayName = \"Card\";\n\nconst CardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"flex flex-col space-y-1.5 p-6\", className)}\n {...props}\n />\n));\nCardHeader.displayName = \"CardHeader\";\n\nconst CardTitle = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"font-semibold leading-none tracking-tight\", className)}\n {...props}\n />\n));\nCardTitle.displayName = \"CardTitle\";\n\nconst CardDescription = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"text-sm text-[var(--muted-foreground)]\", className)}\n {...props}\n />\n));\nCardDescription.displayName = \"CardDescription\";\n\nconst CardContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"p-6 pt-0\", className)} {...props} />\n));\nCardContent.displayName = \"CardContent\";\n\nconst CardFooter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"flex items-center p-6 pt-0\", className)}\n {...props}\n />\n));\nCardFooter.displayName = \"CardFooter\";\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };\n","import { useState, useEffect, type FormEvent } from \"react\";\nimport { useNavigate, useSearchParams, Link } from \"react-router-dom\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { toast } from \"sonner\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Card, CardContent, CardHeader, CardTitle, CardDescription } from \"@/components/ui/card\";\nimport { useAuth } from \"@/hooks/useAuth\";\nimport { checkSetup, listSSOProviders, ssoAuthorizeUrl } from \"@/api/auth\";\nimport type { SSOProvider } from \"@/types/api\";\n\nexport function LoginPage() {\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const { login, isLoginPending, isAuthenticated } = useAuth();\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const rawRedirect = searchParams.get(\"redirect\") || \"/\";\n const redirectTo = rawRedirect.startsWith(\"/\") && !rawRedirect.startsWith(\"//\") ? rawRedirect : \"/\";\n const ssoError = searchParams.get(\"sso_error\");\n\n const { data: setupStatus } = useQuery({\n queryKey: [\"check-setup\"],\n queryFn: checkSetup,\n });\n\n const { data: ssoProviders } = useQuery<SSOProvider[]>({\n queryKey: [\"sso-providers\"],\n queryFn: () => listSSOProviders(),\n staleTime: 60_000,\n });\n\n useEffect(() => {\n if (setupStatus?.needs_setup) {\n navigate(\"/signup\", { replace: true });\n }\n }, [setupStatus, navigate]);\n\n useEffect(() => {\n if (isAuthenticated) {\n navigate(redirectTo, { replace: true });\n }\n }, [isAuthenticated, navigate, redirectTo]);\n\n useEffect(() => {\n if (ssoError) {\n toast.error(ssoError);\n }\n }, [ssoError]);\n\n function handleSubmit(e: FormEvent) {\n e.preventDefault();\n login({ email, password });\n }\n\n const hasProviders = ssoProviders && ssoProviders.length > 0;\n\n return (\n <div className=\"flex min-h-screen items-center justify-center bg-[var(--background)] px-4\">\n <Card className=\"w-full max-w-sm\">\n <CardHeader className=\"text-center\">\n <div className=\"mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-xl bg-[var(--primary)]\">\n <span className=\"text-lg font-bold text-[var(--primary-foreground)]\">D</span>\n </div>\n <CardTitle className=\"text-2xl\">Sign in</CardTitle>\n <CardDescription>Enter your credentials to continue</CardDescription>\n </CardHeader>\n <CardContent>\n {hasProviders && (\n <div className=\"space-y-2 mb-4\">\n {ssoProviders.map((provider) => (\n <Button\n key={provider.slug}\n variant=\"outline\"\n className=\"w-full\"\n asChild\n >\n <a href={ssoAuthorizeUrl(provider.slug, undefined, redirectTo)}>\n Sign in with {provider.name}\n </a>\n </Button>\n ))}\n <div className=\"relative my-4\">\n <div className=\"absolute inset-0 flex items-center\">\n <span className=\"w-full border-t\" />\n </div>\n <div className=\"relative flex justify-center text-xs uppercase\">\n <span className=\"bg-[var(--card)] px-2 text-[var(--muted-foreground)]\">\n or continue with email\n </span>\n </div>\n </div>\n </div>\n )}\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"email\">Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"you@example.com\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n autoFocus\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"password\">Password</Label>\n <Input\n id=\"password\"\n type=\"password\"\n placeholder=\"Enter your password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n required\n />\n </div>\n <Button type=\"submit\" className=\"w-full\" disabled={isLoginPending}>\n {isLoginPending ? \"Signing in...\" : \"Sign in\"}\n </Button>\n </form>\n <p className=\"mt-4 text-center text-sm text-[var(--muted-foreground)]\">\n First time?{\" \"}\n <Link to=\"/signup\" className=\"text-[var(--primary)] hover:underline\">\n Create account\n </Link>\n </p>\n </CardContent>\n </Card>\n </div>\n );\n}\n","import { useState, useEffect, type FormEvent } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Card, CardContent, CardHeader, CardTitle, CardDescription } from \"@/components/ui/card\";\nimport { useAuth } from \"@/hooks/useAuth\";\nimport { checkSetup } from \"@/api/auth\";\n\nexport function SignupPage() {\n const navigate = useNavigate();\n const { signup, isSignupPending, isAuthenticated } = useAuth();\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [displayName, setDisplayName] = useState(\"\");\n\n const { data: setupStatus } = useQuery({\n queryKey: [\"check-setup\"],\n queryFn: checkSetup,\n });\n\n useEffect(() => {\n if (setupStatus && !setupStatus.needs_setup) {\n navigate(\"/login\", { replace: true });\n }\n }, [setupStatus, navigate]);\n\n useEffect(() => {\n if (isAuthenticated) {\n navigate(\"/\", { replace: true });\n }\n }, [isAuthenticated, navigate]);\n\n function handleSubmit(e: FormEvent) {\n e.preventDefault();\n signup({ email, password, displayName });\n }\n\n return (\n <div className=\"flex min-h-screen items-center justify-center bg-[var(--background)] px-4\">\n <Card className=\"w-full max-w-sm\">\n <CardHeader className=\"text-center\">\n <div className=\"mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-xl bg-[var(--primary)]\">\n <span className=\"text-lg font-bold text-[var(--primary-foreground)]\">D</span>\n </div>\n <CardTitle className=\"text-2xl\">Create account</CardTitle>\n <CardDescription>Set up the first admin account</CardDescription>\n </CardHeader>\n <CardContent>\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"displayName\">Name</Label>\n <Input\n id=\"displayName\"\n type=\"text\"\n placeholder=\"Your name\"\n value={displayName}\n onChange={(e) => setDisplayName(e.target.value)}\n required\n autoFocus\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"email\">Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"you@example.com\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"password\">Password</Label>\n <Input\n id=\"password\"\n type=\"password\"\n placeholder=\"Min 8 characters\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n required\n minLength={8}\n />\n </div>\n <Button type=\"submit\" className=\"w-full\" disabled={isSignupPending}>\n {isSignupPending ? \"Creating...\" : \"Create account\"}\n </Button>\n </form>\n </CardContent>\n </Card>\n </div>\n );\n}\n","import { useEffect } from \"react\";\nimport { useNavigate, useSearchParams } from \"react-router-dom\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport { getMe, listTenants } from \"@/api/auth\";\n\nexport function SSOCallbackPage() {\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const { setUser, setTenants } = useAuthStore();\n\n useEffect(() => {\n // The backend has already set the __Host- session cookies on the SSO\n // callback response. All we need to do is hydrate the store by\n // dispatching auth.me (the browser sends the cookie automatically).\n const rawRedirect = searchParams.get(\"redirect\") || \"/\";\n const redirect =\n rawRedirect.startsWith(\"/\") && !rawRedirect.startsWith(\"//\") ? rawRedirect : \"/\";\n\n getMe()\n .then((user) => {\n setUser(user, user.tenant);\n listTenants().then(setTenants).catch(() => {});\n navigate(redirect, { replace: true });\n })\n .catch(() => {\n navigate(\"/login?sso_error=authentication+failed\", { replace: true });\n });\n }, [navigate, searchParams, setUser, setTenants]);\n\n return (\n <div className=\"flex min-h-screen items-center justify-center\">\n <p className=\"text-[var(--muted-foreground)]\">Completing sign in...</p>\n </div>\n );\n}\n","import { Link } from \"react-router-dom\";\nimport { Button } from \"@/components/ui/button\";\n\nexport function NotFoundPage() {\n return (\n <div className=\"flex h-full items-center justify-center\">\n <div className=\"text-center\">\n <h1 className=\"text-6xl font-bold text-[var(--muted-foreground)]\">404</h1>\n <p className=\"mt-2 text-lg text-[var(--muted-foreground)]\">Page not found</p>\n <Button asChild variant=\"outline\" className=\"mt-6\">\n <Link to=\"/\">Go home</Link>\n </Button>\n </div>\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { ArrowLeft } from \"lucide-react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { Button } from \"@/components/ui/button\";\nimport { useTabStore } from \"@/stores/tabs\";\n\ninterface PageHeaderProps {\n title: string;\n backTo?: string;\n actions?: ReactNode;\n}\n\nexport function PageHeader({ title, backTo, actions }: PageHeaderProps) {\n const navigate = useNavigate();\n const { switchTab, findTabByPathname } = useTabStore();\n\n function handleBack() {\n if (!backTo) return;\n const tab = findTabByPathname(backTo);\n if (tab) {\n switchTab(tab.id);\n }\n navigate(backTo);\n }\n\n return (\n <div className=\"flex items-center justify-between mb-6\">\n <div className=\"flex items-center gap-3\">\n {backTo && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={handleBack}\n >\n <ArrowLeft className=\"w-4 h-4\" />\n </Button>\n )}\n <h1 className=\"text-2xl font-semibold\">{title}</h1>\n </div>\n {actions && <div className=\"flex items-center gap-2\">{actions}</div>}\n </div>\n );\n}\n","import { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/utils\";\n\nconst badgeVariants = cva(\n \"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-[var(--ring)] focus:ring-offset-2\",\n {\n variants: {\n variant: {\n default:\n \"border-transparent bg-[var(--primary)] text-[var(--primary-foreground)]\",\n secondary:\n \"border-transparent bg-[var(--secondary)] text-[var(--secondary-foreground)]\",\n destructive:\n \"border-transparent bg-[var(--destructive)] text-[var(--destructive-foreground)]\",\n outline: \"text-[var(--foreground)]\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n },\n);\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof badgeVariants> {\n color?: string;\n}\n\nfunction Badge({ className, variant, color, style, ...props }: BadgeProps) {\n const colorStyle = color\n ? {\n backgroundColor: color + \"1a\",\n color: color,\n borderColor: color + \"33\",\n ...style,\n }\n : style;\n\n return (\n <div\n className={cn(badgeVariants({ variant: color ? undefined : variant }), className)}\n style={colorStyle}\n {...props}\n />\n );\n}\n\nexport { Badge, badgeVariants };\n","import { useState, useMemo } from \"react\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { PageHeader } from \"@/components/shared/PageHeader\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\nimport { loc } from \"@/types/schema\";\nimport type { Action, HandlerDef, HandlerParam } from \"@/types/schema\";\n\ntype Tab = \"handlers\" | \"actions\";\n\nexport function AdminCatalogPage() {\n const { data: schema } = useSchema();\n const [activeTab, setActiveTab] = useState<Tab>(\"handlers\");\n\n if (!schema) return null;\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"px-6 pt-6\">\n <PageHeader title=\"Handler & Action Catalog\" />\n <div className=\"flex gap-2 mb-4\">\n <Button\n variant={activeTab === \"handlers\" ? \"default\" : \"outline\"}\n size=\"sm\"\n onClick={() => setActiveTab(\"handlers\")}\n >\n Handlers\n </Button>\n <Button\n variant={activeTab === \"actions\" ? \"default\" : \"outline\"}\n size=\"sm\"\n onClick={() => setActiveTab(\"actions\")}\n >\n Actions\n </Button>\n </div>\n </div>\n <div className=\"flex-1 overflow-auto px-6 pb-6\">\n {activeTab === \"handlers\" && <HandlersTab schema={schema} />}\n {activeTab === \"actions\" && <ActionsTab schema={schema} />}\n </div>\n </div>\n );\n}\n\nfunction HandlersTab({ schema }: { schema: NonNullable<ReturnType<typeof useSchema>[\"data\"]> }) {\n const allHandlers = useMemo(() => {\n const result: Array<{ code: string; handler: HandlerDef; entity?: string }> = [];\n\n // Top-level handlers.\n if (schema.handlers) {\n for (const [code, h] of Object.entries(schema.handlers)) {\n result.push({ code, handler: h });\n }\n }\n\n // Entity-scoped handlers.\n for (const [entityCode, entity] of Object.entries(schema.entities)) {\n if (entity.handlers) {\n for (const [code, h] of Object.entries(entity.handlers as Record<string, HandlerDef>)) {\n result.push({ code: `${entityCode}.${code}`, handler: h, entity: entityCode });\n }\n }\n }\n\n return result.sort((a, b) => a.code.localeCompare(b.code));\n }, [schema]);\n\n return (\n <div className=\"space-y-3\">\n <p className=\"text-sm text-[var(--muted-foreground)]\">\n {allHandlers.length} handlers registered (view-only - source of truth is code/YAML)\n </p>\n <div className=\"grid gap-3\">\n {allHandlers.map(({ code, handler, entity }) => (\n <HandlerCard key={code} code={code} handler={handler} entity={entity} />\n ))}\n </div>\n </div>\n );\n}\n\nfunction HandlerCard({ code, handler, entity }: { code: string; handler: HandlerDef; entity?: string }) {\n const [expanded, setExpanded] = useState(false);\n const displayName = handler.display?.name ? loc(handler.display.name) : code;\n\n return (\n <div className=\"border border-[var(--border)] rounded-lg p-4\">\n <div className=\"flex items-center justify-between cursor-pointer\" onClick={() => setExpanded(!expanded)}>\n <div className=\"flex items-center gap-3\">\n {handler.display?.icon && <DynamicIcon name={handler.display.icon} className=\"w-4 h-4 text-[var(--muted-foreground)]\" />}\n <div>\n <span className=\"font-mono text-sm font-medium\">{code}</span>\n {displayName !== code && (\n <span className=\"ml-2 text-sm text-[var(--muted-foreground)]\">{displayName}</span>\n )}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Badge variant=\"outline\">{handler.type}</Badge>\n {entity && <Badge variant=\"secondary\">{entity}</Badge>}\n {handler.success_event && <Badge variant=\"secondary\">event: {handler.success_event}</Badge>}\n </div>\n </div>\n {expanded && handler.params && Object.keys(handler.params).length > 0 && (\n <div className=\"mt-3 border-t border-[var(--border)] pt-3\">\n <p className=\"text-xs font-medium text-[var(--muted-foreground)] mb-2\">Parameters</p>\n <div className=\"space-y-1\">\n {(handler.param_order || Object.keys(handler.params)).map((paramCode) => {\n const param = handler.params![paramCode];\n if (!param) return null;\n return <ParamRow key={paramCode} code={paramCode} param={param} />;\n })}\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction ParamRow({ code, param }: { code: string; param: HandlerParam }) {\n const displayName = param.display?.name ? loc(param.display.name) : undefined;\n return (\n <div className=\"flex items-center gap-3 text-sm py-1\">\n <span className=\"font-mono text-xs w-32 shrink-0\">{code}</span>\n <Badge variant=\"outline\" className=\"text-xs\">{param.type || \"string\"}</Badge>\n {param.required && <Badge variant=\"destructive\" className=\"text-xs\">required</Badge>}\n {param.hidden && <Badge variant=\"secondary\" className=\"text-xs\">hidden</Badge>}\n {param.default != null && (\n <span className=\"text-xs text-[var(--muted-foreground)]\">default: {String(param.default)}</span>\n )}\n {displayName && (\n <span className=\"text-xs text-[var(--muted-foreground)]\">{displayName}</span>\n )}\n </div>\n );\n}\n\nfunction ActionsTab({ schema }: { schema: NonNullable<ReturnType<typeof useSchema>[\"data\"]> }) {\n const allActions = useMemo(() => {\n const result: Array<{ code: string; action: Action; entity?: string }> = [];\n\n // Global actions.\n if (schema.actions) {\n for (const [code, action] of Object.entries(schema.actions)) {\n result.push({ code, action });\n }\n }\n\n // Entity-scoped actions.\n for (const [entityCode, entity] of Object.entries(schema.entities)) {\n if (entity.actions) {\n for (const [code, action] of Object.entries(entity.actions)) {\n result.push({ code: `${entityCode}.${code}`, action, entity: entityCode });\n }\n }\n }\n\n return result.sort((a, b) => a.code.localeCompare(b.code));\n }, [schema]);\n\n // Group by entity.\n const grouped = useMemo(() => {\n const groups: Record<string, typeof allActions> = {};\n for (const item of allActions) {\n const key = item.entity || \"(global)\";\n if (!groups[key]) groups[key] = [];\n groups[key].push(item);\n }\n return Object.entries(groups).sort(([a], [b]) => a.localeCompare(b));\n }, [allActions]);\n\n return (\n <div className=\"space-y-4\">\n <p className=\"text-sm text-[var(--muted-foreground)]\">\n {allActions.length} actions defined (view-only - source of truth is code/YAML)\n </p>\n {grouped.map(([group, actions]) => (\n <div key={group}>\n <h3 className=\"text-sm font-medium mb-2 text-[var(--foreground)]\">{group}</h3>\n <div className=\"grid gap-2\">\n {actions.map(({ code, action }) => (\n <ActionCard key={code} code={code} action={action} />\n ))}\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction ActionCard({ code, action }: { code: string; action: Action }) {\n const displayName = loc(action.display?.name);\n return (\n <div className=\"border border-[var(--border)] rounded-lg p-3 flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n {action.display?.icon && <DynamicIcon name={action.display.icon} className=\"w-4 h-4 text-[var(--muted-foreground)]\" />}\n <div>\n <span className=\"font-mono text-sm\">{code}</span>\n {displayName && displayName !== code && (\n <span className=\"ml-2 text-sm text-[var(--muted-foreground)]\">{displayName}</span>\n )}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n {action.type && <Badge variant=\"outline\">{action.type}</Badge>}\n {action.scope && <Badge variant=\"secondary\">{action.scope}</Badge>}\n {action.handler && (\n <span className=\"text-xs text-[var(--muted-foreground)] font-mono\">handler: {action.handler}</span>\n )}\n {action.visibility && action.visibility.length > 0 && (\n <div className=\"flex gap-1\">\n {action.visibility.map((v) => (\n <Badge key={v} variant=\"outline\" className=\"text-xs\">{v}</Badge>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { apiFetch } from \"./client\";\nimport type { ListParams, ListResponse, DataResponse } from \"@/types/api\";\nimport type { PkValues } from \"@/types/schema\";\n\nfunction buildListUrl(entity: string, params: ListParams): string {\n const url = new URL(`/api/data/${entity}`, window.location.origin);\n\n if (params.page) url.searchParams.set(\"page\", String(params.page));\n if (params.per_page) url.searchParams.set(\"per_page\", String(params.per_page));\n if (params.sort) url.searchParams.set(\"sort\", params.sort);\n if (params.search) url.searchParams.set(\"search\", params.search);\n\n if (params.filters && params.filters.length > 0) {\n url.searchParams.set(\"filters\", JSON.stringify(params.filters));\n }\n\n if (params.include_deleted) {\n url.searchParams.set(\"include_deleted\", \"true\");\n }\n\n if (params.expand) {\n for (const e of params.expand) {\n url.searchParams.append(\"expand\", e);\n }\n }\n\n if (params.screen) url.searchParams.set(\"screen\", params.screen);\n\n return url.pathname + url.search;\n}\n\nexport async function listEntities(\n entity: string,\n params: ListParams = {},\n): Promise<ListResponse> {\n return apiFetch<ListResponse>(buildListUrl(entity, params));\n}\n\n// getEntity fetches a single record by primary key values.\n// Accepts either a PkValues object (composite PK support) or a plain string\n// (backward compat for single-PK entities - sent as query param `id=<value>`).\nexport async function getEntity(\n entity: string,\n pkValues: PkValues | string,\n): Promise<DataResponse> {\n const params = new URLSearchParams();\n if (typeof pkValues === \"string\") {\n params.set(\"id\", pkValues);\n } else {\n for (const [key, value] of Object.entries(pkValues)) {\n params.set(key, value);\n }\n }\n return apiFetch<DataResponse>(`/api/data/${entity}?${params.toString()}`);\n}\n\nexport async function createEntity(\n entity: string,\n data: Record<string, unknown>,\n): Promise<DataResponse> {\n const results = await apiFetch<Record<string, unknown>[]>(`/api/data/${entity}`, {\n method: \"POST\",\n body: JSON.stringify([data]),\n });\n return { data: results[0] };\n}\n\n// updateEntity sends a PATCH with PK fields included in the body item.\n// Accepts either a PkValues object (composite PK) or a plain string id\n// (backward compat - sent as { id: <value> }).\nexport async function updateEntity(\n entity: string,\n pkValues: PkValues | string,\n data: Record<string, unknown>,\n): Promise<DataResponse> {\n const pkFields = typeof pkValues === \"string\" ? { id: pkValues } : pkValues;\n const results = await apiFetch<Record<string, unknown>[]>(`/api/data/${entity}`, {\n method: \"PATCH\",\n body: JSON.stringify([{ ...pkFields, ...data }]),\n });\n return { data: results[0] };\n}\n\n// deleteEntity sends a POST /delete with PK fields in the body items.\n// Accepts either a PkValues object (composite PK) or a plain string id.\nexport async function deleteEntity(\n entity: string,\n pkValues: PkValues | string,\n): Promise<void> {\n const item = typeof pkValues === \"string\" ? { id: pkValues } : pkValues;\n await apiFetch(`/api/data/${entity}/delete`, {\n method: \"POST\",\n body: JSON.stringify([item]),\n });\n}\n\n// restoreEntity sends a POST /restore with PK fields in the body items.\n// Accepts either a PkValues object (composite PK) or a plain string id.\nexport async function restoreEntity(\n entity: string,\n pkValues: PkValues | string,\n): Promise<void> {\n const item = typeof pkValues === \"string\" ? { id: pkValues } : pkValues;\n await apiFetch(`/api/data/${entity}/restore`, {\n method: \"POST\",\n body: JSON.stringify([item]),\n });\n}\n\n/**\n * Action request body is flat: top-level keys are handler params. The only\n * reserved control key is `_ids` (array of object IDs for single/batch\n * scope). The server resolves entity from the action's registration; the\n * URL code is fully qualified (\"entity.action\" for entity-scoped,\n * \"action\" for global).\n */\nexport type ActionExecuteRequest = Record<string, unknown>;\n\nexport interface ActionExecuteResponse {\n status: string;\n result?: unknown;\n audit_operation_id?: string;\n object_count?: number;\n /** IDs that succeeded (batch_mode: each responses). */\n success?: string[];\n}\n\n/**\n * Build a flat action body from handler params + optional object IDs.\n * Promotes `ids` to the reserved `_ids` key. Throws if a caller passes a\n * param literally named `_ids` (collision with the reserved control key).\n */\nexport function buildActionBody(\n params: Record<string, unknown> | undefined,\n ids?: string[] | undefined,\n): ActionExecuteRequest {\n const body: Record<string, unknown> = { ...(params ?? {}) };\n if (\"_ids\" in body) {\n throw new Error('handler param \"_ids\" collides with reserved key');\n }\n if (ids !== undefined) {\n body._ids = ids;\n }\n return body;\n}\n\n/**\n * Invoke an action. The URL `code` must be fully qualified for\n * entity-scoped actions (e.g. `lead.archive`). For global actions it's the\n * action code on its own (e.g. `auth.login`).\n */\nexport async function executeAction(\n code: string,\n body: ActionExecuteRequest,\n): Promise<ActionExecuteResponse> {\n return apiFetch<ActionExecuteResponse>(`/api/actions/${code}`, {\n method: \"POST\",\n body: JSON.stringify(body),\n });\n}\n\nexport interface AssociationResponse {\n target_entity: string;\n ids: string[];\n count: number;\n}\n\nexport async function resolveAssociation(\n code: string,\n ids: string[],\n): Promise<AssociationResponse> {\n const params = new URLSearchParams();\n params.set(\"ids\", ids.join(\",\"));\n return apiFetch<AssociationResponse>(`/api/associations/${code}?${params.toString()}`);\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { listEntities } from \"@/api/data\";\nimport type { ListParams } from \"@/types/api\";\n\nexport function useEntityData(entity: string | undefined, params: ListParams) {\n return useQuery({\n queryKey: [\"entity-data\", entity, params],\n queryFn: () => listEntities(entity!, params),\n enabled: !!entity,\n placeholderData: (prev, prevQuery) => {\n // Only reuse previous data within the same entity (pagination/sorting).\n // Cross-entity placeholder causes wrong rows/columns flash.\n const prevEntity = (prevQuery?.queryKey as unknown[])?.[1];\n return prevEntity === entity ? prev : undefined;\n },\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { toast } from \"sonner\";\nimport { createEntity, updateEntity, deleteEntity, restoreEntity, executeAction } from \"@/api/data\";\nimport type { PkValues } from \"@/types/schema\";\nimport { ENTITY_CHILDREN_KEY } from \"@/hooks/useChildrenData\";\n\nimport type { ActionExecuteRequest } from \"@/api/data\";\n\nexport function useCreateEntity(entityCode: string) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (data: Record<string, unknown>) =>\n createEntity(entityCode, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [\"entity-data\", entityCode] });\n toast.success(\"Record created\");\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n\nexport function useUpdateEntity(entityCode: string) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({ pkValues, data }: { pkValues: PkValues | string; data: Record<string, unknown> }) =>\n updateEntity(entityCode, pkValues, data),\n onSuccess: (_result, _variables) => {\n // Invalidate all caches by entity-level prefix. We avoid setQueryData\n // because cache keys use different ID formats across consumers\n // (pkCacheKey \"k=v&...\" vs raw URL id vs \"|\"-joined composite).\n // Prefix invalidation always matches regardless of format.\n queryClient.invalidateQueries({ queryKey: [\"entity-data\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"entity-item\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [ENTITY_CHILDREN_KEY, entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"object-status\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"object-properties\", entityCode] });\n toast.success(\"Record updated\");\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n\nexport function useDeleteEntity(entityCode: string) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (pkValues: PkValues | string) => deleteEntity(entityCode, pkValues),\n onSuccess: (_result, _pkValues) => {\n queryClient.invalidateQueries({ queryKey: [\"entity-data\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"entity-item\", entityCode] });\n toast.success(\"Record deleted\");\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n\nexport function useRestoreEntity(entityCode: string) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (pkValues: PkValues | string) => restoreEntity(entityCode, pkValues),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [\"entity-data\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"entity-item\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"object-status\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"object-properties\", entityCode] });\n toast.success(\"Record restored\");\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n\nexport function useExecuteAction(entityCode?: string) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ actionCode, body }: { actionCode: string; body: ActionExecuteRequest }) => {\n const result = await executeAction(actionCode, body);\n if (result.status === \"error\") {\n throw new Error(\"Action failed for all items\");\n }\n return result;\n },\n onSuccess: (result) => {\n if (entityCode) {\n queryClient.invalidateQueries({ queryKey: [\"entity-data\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"entity-item\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [ENTITY_CHILDREN_KEY, entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"object-status\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"object-properties\", entityCode] });\n }\n if (result.status === \"accepted\") {\n toast.success(\"Action started - check audit for progress\");\n } else if (result.status === \"partial\") {\n toast.warning(\"Action partially completed - some items failed or were skipped\");\n } else {\n toast.success(\"Action executed\");\n }\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n","import { useState, useEffect } from \"react\";\n\nexport function useDebounce<T>(value: T, delay: number): T {\n const [debounced, setDebounced] = useState(value);\n\n useEffect(() => {\n const timer = setTimeout(() => setDebounced(value), delay);\n return () => clearTimeout(timer);\n }, [value, delay]);\n\n return debounced;\n}\n","import { useState, useCallback } from \"react\";\nimport { Copy, Check } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface CopyButtonProps {\n value: string;\n title?: string;\n className?: string;\n size?: \"sm\" | \"icon\";\n}\n\n// CopyButton is the single platform-wide control for copy-to-clipboard.\n// Dumb by design: it copies the given value and briefly swaps to a check icon.\n// No side effects, no hooks, no extra behavior. Multi-step workflows must live\n// on a separate action button with ui_steps.\nexport function CopyButton({ value, title, className, size = \"icon\" }: CopyButtonProps) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(async (e: React.MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch {\n // Clipboard API may be unavailable (non-secure context). Swallow:\n // the caller can select text manually.\n }\n }, [value]);\n\n const iconSize = size === \"sm\" ? \"h-3 w-3\" : \"h-4 w-4\";\n const buttonClass = size === \"sm\" ? \"h-6 w-6\" : \"h-8 w-8\";\n\n return (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className={`${buttonClass} shrink-0 ${className ?? \"\"}`}\n onClick={handleCopy}\n title={title ?? \"Copy to clipboard\"}\n >\n {copied ? (\n <Check className={`${iconSize} text-green-500`} />\n ) : (\n <Copy className={`${iconSize} text-[var(--muted-foreground)]`} />\n )}\n </Button>\n );\n}\n","import { Input } from \"@/components/ui/input\";\nimport { CopyButton } from \"@/components/shared/CopyButton\";\nimport type { FieldRendererProps } from \"./index\";\n\nexport function StringField({ field, value, mode, onChange }: FieldRendererProps) {\n if (mode === \"display\") {\n const text = String(value ?? \"\");\n if (field.copyable && text) {\n return (\n <span className=\"inline-flex items-center gap-1\">\n <span className=\"text-sm\">{text}</span>\n <CopyButton value={text} size=\"sm\" />\n </span>\n );\n }\n return <span className=\"text-sm\">{text}</span>;\n }\n\n return (\n <Input\n value={String(value ?? \"\")}\n onChange={(e) => onChange?.(e.target.value)}\n />\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nconst Textarea = React.forwardRef<\n HTMLTextAreaElement,\n React.TextareaHTMLAttributes<HTMLTextAreaElement>\n>(({ className, ...props }, ref) => {\n return (\n <textarea\n className={cn(\n \"flex min-h-[60px] w-full rounded-md border border-[var(--input)] bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-[var(--muted-foreground)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[var(--ring)] disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n});\nTextarea.displayName = \"Textarea\";\n\nexport { Textarea };\n","import Markdown from \"react-markdown\";\nimport remarkBreaks from \"remark-breaks\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { CopyButton } from \"@/components/shared/CopyButton\";\nimport type { FieldRendererProps } from \"./index\";\n\nconst remarkPlugins = [remarkBreaks];\n\nexport function TextField({ field, value, mode, onChange }: FieldRendererProps) {\n const widget = field.display?.widget;\n\n if (mode === \"display\") {\n const text = String(value ?? \"\");\n if (!text) return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n\n const rendered = widget === \"markdown\" ? (\n <div className=\"prose prose-sm dark:prose-invert max-w-none break-words overflow-hidden\">\n {/* skipHtml blocks raw HTML injection (script, img onerror, etc.).\n react-markdown v10's defaultUrlTransform blocks javascript: URLs.\n Do not pass urlTransform or allowedElements without security review. */}\n <Markdown skipHtml remarkPlugins={remarkPlugins}>{text}</Markdown>\n </div>\n ) : widget === \"code\" ? (\n <pre className=\"text-sm font-mono bg-[var(--muted)] text-[var(--foreground)] rounded-md border border-[var(--border)] p-4 overflow-x-auto max-h-[600px] overflow-y-auto whitespace-pre\">\n {text}\n </pre>\n ) : (\n <p className=\"text-sm whitespace-pre-wrap break-words\">{text}</p>\n );\n\n if (field.copyable) {\n return (\n <div className=\"group relative\">\n {rendered}\n <div className=\"absolute top-0 right-0 opacity-0 group-hover:opacity-100 transition-opacity\">\n <CopyButton value={text} size=\"sm\" />\n </div>\n </div>\n );\n }\n\n return rendered;\n }\n\n const rows = widget === \"markdown\" || widget === \"code\" ? 10 : 4;\n return (\n <Textarea\n value={String(value ?? \"\")}\n onChange={(e) => onChange?.(e.target.value)}\n rows={rows}\n className=\"resize-y font-mono text-sm\"\n />\n );\n}\n","import * as React from \"react\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { Check, ChevronDown, ChevronUp } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\nconst Select = SelectPrimitive.Root;\nconst SelectGroup = SelectPrimitive.Group;\nconst SelectValue = SelectPrimitive.Value;\n\nconst SelectTrigger = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Trigger\n ref={ref}\n className={cn(\n \"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-[var(--input)] bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-[var(--background)] placeholder:text-[var(--muted-foreground)] focus:outline-none focus:ring-1 focus:ring-[var(--ring)] disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1\",\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDown className=\"h-4 w-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n));\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName;\n\nconst SelectScrollUpButton = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.ScrollUpButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollUpButton\n ref={ref}\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className,\n )}\n {...props}\n >\n <ChevronUp className=\"h-4 w-4\" />\n </SelectPrimitive.ScrollUpButton>\n));\nSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;\n\nconst SelectScrollDownButton = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.ScrollDownButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollDownButton\n ref={ref}\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className,\n )}\n {...props}\n >\n <ChevronDown className=\"h-4 w-4\" />\n </SelectPrimitive.ScrollDownButton>\n));\nSelectScrollDownButton.displayName =\n SelectPrimitive.ScrollDownButton.displayName;\n\nconst SelectContent = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>\n>(({ className, children, position = \"popper\", ...props }, ref) => (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n ref={ref}\n className={cn(\n \"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-[var(--popover)] text-[var(--popover-foreground)] shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className,\n )}\n position={position}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]\",\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n));\nSelectContent.displayName = SelectPrimitive.Content.displayName;\n\nconst SelectItem = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-[var(--accent)] focus:text-[var(--accent-foreground)] data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n));\nSelectItem.displayName = SelectPrimitive.Item.displayName;\n\nconst SelectLabel = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label\n ref={ref}\n className={cn(\"px-2 py-1.5 text-sm font-semibold\", className)}\n {...props}\n />\n));\nSelectLabel.displayName = SelectPrimitive.Label.displayName;\n\nconst SelectSeparator = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-[var(--muted)]\", className)}\n {...props}\n />\n));\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName;\n\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectItem,\n SelectLabel,\n SelectSeparator,\n SelectScrollUpButton,\n SelectScrollDownButton,\n};\n","import { Badge } from \"@/components/ui/badge\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { loc } from \"@/types/schema\";\nimport type { FieldRendererProps } from \"./index\";\n\n// Sentinel for the \"clear / no value\" item in the dropdown. shadcn/ui's\n// SelectItem forbids an empty string as value (it's reserved for the\n// unset state), so we use a unique sentinel that cannot collide with a\n// real enum code and map it back to null on change.\nconst NULL_SENTINEL = \"__declarion_enum_null__\";\n\nexport function EnumField({ field, value, mode, onChange }: FieldRendererProps) {\n const values = field.values ?? [];\n const current = values.find((v) => v.code === value);\n\n if (mode === \"display\") {\n if (!current) {\n return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n }\n return <Badge color={current.color}>{loc(current.name)}</Badge>;\n }\n\n // Non-required enums render a leading \"— None —\" item so users can\n // clear a previously-set value (e.g. activity.intent, which is only\n // valid for specific channel/direction combos and must stay null for\n // everything else). Required enums have no clear option.\n const showClearOption = !field.required;\n const currentValue = value != null && value !== \"\" ? String(value) : NULL_SENTINEL;\n\n return (\n <Select\n value={currentValue}\n onValueChange={(v) => onChange?.(v === NULL_SENTINEL ? null : v)}\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Select...\" />\n </SelectTrigger>\n <SelectContent>\n {showClearOption && (\n <SelectItem value={NULL_SENTINEL}>\n <span className=\"text-[var(--muted-foreground)]\">— None —</span>\n </SelectItem>\n )}\n {values.map((v) => (\n <SelectItem key={v.code} value={v.code}>\n {loc(v.name)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n","import { Input } from \"@/components/ui/input\";\nimport type { FieldRendererProps } from \"./index\";\n\nexport function EmailField({ value, mode, onChange }: FieldRendererProps) {\n const str = String(value ?? \"\");\n\n if (mode === \"display\") {\n if (!str) return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n return (\n <a\n href={`mailto:${str}`}\n className=\"text-sm text-[var(--primary)] hover:underline\"\n >\n {str}\n </a>\n );\n }\n\n return (\n <Input\n type=\"email\"\n value={str}\n onChange={(e) => onChange?.(e.target.value)}\n />\n );\n}\n","import { useState } from \"react\";\nimport { ExternalLink } from \"lucide-react\";\nimport { Input } from \"@/components/ui/input\";\nimport type { FieldRendererProps } from \"./index\";\n\nconst FAVICON_BASE = \"https://www.google.com/s2/favicons\";\nconst SAFE_PROTOCOLS = /^(https?|ftps?|ssh|mailto|tel):/i;\n// Known gTLDs with 4+ characters commonly seen in URLs.\nconst LONG_TLD = /^(info|name|tech|site|cloud|online|store|shop|blog|space|world|link|live|page|zone|life|team|work|host|land|news|wiki|mobi|coop|aero|asia)$/i;\n\n// Checks whether a label looks like a TLD. All 2-3 character all-alpha labels\n// are treated as TLDs (covers ccTLDs like .uk, .de, .ai and short gTLDs like\n// .com, .xyz, .app). Longer labels are checked against a known gTLD list.\nfunction looksLikeTLD(label: string): boolean {\n return /^[a-z]{2,3}$/i.test(label) || LONG_TLD.test(label);\n}\n\nfunction looksLikeHostname(candidate: string): boolean {\n if (!candidate.includes(\".\")) return false;\n const labels = candidate.split(\".\");\n if (labels.length < 3) return true;\n const first = labels[0].toLowerCase();\n // Traditional gTLDs as first label always indicate reverse-DNS (com.google.android)\n if (/^(com|org|net|edu|gov)$/.test(first)) return false;\n // io/app/dev as first label are ambiguous: they're TLDs used in reverse-DNS\n // (io.github.user) but also common subdomain prefixes (app.example.com).\n // Disambiguate by checking the last label: if it looks like a TLD, the name\n // is structured as subdomain.domain.TLD (hostname), not TLD.domain.product.\n if (/^(io|app|dev)$/.test(first)) {\n return looksLikeTLD(labels[labels.length - 1]);\n }\n return true;\n}\n\nfunction normalizeUrl(raw: string): string | null {\n // Allow known-safe protocols through\n if (SAFE_PROTOCOLS.test(raw)) return raw;\n // Check for protocol-like pattern (scheme \":\" per RFC 3986)\n const schemeMatch = raw.match(/^([a-z][a-z0-9+.-]*):/i);\n if (schemeMatch) {\n const scheme = schemeMatch[1];\n const afterColon = raw.slice(schemeMatch[0].length);\n // Port numbers are always digits optionally followed by /, ?, #, or\n // end-of-string. If that pattern matches and the number is a valid TCP\n // port (1-65535), the part before : is likely a hostname. We apply this\n // when the candidate looks like a multi-label hostname (contains a dot)\n // and is NOT a reverse-DNS identifier (com.example.app). Single-label\n // names (sip:1234, minio:9000) are syntactically identical to\n // scheme:argument URIs and are treated as unknown protocols - users can\n // prefix with http:// to disambiguate.\n if (/^\\d+([/?#]|$)/.test(afterColon) && looksLikeHostname(scheme)) {\n const port = parseInt(afterColon, 10);\n if (port >= 1 && port <= 65535) {\n return `https://${raw}`;\n }\n }\n // \"localhost\" is a bare hostname (with or without port)\n if (scheme.toLowerCase() === \"localhost\") {\n return `https://${raw}`;\n }\n // Unknown protocol - reject (includes custom schemes like my.app://open)\n return null;\n }\n // No protocol - bare domain, prepend https://\n return `https://${raw}`;\n}\n\nfunction parseDomain(href: string): string | null {\n try {\n const hostname = new URL(href).hostname.replace(/^www\\./i, \"\");\n return hostname || null;\n } catch {\n return null;\n }\n}\n\nfunction isValidUrl(href: string): boolean {\n try {\n new URL(href);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function UrlField({ field, value, mode, onChange }: FieldRendererProps) {\n const str = String(value ?? \"\");\n const [errorDomain, setErrorDomain] = useState<string | null>(null);\n\n if (mode === \"display\") {\n if (!str) return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n\n const widget = field.display?.widget;\n const isLink = widget === \"link\";\n const href = normalizeUrl(str);\n\n // If the URL uses an unsafe protocol or is not parseable, render as plain text\n if (href == null || !isValidUrl(href)) {\n return <span className=\"text-sm\">{str}</span>;\n }\n\n const domain = parseDomain(href);\n\n // domain widget (default): show favicon + domain name\n // link widget: show full URL, no favicon\n // fallback: if domain parsing fails, show raw value as link\n const showFavicon = !isLink && domain != null && errorDomain !== domain;\n const linkText = isLink ? str : (domain ?? str);\n\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title={str}\n className=\"inline-flex items-center gap-1 text-sm text-[var(--primary)] hover:underline\"\n >\n {showFavicon && (\n <img\n src={`${FAVICON_BASE}?domain=${encodeURIComponent(domain)}&sz=16`}\n alt=\"\"\n width={16}\n height={16}\n loading=\"lazy\"\n className=\"shrink-0\"\n onError={() => setErrorDomain(domain)}\n />\n )}\n {linkText}\n <ExternalLink className=\"w-3 h-3 shrink-0\" />\n </a>\n );\n }\n\n return (\n <Input\n type=\"url\"\n value={str}\n onChange={(e) => onChange?.(e.target.value)}\n placeholder=\"https://\"\n />\n );\n}\n","import { Input } from \"@/components/ui/input\";\nimport type { FieldRendererProps } from \"./index\";\n\n/**\n * Parse an offset-aware ISO timestamp (e.g. \"2026-03-27T14:30:00+03:00\") and\n * format it for display WITHOUT browser-local conversion. When the server\n * returns a timestamp with an offset, we want to show the exact local time the\n * server computed - not the browser's reinterpretation of it.\n *\n * If the value has an explicit offset or Z suffix we use Intl.DateTimeFormat\n * with the timeZone extracted from the offset so the browser doesn't shift the\n * time. For bare datetime strings (no offset) we fall back to simple parsing.\n */\nfunction formatTimestamp(raw: string, isDateOnly: boolean): string {\n if (isDateOnly) {\n // Date-only: just format the date portion.\n const d = new Date(raw + \"T00:00:00\");\n if (isNaN(d.getTime())) return raw;\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n }).format(d);\n }\n\n // Try to extract the IANA-compatible fixed offset from the string so we can\n // tell Intl.DateTimeFormat to use it (prevents browser-local shift).\n const offsetMatch = raw.match(/([+-]\\d{2}:\\d{2})$/);\n const isUTC = raw.endsWith(\"Z\");\n\n if (offsetMatch || isUTC) {\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n\n // Build a formatter that locks to the original offset. For UTC we pass\n // \"UTC\"; for fixed offsets like +03:00 we pass \"Etc/GMT-3\" style (note\n // the sign inversion in Etc/GMT). However, Etc/GMT doesn't handle\n // non-hour offsets well, so for those we fall back to manual formatting.\n let tz: string | undefined;\n if (isUTC) {\n tz = \"UTC\";\n } else if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0);\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n if (minutes === 0) {\n // Etc/GMT sign is inverted: +03:00 -> Etc/GMT-3\n tz = hours === 0 ? \"UTC\" : `Etc/GMT${sign === \"+\" ? \"-\" : \"+\"}${hours}`;\n }\n // For non-zero minute offsets (e.g. +05:30), tz stays undefined\n // and we fall through to manual formatting below.\n }\n\n if (tz) {\n try {\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n timeZone: tz,\n }).format(date);\n } catch {\n // Fall through to manual formatting if the tz string is invalid.\n }\n }\n\n // Manual formatting for non-standard offsets (e.g. +05:30).\n // Parse the offset and compute the local time manually.\n if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0) === \"+\" ? 1 : -1;\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n const offsetMs = sign * (hours * 60 + minutes) * 60 * 1000;\n const localMs = date.getTime() + offsetMs;\n const localDate = new Date(localMs);\n // Format using UTC methods (since we already applied the offset).\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n timeZone: \"UTC\",\n }).format(localDate);\n }\n }\n\n // Bare datetime string or unparseable offset - format via browser locale.\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n }).format(date);\n}\n\n/**\n * Extract a short timezone abbreviation from a timestamp string for display.\n * E.g. \"+03:00\" -> \"UTC+3\", \"Z\" -> \"UTC\", \"+05:30\" -> \"UTC+5:30\".\n */\nfunction extractTzAbbrev(raw: string): string | null {\n if (raw.endsWith(\"Z\")) return \"UTC\";\n const m = raw.match(/([+-]\\d{2}:\\d{2})$/);\n if (!m) return null;\n const sign = m[1].charAt(0);\n const hours = parseInt(m[1].substring(1, 3), 10);\n const minutes = parseInt(m[1].substring(4, 6), 10);\n if (hours === 0 && minutes === 0) return \"UTC\";\n const minPart = minutes > 0 ? `:${String(minutes).padStart(2, \"0\")}` : \"\";\n return `UTC${sign}${hours}${minPart}`;\n}\n\n/**\n * Convert a server-provided offset-aware timestamp to \"YYYY-MM-DDTHH:MM\"\n * for the datetime-local input, preserving the server's local time (not\n * converting to browser local).\n */\nfunction toInputValue(raw: string, isDateOnly: boolean): string {\n const offsetMatch = raw.match(/([+-]\\d{2}:\\d{2})$/);\n const isUTC = raw.endsWith(\"Z\");\n\n if (offsetMatch || isUTC) {\n const date = new Date(raw);\n if (isNaN(date.getTime())) return \"\";\n\n if (isUTC) {\n // UTC: use UTC methods to get the digits.\n const y = date.getUTCFullYear();\n const mo = String(date.getUTCMonth() + 1).padStart(2, \"0\");\n const d = String(date.getUTCDate()).padStart(2, \"0\");\n if (isDateOnly) return `${y}-${mo}-${d}`;\n const h = String(date.getUTCHours()).padStart(2, \"0\");\n const mi = String(date.getUTCMinutes()).padStart(2, \"0\");\n return `${y}-${mo}-${d}T${h}:${mi}`;\n }\n\n // Fixed offset: compute local time manually.\n const sign = offsetMatch![1].charAt(0) === \"+\" ? 1 : -1;\n const hours = parseInt(offsetMatch![1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch![1].substring(4, 6), 10);\n const offsetMs = sign * (hours * 60 + minutes) * 60 * 1000;\n const localMs = date.getTime() + offsetMs;\n const localDate = new Date(localMs);\n const y = localDate.getUTCFullYear();\n const mo = String(localDate.getUTCMonth() + 1).padStart(2, \"0\");\n const d = String(localDate.getUTCDate()).padStart(2, \"0\");\n if (isDateOnly) return `${y}-${mo}-${d}`;\n const h = String(localDate.getUTCHours()).padStart(2, \"0\");\n const mi = String(localDate.getUTCMinutes()).padStart(2, \"0\");\n return `${y}-${mo}-${d}T${h}:${mi}`;\n }\n\n // Bare datetime string - extract digits directly.\n // Format: \"2026-03-27T14:30\" or \"2026-03-27T14:30:00\"\n if (isDateOnly) return raw.slice(0, 10);\n // Take up to minutes precision.\n return raw.slice(0, 16);\n}\n\nexport function TimestampField({ field, value, mode, onChange }: FieldRendererProps) {\n const isDateOnly = field.type === \"date\";\n const hasTz = !!field.timezone;\n\n if (mode === \"display\") {\n if (!value) return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n const raw = String(value);\n const formatted = formatTimestamp(raw, isDateOnly);\n // Show timezone abbreviation when field has timezone config.\n const tzAbbrev = hasTz && !isDateOnly ? extractTzAbbrev(raw) : null;\n return (\n <span className=\"text-sm\">\n {formatted}\n {tzAbbrev && <span className=\"ml-1 text-[var(--muted-foreground)]\">{tzAbbrev}</span>}\n </span>\n );\n }\n\n // Edit mode: convert server value to input format preserving server's local\n // time (not browser local), then send the raw datetime-local value as-is on\n // change. The server handles timezone attachment and UTC conversion.\n let inputValue = \"\";\n if (value) {\n inputValue = toInputValue(String(value), isDateOnly);\n }\n\n return (\n <Input\n type={isDateOnly ? \"date\" : \"datetime-local\"}\n value={inputValue}\n onChange={(e) => {\n if (!e.target.value) {\n onChange?.(null);\n return;\n }\n // Send the raw datetime-local value as-is. The server will interpret\n // this as local time in the field's configured timezone.\n onChange?.(e.target.value);\n }}\n />\n );\n}\n","import type { FieldRendererProps } from \"./index\";\n\nexport function BoolField({ value, mode, onChange }: FieldRendererProps) {\n const checked = Boolean(value);\n\n if (mode === \"display\") {\n return (\n <span className=\"inline-flex items-center gap-1.5 text-sm\">\n <span\n className={`inline-block w-2 h-2 rounded-full ${\n checked ? \"bg-[var(--primary)]\" : \"bg-[var(--muted-foreground)]\"\n }`}\n />\n {checked ? \"Yes\" : \"No\"}\n </span>\n );\n }\n\n return (\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={checked}\n onChange={(e) => onChange?.(e.target.checked)}\n className=\"h-4 w-4 rounded border-[var(--input)] text-[var(--primary)] focus:ring-[var(--ring)]\"\n />\n <span className=\"text-sm\">{checked ? \"Yes\" : \"No\"}</span>\n </label>\n );\n}\n","import { Input } from \"@/components/ui/input\";\nimport type { FieldRendererProps } from \"./index\";\n\n/**\n * Format a decimal string for display using locale-aware grouping.\n * Splits on \".\" to preserve exact decimal places without parseFloat precision loss.\n */\nfunction formatDecimalString(value: string): string {\n const trimmed = value.trim();\n if (trimmed === \"\" || trimmed === \"-\") return trimmed;\n\n const negative = trimmed.startsWith(\"-\");\n const abs = negative ? trimmed.slice(1) : trimmed;\n const [intPart, fracPart] = abs.split(\".\");\n\n let formattedInt: string;\n try {\n formattedInt = new Intl.NumberFormat().format(BigInt(intPart || \"0\"));\n } catch {\n return value; // fallback to raw string on invalid input\n }\n\n let result = negative ? `-${formattedInt}` : formattedInt;\n if (fracPart !== undefined) {\n result += `.${fracPart}`;\n }\n return result;\n}\n\nconst numFormatter = new Intl.NumberFormat();\n\nexport function NumberField({ field, fieldName, value, mode, onChange, record }: FieldRendererProps) {\n const isMoney = field.display?.widget === \"money\";\n const isDecimal = field.type === \"decimal\" || isMoney;\n\n // Resolve unit suffix from $units metadata on the record.\n const units = record?.[\"$units\"] as Record<string, string> | undefined;\n const unitSuffix = units?.[fieldName];\n\n // If no $units metadata, fall back to static unit config from schema.\n const staticUnit = !unitSuffix && field.unit\n ? (field.unit.display || field.unit.storage)\n : undefined;\n // Only show static unit if it doesn't start with $ (dynamic units are resolved in $units).\n const displayUnit = unitSuffix\n || (staticUnit && !staticUnit.startsWith(\"$\") ? staticUnit : undefined);\n\n if (mode === \"display\") {\n if (value == null) return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n\n let formatted: string | null;\n if (isDecimal && typeof value === \"string\") {\n formatted = formatDecimalString(value);\n } else {\n const num = Number(value);\n formatted = isNaN(num) ? null : numFormatter.format(num);\n }\n\n if (formatted == null) return <span className=\"text-sm\">-</span>;\n\n return (\n <span className=\"text-sm tabular-nums\">\n {formatted}\n {displayUnit && <span className=\"text-[var(--muted-foreground)] ml-1\">{displayUnit}</span>}\n </span>\n );\n }\n\n // Edit mode: use text input for decimal to avoid IEEE 754 precision loss.\n if (isDecimal) {\n return (\n <Input\n type=\"text\"\n inputMode=\"decimal\"\n pattern=\"-?\\d*\\.?\\d*\"\n value={value != null ? String(value) : \"\"}\n onChange={(e) => {\n const v = e.target.value;\n if (v === \"\") {\n onChange?.(null);\n } else {\n // Keep as string - do NOT parseFloat. Server expects decimal strings.\n onChange?.(v);\n }\n }}\n />\n );\n }\n\n // int/float: use number input\n return (\n <Input\n type=\"number\"\n step={field.type === \"float\" ? \"0.01\" : \"1\"}\n value={value != null ? String(value) : \"\"}\n onChange={(e) => {\n const v = e.target.value;\n if (v === \"\") {\n onChange?.(null);\n } else {\n onChange?.(field.type === \"int\" ? parseInt(v, 10) : parseFloat(v));\n }\n }}\n />\n );\n}\n","import { useSchema } from \"./useSchema\";\nimport type { Entity } from \"@/types/schema\";\n\nexport function useEntity(entityCode: string | undefined): Entity | undefined {\n const { data: schema } = useSchema();\n if (!schema || !entityCode) return undefined;\n return schema.entities[entityCode];\n}\n","import { useMemo } from \"react\";\nimport { useEntityData } from \"@/hooks/useEntityData\";\nimport { useEntity } from \"@/hooks/useEntity\";\nimport type { FieldRendererProps } from \"./index\";\n\n/** Resolve a display value that may be a plain string or a multilang object. */\nfunction resolveDisplay(val: unknown): string {\n if (val == null) return \"-\";\n if (typeof val === \"object\" && !Array.isArray(val)) {\n const first = Object.values(val)[0];\n return first != null ? String(first) : \"-\";\n }\n return String(val);\n}\n\nexport function RefField({\n field,\n value,\n mode,\n onChange,\n refs,\n}: FieldRendererProps) {\n const refEntityCode = field.ref?.entity;\n const entity = useEntity(refEntityCode);\n\n // Display field: ref.display.field overrides entity.display.display_field.\n const displayField = field.display?.ref_display_field ?? field.ref?.display?.field ?? entity?.display?.display_field;\n const pk = useMemo(\n () =>\n entity\n ? Object.entries(entity.fields).find(([, f]) => f.primary)?.[0] ?? \"id\"\n : \"id\",\n [entity],\n );\n\n // Only fetch ref options in edit mode (display mode uses $refs from the response).\n const { data: response, isLoading: optionsLoading } = useEntityData(mode === \"edit\" ? refEntityCode : undefined, {\n per_page: 200,\n sort: displayField ? `${displayField}:asc` : undefined,\n });\n const options = response?.data ?? [];\n\n // Resolve display value from $refs (list/detail response) or fetched options (edit mode).\n const displayValue = useMemo(() => {\n if (value == null) return \"-\";\n const strVal = String(value);\n\n // Look up from $refs (provided by list or detail response).\n if (refs && refEntityCode) {\n const entityRefs = refs[refEntityCode];\n if (entityRefs) {\n const refRecord = entityRefs[strVal];\n if (refRecord) {\n if (displayField) return resolveDisplay(refRecord[displayField]);\n return strVal;\n }\n }\n }\n\n // Fallback: look up from fetched options (edit mode dropdown data).\n if (displayField && options.length > 0) {\n const match = options.find((r) => String(r[pk]) === strVal);\n if (match) return resolveDisplay(match[displayField] ?? value);\n }\n\n return strVal;\n }, [value, refs, refEntityCode, displayField, options, pk]);\n\n if (mode === \"display\") {\n return <span className=\"text-sm\">{displayValue}</span>;\n }\n\n // While options are loading, show a temporary option with the current display value\n // so the select doesn't jump to \"Select...\".\n const currentId = String(value ?? \"\");\n const hasCurrentInOptions = options.some((r) => String(r[pk]) === currentId);\n\n return (\n <select\n className=\"flex h-9 w-full rounded-md border border-[var(--input)] bg-[var(--background)] px-3 py-1 text-sm text-[var(--foreground)] shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[var(--ring)]\"\n value={currentId}\n onChange={(e) => onChange?.(e.target.value || null)}\n disabled={optionsLoading}\n >\n <option value=\"\">Select...</option>\n {optionsLoading && currentId && (\n <option value={currentId}>{displayValue}</option>\n )}\n {!optionsLoading && currentId && !hasCurrentInOptions && (\n <option value={currentId}>{displayValue}</option>\n )}\n {options.map((r) => {\n const id = String(r[pk]);\n const label = displayField\n ? resolveDisplay(r[displayField] ?? id)\n : id;\n return (\n <option key={id} value={id}>\n {label}\n </option>\n );\n })}\n </select>\n );\n}\n","import { lazy, Suspense } from \"react\";\nimport type { FieldRendererProps } from \"./index\";\n\nconst JsonEditor = lazy(() =>\n import(\"./JsonEditor\").then((m) => ({ default: m.JsonEditor })),\n);\n\nfunction JsonEditorFallback() {\n return (\n <div className=\"h-20 rounded-md border border-[var(--border)] bg-[var(--muted)] animate-pulse\" />\n );\n}\n\nexport function JsonField({ value, mode, onChange }: FieldRendererProps) {\n if (mode === \"display\") {\n if (value == null || (typeof value === \"string\" && !value)) {\n return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n }\n return (\n <Suspense fallback={<JsonEditorFallback />}>\n <JsonEditor value={value} readOnly />\n </Suspense>\n );\n }\n\n return (\n <Suspense fallback={<JsonEditorFallback />}>\n <JsonEditor value={value} onChange={onChange} />\n </Suspense>\n );\n}\n","import { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport type { FieldRendererProps } from \"./index\";\n\ntype LangMap = Record<string, string>;\n\nfunction parseLangMap(value: unknown): LangMap {\n if (value == null) return {};\n if (typeof value === \"object\" && !Array.isArray(value)) {\n return value as LangMap;\n }\n if (typeof value === \"string\") {\n return { en: value };\n }\n return {};\n}\n\nexport function MultilangField({\n value,\n mode,\n onChange,\n}: FieldRendererProps) {\n const { data: schema } = useSchema();\n const languages = schema?.languages?.length\n ? schema.languages\n : [{ code: \"en\", name: { en: \"English\" } }];\n const langMap = parseLangMap(value);\n\n if (mode === \"display\") {\n // Show the first available language value.\n const displayVal =\n Object.values(langMap)[0] ?? \"-\";\n return <span className=\"text-sm\">{displayVal}</span>;\n }\n\n const handleLangChange = (lang: string, text: string) => {\n const updated = { ...langMap, [lang]: text };\n // Remove empty language entries.\n for (const k of Object.keys(updated)) {\n if (!updated[k]) delete updated[k];\n }\n onChange?.(Object.keys(updated).length > 0 ? updated : null);\n };\n\n return (\n <div className=\"space-y-2\">\n {languages.map((lang) => (\n <div key={lang.code} className=\"flex items-center gap-2\">\n <Label className=\"w-8 text-xs text-[var(--muted-foreground)] uppercase shrink-0\">\n {lang.code}\n </Label>\n <Input\n value={langMap[lang.code] ?? \"\"}\n onChange={(e) => handleLangChange(lang.code, e.target.value)}\n placeholder={`Value (${lang.code})`}\n />\n </div>\n ))}\n </div>\n );\n}\n","import { Textarea } from \"@/components/ui/textarea\";\nimport { Label } from \"@/components/ui/label\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport type { FieldRendererProps } from \"./index\";\n\ntype LangMap = Record<string, string>;\n\nfunction parseLangMap(value: unknown): LangMap {\n if (value == null) return {};\n if (typeof value === \"object\" && !Array.isArray(value)) {\n return value as LangMap;\n }\n if (typeof value === \"string\") {\n return { en: value };\n }\n return {};\n}\n\nexport function MultilangTextField({\n value,\n mode,\n onChange,\n}: FieldRendererProps) {\n const { data: schema } = useSchema();\n const languages = schema?.languages?.length\n ? schema.languages\n : [{ code: \"en\", name: { en: \"English\" } }];\n const langMap = parseLangMap(value);\n\n if (mode === \"display\") {\n const displayVal = Object.values(langMap)[0] ?? \"-\";\n return <p className=\"text-sm whitespace-pre-wrap\">{displayVal}</p>;\n }\n\n const handleLangChange = (lang: string, text: string) => {\n const updated = { ...langMap, [lang]: text };\n for (const k of Object.keys(updated)) {\n if (!updated[k]) delete updated[k];\n }\n onChange?.(Object.keys(updated).length > 0 ? updated : null);\n };\n\n return (\n <div className=\"space-y-3\">\n {languages.map((lang) => (\n <div key={lang.code} className=\"space-y-1\">\n <Label className=\"text-xs text-[var(--muted-foreground)] uppercase\">\n {lang.code}\n </Label>\n <Textarea\n value={langMap[lang.code] ?? \"\"}\n onChange={(e) => handleLangChange(lang.code, e.target.value)}\n placeholder={`Value (${lang.code})`}\n rows={4}\n className=\"resize-y\"\n />\n </div>\n ))}\n </div>\n );\n}\n","import { useSchema } from \"@/hooks/useSchema\";\nimport { loc } from \"@/types/schema\";\nimport type { StructureDef } from \"@/types/schema\";\nimport type { FieldRendererProps } from \"./index\";\nimport { renderField } from \"./index\";\nimport { JsonField } from \"./JsonField\";\nimport { Label } from \"@/components/ui/label\";\nimport { Button } from \"@/components/ui/button\";\nimport { Plus, Trash2 } from \"lucide-react\";\n\nexport function StructureField(props: FieldRendererProps) {\n const { field, value, mode, onChange } = props;\n const { data: schema } = useSchema();\n\n const structDef = field.structure\n ? schema?.structures?.[field.structure]\n : undefined;\n\n // Fall back to raw JsonField if structure def not found.\n if (!structDef) {\n return <JsonField {...props} />;\n }\n\n if (field.array) {\n return (\n <StructureArrayRenderer\n structDef={structDef}\n value={value}\n mode={mode}\n onChange={onChange}\n />\n );\n }\n\n return (\n <StructureObjectRenderer\n structDef={structDef}\n value={value}\n mode={mode}\n onChange={onChange}\n />\n );\n}\n\nfunction StructureObjectRenderer({\n structDef,\n value,\n mode,\n onChange,\n}: {\n structDef: StructureDef;\n value: unknown;\n mode: \"display\" | \"edit\";\n onChange?: (value: unknown) => void;\n}) {\n const obj = (typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? value\n : {}) as Record<string, unknown>;\n\n const fieldOrder = structDef.field_order?.length\n ? structDef.field_order\n : Object.keys(structDef.fields);\n\n if (mode === \"display\") {\n const hasAnyValue = fieldOrder.some((key) => obj[key] != null && obj[key] !== \"\");\n if (!hasAnyValue) {\n return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n }\n\n return (\n <div className=\"space-y-2 rounded-md border border-[var(--border)] p-3\">\n {fieldOrder.map((key) => {\n const field = structDef.fields[key];\n if (!field) return null;\n const fieldValue = obj[key];\n if (fieldValue == null) return null;\n\n return (\n <div key={key} className=\"flex items-baseline gap-2\">\n <span className=\"text-xs font-medium text-[var(--muted-foreground)] min-w-[100px] shrink-0\">\n {field.display ? loc(field.display.name) : key}\n </span>\n <div className=\"min-w-0 flex-1\">\n {field.type === \"structure\" && field.structure ? (\n <StructureField\n field={field}\n fieldName={key}\n value={fieldValue}\n mode=\"display\"\n />\n ) : (\n renderField({\n field,\n fieldName: key,\n value: fieldValue,\n mode: \"display\",\n })\n )}\n </div>\n </div>\n );\n })}\n </div>\n );\n }\n\n // Edit mode\n const handleFieldChange = (key: string) => (fieldValue: unknown) => {\n onChange?.({ ...obj, [key]: fieldValue });\n };\n\n return (\n <div className=\"space-y-3 rounded-md border border-[var(--border)] p-3\">\n {fieldOrder.map((key) => {\n const field = structDef.fields[key];\n if (!field) return null;\n\n return (\n <div key={key} className=\"space-y-1\">\n <Label className=\"text-xs\">\n {field.display ? loc(field.display.name) : key}\n {field.required && (\n <span className=\"text-[var(--destructive)] ml-0.5\">*</span>\n )}\n </Label>\n {field.type === \"structure\" && field.structure ? (\n <StructureField\n field={field}\n fieldName={key}\n value={obj[key]}\n mode=\"edit\"\n onChange={handleFieldChange(key)}\n />\n ) : (\n renderField({\n field,\n fieldName: key,\n value: obj[key],\n mode: \"edit\",\n onChange: handleFieldChange(key),\n })\n )}\n </div>\n );\n })}\n </div>\n );\n}\n\nfunction StructureArrayRenderer({\n structDef,\n value,\n mode,\n onChange,\n}: {\n structDef: StructureDef;\n value: unknown;\n mode: \"display\" | \"edit\";\n onChange?: (value: unknown) => void;\n}) {\n const items = Array.isArray(value) ? value : [];\n\n if (mode === \"display\") {\n if (items.length === 0) {\n return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n }\n\n return (\n <div className=\"space-y-2\">\n {items.map((item, idx) => (\n <StructureObjectRenderer\n key={idx}\n structDef={structDef}\n value={item}\n mode=\"display\"\n />\n ))}\n </div>\n );\n }\n\n // Edit mode\n const handleItemChange = (idx: number) => (itemValue: unknown) => {\n const next = [...items];\n next[idx] = itemValue;\n onChange?.(next);\n };\n\n const handleAdd = () => {\n onChange?.([...items, {}]);\n };\n\n const handleRemove = (idx: number) => () => {\n const next = items.filter((_, i) => i !== idx);\n onChange?.(next);\n };\n\n return (\n <div className=\"space-y-2\">\n {items.map((item, idx) => (\n <div key={idx} className=\"relative\">\n <StructureObjectRenderer\n structDef={structDef}\n value={item}\n mode=\"edit\"\n onChange={handleItemChange(idx)}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"absolute top-1 right-1 h-6 w-6 p-0 text-[var(--muted-foreground)] hover:text-[var(--destructive)]\"\n onClick={handleRemove(idx)}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1\"\n onClick={handleAdd}\n >\n <Plus className=\"h-3.5 w-3.5\" />\n Add\n </Button>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { Eye, EyeOff } from \"lucide-react\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport type { FieldRendererProps } from \"./index\";\n\n// The sentinel value returned by the server for non-null secret fields.\n// Must match secrets.SecretSentinel in the Go backend.\nconst SECRET_SENTINEL = \"[SET]\";\n\nexport function SecretField({ value, mode, onChange, record }: FieldRendererProps) {\n const [showValue, setShowValue] = useState(false);\n // track user input separately from the underlying record value\n const [inputValue, setInputValue] = useState(\"\");\n\n const isUpdate = record !== undefined;\n const hasExistingValue =\n value === SECRET_SENTINEL || (typeof value === \"string\" && value !== \"\");\n\n if (mode === \"display\") {\n if (hasExistingValue) {\n return (\n <span className=\"text-sm font-mono text-[var(--muted-foreground)]\">\n {SECRET_SENTINEL}\n </span>\n );\n }\n return (\n <span className=\"text-sm text-[var(--muted-foreground)] italic\">Not set</span>\n );\n }\n\n // Edit mode.\n // On Update: leaving blank preserves the DB value ([SET] is sent).\n // On Create: leaving blank writes NULL.\n const handleChange = (v: string) => {\n setInputValue(v);\n if (isUpdate) {\n // Send the typed value; if blank and there was an existing value, send [SET]\n // to signal \"preserve existing\". If blank and no existing value, send \"\".\n if (v === \"\") {\n onChange?.(hasExistingValue ? SECRET_SENTINEL : \"\");\n } else {\n onChange?.(v);\n }\n } else {\n // Create: blank means NULL\n onChange?.(v);\n }\n };\n\n return (\n <div className=\"flex items-center gap-1\">\n <Input\n type={showValue ? \"text\" : \"password\"}\n value={inputValue}\n placeholder={isUpdate ? \"Leave blank to keep existing value\" : \"Enter value\"}\n onChange={(e) => handleChange(e.target.value)}\n className=\"flex-1\"\n autoComplete=\"new-password\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 shrink-0\"\n onClick={() => setShowValue((v) => !v)}\n title={showValue ? \"Hide value\" : \"Show typed value\"}\n >\n {showValue ? (\n <EyeOff className=\"h-4 w-4\" />\n ) : (\n <Eye className=\"h-4 w-4\" />\n )}\n </Button>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { Eye, EyeOff } from \"lucide-react\";\nimport { Input } from \"@/components/ui/input\";\nimport type { FieldRendererProps } from \"./index\";\n\n// The sentinel value returned by the server for non-null password fields.\n// Must match secrets.SecretSentinel in the Go backend.\nconst SECRET_SENTINEL = \"[SET]\";\n\nexport function PasswordField({ value, mode, onChange, record }: FieldRendererProps) {\n // track user input separately from the underlying record value\n const [inputValue, setInputValue] = useState(\"\");\n // show/hide toggle for the eye icon - defaults to masked (type=password).\n const [revealed, setRevealed] = useState(false);\n\n const isUpdate = record !== undefined;\n const hasExistingValue =\n value === SECRET_SENTINEL || (typeof value === \"string\" && value !== \"\");\n\n if (mode === \"display\") {\n if (hasExistingValue) {\n return (\n <span className=\"text-sm font-mono text-[var(--muted-foreground)]\">\n {SECRET_SENTINEL}\n </span>\n );\n }\n return (\n <span className=\"text-sm text-[var(--muted-foreground)] italic\">Not set</span>\n );\n }\n\n // Edit mode.\n // On Update: leaving blank preserves the DB value ([SET] is sent).\n // On Create: leaving blank writes NULL.\n const handleChange = (v: string) => {\n setInputValue(v);\n if (isUpdate) {\n if (v === \"\") {\n onChange?.(hasExistingValue ? SECRET_SENTINEL : \"\");\n } else {\n onChange?.(v);\n }\n } else {\n onChange?.(v);\n }\n };\n\n // Wrapper positions the eye-toggle absolutely inside the input's right edge.\n // The input gets right-padding so the masked text never overlaps the icon.\n return (\n <div className=\"relative\">\n <Input\n type={revealed ? \"text\" : \"password\"}\n value={inputValue}\n placeholder={isUpdate ? \"Leave blank to keep existing value\" : \"Enter password\"}\n onChange={(e) => handleChange(e.target.value)}\n autoComplete=\"new-password\"\n className=\"pr-9\"\n />\n <button\n type=\"button\"\n onClick={() => setRevealed((r) => !r)}\n aria-label={revealed ? \"Hide password\" : \"Show password\"}\n tabIndex={-1}\n className=\"absolute inset-y-0 right-0 flex items-center pr-2 text-[var(--muted-foreground)] hover:text-[var(--foreground)]\"\n >\n {revealed ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\n </button>\n </div>\n );\n}\n","import { useState, type KeyboardEvent } from \"react\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { X, Plus } from \"lucide-react\";\nimport type { FieldRendererProps } from \"./index\";\n\nfunction toStringArray(value: unknown): string[] {\n if (Array.isArray(value)) return value.filter((v) => v != null).map(String);\n return [];\n}\n\nexport function StringArrayField({ value, mode, onChange }: FieldRendererProps) {\n const items = toStringArray(value);\n const [draft, setDraft] = useState(\"\");\n\n if (mode === \"display\") {\n if (items.length === 0) return <span className=\"text-sm text-muted-foreground\">-</span>;\n return (\n <div className=\"flex flex-wrap gap-1\">\n {items.map((item, i) => (\n <span\n key={i}\n className=\"inline-flex items-center rounded-md bg-secondary px-2 py-0.5 text-xs text-secondary-foreground\"\n >\n {item}\n </span>\n ))}\n </div>\n );\n }\n\n const addItem = () => {\n const trimmed = draft.trim();\n if (!trimmed) return;\n onChange?.([...items, trimmed]);\n setDraft(\"\");\n };\n\n const removeItem = (index: number) => {\n onChange?.(items.filter((_, i) => i !== index));\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n addItem();\n }\n };\n\n return (\n <div className=\"space-y-2\">\n {items.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {items.map((item, i) => (\n <span\n key={i}\n className=\"inline-flex items-center gap-1 rounded-md bg-secondary px-2 py-0.5 text-xs text-secondary-foreground\"\n >\n {item}\n <button\n type=\"button\"\n onClick={() => removeItem(i)}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n </span>\n ))}\n </div>\n )}\n <div className=\"flex gap-1\">\n <Input\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder=\"Add item...\"\n className=\"flex-1\"\n />\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addItem}>\n <Plus className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n}\n","import { useState, type KeyboardEvent } from \"react\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { X, Plus } from \"lucide-react\";\nimport type { FieldRendererProps } from \"./index\";\n\nfunction toIntArray(value: unknown): number[] {\n if (Array.isArray(value)) {\n return value.filter((v) => v != null).map(Number).filter((n) => !isNaN(n));\n }\n return [];\n}\n\nexport function IntArrayField({ value, mode, onChange }: FieldRendererProps) {\n const items = toIntArray(value);\n const [draft, setDraft] = useState(\"\");\n\n if (mode === \"display\") {\n if (items.length === 0) return <span className=\"text-sm text-muted-foreground\">-</span>;\n return (\n <div className=\"flex flex-wrap gap-1\">\n {items.map((item, i) => (\n <span\n key={i}\n className=\"inline-flex items-center rounded-md bg-secondary px-2 py-0.5 text-xs text-secondary-foreground\"\n >\n {item}\n </span>\n ))}\n </div>\n );\n }\n\n const addItem = () => {\n const trimmed = draft.trim();\n if (!trimmed) return;\n const num = Number(trimmed);\n if (isNaN(num) || !Number.isInteger(num)) return;\n onChange?.([...items, num]);\n setDraft(\"\");\n };\n\n const removeItem = (index: number) => {\n onChange?.(items.filter((_, i) => i !== index));\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n addItem();\n }\n };\n\n return (\n <div className=\"space-y-2\">\n {items.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {items.map((item, i) => (\n <span\n key={i}\n className=\"inline-flex items-center gap-1 rounded-md bg-secondary px-2 py-0.5 text-xs text-secondary-foreground\"\n >\n {item}\n <button\n type=\"button\"\n onClick={() => removeItem(i)}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n </span>\n ))}\n </div>\n )}\n <div className=\"flex gap-1\">\n <Input\n type=\"number\"\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder=\"Add number...\"\n className=\"flex-1\"\n />\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addItem}>\n <Plus className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n}\n","import type { EntityField } from \"@/types/schema\";\nimport { StringField } from \"./StringField\";\nimport { TextField } from \"./TextField\";\nimport { EnumField } from \"./EnumField\";\nimport { EmailField } from \"./EmailField\";\nimport { UrlField } from \"./UrlField\";\nimport { TimestampField } from \"./TimestampField\";\nimport { BoolField } from \"./BoolField\";\nimport { NumberField } from \"./NumberField\";\nimport { RefField } from \"./RefField\";\nimport { JsonField } from \"./JsonField\";\nimport { MultilangField } from \"./MultilangField\";\nimport { MultilangTextField } from \"./MultilangTextField\";\nimport { StructureField } from \"./StructureField\";\nimport { SecretField } from \"./SecretField\";\nimport { PasswordField } from \"./PasswordField\";\nimport { StringArrayField } from \"./StringArrayField\";\nimport { IntArrayField } from \"./IntArrayField\";\n\n// RefsMap is the $refs structure from list/detail API responses.\n// Shape: { entityCode: { recordId: { field: value, ... } } }\nexport type RefsMap = Record<string, Record<string, Record<string, unknown>>>;\n\nexport interface FieldRendererProps {\n field: EntityField;\n fieldName: string;\n value: unknown;\n mode: \"display\" | \"edit\";\n onChange?: (value: unknown) => void;\n record?: Record<string, unknown>;\n refs?: RefsMap;\n}\n\ntype FieldRenderer = React.ComponentType<FieldRendererProps>;\n\nconst fieldRenderers: Record<string, FieldRenderer> = {\n string: StringField,\n text: TextField,\n enum: EnumField,\n email: EmailField,\n url: UrlField,\n phone: StringField,\n timestamp: TimestampField,\n date: TimestampField,\n time: TimestampField,\n bool: BoolField,\n int: NumberField,\n float: NumberField,\n decimal: NumberField,\n uuid: StringField,\n ref: RefField,\n json: JsonField,\n tags: StringField,\n string_array: StringArrayField,\n int_array: IntArrayField,\n multilang: MultilangField,\n multilang_text: MultilangTextField,\n structure: StructureField,\n secret: SecretField,\n password: PasswordField,\n};\n\nexport function renderField(props: FieldRendererProps): React.ReactNode {\n // type: json + structure: \"code\" → use StructureField instead of JsonField\n if (props.field.type === \"json\" && props.field.structure) {\n return <StructureField {...props} />;\n }\n // Widget-first dispatch: if display.widget names a known renderer, use it.\n // Lets a handler param declare widget:\"password\" on a type:\"string\" to\n // render with PasswordField without polluting the backend type system.\n // Falls through to type when widget is absent or unknown.\n const widget = props.field.display?.widget;\n if (widget && fieldRenderers[widget]) {\n const Renderer = fieldRenderers[widget];\n return <Renderer {...props} />;\n }\n const Renderer = fieldRenderers[props.field.type] ?? StringField;\n return <Renderer {...props} />;\n}\n\nexport function getFieldRenderer(type: string): FieldRenderer {\n return fieldRenderers[type] ?? StringField;\n}\n\n// hasFieldRenderer reports whether a given key has a registered renderer.\n// Used by callers that want to validate a widget hint before passing it in.\nexport function hasFieldRenderer(key: string): boolean {\n return key in fieldRenderers;\n}\n","import type { ReactNode } from \"react\";\nimport { DynamicIcon } from \"./DynamicIcon\";\n\ninterface EmptyStateProps {\n icon?: string;\n title: string;\n description?: string;\n action?: ReactNode;\n}\n\nexport function EmptyState({ icon, title, description, action }: EmptyStateProps) {\n return (\n <div className=\"flex flex-col items-center justify-center py-16 text-center\">\n {icon && (\n <div className=\"mb-4 rounded-full bg-[var(--muted)] p-4\">\n <DynamicIcon name={icon} className=\"w-8 h-8 text-[var(--muted-foreground)]\" />\n </div>\n )}\n <h3 className=\"text-lg font-medium text-[var(--foreground)]\">{title}</h3>\n {description && (\n <p className=\"mt-1 text-sm text-[var(--muted-foreground)] max-w-sm\">\n {description}\n </p>\n )}\n {action && <div className=\"mt-4\">{action}</div>}\n </div>\n );\n}\n","import { cn } from \"@/lib/utils\";\n\nfunction Skeleton({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn(\n \"animate-pulse rounded-md bg-[var(--muted)]\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Skeleton };\n","import { Skeleton } from \"@/components/ui/skeleton\";\n\nexport function TableSkeleton({ rows = 8, cols = 4 }: { rows?: number; cols?: number }) {\n return (\n <div className=\"space-y-3 p-6\">\n {/* Header */}\n <div className=\"flex gap-4\">\n {Array.from({ length: cols }).map((_, i) => (\n <Skeleton key={i} className=\"h-4 flex-1\" />\n ))}\n </div>\n {/* Rows */}\n {Array.from({ length: rows }).map((_, i) => (\n <div key={i} className=\"flex gap-4\">\n {Array.from({ length: cols }).map((_, j) => (\n <Skeleton key={j} className=\"h-8 flex-1\" />\n ))}\n </div>\n ))}\n </div>\n );\n}\n\nexport function DetailSkeleton() {\n return (\n <div className=\"space-y-6 p-6\">\n <Skeleton className=\"h-8 w-48\" />\n <div className=\"space-y-4\">\n {Array.from({ length: 4 }).map((_, i) => (\n <div key={i} className=\"space-y-2\">\n <Skeleton className=\"h-4 w-24\" />\n <Skeleton className=\"h-9 w-full max-w-md\" />\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\";\nimport { cn } from \"@/lib/utils\";\nimport { buttonVariants } from \"@/components/ui/button\";\n\nconst AlertDialog = AlertDialogPrimitive.Root;\nconst AlertDialogTrigger = AlertDialogPrimitive.Trigger;\nconst AlertDialogPortal = AlertDialogPrimitive.Portal;\n\nconst AlertDialogOverlay = React.forwardRef<\n React.ComponentRef<typeof AlertDialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Overlay\n className={cn(\n \"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n ref={ref}\n />\n));\nAlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;\n\nconst AlertDialogContent = React.forwardRef<\n React.ComponentRef<typeof AlertDialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>\n>(({ className, ...props }, ref) => (\n <AlertDialogPortal>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Content\n ref={ref}\n className={cn(\n \"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-[var(--background)] p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg\",\n className,\n )}\n {...props}\n />\n </AlertDialogPortal>\n));\nAlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;\n\nfunction AlertDialogHeader({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn(\n \"flex flex-col space-y-2 text-center sm:text-left\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogFooter({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n className,\n )}\n {...props}\n />\n );\n}\n\nconst AlertDialogTitle = React.forwardRef<\n React.ComponentRef<typeof AlertDialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Title\n ref={ref}\n className={cn(\"text-lg font-semibold\", className)}\n {...props}\n />\n));\nAlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;\n\nconst AlertDialogDescription = React.forwardRef<\n React.ComponentRef<typeof AlertDialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Description\n ref={ref}\n className={cn(\"text-sm text-[var(--muted-foreground)]\", className)}\n {...props}\n />\n));\nAlertDialogDescription.displayName =\n AlertDialogPrimitive.Description.displayName;\n\nconst AlertDialogAction = React.forwardRef<\n React.ComponentRef<typeof AlertDialogPrimitive.Action>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Action\n ref={ref}\n className={cn(buttonVariants(), className)}\n {...props}\n />\n));\nAlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;\n\nconst AlertDialogCancel = React.forwardRef<\n React.ComponentRef<typeof AlertDialogPrimitive.Cancel>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Cancel\n ref={ref}\n className={cn(\n buttonVariants({ variant: \"outline\" }),\n \"mt-2 sm:mt-0\",\n className,\n )}\n {...props}\n />\n));\nAlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;\n\nexport {\n AlertDialog,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogTrigger,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogAction,\n AlertDialogCancel,\n};\n","import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from \"@/components/ui/alert-dialog\";\n\ninterface ConfirmDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: string;\n description: string;\n confirmLabel?: string;\n onConfirm: () => void;\n destructive?: boolean;\n}\n\nexport function ConfirmDialog({\n open,\n onOpenChange,\n title,\n description,\n confirmLabel = \"Confirm\",\n onConfirm,\n destructive = false,\n}: ConfirmDialogProps) {\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{title}</AlertDialogTitle>\n <AlertDialogDescription>{description}</AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={onConfirm}\n className={destructive ? \"bg-[var(--destructive)] text-[var(--destructive-foreground)] hover:bg-[var(--destructive)]/90\" : \"\"}\n >\n {confirmLabel}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n","import * as React from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { X } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\nconst Dialog = DialogPrimitive.Root;\nconst DialogTrigger = DialogPrimitive.Trigger;\nconst DialogPortal = DialogPrimitive.Portal;\nconst DialogClose = DialogPrimitive.Close;\n\nconst DialogOverlay = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n \"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n />\n));\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;\n\nconst DialogContent = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n className={cn(\n \"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-[var(--background)] p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg\",\n className,\n )}\n {...props}\n >\n {children}\n <DialogPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-[var(--background)] transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-[var(--ring)] focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-[var(--accent)] data-[state=open]:text-[var(--muted-foreground)]\">\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPortal>\n));\nDialogContent.displayName = DialogPrimitive.Content.displayName;\n\nfunction DialogHeader({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn(\n \"flex flex-col space-y-1.5 text-center sm:text-left\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogFooter({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n className,\n )}\n {...props}\n />\n );\n}\n\nconst DialogTitle = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n className={cn(\n \"text-lg font-semibold leading-none tracking-tight\",\n className,\n )}\n {...props}\n />\n));\nDialogTitle.displayName = DialogPrimitive.Title.displayName;\n\nconst DialogDescription = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n className={cn(\"text-sm text-[var(--muted-foreground)]\", className)}\n {...props}\n />\n));\nDialogDescription.displayName = DialogPrimitive.Description.displayName;\n\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogTrigger,\n DialogClose,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n};\n","import { useState, useCallback, useMemo } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from \"@/components/ui/dialog\";\nimport { Button } from \"@/components/ui/button\";\nimport { Label } from \"@/components/ui/label\";\nimport { renderField } from \"@/components/fields\";\nimport { loc } from \"@/types/schema\";\nimport type { Action, HandlerParam, EntityField } from \"@/types/schema\";\n\ninterface ActionDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n action: Action;\n actionName: string;\n onSubmit: (params: Record<string, unknown>) => void;\n isPending: boolean;\n /**\n * Target record for default-value prefill via the `$row.<field>` template\n * syntax. When a param default is a string literal `$row.foo`, the dialog\n * substitutes `row.foo` at open time. For batch invocations on a list\n * page, pass the first selected row (or omit - callers that invoke the\n * action without a single-row context simply don't get row prefills).\n *\n * The substitution is client-side only. The server ignores template\n * syntax - it only sees the concrete value the admin submits.\n */\n row?: Record<string, unknown>;\n}\n\n// Regex for the supported prefill syntax: $row.<field>.\n// Matches only bare `$row.foo`, not `$row.foo.bar` (no nesting), not\n// `$user.foo`, not arbitrary expressions. Narrow on purpose - see the plan.\nconst ROW_PREFILL_RE = /^\\$row\\.([a-zA-Z_][a-zA-Z0-9_]*)$/;\n\nfunction resolveParamDefault(\n raw: unknown,\n row: Record<string, unknown> | undefined,\n): unknown {\n if (typeof raw !== \"string\") {\n return raw ?? \"\";\n }\n const match = raw.match(ROW_PREFILL_RE);\n if (!match) {\n return raw;\n }\n const field = match[1];\n if (row && field in row) {\n return row[field] ?? \"\";\n }\n // Template was requested but no row or no such field - fall back to empty.\n // Emits a dev-mode warning; the action dialog must not render \"$row.foo\"\n // literally into a text input.\n if (typeof console !== \"undefined\" && console.warn) {\n console.warn(\n `ActionDialog: prefill template ${raw} could not be resolved; row missing or has no field '${field}'`,\n );\n }\n return \"\";\n}\n\n/**\n * Converts a HandlerParam to an EntityField so we can reuse existing field renderers.\n */\nfunction paramToEntityField(param: HandlerParam): EntityField {\n return {\n type: param.type ?? \"string\",\n required: param.required,\n display: param.display\n ? {\n name: param.display.name ?? {},\n widget: param.display.widget,\n }\n : undefined,\n enum: param.enum,\n values: param.values,\n ref: param.ref ? { entity: param.ref } : undefined,\n };\n}\n\nexport function ActionDialog({\n open,\n onOpenChange,\n action,\n actionName,\n onSubmit,\n isPending,\n row,\n}: ActionDialogProps) {\n const params = action.resolved_params ?? {};\n const paramEntries = useMemo(() => {\n const order = action.resolved_param_order;\n if (order && order.length > 0) {\n return order\n .filter((key) => key in params)\n .map((key) => [key, params[key]] as [string, typeof params[string]]);\n }\n return Object.entries(params);\n }, [params, action.resolved_param_order]);\n\n const buildInitialFormData = useCallback(() => {\n const initial: Record<string, unknown> = {};\n for (const [key, param] of paramEntries) {\n initial[key] = resolveParamDefault(param.default, row);\n }\n return initial;\n }, [paramEntries, row]);\n\n const [formData, setFormData] = useState<Record<string, unknown>>(\n buildInitialFormData,\n );\n\n // Reset form when dialog opens.\n const handleOpenChange = useCallback(\n (isOpen: boolean) => {\n if (isOpen) {\n setFormData(buildInitialFormData());\n }\n onOpenChange(isOpen);\n },\n [onOpenChange, buildInitialFormData],\n );\n\n const handleFieldChange = useCallback((fieldName: string, value: unknown) => {\n setFormData((prev) => ({ ...prev, [fieldName]: value }));\n }, []);\n\n const handleSubmit = useCallback(() => {\n // Basic client-side validation: check required fields.\n for (const [key, param] of paramEntries) {\n if (param.required) {\n const val = formData[key];\n if (val == null || val === \"\") {\n return; // Don't submit if required field is empty.\n }\n }\n }\n onSubmit(formData);\n }, [formData, paramEntries, onSubmit]);\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogContent className=\"max-w-lg\">\n <DialogHeader>\n <DialogTitle>{actionName}</DialogTitle>\n <DialogDescription>Fill in the parameters below to execute this action.</DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 py-2\">\n {paramEntries.map(([key, param]) => {\n const field = paramToEntityField(param);\n const paramName =\n loc(param.display?.name) || key;\n\n return (\n <div key={key} className=\"space-y-1.5\">\n <Label>\n {paramName}\n {param.required && (\n <span className=\"text-[var(--destructive)] ml-0.5\">*</span>\n )}\n </Label>\n {renderField({\n field,\n fieldName: key,\n value: formData[key],\n mode: \"edit\",\n onChange: (v) => handleFieldChange(key, v),\n })}\n {param.display?.description && (\n <p className=\"text-xs text-[var(--muted-foreground)]\">\n {loc(param.display.description)}\n </p>\n )}\n </div>\n );\n })}\n </div>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => onOpenChange(false)} disabled={isPending}>\n Cancel\n </Button>\n <Button onClick={handleSubmit} disabled={isPending}>\n {isPending ? \"Executing...\" : \"Execute\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n","import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from \"@/components/ui/alert-dialog\";\n\ninterface ActionConfirmDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n actionName: string;\n message: string;\n onConfirm: () => void;\n isPending: boolean;\n}\n\nexport function ActionConfirmDialog({\n open,\n onOpenChange,\n actionName,\n message,\n onConfirm,\n isPending,\n}: ActionConfirmDialogProps) {\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{actionName}</AlertDialogTitle>\n <AlertDialogDescription>{message}</AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isPending}>Cancel</AlertDialogCancel>\n <AlertDialogAction onClick={onConfirm} disabled={isPending}>\n {isPending ? \"Executing...\" : \"Confirm\"}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n","import {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from \"@/components/ui/dialog\";\nimport { Button } from \"@/components/ui/button\";\nimport { CopyButton } from \"./CopyButton\";\n\nexport interface DisplayField {\n label: string;\n value: string;\n copyable?: boolean;\n monospace?: boolean;\n}\n\nexport interface ActionDisplayResult {\n title?: string;\n message?: string;\n fields?: DisplayField[];\n}\n\ninterface ActionResultDialogProps {\n open: boolean;\n onClose: () => void;\n display: ActionDisplayResult;\n}\n\n// ActionResultDialog renders the $display result from a handler action.\n// Requires explicit close (no click-outside, no auto-dismiss) for sensitive data.\nexport function ActionResultDialog({ open, onClose, display }: ActionResultDialogProps) {\n return (\n <Dialog open={open} onOpenChange={(isOpen) => { if (!isOpen) onClose(); }}>\n <DialogContent className=\"max-w-lg\" onInteractOutside={(e) => e.preventDefault()} onEscapeKeyDown={(e) => e.preventDefault()}>\n <DialogHeader>\n <DialogTitle>{display.title ?? \"Action Result\"}</DialogTitle>\n {display.message && (\n <DialogDescription>{display.message}</DialogDescription>\n )}\n </DialogHeader>\n\n {display.fields && display.fields.length > 0 && (\n <div className=\"space-y-3 py-2\">\n {display.fields.map((field, i) => (\n <DisplayFieldRow key={i} field={field} />\n ))}\n </div>\n )}\n\n <DialogFooter>\n <Button onClick={onClose}>Close</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction DisplayFieldRow({ field }: { field: DisplayField }) {\n return (\n <div className=\"space-y-1\">\n <div className=\"text-sm font-medium text-[var(--muted-foreground)]\">\n {field.label}\n </div>\n <div className=\"flex items-center gap-2\">\n <div\n className={`flex-1 rounded-md border bg-[var(--muted)] px-3 py-2 text-sm break-all ${\n field.monospace ? \"font-mono\" : \"\"\n }`}\n >\n {field.value}\n </div>\n {field.copyable && <CopyButton value={field.value} />}\n </div>\n </div>\n );\n}\n","import type { Action, ActionCondition, Schema } from \"@/types/schema\";\n\n/**\n * Evaluates action conditions against row data.\n * Returns true if the action is available (all conditions pass).\n * An action with no conditions is always available.\n */\nexport function evaluateConditions(\n conditions: ActionCondition[] | undefined,\n row: Record<string, unknown>,\n): boolean {\n if (!conditions || conditions.length === 0) return true;\n\n for (const cond of conditions) {\n // Status-based conditions.\n if (cond.status && cond.status.length > 0) {\n const rowStatus = row.status;\n if (typeof rowStatus !== \"string\") return false;\n if (!cond.status.includes(rowStatus)) return false;\n }\n // Field-based conditions with operators.\n if (cond.field) {\n if (!evaluateFieldCondition(cond, row)) return false;\n }\n }\n return true;\n}\n\n/**\n * Evaluates a single field-based condition against row data.\n * Supports operators: eq, ne, gt, gte, lt, lte.\n * Defaults to \"eq\" when op is not specified.\n */\nfunction evaluateFieldCondition(\n cond: ActionCondition,\n row: Record<string, unknown>,\n): boolean {\n const fieldVal = row[cond.field!];\n const op = cond.op || \"eq\";\n\n // Boolean truthiness check: {field: \"is_active\", value: true/false}\n if (typeof cond.value === \"boolean\" && op === \"eq\") {\n return isTruthy(fieldVal) === cond.value;\n }\n\n // Numeric comparison when both values are numbers.\n if (typeof fieldVal === \"number\" && typeof cond.value === \"number\") {\n return compareValues(fieldVal, cond.value, op);\n }\n\n // String comparison (coerce to string).\n const fieldStr = fieldVal == null ? \"\" : String(fieldVal);\n const condStr = cond.value == null ? \"\" : String(cond.value);\n return compareValues(fieldStr, condStr, op);\n}\n\nfunction isTruthy(val: unknown): boolean {\n if (val == null) return false;\n if (typeof val === \"boolean\") return val;\n if (typeof val === \"string\") return val !== \"\";\n if (typeof val === \"number\") return val !== 0;\n return true;\n}\n\nfunction compareValues<T extends number | string>(a: T, b: T, op: string): boolean {\n switch (op) {\n case \"eq\": return a === b;\n case \"ne\": return a !== b;\n case \"gt\": return a > b;\n case \"gte\": return a >= b;\n case \"lt\": return a < b;\n case \"lte\": return a <= b;\n default: return false;\n }\n}\n\n/**\n * Returns actions from an entity whose visibility array contains the given\n * placement. Canonical values: detail | list_row | list_toolbar | app_menu |\n * nav_create | command_palette. Schema validator rejects unknown values at\n * load time so we don't need runtime alias handling here.\n */\nexport function getActionsByVisibility(\n actions: Record<string, Action> | undefined,\n visibility: string,\n): Array<{ code: string; action: Action }> {\n if (!actions) return [];\n return Object.entries(actions)\n .filter(([, action]) => action.visibility?.includes(visibility))\n .map(([code, action]) => ({ code, action }));\n}\n\n/**\n * Returns actions bound to a screen. When the screen defines explicit action/row_action\n * codes, only those are returned (resolved from entity.actions first, then global actions).\n * When no screen binding exists, falls back to visibility-based filtering.\n */\nexport function getScreenActions(\n entityActions: Record<string, Action> | undefined,\n screenActionCodes: string[] | undefined,\n fallbackVisibility: string,\n globalActions?: Record<string, Action>,\n): Array<{ code: string; action: Action }> {\n if (!entityActions && !globalActions) return [];\n if (screenActionCodes !== undefined) {\n return screenActionCodes\n .map((code) => {\n const action = entityActions?.[code] ?? globalActions?.[code];\n return action ? { code, action } : null;\n })\n .filter((item): item is { code: string; action: Action } => item !== null);\n }\n return getActionsByVisibility(entityActions, fallbackVisibility);\n}\n\n/**\n * Checks if an action has parameters that need user input.\n */\nexport function actionHasParams(action: Action): boolean {\n const params = action.resolved_params;\n if (!params) return false;\n return Object.keys(params).length > 0;\n}\n\n/**\n * Builds the full dot-qualified action code for API calls.\n */\nexport function fullActionCode(entityCode: string | undefined, actionCode: string): string {\n if (entityCode) return `${entityCode}.${actionCode}`;\n return actionCode;\n}\n\n/**\n * Checks if an action is an association navigation action.\n */\nexport function isAssociationAction(action: Action): boolean {\n return action.type === \"association\" && !!action.association;\n}\n\n/**\n * Finds the list screen route for a given entity code.\n * Returns the screen route and display info, or undefined if no list screen exists.\n */\nexport function findListScreenForEntity(\n schema: Schema | undefined,\n entityCode: string,\n): { route: string; icon: string } | undefined {\n if (!schema) return undefined;\n for (const screen of Object.values(schema.screens)) {\n if (screen.entity === entityCode && screen.type === \"list\") {\n const entity = schema.entities[entityCode];\n return {\n route: screen.route,\n icon: screen.display?.icon || entity?.display?.icon || \"\",\n };\n }\n }\n return undefined;\n}\n","import { useEffect } from \"react\";\n\n// FieldRegion is an imperative handle for a named region of form fields.\n// Regions register themselves on mount and unregister on unmount. ui_steps\n// reference fields as \"{region}.{field}\" (e.g. \"quick_entry.body\").\nexport interface FieldRegion {\n getField: (fieldName: string) => unknown;\n setField: (fieldName: string, value: unknown) => void;\n focusField: (fieldName: string) => void;\n}\n\n// Module-scope registry. Declarion is a single-app SPA; a module-scope map is\n// simpler than threading context through every tree and matches how toast\n// (sonner) is already consumed.\nconst regions = new Map<string, FieldRegion>();\n\nexport function registerFieldRegion(name: string, region: FieldRegion): () => void {\n regions.set(name, region);\n return () => {\n // Only unregister if still the same instance (remount races).\n if (regions.get(name) === region) regions.delete(name);\n };\n}\n\nexport function getFieldRegion(name: string): FieldRegion | undefined {\n return regions.get(name);\n}\n\n// useFieldRegion is a convenience hook for components to register themselves\n// for the lifetime of the mount. The handle MUST be stable or wrapped in useMemo\n// to avoid re-registration on every render.\nexport function useFieldRegion(name: string, region: FieldRegion): void {\n useEffect(() => registerFieldRegion(name, region), [name, region]);\n}\n","import { toast } from \"sonner\";\nimport { getFieldRegion } from \"./field-regions\";\nimport type { UIStep } from \"@/types/schema\";\n\n// UIActionContext is everything a ui_step sequence may read from.\n// row: current record (populated for row_actions). May be undefined for global actions.\nexport interface UIActionContext {\n row?: Record<string, unknown>;\n}\n\n// interpolate replaces `{{path}}` tokens with values from the context.\n// Supported paths:\n// {{row.FIELD}} - read from ctx.row[FIELD]\n// {{field.REGION.FIELD}} - read from a registered field region\n// Unknown tokens are replaced with an empty string. Whitespace around the path\n// inside the braces is ignored.\nexport function interpolate(template: string, ctx: UIActionContext): string {\n return template.replace(/\\{\\{\\s*([^}]+?)\\s*\\}\\}/g, (_match, path: string) => {\n const value = resolvePath(path, ctx);\n return value == null ? \"\" : String(value);\n });\n}\n\nfunction resolvePath(path: string, ctx: UIActionContext): unknown {\n const parts = path.split(\".\");\n if (parts.length < 2) return undefined;\n const [root, ...rest] = parts;\n if (root === \"row\") {\n if (!ctx.row) return undefined;\n return rest.reduce<unknown>((acc, key) => {\n if (acc && typeof acc === \"object\") return (acc as Record<string, unknown>)[key];\n return undefined;\n }, ctx.row);\n }\n if (root === \"field\" && rest.length >= 2) {\n const [regionName, fieldName] = rest;\n const region = getFieldRegion(regionName);\n return region?.getField(fieldName);\n }\n return undefined;\n}\n\n// executeUISteps runs the step sequence in order. Errors surface as toasts and\n// stop the sequence - a partial execution is preferable to silent failure\n// because the steps mutate client state.\nexport async function executeUISteps(steps: UIStep[], ctx: UIActionContext): Promise<void> {\n for (const step of steps) {\n try {\n await runStep(step, ctx);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n toast.error(`ui_step failed: ${msg}`);\n return;\n }\n }\n}\n\nasync function runStep(step: UIStep, ctx: UIActionContext): Promise<void> {\n if (step.copy_to_clipboard != null) {\n const value = interpolate(step.copy_to_clipboard, ctx);\n await navigator.clipboard.writeText(value);\n return;\n }\n if (step.set_field) {\n const { target, value } = step.set_field;\n const { region, field } = splitPath(target);\n const r = getFieldRegion(region);\n if (!r) throw new Error(`region \"${region}\" not registered`);\n r.setField(field, interpolate(value, ctx));\n return;\n }\n if (step.focus_field) {\n const { region, field } = splitPath(step.focus_field);\n const r = getFieldRegion(region);\n if (!r) throw new Error(`region \"${region}\" not registered`);\n r.focusField(field);\n return;\n }\n if (step.show_toast) {\n const msg = interpolate(step.show_toast.message, ctx);\n const kind = step.show_toast.kind ?? \"info\";\n if (kind === \"success\") toast.success(msg);\n else if (kind === \"error\") toast.error(msg);\n else toast(msg);\n return;\n }\n}\n\nfunction splitPath(path: string): { region: string; field: string } {\n const dot = path.indexOf(\".\");\n if (dot <= 0) throw new Error(`invalid path \"${path}\" (expected \"region.field\")`);\n return { region: path.slice(0, dot), field: path.slice(dot + 1) };\n}\n\n// isUIAction returns true when the action is a client-only ui_steps action.\nexport function isUIAction(action: { ui_steps?: UIStep[]; handler?: string }): boolean {\n return !action.handler && !!action.ui_steps && action.ui_steps.length > 0;\n}\n","import { useState, useCallback } from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\nimport { ActionDialog } from \"@/components/shared/ActionDialog\";\nimport { ActionConfirmDialog } from \"@/components/shared/ActionConfirmDialog\";\nimport { ActionResultDialog, type ActionDisplayResult } from \"@/components/shared/ActionResultDialog\";\nimport { useExecuteAction } from \"@/hooks/useMutations\";\nimport { buildActionBody } from \"@/api/data\";\nimport { evaluateConditions, actionHasParams, isAssociationAction, findListScreenForEntity } from \"@/lib/actions\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { useTabNavigate } from \"@/hooks/useTabNavigate\";\nimport { resolveAssociation } from \"@/api/data\";\nimport { toast } from \"sonner\";\nimport { loc } from \"@/types/schema\";\nimport type { Action } from \"@/types/schema\";\nimport { executeUISteps, isUIAction } from \"@/lib/ui-actions\";\n\ninterface ActionButtonProps {\n actionCode: string;\n action: Action;\n entityCode?: string;\n /** Selected object IDs (for single/batch scope). */\n objectIds?: string[];\n /** Current row data for condition evaluation (single row context). */\n row?: Record<string, unknown>;\n /** Variant for the button. */\n variant?: \"default\" | \"outline\" | \"ghost\" | \"secondary\";\n /** Size for the button. */\n size?: \"default\" | \"sm\" | \"icon\";\n /** Called after action execution succeeds. */\n onSuccess?: () => void;\n /** Called when a batch action starts executing. */\n onBatchStart?: (count: number) => void;\n /** Called when a batch action fails. */\n onBatchError?: (count: number) => void;\n /** Called when a batch action partially succeeds (some items failed/skipped). */\n onBatchPartial?: (count: number, successIds?: string[]) => void;\n}\n\nexport function ActionButton({\n actionCode,\n action,\n entityCode,\n objectIds = [],\n row,\n variant = \"outline\",\n size = \"default\",\n onSuccess,\n onBatchStart,\n onBatchError,\n onBatchPartial,\n}: ActionButtonProps) {\n const [showDialog, setShowDialog] = useState(false);\n const [showConfirm, setShowConfirm] = useState(false);\n const [navigating, setNavigating] = useState(false);\n const [displayResult, setDisplayResult] = useState<ActionDisplayResult | null>(null);\n const executeMutation = useExecuteAction(entityCode);\n const { data: schema } = useSchema();\n const tabNavigate = useTabNavigate();\n\n const isAssociation = isAssociationAction(action);\n const hasParams = actionHasParams(action);\n const hasConfirmation = !!action.confirmation && Object.keys(action.confirmation).length > 0;\n\n // Evaluate conditions - if row data is provided and conditions fail, disable button.\n const conditionsMet = row ? evaluateConditions(action.conditions, row) : true;\n\n // Scope-based disable: batch requires >= 1, single requires exactly 1.\n const isBatchEmpty = action.scope === \"batch\" && objectIds.length === 0;\n const isSingleInvalid = action.scope === \"single\" && objectIds.length !== 1;\n\n const handleAssociationNavigate = useCallback(async () => {\n if (!action.association || objectIds.length === 0) return;\n setNavigating(true);\n try {\n const assocCode = entityCode ? `${entityCode}.${action.association}` : action.association;\n const result = await resolveAssociation(assocCode, objectIds);\n const targetScreen = findListScreenForEntity(schema, result.target_entity);\n if (!targetScreen) {\n toast.error(`No list screen found for ${result.target_entity}`);\n return;\n }\n const targetEntity = schema?.entities[result.target_entity];\n const displayName = loc(action.display?.name) || result.target_entity;\n if (result.ids.length === 0) {\n toast.info(`No related ${displayName} found`);\n return;\n }\n // Navigate to target entity's list with ID filter.\n const pk = targetEntity?.field_order?.find((f) => targetEntity.fields[f]?.primary) ?? \"id\";\n const search = new URLSearchParams();\n search.set(`filter_${pk}`, result.ids.join(\",\"));\n tabNavigate(targetScreen.route, {\n title: displayName,\n icon: action.display?.icon || targetScreen.icon,\n search: search.toString(),\n });\n onSuccess?.();\n } catch (err) {\n toast.error(err instanceof Error ? err.message : \"Failed to resolve association\");\n } finally {\n setNavigating(false);\n }\n }, [action, entityCode, objectIds, schema, tabNavigate, onSuccess]);\n\n // Fully-qualified URL code: \"entity.action\" for entity-scoped, bare\n // \"action\" for globals. The entityCode prop is only used for cache\n // invalidation, not URL composition.\n const qualifiedActionCode = action.entity ? `${action.entity}.${actionCode}` : actionCode;\n // Only pass _ids when the scope is non-global.\n const actionIds = objectIds.length > 0 ? objectIds : undefined;\n\n // Shared success handler: checks for $display in the result and opens\n // ActionResultDialog instead of firing the regular onSuccess callback.\n const handleActionSuccess = useCallback(\n (result: { status: string; result?: unknown; success?: string[]; audit_operation_id?: string }, closeDialog?: () => void) => {\n closeDialog?.();\n // Async handler: enqueued for background execution.\n if (result.status === \"accepted\") {\n onSuccess?.();\n return;\n }\n // Check if the handler returned a $display result.\n const display = (result.result as Record<string, unknown> | undefined)?.$display as ActionDisplayResult | undefined;\n if (display) {\n setDisplayResult(display);\n return;\n }\n if (result.status === \"partial\") {\n onBatchPartial?.(objectIds.length, result.success);\n } else {\n onSuccess?.();\n }\n },\n [objectIds.length, onSuccess, onBatchPartial],\n );\n\n const handleClick = useCallback(() => {\n if (isUIAction(action)) {\n // Client-only action: run ui_steps sequentially. No server round-trip.\n void executeUISteps(action.ui_steps!, { row }).then(() => onSuccess?.());\n return;\n }\n if (isAssociation) {\n handleAssociationNavigate();\n return;\n }\n if (hasParams) {\n setShowDialog(true);\n } else if (hasConfirmation) {\n setShowConfirm(true);\n } else {\n // Execute immediately.\n onBatchStart?.(objectIds.length);\n executeMutation.mutate(\n { actionCode: qualifiedActionCode, body: buildActionBody(undefined, actionIds) },\n {\n onSuccess: (result) => handleActionSuccess(result),\n onError: () => onBatchError?.(objectIds.length),\n },\n );\n }\n }, [action, row, isAssociation, hasParams, hasConfirmation, qualifiedActionCode, actionIds, objectIds, executeMutation, handleActionSuccess, handleAssociationNavigate, onBatchStart, onBatchError, onSuccess]);\n\n const handleConfirm = useCallback(() => {\n onBatchStart?.(objectIds.length);\n executeMutation.mutate(\n { actionCode: qualifiedActionCode, body: buildActionBody(undefined, actionIds) },\n {\n onSuccess: (result) => handleActionSuccess(result, () => setShowConfirm(false)),\n onError: () => onBatchError?.(objectIds.length),\n },\n );\n }, [qualifiedActionCode, actionIds, objectIds, executeMutation, handleActionSuccess, onBatchStart, onBatchError]);\n\n const handleDialogSubmit = useCallback(\n (params: Record<string, unknown>) => {\n onBatchStart?.(objectIds.length);\n executeMutation.mutate(\n { actionCode: qualifiedActionCode, body: buildActionBody(params, actionIds) },\n {\n onSuccess: (result) => handleActionSuccess(result, () => setShowDialog(false)),\n onError: () => onBatchError?.(objectIds.length),\n },\n );\n },\n [qualifiedActionCode, actionIds, objectIds, executeMutation, handleActionSuccess, onBatchStart, onBatchError],\n );\n\n const displayName = loc(action.display?.name);\n const icon = action.display?.icon;\n\n return (\n <>\n <Button\n variant={variant}\n size={size}\n onClick={handleClick}\n disabled={!conditionsMet || isBatchEmpty || isSingleInvalid || executeMutation.isPending || navigating}\n title={displayName}\n aria-label={displayName}\n >\n {icon && <DynamicIcon name={icon} className=\"w-4 h-4\" />}\n {size !== \"icon\" && displayName}\n </Button>\n\n {hasParams && (\n <ActionDialog\n open={showDialog}\n onOpenChange={setShowDialog}\n action={action}\n actionName={displayName}\n onSubmit={handleDialogSubmit}\n isPending={executeMutation.isPending}\n row={row}\n />\n )}\n\n {hasConfirmation && (\n <ActionConfirmDialog\n open={showConfirm}\n onOpenChange={setShowConfirm}\n actionName={displayName}\n message={loc(action.confirmation)}\n onConfirm={handleConfirm}\n isPending={executeMutation.isPending}\n />\n )}\n\n {displayResult && (\n <ActionResultDialog\n open={!!displayResult}\n onClose={() => {\n setDisplayResult(null);\n onSuccess?.();\n }}\n display={displayResult}\n />\n )}\n </>\n );\n}\n","import { useState, useCallback } from \"react\";\nimport { DropdownMenuItem } from \"@/components/ui/dropdown-menu\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\nimport { ActionDialog } from \"@/components/shared/ActionDialog\";\nimport { ActionConfirmDialog } from \"@/components/shared/ActionConfirmDialog\";\nimport { useExecuteAction } from \"@/hooks/useMutations\";\nimport { evaluateConditions, actionHasParams, isAssociationAction, findListScreenForEntity } from \"@/lib/actions\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { useTabNavigate } from \"@/hooks/useTabNavigate\";\nimport { resolveAssociation, buildActionBody } from \"@/api/data\";\nimport { toast } from \"sonner\";\nimport { loc } from \"@/types/schema\";\nimport type { Action } from \"@/types/schema\";\n\ninterface RowActionItemProps {\n actionCode: string;\n action: Action;\n entityCode?: string;\n objectId: string;\n row: Record<string, unknown>;\n onSuccess?: () => void;\n}\n\nexport function RowActionItem({\n actionCode,\n action,\n entityCode,\n objectId,\n row,\n onSuccess,\n}: RowActionItemProps) {\n const [showDialog, setShowDialog] = useState(false);\n const [showConfirm, setShowConfirm] = useState(false);\n const executeMutation = useExecuteAction(entityCode);\n const { data: schema } = useSchema();\n const tabNavigate = useTabNavigate();\n\n const isAssociation = isAssociationAction(action);\n const hasParams = actionHasParams(action);\n const hasConfirmation = !!action.confirmation && Object.keys(action.confirmation).length > 0;\n const conditionsMet = evaluateConditions(action.conditions, row);\n\n const displayName = loc(action.display?.name);\n const icon = action.display?.icon;\n\n const handleAssociationNavigate = useCallback(async () => {\n if (!action.association) return;\n try {\n const assocCode = entityCode ? `${entityCode}.${action.association}` : action.association;\n const result = await resolveAssociation(assocCode, [objectId]);\n const targetScreen = findListScreenForEntity(schema, result.target_entity);\n if (!targetScreen) {\n toast.error(`No list screen found for ${result.target_entity}`);\n return;\n }\n const targetEntity = schema?.entities[result.target_entity];\n const name = loc(action.display?.name) || result.target_entity;\n if (result.ids.length === 0) {\n toast.info(`No related ${name} found`);\n return;\n }\n const pk = targetEntity?.field_order?.find((f) => targetEntity.fields[f]?.primary) ?? \"id\";\n const search = new URLSearchParams();\n search.set(`filter_${pk}`, result.ids.join(\",\"));\n tabNavigate(targetScreen.route, {\n title: name,\n icon: action.display?.icon || targetScreen.icon,\n search: search.toString(),\n });\n onSuccess?.();\n } catch (err) {\n toast.error(err instanceof Error ? err.message : \"Failed to resolve association\");\n }\n }, [action, entityCode, objectId, schema, tabNavigate, onSuccess]);\n\n // Use action.entity for the API code (global actions have no entity prefix).\n // The entityCode prop is only used for cache invalidation.\n const qualifiedActionCode = action.entity ? `${action.entity}.${actionCode}` : actionCode;\n\n const handleClick = useCallback(() => {\n if (isAssociation) {\n handleAssociationNavigate();\n return;\n }\n if (hasParams) {\n setShowDialog(true);\n } else if (hasConfirmation) {\n setShowConfirm(true);\n } else {\n executeMutation.mutate(\n { actionCode: qualifiedActionCode, body: buildActionBody(undefined, [objectId]) },\n { onSuccess },\n );\n }\n }, [isAssociation, hasParams, hasConfirmation, qualifiedActionCode, objectId, executeMutation, onSuccess, handleAssociationNavigate]);\n\n const handleConfirm = useCallback(() => {\n executeMutation.mutate(\n { actionCode: qualifiedActionCode, body: buildActionBody(undefined, [objectId]) },\n { onSuccess: () => { setShowConfirm(false); onSuccess?.(); } },\n );\n }, [qualifiedActionCode, objectId, executeMutation, onSuccess]);\n\n const handleDialogSubmit = useCallback(\n (params: Record<string, unknown>) => {\n executeMutation.mutate(\n { actionCode: qualifiedActionCode, body: buildActionBody(params, [objectId]) },\n { onSuccess: () => { setShowDialog(false); onSuccess?.(); } },\n );\n },\n [qualifiedActionCode, objectId, executeMutation, onSuccess],\n );\n\n return (\n <>\n <DropdownMenuItem\n onClick={handleClick}\n disabled={!conditionsMet}\n >\n {icon && <DynamicIcon name={icon} className=\"mr-2 h-4 w-4\" />}\n {displayName}\n </DropdownMenuItem>\n\n {hasParams && (\n <ActionDialog\n open={showDialog}\n onOpenChange={setShowDialog}\n action={action}\n actionName={displayName}\n onSubmit={handleDialogSubmit}\n isPending={executeMutation.isPending}\n />\n )}\n\n {hasConfirmation && (\n <ActionConfirmDialog\n open={showConfirm}\n onOpenChange={setShowConfirm}\n actionName={displayName}\n message={loc(action.confirmation)}\n onConfirm={handleConfirm}\n isPending={executeMutation.isPending}\n />\n )}\n </>\n );\n}\n","import { Loader2, CheckCircle2, XCircle, AlertTriangle } from \"lucide-react\";\n\ninterface BatchActionProgressProps {\n /** Number of items being processed. */\n count: number;\n /** Whether the action is currently executing. */\n isPending: boolean;\n /** Whether the last execution succeeded. */\n isSuccess?: boolean;\n /** Whether the last execution errored. */\n isError?: boolean;\n /** Whether the last execution partially succeeded (some items failed/skipped). */\n isPartial?: boolean;\n}\n\n/**\n * Inline progress indicator for batch actions.\n * Shows selected count, a spinner during execution, and success/error/partial state.\n */\nexport function BatchActionProgress({\n count,\n isPending,\n isSuccess,\n isError,\n isPartial,\n}: BatchActionProgressProps) {\n if (count === 0 && !isPending && !isSuccess && !isError && !isPartial) return null;\n\n return (\n <div className=\"flex items-center gap-2 text-sm text-[var(--muted-foreground)]\">\n {isPending && (\n <>\n <Loader2 className=\"w-4 h-4 animate-spin\" />\n <span>Processing {count} {count === 1 ? \"item\" : \"items\"}...</span>\n </>\n )}\n {!isPending && isSuccess && (\n <>\n <CheckCircle2 className=\"w-4 h-4 text-green-600\" />\n <span>{count} {count === 1 ? \"item\" : \"items\"} processed</span>\n </>\n )}\n {!isPending && isPartial && (\n <>\n <AlertTriangle className=\"w-4 h-4 text-yellow-600\" />\n <span>Partially completed - some items failed or were skipped</span>\n </>\n )}\n {!isPending && isError && (\n <>\n <XCircle className=\"w-4 h-4 text-[var(--destructive)]\" />\n <span>Failed to process {count} {count === 1 ? \"item\" : \"items\"}</span>\n </>\n )}\n {!isPending && !isSuccess && !isError && !isPartial && count > 0 && (\n <span>{count} {count === 1 ? \"item\" : \"items\"} selected</span>\n )}\n </div>\n );\n}\n","/**\n * Filter system types and utilities.\n * One JSON format everywhere: API, URL, DB, frontend state.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** A single node in the recursive filter tree. */\nexport interface FilterNode {\n /** Field condition */\n field?: string;\n op?: FilterOp;\n value?: unknown; // string | number | string[] | number[] | null\n\n /** OR group: each inner array is AND-ed, groups are OR-ed */\n or?: FilterNode[][];\n /** Explicit AND group (rarely needed, top-level is implicit AND) */\n and?: FilterNode[];\n}\n\n/** All supported filter operator codes. */\nexport type FilterOp =\n | \"eq\" | \"not_eq\"\n | \"gt\" | \"gte\" | \"lt\" | \"lte\"\n | \"in\" | \"not_in\" | \"between\"\n | \"contains\" | \"starts_with\"\n | \"is_empty\" | \"is_not_empty\"\n | \"today\" | \"this_week\" | \"this_month\"\n | \"last_7_days\" | \"last_30_days\"\n | \"last_hour\" | \"last_24_hours\";\n\n/** Operators that don't take a value. */\nexport const NO_VALUE_OPS = new Set<FilterOp>([\n \"is_empty\", \"is_not_empty\",\n \"today\", \"this_week\", \"this_month\",\n \"last_7_days\", \"last_30_days\",\n \"last_hour\", \"last_24_hours\",\n]);\n\n/** Human-friendly display names for operators. */\nexport const OP_LABELS: Record<FilterOp, string> = {\n eq: \"is\",\n not_eq: \"is not\",\n gt: \">\",\n gte: \">=\",\n lt: \"<\",\n lte: \"<=\",\n in: \"is any of\",\n not_in: \"is none of\",\n between: \"between\",\n contains: \"contains\",\n starts_with: \"starts with\",\n is_empty: \"is empty\",\n is_not_empty: \"is not empty\",\n today: \"today\",\n this_week: \"this week\",\n this_month: \"this month\",\n last_7_days: \"last 7 days\",\n last_30_days: \"last 30 days\",\n last_hour: \"last hour\",\n last_24_hours: \"last 24 hours\",\n};\n\n// ---------------------------------------------------------------------------\n// URL serialization\n// ---------------------------------------------------------------------------\n\n/** Parse filters from URL search params (JSON `filters` param). */\nexport function parseFiltersFromURL(searchParams: URLSearchParams): FilterNode[] {\n const raw = searchParams.get(\"filters\");\n if (!raw) return [];\n try {\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed) ? parsed : [];\n } catch {\n return [];\n }\n}\n\n/** Write filters to URL search params. */\nexport function setFiltersInURL(\n filters: FilterNode[],\n searchParams: URLSearchParams,\n): void {\n if (filters.length === 0) {\n searchParams.delete(\"filters\");\n } else {\n searchParams.set(\"filters\", JSON.stringify(filters));\n }\n}\n\n// ---------------------------------------------------------------------------\n// API conversion\n// ---------------------------------------------------------------------------\n\n/**\n * Convert FilterNode array to API query params.\n * Uses the JSON `filters` param for the API request.\n */\nexport function filtersToApiParams(filters: FilterNode[]): URLSearchParams {\n const params = new URLSearchParams();\n if (filters.length > 0) {\n params.set(\"filters\", JSON.stringify(filters));\n }\n return params;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Check if the filter tree has any OR groups (needs Level 2 UI). */\nexport function hasOrGroups(nodes: FilterNode[]): boolean {\n return nodes.some((n) => n.or != null);\n}\n\n/** Extract flat field conditions from a FilterNode array (ignoring OR/AND structure). */\nexport function flatFieldConditions(nodes: FilterNode[]): FilterNode[] {\n const result: FilterNode[] = [];\n for (const n of nodes) {\n if (n.field && n.op) {\n result.push(n);\n }\n if (n.or) {\n for (const group of n.or) {\n result.push(...flatFieldConditions(group));\n }\n }\n if (n.and) {\n result.push(...flatFieldConditions(n.and));\n }\n }\n return result;\n}\n\n/** Count active field conditions in the filter tree. */\nexport function countActiveFilters(nodes: FilterNode[]): number {\n return flatFieldConditions(nodes).length;\n}\n\n/** Format a filter node for chip display. */\nexport function formatFilterChip(node: FilterNode): string {\n if (!node.field || !node.op) return \"\";\n const label = OP_LABELS[node.op] || node.op;\n if (NO_VALUE_OPS.has(node.op)) {\n return `${label}`;\n }\n const val = Array.isArray(node.value)\n ? node.value.join(\", \")\n : String(node.value ?? \"\");\n return `${label} ${val}`;\n}\n\n/** Create a simple equality filter node. */\nexport function eqFilter(field: string, value: string): FilterNode {\n return { field, op: \"eq\", value };\n}\n\n/** Remove a filter node by field name, recursing into OR/AND groups. */\nexport function removeFilter(nodes: FilterNode[], field: string): FilterNode[] {\n const result: FilterNode[] = [];\n for (const n of nodes) {\n if (n.field === field) continue;\n if (n.or) {\n const cleaned = n.or\n .map((group) => removeFilter(group, field))\n .filter((group) => group.length > 0);\n if (cleaned.length > 0) result.push({ ...n, or: cleaned });\n continue;\n }\n if (n.and) {\n const cleaned = removeFilter(n.and, field);\n if (cleaned.length > 0) result.push({ ...n, and: cleaned });\n continue;\n }\n result.push(n);\n }\n return result;\n}\n","import { useMemo, useCallback } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\nimport {\n type FilterNode,\n parseFiltersFromURL,\n setFiltersInURL,\n countActiveFilters,\n} from \"@/lib/filters\";\n\n/**\n * useFilters reads/writes the JSON `filters` URL param.\n * URL is the source of truth.\n */\nexport function useFilters() {\n const [searchParams, setSearchParams] = useSearchParams();\n\n const filters = useMemo<FilterNode[]>(\n () => parseFiltersFromURL(searchParams),\n [searchParams],\n );\n\n const activeCount = useMemo(() => countActiveFilters(filters), [filters]);\n\n const setFilters = useCallback(\n (newFilters: FilterNode[]) => {\n const next = new URLSearchParams(searchParams);\n setFiltersInURL(newFilters, next);\n next.set(\"page\", \"1\");\n setSearchParams(next);\n },\n [searchParams, setSearchParams],\n );\n\n const clearFilters = useCallback(() => {\n const next = new URLSearchParams(searchParams);\n next.delete(\"filters\");\n next.set(\"page\", \"1\");\n setSearchParams(next);\n }, [searchParams, setSearchParams]);\n\n return { filters, activeCount, setFilters, clearFilters };\n}\n","import { X } from \"lucide-react\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n type FilterNode,\n hasOrGroups,\n flatFieldConditions,\n OP_LABELS,\n NO_VALUE_OPS,\n} from \"@/lib/filters\";\n\ninterface FilterChipsProps {\n filters: FilterNode[];\n onRemove: (field: string) => void;\n onClearAll: () => void;\n onChipClick?: () => void;\n /** Resolve field name to display label */\n fieldLabel?: (field: string) => string;\n}\n\n/**\n * FilterChips shows active filters as compact chips between toolbar and table.\n * Simple mode: flat chips. OR mode: grouped chips.\n * Zero active filters = hidden (zero height).\n */\nexport function FilterChips({\n filters,\n onRemove,\n onClearAll,\n onChipClick,\n fieldLabel = (f) => f,\n}: FilterChipsProps) {\n if (filters.length === 0) return null;\n\n const isOrMode = hasOrGroups(filters);\n\n if (isOrMode) {\n return (\n <div className=\"flex items-center gap-2 flex-wrap pb-3\">\n {filters.map((node, i) => {\n if (node.or) {\n return (\n <div key={i} className=\"flex items-center gap-1\">\n {node.or.map((group, gi) => (\n <span key={gi} className=\"flex items-center gap-1\">\n {gi > 0 && (\n <span className=\"text-xs text-[var(--muted-foreground)] font-medium px-1\">\n OR\n </span>\n )}\n <Badge\n variant=\"secondary\"\n className=\"cursor-pointer text-xs\"\n onClick={onChipClick}\n >\n {group\n .filter((n) => n.field && n.op)\n .map((n) => `${fieldLabel(n.field!)} ${formatValue(n)}`)\n .join(\" AND \")}\n </Badge>\n </span>\n ))}\n </div>\n );\n }\n if (node.field && node.op) {\n return (\n <FilterChip\n key={`${node.field}-${i}`}\n node={node}\n fieldLabel={fieldLabel}\n onRemove={() => onRemove(node.field!)}\n onClick={onChipClick}\n />\n );\n }\n return null;\n })}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onClearAll}\n className=\"h-6 px-2 text-xs text-[var(--muted-foreground)]\"\n >\n <X className=\"w-3 h-3 mr-1\" />\n Clear all\n </Button>\n </div>\n );\n }\n\n // Simple mode: flat chips.\n const fieldNodes = flatFieldConditions(filters);\n return (\n <div className=\"flex items-center gap-2 flex-wrap pb-3\">\n {fieldNodes.map((node, i) => (\n <FilterChip\n key={`${node.field}-${i}`}\n node={node}\n fieldLabel={fieldLabel}\n onRemove={() => onRemove(node.field!)}\n onClick={onChipClick}\n />\n ))}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onClearAll}\n className=\"h-6 px-2 text-xs text-[var(--muted-foreground)]\"\n >\n <X className=\"w-3 h-3 mr-1\" />\n Clear all\n </Button>\n </div>\n );\n}\n\nfunction FilterChip({\n node,\n fieldLabel,\n onRemove,\n onClick,\n}: {\n node: FilterNode;\n fieldLabel: (f: string) => string;\n onRemove: () => void;\n onClick?: () => void;\n}) {\n return (\n <Badge\n variant=\"secondary\"\n className=\"cursor-pointer text-xs gap-1 pr-1\"\n >\n <span onClick={onClick}>\n {fieldLabel(node.field!)}:{\" \"}\n <span className=\"font-normal\">{formatValue(node)}</span>\n </span>\n <button\n onClick={(e) => {\n e.stopPropagation();\n onRemove();\n }}\n className=\"ml-1 hover:text-[var(--destructive)] rounded-full\"\n >\n <X className=\"w-3 h-3\" />\n </button>\n </Badge>\n );\n}\n\nfunction formatValue(node: FilterNode): string {\n if (!node.op) return \"\";\n const label = OP_LABELS[node.op] || node.op;\n if (NO_VALUE_OPS.has(node.op)) return label;\n const val = Array.isArray(node.value)\n ? node.value.join(\", \")\n : String(node.value ?? \"\");\n return `${label} ${val}`;\n}\n","import { useState, useEffect } from \"react\";\nimport { X, Plus, Filter } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport {\n type FilterNode,\n type FilterOp,\n OP_LABELS,\n NO_VALUE_OPS,\n hasOrGroups,\n} from \"@/lib/filters\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface FilterFieldMeta {\n code: string;\n label: string;\n type: \"string\" | \"enum\" | \"int\" | \"float\" | \"date\" | \"timestamp\" | \"bool\" | \"ref\" | \"status\" | \"property\" | string;\n operators: FilterOp[];\n /** Enum values for enum/status fields. */\n options?: { value: string; label: string; color?: string }[];\n}\n\ninterface FilterDrawerProps {\n open: boolean;\n onClose: () => void;\n filters: FilterNode[];\n onApply: (filters: FilterNode[]) => void;\n availableFields: FilterFieldMeta[];\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * FilterDrawer - right-side panel with progressive disclosure.\n * Level 1: flat AND conditions (default).\n * Level 2: OR groups when \"Add OR group\" is clicked.\n */\nexport function FilterDrawer({\n open,\n onClose,\n filters,\n onApply,\n availableFields,\n}: FilterDrawerProps) {\n // Local state for editing (apply on button click).\n const [draft, setDraft] = useState<FilterNode[]>(filters);\n const [showFieldPicker, setShowFieldPicker] = useState(false);\n\n // Sync draft when filters change externally or drawer opens.\n useEffect(() => {\n if (open) setDraft(filters);\n }, [open, filters]);\n\n if (!open) return null;\n\n const isOrMode = hasOrGroups(draft);\n\n // Active field codes (for hiding in \"Add filter\" picker).\n const activeFields = new Set(\n draft.filter((n) => n.field).map((n) => n.field!),\n );\n\n const addCondition = (fieldCode: string) => {\n const meta = availableFields.find((f) => f.code === fieldCode);\n if (!meta) return;\n const defaultOp = meta.operators[0] || \"eq\";\n setDraft([...draft, { field: fieldCode, op: defaultOp }]);\n setShowFieldPicker(false);\n };\n\n const updateCondition = (index: number, updates: Partial<FilterNode>) => {\n setDraft(draft.map((n, i) => (i === index ? { ...n, ...updates } : n)));\n };\n\n const removeCondition = (index: number) => {\n setDraft(draft.filter((_, i) => i !== index));\n };\n\n const addOrGroup = () => {\n // Convert flat conditions to first OR group, add empty second group.\n const currentConditions = draft.filter((n) => n.field && n.op);\n const otherNodes = draft.filter((n) => !n.field || !n.op);\n setDraft([\n ...otherNodes,\n {\n or: [\n currentConditions.length > 0 ? currentConditions : [],\n [],\n ],\n },\n ]);\n };\n\n const handleApply = () => {\n // Remove empty conditions (without mutating draft in place).\n const cleaned = draft\n .map((n) => {\n if (n.or) {\n const filteredOr = n.or.filter((g) => g.length > 0);\n return filteredOr.length > 0 ? { ...n, or: filteredOr } : null;\n }\n return n.field && n.op ? n : null;\n })\n .filter((n): n is FilterNode => n !== null);\n onApply(cleaned);\n onClose();\n };\n\n const handleReset = () => {\n setDraft([]);\n };\n\n return (\n <div className=\"fixed inset-y-0 right-0 w-[400px] max-w-full bg-[var(--background)] border-l border-[var(--border)] shadow-lg z-50 flex flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-[var(--border)]\">\n <div className=\"flex items-center gap-2\">\n <Filter className=\"w-4 h-4\" />\n <h3 className=\"font-semibold text-sm\">Filters</h3>\n </div>\n <Button variant=\"ghost\" size=\"icon\" onClick={onClose} className=\"h-8 w-8\">\n <X className=\"w-4 h-4\" />\n </Button>\n </div>\n\n {/* Body */}\n <div className=\"flex-1 overflow-auto p-4 space-y-3\">\n {!isOrMode ? (\n // Level 1: flat AND conditions.\n <>\n {draft.map((node, i) => {\n if (!node.field || !node.op) return null;\n const meta = availableFields.find((f) => f.code === node.field);\n if (!meta) return null;\n return (\n <FilterRow\n key={`${node.field}-${i}`}\n node={node}\n meta={meta}\n onUpdate={(updates) => updateCondition(i, updates)}\n onRemove={() => removeCondition(i)}\n />\n );\n })}\n </>\n ) : (\n // Level 2: OR groups.\n draft.map((node, i) => {\n if (!node.or) {\n if (!node.field || !node.op) return null;\n const meta = availableFields.find((f) => f.code === node.field);\n if (!meta) return null;\n return (\n <FilterRow\n key={`${node.field}-${i}`}\n node={node}\n meta={meta}\n onUpdate={(updates) => updateCondition(i, updates)}\n onRemove={() => removeCondition(i)}\n />\n );\n }\n return (\n <OrGroupEditor\n key={`or-${i}`}\n groups={node.or}\n availableFields={availableFields}\n onChange={(newGroups) => {\n const newDraft = [...draft];\n newDraft[i] = { or: newGroups };\n setDraft(newDraft);\n }}\n />\n );\n })\n )}\n\n {/* Add filter / Add OR group buttons */}\n <div className=\"flex items-center gap-2 pt-2\">\n {showFieldPicker ? (\n <FieldPicker\n fields={availableFields}\n activeFields={activeFields}\n onSelect={addCondition}\n onCancel={() => setShowFieldPicker(false)}\n />\n ) : (\n <>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setShowFieldPicker(true)}\n >\n <Plus className=\"w-3 h-3 mr-1\" />\n Add filter\n </Button>\n {!isOrMode && draft.some((n) => n.field) && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={addOrGroup}\n className=\"text-[var(--muted-foreground)]\"\n >\n <Plus className=\"w-3 h-3 mr-1\" />\n Add OR group\n </Button>\n )}\n </>\n )}\n </div>\n </div>\n\n {/* Footer */}\n <div className=\"flex items-center justify-between px-4 py-3 border-t border-[var(--border)]\">\n <Button variant=\"ghost\" size=\"sm\" onClick={handleReset}>\n Reset\n </Button>\n <Button size=\"sm\" onClick={handleApply}>\n Apply\n </Button>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\nfunction FilterRow({\n node,\n meta,\n onUpdate,\n onRemove,\n}: {\n node: FilterNode;\n meta: FilterFieldMeta;\n onUpdate: (updates: Partial<FilterNode>) => void;\n onRemove: () => void;\n}) {\n const isNoValue = NO_VALUE_OPS.has(node.op as FilterOp);\n\n return (\n <div className=\"flex items-center gap-2 group\">\n <span className=\"text-sm font-medium min-w-[100px] truncate\">\n {meta.label}\n </span>\n <Select\n value={node.op}\n onValueChange={(op) => onUpdate({ op: op as FilterOp })}\n >\n <SelectTrigger className=\"w-[130px] h-8 text-xs\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {meta.operators.map((op) => (\n <SelectItem key={op} value={op} className=\"text-xs\">\n {OP_LABELS[op] || op}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n {!isNoValue && (\n meta.options ? (\n <Select\n value={String(node.value ?? \"\")}\n onValueChange={(v) => onUpdate({ value: v })}\n >\n <SelectTrigger className=\"flex-1 h-8 text-xs\">\n <SelectValue placeholder=\"Select...\" />\n </SelectTrigger>\n <SelectContent>\n {meta.options.map((opt) => (\n <SelectItem key={opt.value} value={opt.value} className=\"text-xs\">\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : (\n <Input\n className=\"flex-1 h-8 text-xs\"\n value={String(node.value ?? \"\")}\n onChange={(e) => onUpdate({ value: e.target.value })}\n placeholder=\"Value...\"\n />\n )\n )}\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity\"\n onClick={onRemove}\n >\n <X className=\"w-3 h-3\" />\n </Button>\n </div>\n );\n}\n\nfunction OrGroupEditor({\n groups,\n availableFields,\n onChange,\n}: {\n groups: FilterNode[][];\n availableFields: FilterFieldMeta[];\n onChange: (groups: FilterNode[][]) => void;\n}) {\n return (\n <div className=\"space-y-2\">\n {groups.map((group, gi) => (\n <div key={gi}>\n {gi > 0 && (\n <div className=\"flex items-center gap-2 py-1\">\n <div className=\"flex-1 border-t border-[var(--border)]\" />\n <span className=\"text-xs font-medium text-[var(--muted-foreground)] px-2\">\n OR\n </span>\n <div className=\"flex-1 border-t border-[var(--border)]\" />\n </div>\n )}\n <div className=\"border border-[var(--border)] rounded-md p-3 space-y-2\">\n <div className=\"text-xs text-[var(--muted-foreground)] font-medium mb-2\">\n Match ALL\n </div>\n {group.map((node, ni) => {\n const meta = availableFields.find((f) => f.code === node.field);\n if (!meta) return null;\n return (\n <FilterRow\n key={`${node.field}-${ni}`}\n node={node}\n meta={meta}\n onUpdate={(updates) => {\n const newGroups = groups.map((g, i) =>\n i === gi\n ? g.map((n, j) => (j === ni ? { ...n, ...updates } : n))\n : g,\n );\n onChange(newGroups);\n }}\n onRemove={() => {\n const newGroups = groups.map((g, i) =>\n i === gi ? g.filter((_, j) => j !== ni) : g,\n );\n // Remove empty groups, collapse back to flat if one group.\n onChange(newGroups.filter((g) => g.length > 0));\n }}\n />\n );\n })}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={() => {\n // Placeholder - needs field picker for this group.\n const firstAvailable = availableFields.find(\n (f) => !group.some((n) => n.field === f.code),\n );\n if (firstAvailable) {\n const newGroups = groups.map((g, i) =>\n i === gi\n ? [...g, { field: firstAvailable.code, op: firstAvailable.operators[0] || (\"eq\" as FilterOp) }]\n : g,\n );\n onChange(newGroups);\n }\n }}\n >\n <Plus className=\"w-3 h-3 mr-1\" />\n Add condition\n </Button>\n </div>\n </div>\n ))}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs text-[var(--muted-foreground)]\"\n onClick={() => onChange([...groups, []])}\n >\n <Plus className=\"w-3 h-3 mr-1\" />\n Add OR group\n </Button>\n </div>\n );\n}\n\nfunction FieldPicker({\n fields,\n activeFields,\n onSelect,\n onCancel,\n}: {\n fields: FilterFieldMeta[];\n activeFields: Set<string>;\n onSelect: (code: string) => void;\n onCancel: () => void;\n}) {\n const [search, setSearch] = useState(\"\");\n const filtered = fields.filter(\n (f) =>\n !activeFields.has(f.code) &&\n (search === \"\" || f.label.toLowerCase().includes(search.toLowerCase()) || f.code.toLowerCase().includes(search.toLowerCase())),\n );\n\n return (\n <div className=\"w-full border border-[var(--border)] rounded-md p-2 space-y-2\">\n <Input\n className=\"h-7 text-xs\"\n placeholder=\"Search fields...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n autoFocus\n />\n <div className=\"max-h-[200px] overflow-auto space-y-0.5\">\n {filtered.map((f) => (\n <button\n key={f.code}\n className=\"w-full text-left px-2 py-1 text-xs rounded hover:bg-[var(--muted)] transition-colors\"\n onClick={() => onSelect(f.code)}\n >\n {f.label}\n <span className=\"text-[var(--muted-foreground)] ml-2\">{f.code}</span>\n </button>\n ))}\n {filtered.length === 0 && (\n <div className=\"text-xs text-[var(--muted-foreground)] px-2 py-1\">\n No fields available\n </div>\n )}\n </div>\n <Button variant=\"ghost\" size=\"sm\" className=\"text-xs w-full\" onClick={onCancel}>\n Cancel\n </Button>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { Columns3, Check, RotateCcw } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface ColumnPickerProps {\n availableColumns: string[];\n visibleColumns: string[];\n onToggle: (col: string) => void;\n onReset: () => void;\n onShowAll: () => void;\n /** Resolve column code to display label */\n columnLabel?: (code: string) => string;\n}\n\n/**\n * ColumnPicker - popover-style checklist for toggling column visibility.\n * Drag-reorder deferred to later phase (using @dnd-kit).\n */\nexport function ColumnPicker({\n availableColumns,\n visibleColumns,\n onToggle,\n onReset,\n onShowAll,\n columnLabel = (c) => c,\n}: ColumnPickerProps) {\n const [open, setOpen] = useState(false);\n\n return (\n <div className=\"relative\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setOpen(!open)}\n className=\"h-8\"\n >\n <Columns3 className=\"w-4 h-4 mr-1.5\" />\n Columns\n </Button>\n\n {open && (\n <>\n {/* Backdrop */}\n <div\n className=\"fixed inset-0 z-40\"\n onClick={() => setOpen(false)}\n />\n {/* Popover */}\n <div className=\"absolute right-0 top-full mt-1 w-[250px] bg-[var(--background)] border border-[var(--border)] rounded-md shadow-lg z-50 py-1\">\n <div className=\"max-h-[300px] overflow-auto\">\n {availableColumns.map((col) => {\n const isVisible = visibleColumns.includes(col);\n return (\n <button\n key={col}\n className=\"flex items-center w-full px-3 py-1.5 text-sm hover:bg-[var(--muted)] transition-colors text-left\"\n onClick={() => onToggle(col)}\n >\n <span className=\"w-5 h-5 mr-2 flex items-center justify-center\">\n {isVisible && <Check className=\"w-4 h-4 text-[var(--primary)]\" />}\n </span>\n <span className={isVisible ? \"\" : \"text-[var(--muted-foreground)]\"}>\n {columnLabel(col)}\n </span>\n </button>\n );\n })}\n </div>\n <div className=\"border-t border-[var(--border)] px-2 py-1.5 flex items-center gap-1\">\n <Button variant=\"ghost\" size=\"sm\" className=\"text-xs h-7 flex-1\" onClick={onReset}>\n <RotateCcw className=\"w-3 h-3 mr-1\" />\n Reset\n </Button>\n <Button variant=\"ghost\" size=\"sm\" className=\"text-xs h-7 flex-1\" onClick={onShowAll}>\n Show all\n </Button>\n </div>\n </div>\n </>\n )}\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { ChevronDown, Star, Globe, Save, Plus } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { loc } from \"@/types/schema\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ViewItem {\n /** UUID for DB views, code string for system views */\n id: string;\n name: Record<string, string>;\n icon?: string;\n source: \"system\" | \"personal\" | \"shared\";\n is_default?: boolean;\n filters?: unknown[];\n columns?: string[];\n sort?: string;\n}\n\ninterface ViewSwitcherProps {\n views: ViewItem[];\n activeViewId: string | null;\n isDirty: boolean;\n onSelect: (view: ViewItem) => void;\n onSave?: () => void;\n onSaveAs?: () => void;\n onSetDefault?: (viewId: string) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * ViewSwitcher - dropdown at the top of list pages.\n * Shows system views (presets) + personal/shared DB views.\n * \"Save View\" button appears when dirty.\n */\nexport function ViewSwitcher({\n views,\n activeViewId,\n isDirty,\n onSelect,\n onSave,\n onSaveAs,\n onSetDefault,\n}: ViewSwitcherProps) {\n const [open, setOpen] = useState(false);\n\n const activeView = views.find((v) => v.id === activeViewId);\n const systemViews = views.filter((v) => v.source === \"system\");\n const personalViews = views.filter((v) => v.source === \"personal\");\n const sharedViews = views.filter((v) => v.source === \"shared\");\n\n const displayName = activeView\n ? loc(activeView.name)\n : \"Default view\";\n\n return (\n <div className=\"flex items-center gap-2\">\n <div className=\"relative\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setOpen(!open)}\n className=\"h-8 gap-1.5\"\n >\n {displayName}\n {isDirty && (\n <span className=\"w-2 h-2 rounded-full bg-[var(--primary)]\" />\n )}\n <ChevronDown className=\"w-3 h-3\" />\n </Button>\n\n {open && (\n <>\n <div\n className=\"fixed inset-0 z-40\"\n onClick={() => setOpen(false)}\n />\n <div className=\"absolute left-0 top-full mt-1 w-[280px] bg-[var(--background)] border border-[var(--border)] rounded-md shadow-lg z-50 py-1\">\n {/* Default (no view) */}\n <ViewOption\n label=\"Default view\"\n isActive={!activeViewId}\n onClick={() => {\n onSelect({ id: \"\", name: { en: \"Default\" }, source: \"system\" });\n setOpen(false);\n }}\n />\n\n {systemViews.length > 0 && (\n <>\n <div className=\"px-3 py-1 text-xs text-[var(--muted-foreground)] font-medium\">\n Presets\n </div>\n {systemViews.map((v) => (\n <ViewOption\n key={v.id}\n label={loc(v.name)}\n isActive={activeViewId === v.id}\n onClick={() => {\n onSelect(v);\n setOpen(false);\n }}\n />\n ))}\n </>\n )}\n\n {personalViews.length > 0 && (\n <>\n <div className=\"px-3 py-1 text-xs text-[var(--muted-foreground)] font-medium\">\n My Views\n </div>\n {personalViews.map((v) => (\n <ViewOption\n key={v.id}\n label={loc(v.name)}\n isActive={activeViewId === v.id}\n isDefault={v.is_default}\n onSetDefault={onSetDefault ? () => onSetDefault(v.id) : undefined}\n onClick={() => {\n onSelect(v);\n setOpen(false);\n }}\n />\n ))}\n </>\n )}\n\n {sharedViews.length > 0 && (\n <>\n <div className=\"px-3 py-1 text-xs text-[var(--muted-foreground)] font-medium\">\n Shared\n </div>\n {sharedViews.map((v) => (\n <ViewOption\n key={v.id}\n label={loc(v.name)}\n isActive={activeViewId === v.id}\n isShared\n onClick={() => {\n onSelect(v);\n setOpen(false);\n }}\n />\n ))}\n </>\n )}\n\n {/* Save As button */}\n {onSaveAs && (\n <>\n <div className=\"border-t border-[var(--border)] mt-1 pt-1\">\n <button\n className=\"flex items-center w-full px-3 py-1.5 text-sm hover:bg-[var(--muted)] transition-colors\"\n onClick={() => {\n onSaveAs();\n setOpen(false);\n }}\n >\n <Plus className=\"w-4 h-4 mr-2 text-[var(--muted-foreground)]\" />\n Save as new view...\n </button>\n </div>\n </>\n )}\n </div>\n </>\n )}\n </div>\n\n {/* Save button (when dirty) */}\n {isDirty && activeViewId && onSave && (\n <Button variant=\"outline\" size=\"sm\" className=\"h-8\" onClick={onSave}>\n <Save className=\"w-3 h-3 mr-1\" />\n Save\n </Button>\n )}\n </div>\n );\n}\n\nfunction ViewOption({\n label,\n isActive,\n isDefault,\n isShared,\n onClick,\n onSetDefault: _onSetDefault,\n}: {\n label: string;\n isActive: boolean;\n isDefault?: boolean;\n isShared?: boolean;\n onClick: () => void;\n onSetDefault?: () => void;\n}) {\n return (\n <button\n className={`flex items-center w-full px-3 py-1.5 text-sm hover:bg-[var(--muted)] transition-colors ${\n isActive ? \"bg-[var(--muted)] font-medium\" : \"\"\n }`}\n onClick={onClick}\n >\n <span className=\"flex-1 text-left truncate\">{label}</span>\n {isDefault && (\n <Star className=\"w-3 h-3 text-[var(--primary)] fill-current\" />\n )}\n {isShared && (\n <Globe className=\"w-3 h-3 text-[var(--muted-foreground)]\" />\n )}\n </button>\n );\n}\n","import { useSchema } from \"./useSchema\";\nimport type { Screen } from \"@/types/schema\";\n\nexport function useScreen(screenCode: string | undefined): Screen | undefined {\n const { data: schema } = useSchema();\n if (!schema || !screenCode) return undefined;\n return schema.screens[screenCode];\n}\n","import { useMemo } from \"react\";\nimport { useEntityData } from \"./useEntityData\";\nimport { useScreen } from \"./useScreen\";\nimport type { ViewItem } from \"@/components/views/ViewSwitcher\";\n\n/**\n * useViews fetches DB views for a screen and merges with system views (presets) from DSL.\n * Returns a unified list with source tagging.\n */\nexport function useViews(screenCode: string, userId?: string) {\n const screen = useScreen(screenCode);\n\n // Fetch DB views for this screen (personal + shared).\n const { data: dbResponse } = useEntityData(\"view\", {\n filters: [\n { field: \"screen_code\", op: \"eq\", value: screenCode },\n // Return own views + shared views. The OR ensures visibility.\n ...(userId ? [{ or: [\n [{ field: \"user_id\", op: \"eq\", value: userId }],\n [{ field: \"is_shared\", op: \"eq\", value: \"true\" }],\n ] }] : []),\n ],\n per_page: 100,\n });\n\n const views = useMemo<ViewItem[]>(() => {\n const items: ViewItem[] = [];\n\n // System views (presets from DSL) - always first.\n if (screen?.views) {\n for (const v of screen.views) {\n items.push({\n id: v.code,\n name: v.name,\n icon: v.icon,\n source: \"system\",\n filters: v.filters as unknown[],\n columns: v.columns,\n sort: v.sort,\n });\n }\n }\n\n // DB views (personal + shared).\n if (dbResponse?.data) {\n for (const row of dbResponse.data) {\n const isOwn = userId && String(row.user_id) === userId;\n items.push({\n id: String(row.id),\n name: typeof row.name === \"object\" && row.name !== null ? row.name as Record<string, string> : { en: String(row.name ?? \"\") },\n icon: row.icon as string | undefined,\n source: isOwn ? \"personal\" : \"shared\",\n is_default: row.is_default === true,\n filters: row.filters as unknown[] | undefined,\n columns: row.columns as string[] | undefined,\n sort: row.sort as string | undefined,\n });\n }\n }\n\n return items;\n }, [screen?.views, dbResponse?.data, userId]);\n\n return views;\n}\n","import { useMemo, useRef, useState, useCallback, useEffect } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\nimport {\n useReactTable,\n getCoreRowModel,\n flexRender,\n type ColumnDef,\n type SortingState,\n type RowSelectionState,\n} from \"@tanstack/react-table\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport {\n ChevronLeft,\n ChevronRight,\n Search,\n Plus,\n MoreHorizontal,\n Pencil,\n Trash2,\n ArrowUpDown,\n ArrowUp,\n ArrowDown,\n Eye,\n EyeOff,\n} from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport { useEntityData } from \"@/hooks/useEntityData\";\nimport { useDeleteEntity } from \"@/hooks/useMutations\";\nimport { useDebounce } from \"@/hooks/useDebounce\";\nimport { renderField } from \"@/components/fields\";\nimport { PageHeader } from \"@/components/shared/PageHeader\";\nimport { EmptyState } from \"@/components/shared/EmptyState\";\nimport { TableSkeleton } from \"@/components/shared/LoadingSkeleton\";\nimport { ConfirmDialog } from \"@/components/shared/ConfirmDialog\";\nimport { ActionButton } from \"@/components/shared/ActionButton\";\nimport { RowActionItem } from \"@/components/shared/RowActionItem\";\nimport { BatchActionProgress } from \"@/components/shared/BatchActionProgress\";\nimport { useTabNavigate } from \"@/hooks/useTabNavigate\";\nimport { useTabStore } from \"@/stores/tabs\";\nimport { cn } from \"@/lib/utils\";\nimport { toast } from \"sonner\";\nimport { getScreenActions, evaluateConditions } from \"@/lib/actions\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { loc, fieldDisplayName, DETAIL_SCREEN_NONE } from \"@/types/schema\";\nimport type { EntityField } from \"@/types/schema\";\nimport type { V2StatusInstance, V2PropertyInstance } from \"@/types/api\";\nimport { useFilters } from \"@/hooks/useFilters\";\nimport { removeFilter } from \"@/lib/filters\";\nimport { FilterChips } from \"@/components/filters/FilterChips\";\nimport { FilterDrawer, type FilterFieldMeta } from \"@/components/filters/FilterDrawer\";\nimport { ColumnPicker } from \"@/components/columns/ColumnPicker\";\nimport { ViewSwitcher } from \"@/components/views/ViewSwitcher\";\nimport { useViews } from \"@/hooks/useViews\";\nimport { Filter } from \"lucide-react\";\n\ninterface SmartListPageProps {\n screenCode: string;\n}\n\ntype RowData = Record<string, unknown>;\n\n/**\n * Resolve the target href for a row click on a list screen per the\n * entity-canonical DSL. `list.detail_screen` is tri-valued:\n *\n * absent -> inherit entity.detail_screen\n * DETAIL_SCREEN_NONE (\"none\") -> explicit opt-out (disabled)\n * any other code -> override with that detail screen\n *\n * Resolution:\n * if list.detail_screen === \"none\" -> null (disabled)\n * elif list.detail_screen is set -> use screens[list.detail_screen]\n * elif entity.detail_screen is set -> use screens[entity.detail_screen]\n * else -> null (disabled)\n *\n * Returns null when no navigation target exists; callers MUST render\n * non-interactive rows in that case (no cursor, no click handler).\n */\nexport function resolveDetailHref(\n list: { detail_screen?: string },\n id: string,\n entity: { detail_screen?: string } | undefined,\n allScreens: Record<string, { route?: string }> | undefined,\n): string | null {\n if (list.detail_screen === DETAIL_SCREEN_NONE) return null;\n const code = list.detail_screen ?? entity?.detail_screen;\n if (!code) return null;\n const target = allScreens?.[code];\n if (!target?.route) return null;\n return target.route.replace(\":id\", encodeURIComponent(id));\n}\n\nexport function SmartListPage({ screenCode }: SmartListPageProps) {\n const tabNavigate = useTabNavigate();\n const [searchParams, setSearchParams] = useSearchParams();\n const { data: schema } = useSchema();\n const [deleteState, setDeleteState] = useState<{ ids: string[]; confirmation?: string } | null>(null);\n\n const [rowSelection, setRowSelection] = useState<RowSelectionState>({});\n const [batchState, setBatchState] = useState<{ isPending: boolean; isSuccess: boolean; isError: boolean; isPartial: boolean; count: number }>({ isPending: false, isSuccess: false, isError: false, isPartial: false, count: 0 });\n const [filterDrawerOpen, setFilterDrawerOpen] = useState(false);\n const { filters: jsonFilters, activeCount: filterCount, setFilters: setJsonFilters, clearFilters } = useFilters();\n const user = useAuthStore((s) => s.user);\n const allViews = useViews(screenCode, user?.id);\n\n const screen = schema?.screens[screenCode];\n const entity = screen?.entity ? schema?.entities[screen.entity] : undefined;\n const entityCode = screen?.entity;\n\n // Actions: use screen-bound actions when defined, otherwise fall back to visibility.\n const globalActions = schema?.actions;\n const toolbarActions = useMemo(\n () => getScreenActions(entity?.actions, screen?.actions, \"list_toolbar\", globalActions),\n [entity?.actions, screen?.actions, globalActions],\n );\n const rowActions = useMemo(\n () => getScreenActions(entity?.actions, screen?.row_actions, \"list_row\", globalActions),\n [entity?.actions, screen?.row_actions, globalActions],\n );\n // When the screen explicitly binds row_actions, it controls the full row menu.\n const hasExplicitRowActions = screen?.row_actions !== undefined;\n // Checkboxes appear iff at least one action declares list_toolbar visibility.\n // Schema declares intent; UI follows. No separate selectable: true setting.\n const hasBatchActions = useMemo(\n () => toolbarActions.some((a) => (a.action.visibility ?? []).includes(\"list_toolbar\")),\n [toolbarActions],\n );\n\n // Soft-delete visibility toggle (admin-only).\n const hasSoftDelete = !!entity?.soft_delete;\n const canViewDeleted = hasSoftDelete && (user?.permissions ?? []).some((p) => p === \"feature:view_deleted\" || p === \"feature:*\" || p === \"*\");\n const includeDeleted = canViewDeleted && searchParams.get(\"include_deleted\") === \"true\";\n\n // Ensure this page is tracked as a tab (preserves current search params).\n const { openTab, updateTabSearch, findTabByPathname } = useTabStore();\n useEffect(() => {\n if (screen?.route && entity) {\n const tabName = loc(screen.display?.name) || loc(entity.display.name_plural);\n const tabIcon = screen.display?.icon || entity.display.icon;\n openTab({\n pathname: screen.route,\n search: searchParams.toString(),\n title: tabName,\n icon: tabIcon,\n closable: true,\n });\n }\n }, [screen?.route, screen?.display?.name?.en, entity?.display.name_plural?.en, screen?.display?.icon, entity?.display.icon]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Sync URL search params back to tab store so switching away and back restores the URL.\n useEffect(() => {\n if (!screen?.route) return;\n const tab = findTabByPathname(screen.route);\n if (tab) {\n updateTabSearch(tab.id, searchParams.toString());\n }\n }, [searchParams, screen?.route]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // URL state\n const page = parseInt(searchParams.get(\"page\") ?? \"1\", 10);\n const searchValue = searchParams.get(\"search\") ?? \"\";\n const sortParam = searchParams.get(\"sort\") ?? screen?.sort_default ?? \"\";\n const debouncedSearch = useDebounce(searchValue, 300);\n\n // Visible columns from URL (or screen defaults).\n const visibleCols = useMemo<string[]>(() => {\n const raw = searchParams.get(\"columns\");\n if (raw) return raw.split(\",\").filter(Boolean);\n return screen?.columns ?? [];\n }, [searchParams, screen?.columns]);\n\n // Detect which expand params are needed based on VISIBLE column prefixes.\n // When any expand is requested, $refs must be explicitly included too\n // (the backend disables auto-refs when expand mode is active).\n const expand = useMemo(() => {\n const e: string[] = [];\n // Check both the screen pool and visible columns for $status/$property.\n const allCols = [...(screen?.columns ?? []), ...visibleCols];\n if (allCols.some((c) => c.startsWith(\"$status.\"))) e.push(\"statuses\");\n if (allCols.some((c) => c.startsWith(\"$property.\"))) e.push(\"properties\");\n if (e.length > 0) e.unshift(\"refs\");\n return e.length > 0 ? e : undefined;\n }, [screen?.columns, visibleCols]);\n\n // Data fetching - prefer JSON filters over legacy format.\n const { data: response, isLoading, isError } = useEntityData(entityCode, {\n page,\n per_page: 50,\n sort: sortParam || undefined,\n search: debouncedSearch || undefined,\n filters: jsonFilters.length > 0 ? jsonFilters : undefined,\n include_deleted: includeDeleted || undefined,\n expand,\n screen: screen?.fixed_filters ? screenCode : undefined,\n });\n\n const deleteMutation = useDeleteEntity(entityCode ?? \"\");\n\n // Parse sort state from URL\n const sorting: SortingState = useMemo(() => {\n if (!sortParam) return [];\n const [field, dir] = sortParam.split(\":\");\n return [{ id: field, desc: dir === \"desc\" }];\n }, [sortParam]);\n\n // Primary key field name.\n const pkField = useMemo(\n () => entity?.field_order?.find((f) => entity.fields[f]?.primary) ?? \"id\",\n [entity],\n );\n\n const refs = response?.$refs;\n // Use a ref so the cell render function always reads the latest $refs\n // without adding it to the useMemo deps (which would re-create columns on every fetch).\n const refsRef = useRef(refs);\n refsRef.current = refs;\n\n // Build columns from visible columns (URL state or screen defaults).\n const columns = useMemo<ColumnDef<RowData>[]>(() => {\n if (visibleCols.length === 0 || !entity) return [];\n\n const cols: ColumnDef<RowData>[] = [];\n\n // Checkbox column for batch selection.\n if (hasBatchActions) {\n cols.push({\n id: \"_select\",\n header: ({ table: tbl }) => (\n <input\n type=\"checkbox\"\n className=\"accent-[var(--primary)]\"\n checked={tbl.getIsAllRowsSelected()}\n onChange={tbl.getToggleAllRowsSelectedHandler()}\n />\n ),\n size: 36,\n cell: ({ row }) => (\n <input\n type=\"checkbox\"\n className=\"accent-[var(--primary)]\"\n checked={row.getIsSelected()}\n onChange={row.getToggleSelectedHandler()}\n />\n ),\n });\n }\n\n // Data columns (use visible columns from URL state, not full screen.columns pool).\n for (const colKey of visibleCols) {\n // Status group column: $status.pipeline\n if (colKey.startsWith(\"$status.\")) {\n const groupCode = colKey.slice(8);\n const group = entity.status_groups?.[groupCode];\n if (!group) continue;\n const statusMap = new Map(group.statuses.map((s) => [s.code, s]));\n cols.push({\n id: colKey,\n header: loc(group.name) || groupCode,\n size: 140,\n cell: ({ row }) => {\n const statuses = (row.original as Record<string, unknown>)[\"$statuses\"] as V2StatusInstance[] | undefined;\n const match = statuses?.find((s) => s.group_code === groupCode);\n if (!match) return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n const def = statusMap.get(match.status_code);\n return (\n <Badge color={def?.color}>{loc(def?.name) || match.status_code}</Badge>\n );\n },\n });\n continue;\n }\n\n // Property column: $property.clickup_task_id\n if (colKey.startsWith(\"$property.\")) {\n const propCode = colKey.slice(10);\n const propDef = entity.properties?.[propCode];\n if (!propDef) continue;\n cols.push({\n id: colKey,\n header: loc(propDef.name) || propCode,\n size: 150,\n enableSorting: false,\n cell: ({ row }) => {\n const props = (row.original as Record<string, unknown>)[\"$properties\"] as V2PropertyInstance[] | undefined;\n const match = props?.find((p) => p.property_code === propCode);\n if (!match || match.value == null) return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n return <span className=\"text-sm\">{String(match.value)}</span>;\n },\n });\n continue;\n }\n\n // Regular field column\n const field = entity.fields[colKey];\n if (!field) continue;\n const displayName = fieldDisplayName(field, colKey, schema?.entities);\n const width = field.display?.width;\n cols.push({\n id: colKey,\n accessorKey: colKey,\n header: displayName,\n size: width ?? 150,\n cell: ({ getValue, row }) =>\n renderField({\n field,\n fieldName: colKey,\n value: getValue(),\n mode: \"display\",\n record: row.original,\n refs: refsRef.current,\n }),\n });\n }\n\n // Actions column (dropdown) - only show when there are items to display.\n const hasDefaultActions = !hasExplicitRowActions && !entity?.readonly;\n if (hasDefaultActions || rowActions.length > 0) {\n cols.push({\n id: \"_actions\",\n header: \"\",\n size: 48,\n cell: ({ row }) => {\n const id = String(row.original[pkField] ?? \"\");\n const editHref = resolveDetailHref(screen!, id, entity, schema?.screens);\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\">\n <MoreHorizontal className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {hasDefaultActions && (\n <>\n {editHref && (\n <DropdownMenuItem\n onClick={() =>\n tabNavigate(editHref, {\n title: loc(entity!.display.name),\n icon: entity!.display.icon,\n search: \"edit=true\",\n })\n }\n >\n <Pencil className=\"mr-2 h-4 w-4\" />\n Edit\n </DropdownMenuItem>\n )}\n <DropdownMenuItem\n onClick={() => setDeleteState({ ids: [id] })}\n className=\"text-[var(--destructive)]\"\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n Delete\n </DropdownMenuItem>\n {rowActions.length > 0 && <DropdownMenuSeparator />}\n </>\n )}\n {rowActions.map(({ code, action }) => {\n if (action.type === \"edit\") {\n const conditionsMet = evaluateConditions(action.conditions, row.original);\n if (!editHref) return null;\n return (\n <DropdownMenuItem\n key={code}\n disabled={!conditionsMet}\n onClick={() =>\n tabNavigate(editHref, {\n title: loc(entity!.display.name),\n icon: entity!.display.icon,\n search: \"edit=true\",\n })\n }\n >\n <Pencil className=\"mr-2 h-4 w-4\" />\n {loc(action.display?.name) || \"Edit\"}\n </DropdownMenuItem>\n );\n }\n if (action.type === \"delete\") {\n const conditionsMet = evaluateConditions(action.conditions, row.original);\n return (\n <DropdownMenuItem\n key={code}\n disabled={!conditionsMet}\n onClick={() => setDeleteState({ ids: [id], confirmation: loc(action.confirmation) || undefined })}\n className=\"text-[var(--destructive)]\"\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n {loc(action.display?.name) || \"Delete\"}\n </DropdownMenuItem>\n );\n }\n return (\n <RowActionItem\n key={code}\n actionCode={code}\n action={action}\n entityCode={entityCode}\n objectId={id}\n row={row.original}\n />\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n },\n });\n }\n\n return cols;\n }, [screen, entity, visibleCols, tabNavigate, hasBatchActions, rowActions, hasExplicitRowActions, entityCode, pkField]);\n\n const data = response?.data ?? [];\n const meta = response?.meta;\n\n const table = useReactTable({\n data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n manualSorting: true,\n manualPagination: true,\n state: { sorting, rowSelection },\n onSortingChange: (updater) => {\n const next = typeof updater === \"function\" ? updater(sorting) : updater;\n const params = new URLSearchParams(searchParams);\n if (next.length === 0) {\n params.delete(\"sort\");\n } else {\n const s = next[0];\n params.set(\"sort\", `${s.id}:${s.desc ? \"desc\" : \"asc\"}`);\n }\n params.set(\"page\", \"1\");\n setSearchParams(params);\n },\n onRowSelectionChange: setRowSelection,\n getRowId: (row) => String(row[pkField] ?? \"\"),\n rowCount: meta?.total ?? 0,\n });\n\n // Selected IDs for batch actions.\n const selectedIds = useMemo(\n () => Object.keys(rowSelection).filter((k) => rowSelection[k]),\n [rowSelection],\n );\n\n // Clear selection after data changes (page, search, sort, or filter change).\n useEffect(() => {\n setRowSelection({});\n }, [page, debouncedSearch, sortParam, jsonFilters]);\n\n // Keyboard shortcuts: / = focus search, f = open filter drawer, Escape = close drawer.\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n // Skip when typing in an input/textarea/select.\n const tag = (e.target as HTMLElement)?.tagName;\n if (tag === \"INPUT\" || tag === \"TEXTAREA\" || tag === \"SELECT\") {\n if (e.key === \"Escape\") {\n (e.target as HTMLElement).blur();\n setFilterDrawerOpen(false);\n }\n return;\n }\n if (e.key === \"/\" && !e.metaKey && !e.ctrlKey) {\n e.preventDefault();\n const input = document.querySelector<HTMLInputElement>('[placeholder*=\"Search\"]');\n input?.focus();\n }\n if (e.key === \"f\" && !e.metaKey && !e.ctrlKey) {\n e.preventDefault();\n setFilterDrawerOpen((prev) => !prev);\n }\n if (e.key === \"Escape\") {\n setFilterDrawerOpen(false);\n }\n };\n document.addEventListener(\"keydown\", handler);\n return () => document.removeEventListener(\"keydown\", handler);\n }, []);\n\n // Auto-clear batch success/error/partial state after a few seconds.\n useEffect(() => {\n if (batchState.isSuccess || batchState.isError || batchState.isPartial) {\n const timer = setTimeout(() => setBatchState({ isPending: false, isSuccess: false, isError: false, isPartial: false, count: 0 }), 3000);\n return () => clearTimeout(timer);\n }\n }, [batchState.isSuccess, batchState.isError, batchState.isPartial]);\n\n // Virtual scroll\n const parentRef = useRef<HTMLDivElement>(null);\n const { rows } = table.getRowModel();\n\n const rowVirtualizer = useVirtualizer({\n count: rows.length,\n getScrollElement: () => parentRef.current,\n estimateSize: () => 48,\n overscan: 10,\n });\n\n // URL state helpers\n const updateSearch = useCallback(\n (value: string) => {\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n if (value) {\n next.set(\"search\", value);\n } else {\n next.delete(\"search\");\n }\n next.set(\"page\", \"1\");\n return next;\n });\n },\n [setSearchParams],\n );\n\n const toggleIncludeDeleted = useCallback(() => {\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n if (next.get(\"include_deleted\")) {\n next.delete(\"include_deleted\");\n } else {\n next.set(\"include_deleted\", \"true\");\n }\n next.set(\"page\", \"1\");\n return next;\n });\n }, [setSearchParams]);\n\n const goToPage = useCallback(\n (p: number) => {\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.set(\"page\", String(p));\n return next;\n });\n },\n [setSearchParams],\n );\n\n const hasRowDetailTarget = useMemo(() => {\n if (!screen || !entity) return false;\n return resolveDetailHref(screen, \"_\", entity, schema?.screens) !== null;\n }, [screen, entity, schema?.screens]);\n\n const handleRowClick = useCallback(\n (row: RowData) => {\n if (!entity || !screen) return;\n const pk = entity.field_order?.find((f) => entity.fields[f]?.primary);\n const id = pk ? String(row[pk] ?? \"\") : \"\";\n if (!id) return;\n const href = resolveDetailHref(screen, id, entity, schema?.screens);\n if (!href) return; // no detail target; row is non-interactive\n // Determine a display title for the tab from the first visible column value.\n const firstCol = screen.columns?.find(\n (c) => !c.startsWith(\"$status.\") && !c.startsWith(\"$property.\"),\n );\n const tabTitle = firstCol\n ? String(row[firstCol] ?? loc(entity.display.name))\n : loc(entity.display.name);\n const icon = screen.display?.icon || entity.display.icon;\n tabNavigate(href, {\n title: tabTitle,\n icon,\n });\n },\n [entity, screen, schema, tabNavigate],\n );\n\n const handleDelete = useCallback(async () => {\n if (!deleteState || deleteState.ids.length === 0) return;\n setDeleteState(null);\n const results = await Promise.allSettled(\n deleteState.ids.map((id) => deleteMutation.mutateAsync(id)),\n );\n const failed = results.filter((r) => r.status === \"rejected\").length;\n if (failed === 0) {\n setRowSelection({});\n } else if (failed < deleteState.ids.length) {\n // Remove successfully deleted IDs from selection to prevent stale retries.\n const succeededIds = new Set(\n deleteState.ids.filter((_, i) => results[i].status === \"fulfilled\"),\n );\n setRowSelection((prev) => {\n const next: RowSelectionState = {};\n for (const [key, val] of Object.entries(prev)) {\n if (!succeededIds.has(key)) next[key] = val;\n }\n return next;\n });\n toast.warning(`${failed} of ${deleteState.ids.length} deletes failed`);\n }\n }, [deleteState, deleteMutation]);\n\n if (!screen || !entity) return null;\n\n const entityDisplay = entity.display;\n // Screen display name takes priority over entity display name (supports multiple screens per entity).\n const screenName = loc(screen.display?.name) || loc(entityDisplay.name);\n const screenIcon = screen.display?.icon || entityDisplay.icon;\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"px-6 pt-6\">\n <PageHeader\n title={screenName}\n actions={\n <>\n {hasBatchActions && (\n <BatchActionProgress\n count={(batchState.isPending || batchState.isSuccess || batchState.isError || batchState.isPartial) ? batchState.count : selectedIds.length}\n isPending={batchState.isPending}\n isSuccess={batchState.isSuccess}\n isError={batchState.isError}\n isPartial={batchState.isPartial}\n />\n )}\n {toolbarActions.map(({ code, action }) => {\n if (action.type === \"create\") {\n if (entity?.readonly) return null;\n return (\n <Button key={code} onClick={() => tabNavigate(`${screen.route}/new`, { title: `New ${loc(entityDisplay.name)}`, icon: screenIcon })}>\n <Plus className=\"w-4 h-4\" />\n {loc(action.display?.name) || `New ${loc(entityDisplay.name)}`}\n </Button>\n );\n }\n if (action.type === \"delete\") {\n // Filter selected IDs by conditions when the action defines them.\n const rawIds = action.scope === \"batch\" || action.scope === \"single\" ? selectedIds : [];\n const ids = action.conditions && action.conditions.length > 0\n ? rawIds.filter((id) => {\n const row = data.find((r) => String(r[pkField] ?? \"\") === id);\n return row ? evaluateConditions(action.conditions, row) : false;\n })\n : rawIds;\n const isDisabled = action.scope === \"batch\" ? ids.length === 0 : action.scope === \"single\" ? rawIds.length !== 1 || ids.length !== 1 : false;\n return (\n <Button\n key={code}\n variant=\"outline\"\n onClick={() => setDeleteState({ ids, confirmation: loc(action.confirmation) || undefined })}\n disabled={isDisabled}\n className=\"text-[var(--destructive)] hover:text-[var(--destructive)]\"\n >\n <Trash2 className=\"w-4 h-4\" />\n {loc(action.display?.name) || \"Delete\"}\n </Button>\n );\n }\n if (action.type === \"edit\") {\n // Edit in toolbar is not a standard pattern; render as no-op.\n return null;\n }\n return (\n <ActionButton\n key={code}\n actionCode={code}\n action={action}\n entityCode={entityCode}\n objectIds={action.scope === \"batch\" || action.scope === \"single\" ? selectedIds : undefined}\n variant=\"outline\"\n onSuccess={() => { setRowSelection({}); setBatchState({ isPending: false, isSuccess: true, isError: false, isPartial: false, count: selectedIds.length }); }}\n onBatchStart={action.scope === \"batch\" ? (count: number) => setBatchState({ isPending: true, isSuccess: false, isError: false, isPartial: false, count }) : undefined}\n onBatchError={action.scope === \"batch\" ? (count: number) => setBatchState({ isPending: false, isSuccess: false, isError: true, isPartial: false, count }) : undefined}\n onBatchPartial={action.scope === \"batch\" ? (count: number, successIds?: string[]) => {\n setBatchState({ isPending: false, isSuccess: false, isError: false, isPartial: true, count });\n if (successIds && successIds.length > 0) {\n const succeeded = new Set(successIds);\n setRowSelection((prev) => {\n const next: RowSelectionState = {};\n for (const [key, val] of Object.entries(prev)) {\n if (!succeeded.has(key)) next[key] = val;\n }\n return next;\n });\n }\n } : undefined}\n />\n );\n })}\n {screen.actions === undefined && !entity?.readonly && (\n <Button onClick={() => tabNavigate(`${screen.route}/new`, { title: `New ${loc(entityDisplay.name)}`, icon: screenIcon })}>\n <Plus className=\"w-4 h-4\" />\n New {loc(entityDisplay.name)}\n </Button>\n )}\n </>\n }\n />\n\n {/* Toolbar: view switcher + search + filter + columns + soft-delete */}\n <div className=\"flex items-center gap-3 mb-2\">\n {/* View switcher */}\n <ViewSwitcher\n views={allViews}\n activeViewId={searchParams.get(\"view\")}\n isDirty={false}\n onSelect={(view) => {\n if (!view.id) {\n // Default view - clear all view params.\n const next = new URLSearchParams();\n if (searchParams.get(\"search\")) next.set(\"search\", searchParams.get(\"search\")!);\n setSearchParams(next);\n return;\n }\n const next = new URLSearchParams(searchParams);\n next.set(\"view\", view.id);\n if (view.filters && Array.isArray(view.filters) && view.filters.length > 0) {\n next.set(\"filters\", JSON.stringify(view.filters));\n }\n if (view.columns && view.columns.length > 0) {\n next.set(\"columns\", view.columns.join(\",\"));\n }\n if (view.sort) {\n next.set(\"sort\", view.sort);\n }\n next.set(\"page\", \"1\");\n setSearchParams(next);\n }}\n />\n\n <div className=\"relative flex-1 max-w-sm\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--muted-foreground)]\" />\n <Input\n placeholder={`Search ${screenName.toLowerCase()}...`}\n value={searchValue}\n onChange={(e) => updateSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n\n <Button\n variant={filterCount > 0 ? \"secondary\" : \"outline\"}\n size=\"sm\"\n onClick={() => setFilterDrawerOpen(true)}\n className=\"h-8\"\n >\n <Filter className=\"w-4 h-4 mr-1.5\" />\n Filters\n {filterCount > 0 && (\n <Badge variant=\"secondary\" className=\"ml-1.5 h-5 min-w-[20px] px-1 text-xs\">\n {filterCount}\n </Badge>\n )}\n </Button>\n\n <ColumnPicker\n availableColumns={screen.columns ?? []}\n visibleColumns={visibleCols}\n onToggle={(col) => {\n const next = new URLSearchParams(searchParams);\n const current = visibleCols.includes(col)\n ? visibleCols.filter((c) => c !== col)\n : [...visibleCols, col];\n if (current.length === 0) return; // keep at least 1\n next.set(\"columns\", current.join(\",\"));\n setSearchParams(next);\n }}\n onReset={() => {\n const next = new URLSearchParams(searchParams);\n next.delete(\"columns\");\n setSearchParams(next);\n }}\n onShowAll={() => {\n const next = new URLSearchParams(searchParams);\n next.set(\"columns\", (screen.columns ?? []).join(\",\"));\n setSearchParams(next);\n }}\n columnLabel={(c) => {\n if (c.startsWith(\"$status.\")) {\n const gc = c.slice(8);\n const g = entity.status_groups?.[gc];\n return g ? (loc(g.name) || gc) : c;\n }\n if (c.startsWith(\"$property.\")) {\n const pc = c.slice(10);\n const p = entity.properties?.[pc];\n return p ? (loc(p.name) || pc) : c;\n }\n const f = entity.fields[c];\n return f ? fieldDisplayName(f, c, schema?.entities) : c;\n }}\n />\n\n {canViewDeleted && (\n <Button\n variant={includeDeleted ? \"secondary\" : \"outline\"}\n size=\"sm\"\n onClick={toggleIncludeDeleted}\n className=\"ml-auto\"\n >\n {includeDeleted ? <EyeOff className=\"w-4 h-4 mr-1.5\" /> : <Eye className=\"w-4 h-4 mr-1.5\" />}\n {includeDeleted ? \"Hide deleted\" : \"Show deleted\"}\n </Button>\n )}\n </div>\n\n {/* Filter chips (collapsed filter summary) */}\n <FilterChips\n filters={jsonFilters}\n onRemove={(field) => setJsonFilters(removeFilter(jsonFilters, field))}\n onClearAll={clearFilters}\n onChipClick={() => setFilterDrawerOpen(true)}\n fieldLabel={(f) => {\n if (f.startsWith(\"$status.\")) {\n const groupCode = f.slice(8);\n const group = entity.status_groups?.[groupCode];\n return group ? (loc(group.name) || groupCode) : f;\n }\n if (f.startsWith(\"$property.\")) {\n const propCode = f.slice(10);\n const prop = entity.properties?.[propCode];\n return prop ? (loc(prop.name) || propCode) : f;\n }\n const field = entity.fields[f];\n return field ? fieldDisplayName(field, f, schema?.entities) : f;\n }}\n />\n </div>\n\n {/* Table */}\n {isLoading ? (\n <TableSkeleton cols={screen.columns?.length ?? 4} />\n ) : isError ? (\n <div className=\"px-6\">\n <EmptyState\n icon=\"alert-circle\"\n title=\"Failed to load data\"\n description=\"Something went wrong. Please try again.\"\n />\n </div>\n ) : data.length === 0 ? (\n <div className=\"px-6\">\n <EmptyState\n icon={screenIcon}\n title={debouncedSearch || filterCount > 0 ? \"No results found\" : `No ${screenName.toLowerCase()} yet`}\n description={\n debouncedSearch || filterCount > 0\n ? \"Try adjusting your search or filters\"\n : `Create your first ${loc(entityDisplay.name).toLowerCase()} to get started`\n }\n action={\n !debouncedSearch && filterCount === 0 && !entity?.readonly ? (\n <Button onClick={() => tabNavigate(`${screen.route}/new`, { title: `New ${loc(entityDisplay.name)}`, icon: screenIcon })}>\n <Plus className=\"w-4 h-4\" />\n New {loc(entityDisplay.name)}\n </Button>\n ) : undefined\n }\n />\n </div>\n ) : (\n <div ref={parentRef} className=\"flex-1 overflow-auto px-6\">\n <table className=\"w-full text-sm\">\n <thead className=\"sticky top-0 bg-[var(--background)] z-10\">\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id} className=\"border-b\">\n {headerGroup.headers.map((header) => {\n const canSort = header.id !== \"_actions\";\n const sorted = header.column.getIsSorted();\n\n return (\n <th\n key={header.id}\n className=\"h-10 px-3 text-left align-middle font-medium text-[var(--muted-foreground)]\"\n style={{ width: header.getSize() }}\n >\n {header.isPlaceholder ? null : canSort ? (\n <button\n className=\"inline-flex items-center gap-1 hover:text-[var(--foreground)] transition-colors\"\n onClick={header.column.getToggleSortingHandler()}\n >\n {flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n {sorted === \"asc\" ? (\n <ArrowUp className=\"w-3 h-3\" />\n ) : sorted === \"desc\" ? (\n <ArrowDown className=\"w-3 h-3\" />\n ) : (\n <ArrowUpDown className=\"w-3 h-3 opacity-40\" />\n )}\n </button>\n ) : (\n flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )\n )}\n </th>\n );\n })}\n </tr>\n ))}\n </thead>\n <tbody>\n {rowVirtualizer.getVirtualItems().length > 0 && (\n <tr>\n <td\n style={{ height: rowVirtualizer.getVirtualItems()[0]?.start ?? 0 }}\n colSpan={columns.length}\n />\n </tr>\n )}\n {rowVirtualizer.getVirtualItems().map((virtualRow) => {\n const row = rows[virtualRow.index];\n const isDeleted = hasSoftDelete && row.original[entity!.soft_delete!] != null;\n return (\n <tr\n key={row.id}\n data-index={virtualRow.index}\n ref={(node) => rowVirtualizer.measureElement(node)}\n className={cn(\n \"border-b transition-colors\",\n hasRowDetailTarget && \"hover:bg-[var(--muted)]/50 cursor-pointer\",\n isDeleted && \"opacity-50 italic\",\n )}\n onClick={hasRowDetailTarget ? () => handleRowClick(row.original) : undefined}\n >\n {row.getVisibleCells().map((cell) => (\n <td\n key={cell.id}\n className=\"px-3 py-2.5 align-middle\"\n style={{ width: cell.column.getSize() }}\n onClick={\n cell.column.id === \"_actions\" || cell.column.id === \"_select\"\n ? (e) => e.stopPropagation()\n : undefined\n }\n >\n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n )}\n </td>\n ))}\n </tr>\n );\n })}\n {rowVirtualizer.getVirtualItems().length > 0 && (\n <tr>\n <td\n style={{\n height:\n rowVirtualizer.getTotalSize() -\n (rowVirtualizer.getVirtualItems().at(-1)?.end ?? 0),\n }}\n colSpan={columns.length}\n />\n </tr>\n )}\n </tbody>\n </table>\n </div>\n )}\n\n {/* Pagination */}\n {meta && meta.total_pages > 1 && (\n <div className=\"flex items-center justify-between px-6 py-3 border-t border-[var(--border)]\">\n <span className=\"text-sm text-[var(--muted-foreground)]\">\n {meta.total} {meta.total === 1 ? \"record\" : \"records\"}\n </span>\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => goToPage(page - 1)}\n disabled={page <= 1}\n >\n <ChevronLeft className=\"w-4 h-4\" />\n Prev\n </Button>\n <span className=\"text-sm text-[var(--muted-foreground)]\">\n Page {meta.page} of {meta.total_pages}\n </span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => goToPage(page + 1)}\n disabled={page >= meta.total_pages}\n >\n Next\n <ChevronRight className=\"w-4 h-4\" />\n </Button>\n </div>\n </div>\n )}\n\n {/* Filter drawer */}\n <FilterDrawer\n open={filterDrawerOpen}\n onClose={() => setFilterDrawerOpen(false)}\n filters={jsonFilters}\n onApply={setJsonFilters}\n availableFields={buildFilterFieldMeta(screen, entity, schema?.entities)}\n />\n\n {/* Delete confirmation */}\n <ConfirmDialog\n open={deleteState !== null}\n onOpenChange={(open) => !open && setDeleteState(null)}\n title={`Delete ${loc(entityDisplay.name)}`}\n description={\n deleteState?.confirmation\n ? deleteState.confirmation\n : hasSoftDelete\n ? `Are you sure you want to delete this ${loc(entityDisplay.name).toLowerCase()}? It can be restored later by an admin.`\n : `Are you sure you want to delete this ${loc(entityDisplay.name).toLowerCase()}? This action cannot be undone.`\n }\n confirmLabel=\"Delete\"\n onConfirm={handleDelete}\n destructive\n />\n </div>\n );\n}\n\n/** Build FilterFieldMeta array from screen + entity for the FilterDrawer. */\nfunction buildFilterFieldMeta(\n screen: { filters?: string[] } | undefined,\n entity: { fields: Record<string, EntityField>; status_groups?: Record<string, { name?: Record<string, string>; statuses: { code: string; name?: Record<string, string>; color?: string }[] }>; properties?: Record<string, { name?: Record<string, string>; type?: string }> } | undefined,\n entities?: Record<string, any>,\n): FilterFieldMeta[] {\n if (!screen || !entity) return [];\n const filterFields = screen.filters ?? Object.keys(entity.fields);\n const meta: FilterFieldMeta[] = [];\n\n for (const f of filterFields) {\n if (f.startsWith(\"$status.\")) {\n const groupCode = f.slice(8);\n const group = entity.status_groups?.[groupCode];\n if (!group) continue;\n meta.push({\n code: f,\n label: loc(group.name) || groupCode,\n type: \"status\",\n operators: [\"eq\", \"not_eq\", \"in\", \"not_in\"],\n options: group.statuses.map((s) => ({\n value: s.code,\n label: loc(s.name) || s.code,\n color: s.color,\n })),\n });\n continue;\n }\n if (f.startsWith(\"$property.\")) {\n const propCode = f.slice(10);\n const prop = entity.properties?.[propCode];\n if (!prop) continue;\n meta.push({\n code: f,\n label: loc(prop.name) || propCode,\n type: \"property\",\n operators: [\"eq\", \"not_eq\", \"contains\", \"is_empty\", \"is_not_empty\"],\n });\n continue;\n }\n const field = entity.fields[f];\n if (!field) continue;\n const label = fieldDisplayName(field, f, entities);\n const ops = fieldTypeToOperators(field.type);\n const options = field.values?.map((v) => ({\n value: v.code,\n label: loc(v.name) || v.code,\n color: v.color,\n }));\n meta.push({ code: f, label, type: field.type, operators: ops, options });\n }\n\n return meta;\n}\n\n/** Map field type to available filter operators. */\nfunction fieldTypeToOperators(type: string): import(\"@/lib/filters\").FilterOp[] {\n switch (type) {\n case \"string\": case \"text\": case \"email\": case \"url\": case \"phone\":\n return [\"eq\", \"not_eq\", \"contains\", \"starts_with\", \"is_empty\", \"is_not_empty\"];\n case \"enum\":\n return [\"eq\", \"not_eq\", \"in\", \"not_in\", \"is_empty\", \"is_not_empty\"];\n case \"int\": case \"float\": case \"decimal\":\n return [\"eq\", \"not_eq\", \"gt\", \"gte\", \"lt\", \"lte\", \"between\", \"is_empty\", \"is_not_empty\"];\n case \"date\":\n return [\"eq\", \"not_eq\", \"gt\", \"gte\", \"lt\", \"lte\", \"between\", \"today\", \"this_week\", \"this_month\", \"last_7_days\", \"last_30_days\", \"is_empty\", \"is_not_empty\"];\n case \"timestamp\":\n return [\"eq\", \"not_eq\", \"gt\", \"gte\", \"lt\", \"lte\", \"between\", \"today\", \"this_week\", \"this_month\", \"last_7_days\", \"last_30_days\", \"last_hour\", \"last_24_hours\", \"is_empty\", \"is_not_empty\"];\n case \"bool\":\n return [\"eq\", \"is_empty\"];\n case \"ref\": case \"uuid\":\n return [\"eq\", \"not_eq\", \"is_empty\", \"is_not_empty\"];\n default:\n return [\"eq\", \"not_eq\", \"is_empty\", \"is_not_empty\"];\n }\n}\n\n","/**\n * Format an offset-aware timestamp string (e.g. \"2026-03-27T14:30:00+03:00\")\n * for display WITHOUT browser-local timezone conversion. The server returns\n * timestamps already converted to the target timezone - we display as-is.\n *\n * Falls back to browser-local formatting for bare datetime strings.\n */\nexport function formatOffsetTimestamp(raw: string): string {\n const offsetMatch = raw.match(/([+-]\\d{2}:\\d{2})$/);\n const isUTC = raw.endsWith(\"Z\");\n\n if (offsetMatch || isUTC) {\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n\n let tz: string | undefined;\n if (isUTC) {\n tz = \"UTC\";\n } else if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0);\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n if (minutes === 0) {\n tz = hours === 0 ? \"UTC\" : `Etc/GMT${sign === \"+\" ? \"-\" : \"+\"}${hours}`;\n }\n }\n\n if (tz) {\n try {\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: tz,\n }).format(date);\n } catch {\n // Fall through.\n }\n }\n\n // Non-standard offset (e.g. +05:30): compute local time manually.\n if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0) === \"+\" ? 1 : -1;\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n const offsetMs = sign * (hours * 60 + minutes) * 60 * 1000;\n const localMs = date.getTime() + offsetMs;\n const localDate = new Date(localMs);\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\",\n }).format(localDate);\n }\n }\n\n // Bare datetime or unparseable: fall back to browser-local.\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n }).format(date);\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { getEntity } from \"@/api/data\";\nimport type { PkValues } from \"@/types/schema\";\n\n// useEntityItem fetches a single record by primary key.\n// pkValues can be:\n// - a string (single PK, backward compat)\n// - a PkValues object (composite PK)\n// - undefined (disabled)\nexport function useEntityItem(entity: string | undefined, pkValues: PkValues | string | undefined) {\n // Stable cache key: for string IDs use them directly; for PkValues sort keys\n // so that { a: \"1\", b: \"2\" } and { b: \"2\", a: \"1\" } hit the same cache entry.\n const cacheKey = pkValues === undefined || pkValues === \"new\"\n ? undefined\n : typeof pkValues === \"string\"\n ? pkValues\n : Object.keys(pkValues).sort().map((k) => `${k}=${pkValues[k]}`).join(\"&\");\n\n return useQuery({\n queryKey: [\"entity-item\", entity, cacheKey],\n queryFn: () => getEntity(entity!, pkValues!),\n enabled: !!entity && !!pkValues && pkValues !== \"new\" && cacheKey !== undefined,\n });\n}\n","import { useState, useMemo } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { ExternalLink } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardHeader, CardContent } from \"@/components/ui/card\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\nimport { renderField } from \"@/components/fields\";\nimport { resolveAssociation } from \"@/api/data\";\nimport { listEntities } from \"@/api/data\";\nimport { findListScreenForEntity } from \"@/lib/actions\";\nimport { useTabNavigate } from \"@/hooks/useTabNavigate\";\nimport { cn } from \"@/lib/utils\";\nimport { loc, fieldDisplayName } from \"@/types/schema\";\nimport type { AssociationDef, Schema } from \"@/types/schema\";\n\ninterface AssociationTabsProps {\n entityCode: string;\n recordId: string;\n associations: Record<string, AssociationDef>;\n schema: Schema;\n}\n\nexport function AssociationTabs({\n entityCode,\n recordId,\n associations,\n schema,\n}: AssociationTabsProps) {\n const assocEntries = useMemo(\n () => Object.entries(associations),\n [associations],\n );\n const [activeTab, setActiveTab] = useState(0);\n\n if (assocEntries.length === 0) return null;\n\n const [activeKey, activeAssoc] = assocEntries[activeTab];\n\n return (\n <Card>\n <CardHeader className=\"py-3\">\n <div className=\"flex items-center gap-1 border-b border-[var(--border)]\">\n {assocEntries.map(([key, assoc], idx) => (\n <button\n key={key}\n className={cn(\n \"flex items-center gap-1.5 px-3 py-2 text-sm transition-colors border-b-2 -mb-px\",\n idx === activeTab\n ? \"border-[var(--foreground)] text-[var(--foreground)]\"\n : \"border-transparent text-[var(--muted-foreground)] hover:text-[var(--foreground)]\",\n )}\n onClick={() => setActiveTab(idx)}\n >\n {assoc.display?.icon && (\n <DynamicIcon name={assoc.display.icon} className=\"w-4 h-4\" />\n )}\n {loc(assoc.display?.name) || key}\n </button>\n ))}\n </div>\n </CardHeader>\n <CardContent className=\"pt-0\">\n <AssociationContent\n entityCode={entityCode}\n recordId={recordId}\n assocKey={activeKey}\n association={activeAssoc}\n schema={schema}\n />\n </CardContent>\n </Card>\n );\n}\n\nfunction AssociationContent({\n entityCode,\n recordId,\n assocKey,\n association,\n schema,\n}: {\n entityCode: string;\n recordId: string;\n assocKey: string;\n association: AssociationDef;\n schema: Schema;\n}) {\n const tabNavigate = useTabNavigate();\n const assocCode = `${entityCode}.${assocKey}`;\n\n // Resolve association to get target IDs.\n const { data: assocResult, isLoading: resolving } = useQuery({\n queryKey: [\"association\", assocCode, recordId],\n queryFn: () => resolveAssociation(assocCode, [recordId]),\n });\n\n const targetEntityCode = assocResult?.target_entity ?? association.target;\n const targetEntity = schema.entities[targetEntityCode];\n const targetIds = assocResult?.ids ?? [];\n\n // Fetch target records by IDs.\n const pk = useMemo(\n () => targetEntity?.field_order?.find((f) => targetEntity.fields[f]?.primary) ?? \"id\",\n [targetEntity],\n );\n\n // Limit IDs sent as filter to avoid exceeding URL length limits.\n // The tab only shows 50 rows; \"View all\" links to the full list.\n const filterIds = useMemo(() => targetIds.slice(0, 50), [targetIds]);\n\n const { data: listResponse, isLoading: loadingRecords } = useQuery({\n queryKey: [\"association-records\", targetEntityCode, filterIds],\n queryFn: () =>\n listEntities(targetEntityCode, {\n per_page: 50,\n filters: [{ field: pk, op: \"in\", value: filterIds }],\n }),\n enabled: filterIds.length > 0 && !!targetEntity,\n });\n\n const rows = listResponse?.data ?? [];\n const refs = listResponse?.$refs;\n\n // Determine columns to display - same logic as ChildrenTable.\n const columns = useMemo(() => {\n if (!targetEntity) return [];\n return targetEntity.field_order\n .filter((name) => {\n const f = targetEntity.fields[name];\n return f && !f.primary && !f.auto && f.display?.is_listable !== false;\n })\n .slice(0, 6);\n }, [targetEntity]);\n\n const handleViewAll = () => {\n const targetScreen = findListScreenForEntity(schema, targetEntityCode);\n if (!targetScreen) return;\n const displayName = loc(association.display?.name) || assocKey;\n const search = new URLSearchParams();\n search.set(\"filters\", JSON.stringify([{ field: pk, op: \"in\", value: targetIds }]));\n tabNavigate(targetScreen.route, {\n title: displayName,\n icon: association.display?.icon || targetScreen.icon,\n search: search.toString(),\n });\n };\n\n if (resolving || loadingRecords) {\n return (\n <div className=\"text-sm text-[var(--muted-foreground)] py-4\">\n Loading...\n </div>\n );\n }\n\n if (!targetEntity) {\n return (\n <div className=\"text-sm text-[var(--muted-foreground)] py-4\">\n Entity not found.\n </div>\n );\n }\n\n if (targetIds.length === 0) {\n return (\n <div className=\"text-sm text-[var(--muted-foreground)] py-4\">\n No related records.\n </div>\n );\n }\n\n const targetScreen = findListScreenForEntity(schema, targetEntityCode);\n\n return (\n <div>\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b\">\n {columns.map((col) => (\n <th\n key={col}\n className=\"h-8 px-3 text-left align-middle font-medium text-[var(--muted-foreground)]\"\n >\n {fieldDisplayName(targetEntity.fields[col], col, schema.entities)}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map((row, i) => (\n <tr key={i} className=\"border-b last:border-0\">\n {columns.map((col) => {\n const field = targetEntity.fields[col];\n if (!field) return <td key={col} />;\n return (\n <td key={col} className=\"px-3 py-2 align-middle\">\n {renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"display\",\n record: row,\n refs,\n })}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n {targetScreen && assocResult && assocResult.count > rows.length && (\n <div className=\"pt-3 text-center\">\n <Button variant=\"outline\" size=\"sm\" onClick={handleViewAll}>\n <ExternalLink className=\"w-3 h-3 mr-1.5\" />\n View all {assocResult.count} records\n </Button>\n </div>\n )}\n {targetScreen && rows.length > 0 && assocResult && assocResult.count <= rows.length && (\n <div className=\"pt-3 text-center\">\n <Button variant=\"ghost\" size=\"sm\" onClick={handleViewAll}>\n <ExternalLink className=\"w-3 h-3 mr-1.5\" />\n Open in list view\n </Button>\n </div>\n )}\n </div>\n );\n}\n","import type { SizeValue } from \"@/types/schema\";\n\n// ParsedSizeValue represents a parsed and normalized SizeValue.\nexport type ParsedSizeValue =\n | { kind: \"weight\"; value: number }\n | { kind: \"px\"; value: number }\n | { kind: \"auto\" }\n | { kind: \"fill\" };\n\nconst PX_PATTERN = /^(\\d+)px$/;\n\n// parseSizeValue parses a SizeValue string into a structured representation.\n// Returns null if the value is invalid.\nexport function parseSizeValue(raw: SizeValue | undefined): ParsedSizeValue | null {\n if (raw == null || raw === \"\") return null;\n\n if (raw === \"auto\") return { kind: \"auto\" };\n if (raw === \"fill\") return { kind: \"fill\" };\n\n // Check for \"<n>px\" format.\n const pxMatch = PX_PATTERN.exec(raw);\n if (pxMatch) {\n const n = parseInt(pxMatch[1], 10);\n if (n > 0) return { kind: \"px\", value: n };\n return null; // 0px or negative is invalid\n }\n\n // Check for integer weight (plain number string or actual number coerced to string).\n const intVal = parseInt(raw, 10);\n if (!isNaN(intVal) && String(intVal) === raw && intVal > 0) {\n return { kind: \"weight\", value: intVal };\n }\n\n return null; // unknown token\n}\n\n// isValidSizeValue returns true if the value can be parsed as a valid SizeValue.\nexport function isValidSizeValue(raw: SizeValue | undefined): boolean {\n if (raw == null || raw === \"\") return true; // omitted is valid\n return parseSizeValue(raw) !== null;\n}\n\n// sizeValueToCSS converts a parsed SizeValue into a CSS value string suitable\n// for flex or grid sizing.\n// weight -> flex: <n> (caller should apply to flex container)\n// px -> \"<n>px\"\n// auto -> \"auto\"\n// fill -> \"1fr\" (for grid) or \"flex: 1\" (for flex)\nexport function sizeValueToCSS(parsed: ParsedSizeValue): string {\n switch (parsed.kind) {\n case \"weight\":\n return String(parsed.value);\n case \"px\":\n return parsed.value + \"px\";\n case \"auto\":\n return \"auto\";\n case \"fill\":\n return \"1fr\";\n }\n}\n\n// normalizeSizeValue parses and returns a CSS-ready string, or the default\n// if the input is empty/undefined.\nexport function normalizeSizeValue(\n raw: SizeValue | undefined,\n defaultValue: ParsedSizeValue,\n): ParsedSizeValue {\n if (raw == null || raw === \"\") return defaultValue;\n return parseSizeValue(raw) ?? defaultValue;\n}\n","import { useState, useCallback, useRef, useEffect } from \"react\";\nimport type { RowConfig, SizeValue } from \"@/types/schema\";\nimport { cn } from \"@/lib/utils\";\nimport { parseSizeValue } from \"@/lib/size-value\";\nimport { LayoutNodeRenderer, type LayoutContext } from \"./LayoutRenderer\";\n\ninterface LayoutRowProps {\n config: RowConfig;\n ctx: LayoutContext;\n}\n\n// LayoutRow renders children horizontally with flex layout. Supports:\n// - gap between items\n// - resizable drag handles between items\n// - responsive stacking below a breakpoint\nexport function LayoutRow({ config, ctx }: LayoutRowProps) {\n const { items, gap = 0, resizable = false, stack_below } = config;\n const stackPx = stack_below === \"never\" ? 0 : (stack_below ?? 768);\n const [stacked, setStacked] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Track container width for responsive stacking.\n useEffect(() => {\n if (stackPx === 0) return;\n const el = containerRef.current;\n if (!el) return;\n\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n setStacked(entry.contentRect.width < stackPx);\n }\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, [stackPx]);\n\n // Track flex sizes when resizable.\n const [flexSizes, setFlexSizes] = useState<number[] | null>(null);\n const dragging = useRef<{ index: number; startX: number; startSizes: number[] } | null>(null);\n\n const getInitialSizes = useCallback((): number[] => {\n return items.map((item) => {\n // Width can live at the LayoutNode level OR inside the container config\n // (e.g. `column: { width: 3 }` vs `width: 3` beside `column:`). Check all.\n const w = item.width ?? item.column?.width ?? item.row?.width ?? config.width;\n const parsed = parseSizeValue(w);\n if (parsed && parsed.kind === \"weight\") return parsed.value;\n return 1;\n });\n }, [items, config.width]);\n\n const onDragStart = useCallback(\n (index: number, e: React.MouseEvent) => {\n e.preventDefault();\n const sizes = flexSizes ?? getInitialSizes();\n dragging.current = { index, startX: e.clientX, startSizes: [...sizes] };\n\n const onMove = (ev: MouseEvent) => {\n const d = dragging.current;\n if (!d || !containerRef.current) return;\n const totalWidth = containerRef.current.getBoundingClientRect().width;\n const delta = ev.clientX - d.startX;\n const totalFlex = d.startSizes.reduce((a, b) => a + b, 0);\n const flexDelta = (delta / totalWidth) * totalFlex;\n const newSizes = [...d.startSizes];\n newSizes[d.index] = Math.max(0.1, d.startSizes[d.index] + flexDelta);\n newSizes[d.index + 1] = Math.max(0.1, d.startSizes[d.index + 1] - flexDelta);\n setFlexSizes(newSizes);\n };\n\n const onUp = () => {\n dragging.current = null;\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n };\n\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n },\n [flexSizes, getInitialSizes],\n );\n\n const sizes = flexSizes ?? getInitialSizes();\n\n // Parse height for the row container (enables scrollable children).\n const heightStyle = config.height ? parseHeight(config.height) : undefined;\n\n return (\n <div\n ref={containerRef}\n className={cn(\"flex\", stacked && \"flex-col\")}\n style={{ gap: gap ? `${gap}px` : undefined, ...heightStyle }}\n >\n {items.map((item, i) => (\n <div\n key={i}\n className={cn(\"min-w-0 flex items-stretch\", stacked && \"w-full\")}\n style={stacked ? undefined : itemStyle(item.width ?? item.column?.width ?? item.row?.width ?? config.width, sizes[i], item.min_width, item.max_width)}\n >\n <div className={cn(\"flex-1 min-w-0 flex flex-col\", heightStyle && \"overflow-y-auto overflow-x-hidden\")}>\n <LayoutNodeRenderer node={item} ctx={ctx} />\n </div>\n {resizable && !stacked && i < items.length - 1 && (\n <div\n className=\"w-1 cursor-col-resize hover:bg-[var(--border)] transition-colors shrink-0\"\n onMouseDown={(e) => onDragStart(i, e)}\n />\n )}\n </div>\n ))}\n </div>\n );\n}\n\nfunction itemStyle(\n width: SizeValue | undefined,\n flexValue: number,\n minWidth?: string,\n maxWidth?: string,\n): React.CSSProperties {\n const parsed = parseSizeValue(width);\n let flex: string;\n if (!parsed || parsed.kind === \"weight\") {\n flex = `${flexValue} 1 0%`;\n } else if (parsed.kind === \"px\") {\n flex = `0 0 ${parsed.value}px`;\n } else if (parsed.kind === \"fill\") {\n flex = \"1 1 0%\";\n } else {\n flex = \"0 0 auto\";\n }\n return { flex, minWidth, maxWidth };\n}\n\nfunction parseHeight(height: SizeValue): React.CSSProperties | undefined {\n if (!height) return undefined;\n const parsed = parseSizeValue(height);\n if (parsed?.kind === \"px\") return { height: `${parsed.value}px`, overflow: \"hidden\" };\n // Support raw CSS values like \"calc(100vh - 200px)\" or \"80vh\" passed as strings.\n // parseSizeValue returns null for these, so we handle them directly.\n if (typeof height === \"string\" && (height.includes(\"vh\") || height.includes(\"calc\") || height.includes(\"%\"))) {\n return { height, overflow: \"hidden\" };\n }\n return undefined;\n}\n","import type { ColumnConfig, LayoutNode } from \"@/types/schema\";\nimport { LayoutNodeRenderer, type LayoutContext } from \"./LayoutRenderer\";\n\ninterface LayoutColumnProps {\n config: ColumnConfig;\n node: LayoutNode;\n ctx: LayoutContext;\n}\n\n// LayoutColumn renders children vertically with flex layout and optional gap.\nexport function LayoutColumn({ config, ctx }: LayoutColumnProps) {\n const { items, gap = 12 } = config;\n\n return (\n <div\n className=\"flex flex-col h-full\"\n style={{ gap: gap ? `${gap}px` : undefined }}\n >\n {items.map((item, i) => (\n <LayoutNodeRenderer key={i} node={item} ctx={ctx} />\n ))}\n </div>\n );\n}\n","import { useState } from \"react\";\nimport type { LayoutNode, TabsConfig } from \"@/types/schema\";\nimport { loc } from \"@/types/schema\";\nimport { cn } from \"@/lib/utils\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\nimport { Card, CardHeader, CardContent } from \"@/components/ui/card\";\nimport { LayoutNodeRenderer, type LayoutContext } from \"./LayoutRenderer\";\n\ninterface LayoutTabsProps {\n config: TabsConfig;\n ctx: LayoutContext;\n}\n\n// getTabLabel derives a user-visible label for a tab from its layout node.\nfunction getTabLabel(node: LayoutNode, ctx: LayoutContext): string {\n // Children nodes have a label or derive from the child entity name.\n if (node.children) {\n if (node.label) return loc(node.label);\n const childRelation = ctx.entity.children?.find((c) => c.entity === node.children);\n if (childRelation?.display?.name) return loc(childRelation.display.name);\n const childEntity = ctx.schema.entities[node.children];\n if (childEntity) return loc(childEntity.display.name_plural) || node.children;\n return node.children;\n }\n // Section nodes use the section name.\n if (node.section) {\n return loc(node.section.name);\n }\n return \"Tab\";\n}\n\n// getTabIcon derives an icon name for a tab.\nfunction getTabIcon(node: LayoutNode, ctx: LayoutContext): string | undefined {\n if (node.icon) return node.icon;\n if (node.children) {\n const childRelation = ctx.entity.children?.find((c) => c.entity === node.children);\n if (childRelation?.display?.icon) return childRelation.display.icon;\n const childEntity = ctx.schema.entities[node.children];\n if (childEntity) return childEntity.display.icon;\n }\n return undefined;\n}\n\n// LayoutTabs renders child nodes as switchable tabs, following the existing\n// tab styling pattern from SmartDetailPage.\nexport function LayoutTabs({ config, ctx }: LayoutTabsProps) {\n const { items } = config;\n const [activeTab, setActiveTab] = useState(0);\n\n if (items.length === 0) return null;\n\n return (\n <Card>\n <CardHeader className=\"py-3\">\n <div className=\"flex items-center gap-1 border-b border-[var(--border)]\">\n {items.map((item, idx) => {\n const label = getTabLabel(item, ctx);\n const icon = getTabIcon(item, ctx);\n return (\n <button\n key={idx}\n className={cn(\n \"flex items-center gap-1.5 px-3 py-2 text-sm transition-colors border-b-2 -mb-px\",\n idx === activeTab\n ? \"border-[var(--foreground)] text-[var(--foreground)]\"\n : \"border-transparent text-[var(--muted-foreground)] hover:text-[var(--foreground)]\",\n )}\n onClick={() => setActiveTab(idx)}\n >\n {icon && <DynamicIcon name={icon} className=\"w-4 h-4\" />}\n {label}\n </button>\n );\n })}\n </div>\n </CardHeader>\n <CardContent className=\"pt-0\">\n <LayoutNodeRenderer\n key={activeTab}\n node={items[activeTab]}\n ctx={ctx}\n />\n </CardContent>\n </Card>\n );\n}\n","import { useState } from \"react\";\nimport type { SectionNode } from \"@/types/schema\";\nimport { loc } from \"@/types/schema\";\nimport { cn } from \"@/lib/utils\";\nimport { Card, CardHeader, CardTitle, CardContent } from \"@/components/ui/card\";\nimport { ChevronDown } from \"lucide-react\";\nimport type { LayoutContext } from \"./LayoutRenderer\";\nimport { LayoutRenderer } from \"./LayoutRenderer\";\n\ninterface SectionBlockProps {\n config: SectionNode;\n ctx: LayoutContext;\n}\n\n// SectionBlock renders a collapsible card that wraps nested layout nodes.\nexport function SectionBlock({ config, ctx }: SectionBlockProps) {\n const { name, items, collapsed: defaultCollapsed = false, columns } = config;\n const [collapsed, setCollapsed] = useState(defaultCollapsed);\n const childCtx = columns ? { ...ctx, columns } : ctx;\n\n return (\n <Card>\n <CardHeader\n className=\"cursor-pointer py-4\"\n onClick={() => setCollapsed((c) => !c)}\n >\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">{loc(name)}</CardTitle>\n <ChevronDown\n className={cn(\n \"w-4 h-4 text-[var(--muted-foreground)] transition-transform\",\n collapsed && \"-rotate-90\",\n )}\n />\n </div>\n </CardHeader>\n {!collapsed && (\n <CardContent>\n <LayoutRenderer nodes={items} ctx={childCtx} />\n </CardContent>\n )}\n </Card>\n );\n}\n","import type {\n ChildDisplayMode,\n ChildQuickAdd,\n ChildRelation,\n CardsConfig,\n Entity,\n LayoutNode,\n LocalizedString,\n TimelineConfig,\n} from \"@/types/schema\";\nimport { getPrimaryKeyFields } from \"@/types/schema\";\n\n// ResolvedChildConfig is the fully-resolved rendering configuration for a\n// child entity on a detail screen. All optional fields are filled by the\n// three-layer precedence algorithm or auto-derivation.\nexport interface ResolvedChildConfig {\n entity: string;\n foreign_key: string | string[];\n name: LocalizedString;\n icon: string;\n mode: ChildDisplayMode;\n columns: string[];\n sort: string;\n limit: number;\n timeline?: TimelineConfig;\n cards?: CardsConfig;\n quick_add?: ChildQuickAdd;\n editable: boolean;\n position_field?: string;\n}\n\n// resolveChildConfig applies the three-layer precedence algorithm:\n// 1. Screen node override (highest priority)\n// 2. Entity-level child defaults\n// 3. Auto-derived defaults (lowest priority)\n//\n// Structural fields (entity, foreign_key) come from the relation and are\n// never overridable from screen layout.\nexport function resolveChildConfig(\n relation: ChildRelation,\n childEntity: Entity,\n screenNode?: LayoutNode,\n): ResolvedChildConfig {\n const display = relation.display;\n\n // Start with structural fields from the relation.\n const result: ResolvedChildConfig = {\n entity: relation.entity,\n foreign_key: relation.foreign_key,\n name: resolveField(screenNode?.label, display?.name, inferName(childEntity)),\n icon: resolveField(screenNode?.icon, display?.icon, childEntity.display.icon) ?? \"\",\n mode: resolveField(screenNode?.mode, display?.mode, \"table\") as ChildDisplayMode,\n columns: resolveField(screenNode?.columns, display?.columns, inferColumns(childEntity, relation.foreign_key)),\n sort: resolveField(screenNode?.sort, display?.sort, inferSort(childEntity)),\n limit: resolveField(screenNode?.limit, display?.limit, 20),\n editable: resolveField(screenNode?.editable, display?.editable, true),\n };\n\n // Resolve position_field: screen override > entity-level > undefined.\n const posField = resolveField(screenNode?.position_field, display?.position_field, undefined as string | undefined);\n if (posField) {\n result.position_field = posField;\n // When position_field is active, sort is always position_field:asc.\n result.sort = posField + \":asc\";\n }\n\n // Resolve timeline config.\n const timelineSource = screenNode?.timeline ?? display?.timeline;\n if (result.mode === \"timeline\") {\n result.timeline = inferTimelineFields(timelineSource ?? {}, childEntity);\n } else if (timelineSource) {\n result.timeline = timelineSource;\n }\n\n // Resolve cards config.\n const cardsSource = screenNode?.cards ?? display?.cards;\n if (cardsSource) {\n result.cards = cardsSource;\n }\n\n // Resolve quick_add.\n const quickAdd = screenNode?.quick_add ?? relation.quick_add;\n if (quickAdd) {\n result.quick_add = quickAdd;\n }\n\n return result;\n}\n\n// resolveField returns the first non-nullish value from the precedence chain.\nfunction resolveField<T>(screenOverride: T | undefined, entityDefault: T | undefined, autoDefault: T): T {\n if (screenOverride != null) return screenOverride;\n if (entityDefault != null) return entityDefault;\n return autoDefault;\n}\n\nfunction inferName(entity: Entity): LocalizedString {\n if (entity.display.name_plural && Object.keys(entity.display.name_plural).length > 0) {\n return entity.display.name_plural;\n }\n return entity.display.name;\n}\n\n// inferSort returns a default sort string using the fallback chain:\n// created_at:desc -> updated_at:desc -> first timestamp :desc ->\n// first date :desc -> primary_key:asc\nexport function inferSort(entity: Entity): string {\n if (entity.fields[\"created_at\"]?.type === \"timestamp\") {\n return \"created_at:desc\";\n }\n if (entity.fields[\"updated_at\"]?.type === \"timestamp\") {\n return \"updated_at:desc\";\n }\n for (const name of entity.field_order) {\n const f = entity.fields[name];\n if (f && f.type === \"timestamp\") {\n return name + \":desc\";\n }\n }\n for (const name of entity.field_order) {\n const f = entity.fields[name];\n if (f && f.type === \"date\") {\n return name + \":desc\";\n }\n }\n // Fall back to first primary key field.\n const pk = findPrimaryKey(entity);\n if (pk) return pk + \":asc\";\n return \"\";\n}\n\n// inferColumns returns up to 6 fields from field_order, excluding primary,\n// auto, is_listable, and the parent FK field(s).\nexport function inferColumns(entity: Entity, fk: string | string[]): string[] {\n const fkSet = new Set(Array.isArray(fk) ? fk : [fk]);\n const cols: string[] = [];\n for (const name of entity.field_order) {\n if (cols.length >= 6) break;\n const f = entity.fields[name];\n if (!f) continue;\n if (f.primary || f.auto) continue;\n if (f.display?.is_listable === false) continue;\n if (fkSet.has(name)) continue;\n cols.push(name);\n }\n return cols;\n}\n\n// inferTimelineFields fills missing timeline config fields from entity fields.\n// Missing optional fields are left empty (they are simply not rendered).\nexport function inferTimelineFields(tc: TimelineConfig, entity: Entity): TimelineConfig {\n const result: TimelineConfig = { ...tc };\n\n if (!result.time_field) {\n result.time_field = inferTimeField(entity);\n }\n if (!result.type_field) {\n result.type_field = inferFirstFieldOfType(entity, \"enum\");\n }\n if (!result.summary_field) {\n result.summary_field = inferFirstFieldOfTypes(entity, \"string\", \"text\");\n }\n if (!result.content_field) {\n result.content_field = inferFirstFieldOfType(entity, \"text\");\n }\n if (!result.author_field) {\n if (entity.fields[\"created_by\"]) {\n result.author_field = \"created_by\";\n }\n }\n if (!result.direction_field) {\n result.direction_field = inferDirectionField(entity);\n }\n if (!result.intent_field) {\n result.intent_field = inferIntentField(entity);\n }\n\n return result;\n}\n\nfunction inferDirectionField(entity: Entity): string | undefined {\n const direction = entity.fields[\"direction\"];\n if (direction && direction.type === \"enum\") return \"direction\";\n for (const name of [\"is_outbound\", \"outbound\", \"is_inbound\", \"inbound\"]) {\n const f = entity.fields[name];\n if (f && f.type === \"bool\") return name;\n }\n return undefined;\n}\n\nfunction inferIntentField(entity: Entity): string | undefined {\n const intent = entity.fields[\"intent\"];\n if (intent && intent.type === \"enum\") return \"intent\";\n return undefined;\n}\n\nfunction inferTimeField(entity: Entity): string | undefined {\n // Prefer explicit (non-auto) timestamps first.\n for (const name of entity.field_order) {\n const f = entity.fields[name];\n if (f && f.type === \"timestamp\" && !f.auto) {\n return name;\n }\n }\n // Fall back to auto timestamps: created_at/updated_at first, then any.\n if (entity.fields[\"created_at\"]?.type === \"timestamp\") return \"created_at\";\n if (entity.fields[\"updated_at\"]?.type === \"timestamp\") return \"updated_at\";\n for (const name of entity.field_order) {\n const f = entity.fields[name];\n if (f && f.type === \"timestamp\") return name;\n }\n return undefined;\n}\n\nfunction inferFirstFieldOfType(entity: Entity, type: string): string | undefined {\n for (const name of entity.field_order) {\n const f = entity.fields[name];\n if (f && f.type === type) {\n return name;\n }\n }\n return undefined;\n}\n\nfunction inferFirstFieldOfTypes(entity: Entity, ...types: string[]): string | undefined {\n for (const name of entity.field_order) {\n const f = entity.fields[name];\n if (!f) continue;\n for (const t of types) {\n if (f.type === t) return name;\n }\n }\n return undefined;\n}\n\n// findPrimaryKey returns the first primary key field name.\n// Supports composite PK via entity.primary_key (returns first element).\n// Used for backward-compat scenarios where a single field name is needed\n// (e.g. sort fallback). For full composite PK support, use getPrimaryKeyFields().\nexport function findPrimaryKey(entity: Entity): string | undefined {\n const pks = getPrimaryKeyFields(entity);\n return pks.length > 0 ? pks[0] : undefined;\n}\n\n// findPrimaryKeys returns all primary key field names as an array.\n// Delegates to getPrimaryKeyFields from schema types.\nexport function findPrimaryKeys(entity: Entity): string[] {\n return getPrimaryKeyFields(entity);\n}\n\n// findChildRelation looks up a child relation by entity code on the parent entity.\nexport function findChildRelation(parentEntity: Entity, childCode: string): ChildRelation | undefined {\n return parentEntity.children?.find((c) => c.entity === childCode);\n}\n","// buildQuickAddPayload builds the POST body for a quick-add submission.\n//\n// Precedence (highest first):\n// 1. FK auto-injection - always set, overwrites user input and defaults\n// 2. User field values - user input wins over defaults\n// 3. Configured defaults - from quick_add.defaults\n//\n// The FK is intentionally never shown as an input field and must always\n// reflect the current parent record's ID.\nexport function buildQuickAddPayload(\n fieldValues: Record<string, unknown>,\n defaults: Record<string, unknown> | undefined,\n foreignKey: string | string[],\n parentId: string | string[],\n): Record<string, unknown> {\n const result: Record<string, unknown> = {\n ...(defaults ?? {}),\n ...fieldValues,\n };\n if (Array.isArray(foreignKey)) {\n // For composite FK, parentId may be a pipe-joined string from the URL.\n const ids = Array.isArray(parentId) ? parentId : String(parentId).split(\"|\");\n for (let i = 0; i < foreignKey.length; i++) {\n result[foreignKey[i]] = ids[i];\n }\n } else {\n result[foreignKey] = Array.isArray(parentId) ? parentId[0] : parentId;\n }\n return result;\n}\n\n// isQuickAddReady returns true when all quick_add.fields with required entity\n// fields have non-empty values. Fields that are not marked required in the\n// entity definition are always considered satisfied.\nexport function isQuickAddReady(\n fieldValues: Record<string, unknown>,\n requiredFields: string[],\n): boolean {\n for (const name of requiredFields) {\n const val = fieldValues[name];\n if (val == null || val === \"\") return false;\n }\n return true;\n}\n","import { useState, type FormEvent } from \"react\";\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { createEntity } from \"@/api/data\";\nimport { buildQuickAddPayload, isQuickAddReady } from \"@/lib/quick-add\";\nimport { ENTITY_CHILDREN_KEY } from \"@/hooks/useChildrenData\";\nimport type { ResolvedChildConfig } from \"@/lib/child-config\";\nimport type { Schema } from \"@/types/schema\";\n\n/** Return current time as bare local datetime \"YYYY-MM-DDTHH:MM\" (no offset). */\nfunction toBareLocalNow(): string {\n const now = new Date();\n const y = now.getFullYear();\n const m = String(now.getMonth() + 1).padStart(2, \"0\");\n const d = String(now.getDate()).padStart(2, \"0\");\n const h = String(now.getHours()).padStart(2, \"0\");\n const min = String(now.getMinutes()).padStart(2, \"0\");\n return `${y}-${m}-${d}T${h}:${min}`;\n}\n\nexport interface UseQuickAddResult {\n values: Record<string, unknown>;\n quickAdd: ResolvedChildConfig[\"quick_add\"];\n childEntity: ReturnType<typeof getChildEntity>;\n isPending: boolean;\n error: Error | null;\n isReady: boolean;\n handleSubmit: (e: FormEvent) => void;\n handleFieldChange: (fieldName: string, val: unknown) => void;\n}\n\ntype ChildEntity = Schema[\"entities\"][string] | undefined;\n\nfunction getChildEntity(schema: Schema, entityCode: string): ChildEntity {\n return schema.entities[entityCode];\n}\n\n// useQuickAdd encapsulates all shared state and mutation logic for quick-add\n// forms. It is used by QuickAddForm (table/list/cards) and TimelineComposer\n// (timeline). All hooks are called unconditionally before any early returns\n// in the consuming component.\nexport function useQuickAdd(\n config: ResolvedChildConfig,\n parentEntity: string,\n parentId: string | string[],\n schema: Schema,\n): UseQuickAddResult {\n const [values, setValues] = useState<Record<string, unknown>>(() => {\n const qa0 = config.quick_add;\n const ce = schema.entities[config.entity];\n const initialValues: Record<string, unknown> = {};\n if (qa0?.fields) {\n for (const f of qa0.fields) {\n if (qa0.defaults?.[f] != null) {\n initialValues[f] = qa0.defaults[f];\n } else if (ce?.fields[f]?.type === \"timestamp\") {\n // Default timestamp fields to now as bare local datetime.\n // The server interprets this in the field's configured timezone.\n initialValues[f] = toBareLocalNow();\n }\n }\n }\n return initialValues;\n });\n const queryClient = useQueryClient();\n const { mutate, isPending, error, reset } = useMutation({\n mutationFn: (payload: Record<string, unknown>) => createEntity(config.entity, payload),\n onSuccess: () => {\n // Reset all visible fields to their defaults (or empty), clearing any\n // user-typed values for fields that have no configured default.\n const qa = config.quick_add;\n const ce = schema.entities[config.entity];\n const resetValues: Record<string, unknown> = {};\n if (qa?.fields) {\n for (const f of qa.fields) {\n if (qa?.defaults?.[f] != null) {\n resetValues[f] = qa.defaults[f];\n } else if (ce?.fields[f]?.type === \"timestamp\") {\n resetValues[f] = toBareLocalNow();\n } else {\n resetValues[f] = \"\";\n }\n }\n }\n setValues(resetValues);\n const normalizedParentId = Array.isArray(parentId) ? parentId.join(\"|\") : parentId;\n queryClient.invalidateQueries({\n queryKey: [ENTITY_CHILDREN_KEY, parentEntity, normalizedParentId, config.entity],\n });\n },\n });\n\n const quickAdd = config.quick_add;\n const childEntity = schema.entities[config.entity];\n\n // Derive required fields from the quick_add field list.\n // Only fields marked required on the entity definition are checked.\n const requiredFields = quickAdd?.fields.filter(\n (f) => childEntity?.fields[f]?.required,\n ) ?? [];\n const isReady = isQuickAddReady(values, requiredFields);\n\n function handleSubmit(e: FormEvent) {\n e.preventDefault();\n if (!quickAdd) return;\n const payload = buildQuickAddPayload(values, quickAdd.defaults, config.foreign_key, parentId);\n mutate(payload);\n }\n\n function handleFieldChange(fieldName: string, val: unknown) {\n if (error) reset();\n setValues((prev: Record<string, unknown>) => ({ ...prev, [fieldName]: val }));\n }\n\n return {\n values,\n quickAdd,\n childEntity,\n isPending,\n error,\n isReady,\n handleSubmit,\n handleFieldChange,\n };\n}\n","import { fieldDisplayName } from \"@/types/schema\";\nimport { renderField } from \"@/components/fields\";\nimport { Button } from \"@/components/ui/button\";\nimport { useQuickAdd } from \"./useQuickAdd\";\nimport type { ResolvedChildConfig } from \"@/lib/child-config\";\nimport type { Schema } from \"@/types/schema\";\n\ninterface QuickAddFormProps {\n config: ResolvedChildConfig;\n parentEntity: string;\n parentId: string | string[];\n schema: Schema;\n}\n\n// QuickAddForm renders an inline quick-add row above child content for\n// table, list, and cards display modes. On submit it POSTs to the child\n// entity endpoint, injects the FK, merges defaults, and invalidates the\n// child query so the list refreshes immediately.\nexport function QuickAddForm({ config, parentEntity, parentId, schema }: QuickAddFormProps) {\n // All hooks must be called unconditionally before any early returns.\n const { values, quickAdd, childEntity, isPending, error, isReady, handleSubmit, handleFieldChange } =\n useQuickAdd(config, parentEntity, parentId, schema);\n\n if (!quickAdd || quickAdd.fields.length === 0) return null;\n if (!childEntity) return null;\n\n return (\n <form\n onSubmit={handleSubmit}\n className=\"flex items-end gap-2 py-2 border-b border-[var(--border)]\"\n >\n {quickAdd.fields.map((fieldName) => {\n const field = childEntity.fields[fieldName];\n if (!field) return null;\n return (\n <div key={fieldName} className=\"flex-1 min-w-0\">\n <label className=\"text-xs text-[var(--muted-foreground)] mb-1 block\">\n {fieldDisplayName(field, fieldName, schema.entities)}\n </label>\n {renderField({\n field,\n fieldName,\n value: values[fieldName] ?? \"\",\n mode: \"edit\",\n onChange: (val) => handleFieldChange(fieldName, val),\n record: values,\n })}\n </div>\n );\n })}\n <Button type=\"submit\" size=\"sm\" disabled={isPending || !isReady} className=\"shrink-0 mb-0.5\">\n Add\n </Button>\n {error != null && (\n <span className=\"text-xs text-[var(--destructive)] self-end mb-1\">\n {error.message}\n </span>\n )}\n </form>\n );\n}\n","import { fieldDisplayName } from \"@/types/schema\";\nimport { renderField } from \"@/components/fields\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport { useChildrenData } from \"@/hooks/useChildrenData\";\nimport { QuickAddForm } from \"./QuickAddForm\";\nimport type { ChildDisplayProps } from \"./ChildrenBlock\";\n\n// ChildrenTable renders child records as a table with column headers.\n// Supports configurable columns, sort, and limit. Shows a quick-add form\n// above the table when quick_add is configured.\nexport function ChildrenTable({ config, parentEntity, parentId, schema }: ChildDisplayProps) {\n const childEntity = schema.entities[config.entity];\n const { data: response, isLoading, isError } = useChildrenData(parentEntity, parentId, config.entity, config.foreign_key, config.sort, config.limit);\n const rows = response?.data ?? [];\n const refs = response?.$refs;\n const columns = config.columns;\n\n if (!childEntity) {\n return <div className=\"text-sm text-[var(--muted-foreground)] py-2\">Entity not found.</div>;\n }\n\n const quickAddForm = (\n <QuickAddForm\n config={config}\n parentEntity={parentEntity}\n parentId={parentId}\n schema={schema}\n />\n );\n\n if (isError) {\n return (\n <div>\n {quickAddForm}\n <div className=\"text-sm text-[var(--destructive)] py-2\">Failed to load. Try again.</div>\n </div>\n );\n }\n\n\n if (isLoading) {\n return (\n <div>\n {quickAddForm}\n <div className=\"space-y-2 py-2\">\n <Skeleton className=\"h-8 w-full\" />\n <Skeleton className=\"h-8 w-full\" />\n <Skeleton className=\"h-8 w-full\" />\n </div>\n </div>\n );\n }\n\n if (rows.length === 0) {\n return (\n <div>\n {quickAddForm}\n <div className=\"text-sm text-[var(--muted-foreground)] py-4\">\n No records yet.\n </div>\n </div>\n );\n }\n\n return (\n <div>\n {quickAddForm}\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b\">\n {columns.map((col) => {\n const field = childEntity.fields[col];\n return (\n <th\n key={col}\n className=\"h-8 px-3 text-left align-middle font-medium text-[var(--muted-foreground)]\"\n >\n {field ? fieldDisplayName(field, col, schema.entities) : col}\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {rows.map((row, rowIdx) => (\n <tr key={String((row as Record<string, unknown>)[\"id\"] ?? rowIdx)} className=\"border-b last:border-0 hover:bg-[var(--muted)]/50\">\n {columns.map((col) => {\n const field = childEntity.fields[col];\n return (\n <td key={col} className=\"px-3 py-2 align-middle\">\n {field\n ? renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"display\",\n record: row,\n refs,\n })\n : String(row[col] ?? \"\")}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n","import { renderField } from \"@/components/fields\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport { useChildrenData } from \"@/hooks/useChildrenData\";\nimport { QuickAddForm } from \"./QuickAddForm\";\nimport type { ChildDisplayProps } from \"./ChildrenBlock\";\n\n// ChildrenList renders child records as compact rows without column headers.\n// Best for simple or narrow side panels. Shows a quick-add form above the\n// list when quick_add is configured.\nexport function ChildrenList({ config, parentEntity, parentId, schema }: ChildDisplayProps) {\n const childEntity = schema.entities[config.entity];\n const { data: response, isLoading, isError } = useChildrenData(parentEntity, parentId, config.entity, config.foreign_key, config.sort, config.limit);\n const rows = response?.data ?? [];\n const refs = response?.$refs;\n const columns = config.columns;\n\n if (!childEntity) {\n return <div className=\"text-sm text-[var(--muted-foreground)] py-2\">Entity not found.</div>;\n }\n\n const quickAddForm = (\n <QuickAddForm\n config={config}\n parentEntity={parentEntity}\n parentId={parentId}\n schema={schema}\n />\n );\n\n if (isError) {\n return (\n <div>\n {quickAddForm}\n <div className=\"text-sm text-[var(--destructive)] py-2\">Failed to load. Try again.</div>\n </div>\n );\n }\n\n\n if (isLoading) {\n return (\n <div>\n {quickAddForm}\n <div className=\"space-y-2 py-2\">\n <Skeleton className=\"h-6 w-full\" />\n <Skeleton className=\"h-6 w-full\" />\n <Skeleton className=\"h-6 w-3/4\" />\n </div>\n </div>\n );\n }\n\n if (rows.length === 0) {\n return (\n <div>\n {quickAddForm}\n <div className=\"text-sm text-[var(--muted-foreground)] py-4\">\n No records yet.\n </div>\n </div>\n );\n }\n\n // Use the display field if available, otherwise first column (may be\n // undefined if columns is empty, in which case rows render with no label).\n const displayField = columns.length > 0\n ? (childEntity.display.display_field ?? columns[0])\n : childEntity.display.display_field;\n\n return (\n <div>\n {quickAddForm}\n <div className=\"divide-y divide-[var(--border)]\">\n {rows.map((row, idx) => (\n <div key={String((row as Record<string, unknown>)[\"id\"] ?? idx)} className=\"flex items-center gap-3 py-2 px-1 hover:bg-[var(--muted)]/50\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm truncate\">\n {displayField && childEntity.fields[displayField]\n ? renderField({\n field: childEntity.fields[displayField],\n fieldName: displayField,\n value: row[displayField],\n mode: \"display\",\n record: row,\n refs,\n })\n : displayField && row[displayField] != null\n ? String(row[displayField])\n : null}\n </div>\n {columns.length > 1 && (() => {\n const subCols = columns.slice(1, 3).filter((col) => row[col] != null);\n if (subCols.length === 0) return null;\n return (\n <div className=\"text-xs text-[var(--muted-foreground)] truncate\">\n {subCols.map((col, i) => (\n <span key={col}>\n {i > 0 && \" - \"}\n {childEntity.fields[col]\n ? renderField({\n field: childEntity.fields[col],\n fieldName: col,\n value: row[col],\n mode: \"display\",\n record: row,\n refs,\n })\n : String(row[col])}\n </span>\n ))}\n </div>\n );\n })()}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import { renderField } from \"@/components/fields\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport { useChildrenData } from \"@/hooks/useChildrenData\";\nimport { QuickAddForm } from \"./QuickAddForm\";\nimport type { ChildDisplayProps } from \"./ChildrenBlock\";\n\n// ChildrenCards renders child records as a responsive card grid.\n// Supports configurable columns_count, header_field, and badge_field.\n// Shows a quick-add form above the grid when quick_add is configured.\nexport function ChildrenCards({ config, parentEntity, parentId, schema }: ChildDisplayProps) {\n const childEntity = schema.entities[config.entity];\n const { data: response, isLoading, isError } = useChildrenData(parentEntity, parentId, config.entity, config.foreign_key, config.sort, config.limit);\n const rows = response?.data ?? [];\n const refs = response?.$refs;\n const columns = config.columns;\n const cardsConfig = config.cards;\n const headerField = cardsConfig?.header_field ?? columns[0];\n const badgeField = cardsConfig?.badge_field;\n const colCount = cardsConfig?.columns_count;\n\n if (!childEntity) {\n return <div className=\"text-sm text-[var(--muted-foreground)] py-2\">Entity not found.</div>;\n }\n\n const quickAddForm = (\n <QuickAddForm\n config={config}\n parentEntity={parentEntity}\n parentId={parentId}\n schema={schema}\n />\n );\n\n if (isError) {\n return (\n <div>\n {quickAddForm}\n <div className=\"text-sm text-[var(--destructive)] py-2\">Failed to load. Try again.</div>\n </div>\n );\n }\n\n\n if (isLoading) {\n return (\n <div>\n {quickAddForm}\n <div className={gridClass(colCount)}>\n <Skeleton className=\"h-24 w-full rounded-xl\" />\n <Skeleton className=\"h-24 w-full rounded-xl\" />\n <Skeleton className=\"h-24 w-full rounded-xl\" />\n </div>\n </div>\n );\n }\n\n if (rows.length === 0) {\n return (\n <div>\n {quickAddForm}\n <div className=\"text-sm text-[var(--muted-foreground)] py-4\">\n No records yet.\n </div>\n </div>\n );\n }\n\n // Determine detail fields: columns minus header and badge.\n const detailFields = columns.filter((c) => c !== headerField && c !== badgeField);\n\n return (\n <div>\n {quickAddForm}\n <div className={gridClass(colCount)}>\n {rows.map((row, idx) => (\n <Card key={String((row as Record<string, unknown>)[\"id\"] ?? idx)} className=\"overflow-hidden\">\n <CardHeader className=\"py-3 px-4\">\n <div className=\"flex items-center justify-between gap-2\">\n <CardTitle className=\"text-sm truncate\">\n {headerField && childEntity.fields[headerField]\n ? renderField({\n field: childEntity.fields[headerField],\n fieldName: headerField,\n value: row[headerField],\n mode: \"display\",\n record: row,\n refs,\n })\n : `Record ${idx + 1}`}\n </CardTitle>\n {badgeField && row[badgeField] != null && (\n <Badge variant=\"secondary\" className=\"text-xs shrink-0\">\n {childEntity.fields[badgeField]\n ? renderField({\n field: childEntity.fields[badgeField],\n fieldName: badgeField,\n value: row[badgeField],\n mode: \"display\",\n record: row,\n refs,\n })\n : String(row[badgeField])}\n </Badge>\n )}\n </div>\n </CardHeader>\n {detailFields.length > 0 && (\n <CardContent className=\"px-4 pb-3 pt-0\">\n <div className=\"space-y-1\">\n {detailFields.slice(0, 4).map((col) => {\n const field = childEntity.fields[col];\n if (!field) return null;\n return (\n <div key={col} className=\"flex items-baseline gap-2 text-xs\">\n <span className=\"text-[var(--muted-foreground)] shrink-0\">\n {schema.entities[config.entity]?.fields[col]?.display?.name\n ? Object.values(schema.entities[config.entity].fields[col].display!.name)[0]\n : col}:\n </span>\n <span className=\"truncate\">\n {renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"display\",\n record: row,\n refs,\n })}\n </span>\n </div>\n );\n })}\n </div>\n </CardContent>\n )}\n </Card>\n ))}\n </div>\n </div>\n );\n}\n\nfunction gridClass(colCount: number | undefined): string {\n switch (colCount) {\n case 1: return \"grid grid-cols-1 gap-3\";\n case 2: return \"grid grid-cols-1 sm:grid-cols-2 gap-3\";\n case 3: return \"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3\";\n case 4: return \"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3\";\n default: return \"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3\"; // auto\n }\n}\n","import { useState, useCallback, useRef, useEffect, useMemo } from \"react\";\nimport { renderField } from \"@/components/fields\";\nimport { Button } from \"@/components/ui/button\";\nimport { useQuickAdd } from \"./useQuickAdd\";\nimport { registerFieldRegion } from \"@/lib/field-regions\";\nimport type { ResolvedChildConfig } from \"@/lib/child-config\";\nimport type { Schema } from \"@/types/schema\";\n\n// QUICK_ENTRY_REGION is the registered field-region name for the activity\n// composer. ui_steps reference it as \"quick_entry.FIELD\" (e.g. quick_entry.body).\nconst QUICK_ENTRY_REGION = \"quick_entry\";\n\ninterface TimelineComposerProps {\n config: ResolvedChildConfig;\n parentEntity: string;\n parentId: string | string[];\n schema: Schema;\n}\n\nconst MIN_HEIGHT = 100;\nconst DEFAULT_HEIGHT = 180;\n// Generous ceiling so users can compose long multi-paragraph messages\n// (LinkedIn main/bump messages are often 500-1500 chars) by dragging the\n// top handle up. Concrete pixel cap — not viewport-relative — so the\n// composer never covers more than the intended portion of the panel.\nconst MAX_HEIGHT = 800;\n\n// TimelineComposer renders a resizable bottom composer for timeline mode.\n// Sits at the bottom of the Activity panel. Drag the top edge to resize upward.\nexport function TimelineComposer({ config, parentEntity, parentId, schema }: TimelineComposerProps) {\n const { values, quickAdd, childEntity, isPending, error, isReady, handleSubmit, handleFieldChange } =\n useQuickAdd(config, parentEntity, parentId, schema);\n\n const [height, setHeight] = useState(DEFAULT_HEIGHT);\n const dragging = useRef<{ startY: number; startHeight: number } | null>(null);\n\n // Stable refs for the field region. React state closures would go stale\n // inside the region handle; refs always read the current value.\n const valuesRef = useRef(values);\n valuesRef.current = values;\n const handleFieldChangeRef = useRef(handleFieldChange);\n handleFieldChangeRef.current = handleFieldChange;\n const fieldNodesRef = useRef<Record<string, HTMLElement | null>>({});\n\n const region = useMemo(() => ({\n getField: (fieldName: string) => valuesRef.current[fieldName],\n setField: (fieldName: string, value: unknown) => {\n handleFieldChangeRef.current(fieldName, value);\n },\n focusField: (fieldName: string) => {\n const node = fieldNodesRef.current[fieldName];\n if (!node) return;\n const focusable = node.querySelector<HTMLElement>(\"textarea, input, select, [contenteditable]\");\n (focusable ?? node).focus();\n },\n }), []);\n\n useEffect(() => registerFieldRegion(QUICK_ENTRY_REGION, region), [region]);\n\n const onDragStart = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n dragging.current = { startY: e.clientY, startHeight: height };\n\n const onMove = (ev: MouseEvent) => {\n if (!dragging.current) return;\n const delta = dragging.current.startY - ev.clientY;\n const next = Math.min(MAX_HEIGHT, Math.max(MIN_HEIGHT, dragging.current.startHeight + delta));\n setHeight(next);\n };\n\n const onUp = () => {\n dragging.current = null;\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n };\n\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n },\n [height],\n );\n\n if (!quickAdd || quickAdd.fields.length === 0) return null;\n if (!childEntity) return null;\n\n // Partition the configured quick_add.fields into three zones so the\n // composer reads top-to-bottom as \"classify → write → timestamp+send\":\n // topFields — enum comboboxes (channel, intent, direction, …)\n // contentField — the one text/string field that gets the textarea\n // bottomFields — everything else (typically just the timestamp)\n const contentField = quickAdd.fields.find((f) => {\n const field = childEntity.fields[f];\n return field && (field.type === \"text\" || field.type === \"string\");\n });\n const topFields: string[] = [];\n const bottomFields: string[] = [];\n for (const f of quickAdd.fields) {\n if (f === contentField) continue;\n const field = childEntity.fields[f];\n if (!field) continue;\n if (field.type === \"enum\") {\n topFields.push(f);\n } else {\n bottomFields.push(f);\n }\n }\n\n const renderMetaField = (fieldName: string) => {\n const field = childEntity.fields[fieldName];\n if (!field) return null;\n return (\n <div key={fieldName} ref={(el) => { fieldNodesRef.current[fieldName] = el; }}>\n {renderField({\n field,\n fieldName,\n value: values[fieldName] ?? \"\",\n mode: \"edit\",\n onChange: (val) => handleFieldChange(fieldName, val),\n record: values,\n })}\n </div>\n );\n };\n\n return (\n <div\n className=\"shrink-0 border-t border-[var(--border)] bg-[var(--card)] flex flex-col\"\n style={{ height: `${height}px` }}\n >\n {/* Resize handle — drag up/down to make the composer taller or\n shorter. Wider hit area and a more prominent grip bar make it\n discoverable without cluttering the panel chrome. */}\n <div\n className=\"h-3 cursor-row-resize flex items-center justify-center shrink-0 hover:bg-[var(--muted)]/50 transition-colors group\"\n onMouseDown={onDragStart}\n title=\"Drag to resize\"\n >\n <div className=\"w-16 h-1 rounded-full bg-[var(--border)] group-hover:bg-[var(--muted-foreground)] transition-colors\" />\n </div>\n\n <form onSubmit={handleSubmit} className=\"flex-1 min-h-0 flex flex-col gap-1.5 px-3 pb-2\">\n {/* Top row: classifier enums (channel, intent, direction…).\n flex-wrap so narrow panels (sidebar mode, ~420px) don't cram\n controls into an unreadable strip. */}\n {topFields.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-2 shrink-0\">\n {topFields.map(renderMetaField)}\n </div>\n )}\n\n {/* Content textarea fills the remaining vertical space. */}\n {contentField && childEntity.fields[contentField] && (\n <div\n className=\"flex-1 min-h-0 [&_textarea]:!h-full [&_textarea]:!min-h-0 [&_textarea]:!resize-none\"\n ref={(el) => { fieldNodesRef.current[contentField] = el; }}\n >\n {renderField({\n field: childEntity.fields[contentField],\n fieldName: contentField,\n value: values[contentField] ?? \"\",\n mode: \"edit\",\n onChange: (val) => handleFieldChange(contentField, val),\n record: values,\n })}\n </div>\n )}\n\n {/* Bottom row: non-enum meta (typically the timestamp) + submit\n button. Submit stays right-aligned even when there are no\n bottom meta fields. */}\n <div className=\"flex flex-wrap items-center gap-2 shrink-0\">\n {bottomFields.map(renderMetaField)}\n <div className=\"ml-auto\">\n <Button type=\"submit\" size=\"sm\" disabled={isPending || !isReady}>\n Add Note\n </Button>\n </div>\n </div>\n\n {error != null && (\n <p className=\"text-xs text-[var(--destructive)] shrink-0\">{error.message}</p>\n )}\n </form>\n </div>\n );\n}\n","import { useState, useCallback, useRef, useEffect } from \"react\";\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { Pencil, Check, X, Trash2, ArrowDownLeft, ArrowUpRight } from \"lucide-react\";\nimport { renderField } from \"@/components/fields\";\nimport { Button } from \"@/components/ui/button\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport { useChildrenData, ENTITY_CHILDREN_KEY } from \"@/hooks/useChildrenData\";\nimport { updateEntity, deleteEntity } from \"@/api/data\";\nimport { toast } from \"sonner\";\nimport { loc, fieldDisplayName } from \"@/types/schema\";\nimport type { EntityField } from \"@/types/schema\";\nimport { TimelineComposer } from \"./TimelineComposer\";\nimport type { ChildDisplayProps } from \"./ChildrenBlock\";\n\ntype RowData = Record<string, unknown>;\n\nexport function ChildrenTimeline({ config, parentEntity, parentId, schema }: ChildDisplayProps) {\n const childEntity = schema.entities[config.entity];\n const { data: response, isLoading, isError } = useChildrenData(parentEntity, parentId, config.entity, config.foreign_key, config.sort, config.limit);\n const rows = response?.data ?? [];\n const refs = response?.$refs;\n const timeline = config.timeline;\n const scroll = timeline?.scroll ?? false;\n\n const autoScroll = timeline?.auto_scroll ?? \"none\";\n const scrollRef = useRef<HTMLDivElement>(null);\n const hasAutoScrolled = useRef(false);\n\n const prevRowCount = useRef(0);\n\n useEffect(() => {\n hasAutoScrolled.current = false;\n prevRowCount.current = 0;\n }, [parentId]);\n\n // Auto-scroll to bottom: on initial load (if configured) and whenever new rows appear.\n useEffect(() => {\n if (!scrollRef.current || rows.length === 0) return;\n const isInitialLoad = !hasAutoScrolled.current;\n const hasNewRows = rows.length > prevRowCount.current && prevRowCount.current > 0;\n prevRowCount.current = rows.length;\n\n if ((isInitialLoad && autoScroll === \"bottom\") || hasNewRows) {\n scrollRef.current.scrollTop = scrollRef.current.scrollHeight;\n hasAutoScrolled.current = true;\n }\n }, [rows, autoScroll]);\n\n const [editingId, setEditingId] = useState<string | null>(null);\n\n if (!childEntity) {\n return <div className=\"text-sm text-[var(--muted-foreground)] py-2\">Entity not found.</div>;\n }\n\n const editableFields = config.quick_add?.fields\n ?? [timeline?.content_field].filter(Boolean) as string[];\n\n const title = loc(childEntity.display?.name_plural) || loc(childEntity.display?.name) || config.entity;\n\n // Build entries\n let entries: React.ReactNode;\n if (isError) {\n entries = <div className=\"text-sm text-[var(--destructive)] p-3\">Failed to load.</div>;\n } else if (isLoading) {\n entries = (\n <div className=\"space-y-2 p-3\">\n <Skeleton className=\"h-16 w-full rounded-lg\" />\n <Skeleton className=\"h-16 w-full rounded-lg\" />\n </div>\n );\n } else if (rows.length === 0) {\n entries = <div className=\"text-sm text-[var(--muted-foreground)] p-3\">No activity yet.</div>;\n } else {\n entries = rows.map((row, idx) => {\n const rowId = String((row as RowData)[\"id\"] ?? idx);\n return (\n <TimelineEntry\n key={rowId}\n row={row}\n rowId={rowId}\n childEntity={childEntity}\n entityCode={config.entity}\n parentEntity={parentEntity}\n parentId={parentId}\n timeline={timeline}\n editableFields={editableFields}\n refs={refs}\n isEditing={editingId === rowId}\n onStartEdit={() => setEditingId(rowId)}\n onCancelEdit={() => setEditingId(null)}\n onSaved={() => setEditingId(null)}\n schema={schema}\n />\n );\n });\n }\n\n // Scroll mode: self-contained panel that fills its parent height.\n // Structure: header | scrollable entries | resizable composer\n if (scroll) {\n return (\n <div className=\"flex flex-col h-full border-l border-[var(--border)] bg-[var(--muted)]/50 text-[var(--card-foreground)]\">\n {/* Header */}\n <div className=\"px-4 py-3 border-b border-[var(--border)] bg-[var(--card)]\">\n <h3 className=\"text-sm font-semibold\">{title}</h3>\n </div>\n {/* Scrollable entries */}\n <div ref={scrollRef} className=\"flex-1 overflow-y-auto p-3 space-y-2\">\n {entries}\n </div>\n {/* Composer */}\n <TimelineComposer config={config} parentEntity={parentEntity} parentId={parentId} schema={schema} />\n </div>\n );\n }\n\n // Inline mode (no scroll): entries + composer, no card wrapper.\n return (\n <div>\n <div className=\"space-y-2\">{entries}</div>\n <TimelineComposer config={config} parentEntity={parentEntity} parentId={parentId} schema={schema} />\n </div>\n );\n}\n\n// --- TimelineEntry ---\n\ninterface TimelineEntryProps {\n row: RowData;\n rowId: string;\n childEntity: NonNullable<ChildDisplayProps[\"schema\"][\"entities\"][string]>;\n entityCode: string;\n parentEntity: string;\n parentId: string;\n timeline: ChildDisplayProps[\"config\"][\"timeline\"];\n editableFields: string[];\n refs?: Record<string, Record<string, Record<string, unknown>>>;\n isEditing: boolean;\n onStartEdit: () => void;\n onCancelEdit: () => void;\n onSaved: () => void;\n schema: ChildDisplayProps[\"schema\"];\n}\n\nfunction TimelineEntry({\n row, rowId, childEntity, entityCode, parentEntity, parentId,\n timeline, editableFields, refs, isEditing, onStartEdit, onCancelEdit, onSaved, schema,\n}: TimelineEntryProps) {\n const queryClient = useQueryClient();\n const [formData, setFormData] = useState<Record<string, unknown>>({});\n\n const invalidate = useCallback(() => {\n queryClient.invalidateQueries({ queryKey: [ENTITY_CHILDREN_KEY, parentEntity, parentId, entityCode] });\n }, [queryClient, parentEntity, parentId, entityCode]);\n\n const updateMut = useMutation({\n mutationFn: (data: Record<string, unknown>) => updateEntity(entityCode, rowId, data),\n onSuccess: () => { invalidate(); toast.success(\"Updated\"); onSaved(); },\n onError: (err: Error) => toast.error(err.message),\n });\n\n const deleteMut = useMutation({\n mutationFn: () => deleteEntity(entityCode, rowId),\n onSuccess: () => { invalidate(); toast.success(\"Deleted\"); },\n onError: (err: Error) => toast.error(err.message),\n });\n\n const startEdit = useCallback(() => {\n const data: Record<string, unknown> = {};\n for (const f of editableFields) data[f] = row[f] ?? \"\";\n setFormData(data);\n onStartEdit();\n }, [row, editableFields, onStartEdit]);\n\n const handleFieldChange = useCallback((fieldName: string, val: unknown) => {\n setFormData((prev) => ({ ...prev, [fieldName]: val }));\n }, []);\n\n const timeField = timeline?.time_field;\n const typeField = timeline?.type_field;\n const summaryField = timeline?.summary_field;\n const contentField = timeline?.content_field;\n const authorField = timeline?.author_field;\n const directionField = timeline?.direction_field;\n const intentField = timeline?.intent_field;\n\n // Edit mode\n if (isEditing) {\n return (\n <div className=\"rounded-lg border-2 border-[var(--primary)]/40 bg-[var(--card)] p-3 space-y-2\">\n {editableFields.map((fieldName) => {\n const field = childEntity.fields[fieldName];\n if (!field) return null;\n return (\n <div key={fieldName}>\n <label className=\"text-xs text-[var(--muted-foreground)] mb-1 block\">\n {fieldDisplayName(field, fieldName, schema.entities)}\n </label>\n {renderField({ field, fieldName, value: formData[fieldName] ?? \"\", mode: \"edit\", onChange: (val) => handleFieldChange(fieldName, val), record: formData })}\n </div>\n );\n })}\n <div className=\"flex items-center gap-1.5 pt-1\">\n <Button size=\"sm\" onClick={() => updateMut.mutate(formData)} disabled={updateMut.isPending} className=\"h-7 text-xs gap-1\">\n <Check className=\"h-3 w-3\" /> {updateMut.isPending ? \"Saving...\" : \"Save\"}\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={() => { setFormData({}); onCancelEdit(); }} disabled={updateMut.isPending} className=\"h-7 text-xs gap-1\">\n <X className=\"h-3 w-3\" /> Cancel\n </Button>\n </div>\n </div>\n );\n }\n\n // Display mode\n return (\n <div className=\"group rounded-lg border border-[var(--border)] bg-[var(--card)] p-3 hover:border-[var(--muted-foreground)]/30 transition-colors\">\n {/* Header row */}\n <div className=\"flex items-center gap-2 flex-wrap text-xs text-[var(--muted-foreground)]\">\n {timeField && row[timeField] != null && childEntity.fields[timeField] && (\n <span className=\"font-medium\">\n {renderField({ field: childEntity.fields[timeField], fieldName: timeField, value: row[timeField], mode: \"display\", record: row, refs })}\n </span>\n )}\n {typeField && row[typeField] != null && childEntity.fields[typeField] && (\n <span className=\"px-1.5 py-0.5 rounded bg-[var(--muted)] text-[10px] uppercase tracking-wide font-semibold\">\n {renderField({ field: childEntity.fields[typeField], fieldName: typeField, value: row[typeField], mode: \"display\", record: row, refs })}\n </span>\n )}\n {directionField && row[directionField] != null && childEntity.fields[directionField] && (\n <DirectionChip value={row[directionField]} field={childEntity.fields[directionField]} />\n )}\n {intentField && row[intentField] != null && childEntity.fields[intentField] && (\n <span className=\"px-1.5 py-0.5 rounded bg-[var(--muted)] text-[10px] uppercase tracking-wide font-medium\">\n {renderField({ field: childEntity.fields[intentField], fieldName: intentField, value: row[intentField], mode: \"display\", record: row, refs })}\n </span>\n )}\n {authorField && row[authorField] != null && childEntity.fields[authorField] && (\n <span>by {renderField({ field: childEntity.fields[authorField], fieldName: authorField, value: row[authorField], mode: \"display\", record: row, refs })}</span>\n )}\n <div className=\"ml-auto flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity\">\n <button onClick={startEdit} className=\"p-1 rounded hover:bg-[var(--muted)]\" title=\"Edit\"><Pencil className=\"h-3 w-3\" /></button>\n <button onClick={() => deleteMut.mutate()} disabled={deleteMut.isPending} className=\"p-1 rounded hover:bg-[var(--destructive)]/10 hover:text-[var(--destructive)]\" title=\"Delete\"><Trash2 className=\"h-3 w-3\" /></button>\n </div>\n </div>\n {/* Summary */}\n {summaryField && row[summaryField] != null && childEntity.fields[summaryField] && (\n <div className=\"text-sm font-medium mt-1.5\">\n {renderField({ field: childEntity.fields[summaryField], fieldName: summaryField, value: row[summaryField], mode: \"display\", record: row, refs })}\n </div>\n )}\n {/* Content — explicit font-normal (class + inline style) to override\n any inherited medium weight from host pages / reset chains that\n was reading as \"bold\" on multi-paragraph activity bodies. Inline\n style trumps CSS specificity without needing !important in the\n Tailwind class. */}\n {contentField && row[contentField] != null && contentField !== summaryField && childEntity.fields[contentField] && (\n <div className=\"text-sm font-normal mt-1.5\" style={{ fontWeight: 400 }}>\n {renderField({ field: childEntity.fields[contentField], fieldName: contentField, value: row[contentField], mode: \"display\", record: row, refs })}\n </div>\n )}\n </div>\n );\n}\n\n// DirectionChip shows an inbound/outbound indicator next to the activity type.\n// Supports enum \"direction\" (values inbound|outbound) or boolean flags\n// (is_outbound/outbound: true = outbound; is_inbound/inbound: true = inbound).\nfunction DirectionChip({ value, field }: { value: unknown; field: EntityField }) {\n const outbound = isOutbound(value, field);\n if (outbound === null) return null;\n const Icon = outbound ? ArrowUpRight : ArrowDownLeft;\n const label = outbound ? \"Out\" : \"In\";\n return (\n <span className=\"inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded bg-[var(--muted)] text-[10px] uppercase tracking-wide font-medium\">\n <Icon className=\"h-3 w-3\" />\n {label}\n </span>\n );\n}\n\nfunction isOutbound(value: unknown, field: EntityField): boolean | null {\n if (field.type === \"bool\") {\n // bool semantics depend on field name; pass field name via caller. Here we\n // assume truthy means the chip's polarity - caller chose the field name.\n // is_outbound=true -> outbound; is_inbound=true -> inbound.\n // Without the name we can't invert; ChildrenTimeline picks the field, so we\n // just read the value and assume \"true means outbound\" for the default\n // inferred cases (is_outbound/outbound). Inbound fields come through as\n // false-means-outbound via schema authoring.\n return value === true;\n }\n if (typeof value === \"string\") {\n const v = value.toLowerCase();\n if (v === \"outbound\" || v === \"out\") return true;\n if (v === \"inbound\" || v === \"in\") return false;\n }\n return null;\n}\n","import { useCallback, useRef } from \"react\";\nimport { Plus, Trash2, Undo2 } from \"lucide-react\";\nimport { fieldDisplayName } from \"@/types/schema\";\nimport type { Entity, Schema } from \"@/types/schema\";\nimport { renderField } from \"@/components/fields\";\nimport type { RefsMap } from \"@/components/fields\";\nimport { Button } from \"@/components/ui/button\";\nimport type { PendingChildRow } from \"./LayoutRenderer\";\nimport type { ResolvedChildConfig } from \"@/lib/child-config\";\n\ninterface EditableChildrenTableProps {\n config: ResolvedChildConfig;\n childEntity: Entity;\n schema: Schema;\n rows: PendingChildRow[];\n onChange: (rows: PendingChildRow[]) => void;\n validationErrors?: Record<string, string[]>; // rowKey -> fieldNames\n refs?: RefsMap;\n}\n\n// EditableChildrenTable renders child rows with all cells in edit mode.\n// Used for direct (aggregate) children when the parent detail page is in edit mode.\nexport function EditableChildrenTable({\n config,\n childEntity,\n schema,\n rows,\n onChange,\n validationErrors,\n refs,\n}: EditableChildrenTableProps) {\n const tableRef = useRef<HTMLTableElement>(null);\n const columns = config.columns;\n\n // Editable columns: exclude FK, auto, primary, and position_field.\n const fkSet = new Set(Array.isArray(config.foreign_key) ? config.foreign_key : [config.foreign_key]);\n const editableColumns = columns.filter((col) => {\n if (fkSet.has(col)) return false;\n if (config.position_field && col === config.position_field) return false;\n const field = childEntity.fields[col];\n if (!field) return false;\n if (field.auto || field.primary) return false;\n return true;\n });\n\n // Display-only columns (auto/primary but visible in column list, or position_field).\n const displayOnlyColumns = new Set(\n columns.filter((col) => {\n if (config.position_field && col === config.position_field) return true;\n const field = childEntity.fields[col];\n return field && (field.auto || field.primary);\n }),\n );\n\n const handleCellChange = useCallback(\n (rowKey: string, fieldName: string, value: unknown) => {\n const updated = rows.map((row) =>\n row._key === rowKey\n ? { ...row, [fieldName]: value, _dirty: true }\n : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleAddRow = useCallback(() => {\n const newRow: PendingChildRow = {\n _key: crypto.randomUUID(),\n _dirty: true,\n };\n // Pre-fill from quick_add.defaults first, then field-level defaults.\n const quickDefaults = config.quick_add?.defaults ?? {};\n for (const col of editableColumns) {\n const field = childEntity.fields[col];\n if (!field) continue;\n if (quickDefaults[col] !== undefined) {\n newRow[col] = quickDefaults[col];\n } else if (field.default !== undefined) {\n newRow[col] = field.default;\n } else if (field.type === \"bool\") {\n newRow[col] = false;\n }\n }\n onChange([...rows, newRow]);\n }, [rows, onChange, editableColumns, childEntity, config.quick_add?.defaults]);\n\n const handleDeleteRow = useCallback(\n (rowKey: string) => {\n const updated = rows.map((row) =>\n row._key === rowKey ? { ...row, _deleted: true } : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleUndoDelete = useCallback(\n (rowKey: string) => {\n const updated = rows.map((row) =>\n row._key === rowKey ? { ...row, _deleted: false } : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTableElement>) => {\n const target = e.target as HTMLElement;\n const cell = target.closest(\"td\");\n if (!cell) return;\n const row = cell.closest(\"tr\");\n if (!row) return;\n const tbody = row.closest(\"tbody\");\n if (!tbody) return;\n\n const cellIndex = Array.from(row.cells).indexOf(cell as HTMLTableCellElement);\n const rowIndex = Array.from(tbody.rows).indexOf(row as HTMLTableRowElement);\n\n if (e.key === \"Tab\") {\n // Tab/Shift+Tab navigate between editable cells.\n const direction = e.shiftKey ? -1 : 1;\n const allRows = Array.from(tbody.rows);\n let nextRow = rowIndex;\n let nextCell = cellIndex + direction;\n\n // Walk across rows to find next editable cell.\n while (nextRow >= 0 && nextRow < allRows.length) {\n if (nextCell >= 0 && nextCell < allRows[nextRow].cells.length) {\n const nextTd = allRows[nextRow].cells[nextCell];\n const input = nextTd.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (input) {\n e.preventDefault();\n input.focus();\n return;\n }\n nextCell += direction;\n } else {\n // Move to next/previous row.\n nextRow += direction;\n nextCell = direction > 0 ? 0 : (allRows[nextRow]?.cells.length ?? 1) - 1;\n }\n }\n // Let the browser handle focus leaving the table.\n } else if (e.key === \"Enter\") {\n // Enter: move to same column in next row, or add row if at last.\n e.preventDefault();\n const allRows = Array.from(tbody.rows);\n if (rowIndex < allRows.length - 1) {\n const nextTd = allRows[rowIndex + 1].cells[cellIndex];\n const input = nextTd?.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (input) input.focus();\n } else {\n // At last row: add a new row.\n handleAddRow();\n // Focus will happen on next render via autoFocus-like mechanism.\n requestAnimationFrame(() => {\n const newRows = tbody.querySelectorAll(\"tr\");\n const lastRow = newRows[newRows.length - 1];\n if (lastRow) {\n const firstInput = lastRow.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (firstInput) firstInput.focus();\n }\n });\n }\n } else if (e.key === \"Escape\") {\n // Escape: blur the current cell.\n (target as HTMLElement).blur?.();\n }\n },\n [handleAddRow],\n );\n\n return (\n <div>\n <div className=\"overflow-x-auto\">\n <table ref={tableRef} className=\"w-full text-sm\" onKeyDown={handleKeyDown}>\n <thead>\n <tr className=\"border-b\">\n {columns.map((col) => {\n const field = childEntity.fields[col];\n return (\n <th\n key={col}\n className=\"h-8 px-3 text-left align-middle font-medium text-[var(--muted-foreground)]\"\n >\n {field ? fieldDisplayName(field, col, schema.entities) : col}\n </th>\n );\n })}\n <th className=\"h-8 w-10 px-2\" />\n </tr>\n </thead>\n <tbody>\n {rows.map((row) => {\n const isDeleted = !!row._deleted;\n const rowErrors = validationErrors?.[row._key];\n return (\n <tr\n key={row._key}\n className={`border-b last:border-0 ${isDeleted ? \"opacity-50\" : \"\"}`}\n >\n {columns.map((col) => {\n const field = childEntity.fields[col];\n const hasError = rowErrors?.includes(col);\n const isDisplayOnly = displayOnlyColumns.has(col);\n\n if (isDeleted || isDisplayOnly) {\n return (\n <td\n key={col}\n className={`px-3 py-2 align-middle ${isDeleted ? \"line-through\" : \"\"}`}\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"display\",\n record: row as Record<string, unknown>,\n refs,\n })\n : String(row[col] ?? \"\")}\n </td>\n );\n }\n\n return (\n <td\n key={col}\n className={`px-1 py-1 align-middle ${hasError ? \"ring-1 ring-inset ring-[var(--destructive)] rounded\" : \"\"}`}\n title={hasError ? `${col} is required` : undefined}\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"edit\",\n onChange: (val) => handleCellChange(row._key, col, val),\n record: row as Record<string, unknown>,\n refs,\n })\n : String(row[col] ?? \"\")}\n </td>\n );\n })}\n <td className=\"px-2 py-1 align-middle\">\n {isDeleted ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7\"\n onClick={() => handleUndoDelete(row._key)}\n title=\"Undo delete\"\n >\n <Undo2 className=\"h-4 w-4\" />\n </Button>\n ) : (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 text-[var(--muted-foreground)] hover:text-[var(--destructive)]\"\n onClick={() => handleDeleteRow(row._key)}\n title=\"Delete row\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n )}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"mt-2 text-[var(--muted-foreground)]\"\n onClick={handleAddRow}\n >\n <Plus className=\"h-4 w-4 mr-1\" />\n Add row\n </Button>\n </div>\n );\n}\n","import { useCallback, useMemo, useRef } from \"react\";\nimport {\n DndContext,\n closestCenter,\n PointerSensor,\n useSensor,\n useSensors,\n type DragEndEvent,\n} from \"@dnd-kit/core\";\nimport {\n SortableContext,\n verticalListSortingStrategy,\n useSortable,\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { GripVertical, Plus, Trash2, Undo2 } from \"lucide-react\";\nimport { fieldDisplayName } from \"@/types/schema\";\nimport type { Entity, Schema } from \"@/types/schema\";\nimport { renderField } from \"@/components/fields\";\nimport type { RefsMap } from \"@/components/fields\";\nimport { Button } from \"@/components/ui/button\";\nimport type { PendingChildRow } from \"./LayoutRenderer\";\nimport type { ResolvedChildConfig } from \"@/lib/child-config\";\n\ninterface DraggableChildrenTableProps {\n config: ResolvedChildConfig;\n childEntity: Entity;\n schema: Schema;\n rows: PendingChildRow[];\n onChange: (rows: PendingChildRow[]) => void;\n validationErrors?: Record<string, string[]>;\n refs?: RefsMap;\n}\n\n// DraggableChildrenTable renders child rows with drag handles for reordering.\n// Used when position_field is configured on a child relation.\nexport function DraggableChildrenTable({\n config,\n childEntity,\n schema,\n rows,\n onChange,\n validationErrors,\n refs,\n}: DraggableChildrenTableProps) {\n const tableRef = useRef<HTMLTableElement>(null);\n const positionField = config.position_field!;\n const columns = config.columns;\n\n // distance: 5 separates click from drag.\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),\n );\n\n // Editable columns: exclude FK, auto, primary, and position_field.\n const fkSet = new Set(Array.isArray(config.foreign_key) ? config.foreign_key : [config.foreign_key]);\n const editableColumns = columns.filter((col) => {\n if (fkSet.has(col)) return false;\n if (col === positionField) return false;\n const field = childEntity.fields[col];\n if (!field) return false;\n if (field.auto || field.primary) return false;\n return true;\n });\n\n // Display-only columns (auto/primary but visible in column list, or position_field).\n const displayOnlyColumns = new Set(\n columns.filter((col) => {\n if (col === positionField) return true;\n const field = childEntity.fields[col];\n return field && (field.auto || field.primary);\n }),\n );\n\n // Visible columns: exclude position_field from display since it's managed by drag.\n const visibleColumns = columns.filter((col) => col !== positionField);\n\n // Row IDs for SortableContext - only non-deleted rows participate in drag.\n const rowIds = useMemo(\n () => rows.filter((r) => !r._deleted).map((r) => r._key),\n [rows],\n );\n\n const handleCellChange = useCallback(\n (rowKey: string, fieldName: string, value: unknown) => {\n const updated = rows.map((row) =>\n row._key === rowKey\n ? { ...row, [fieldName]: value, _dirty: true }\n : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleAddRow = useCallback(() => {\n const maxPosition = rows\n .filter((r) => !r._deleted)\n .reduce((max, r) => {\n const pos = typeof r[positionField] === \"number\" ? (r[positionField] as number) : -1;\n return Math.max(max, pos);\n }, -1);\n\n const newRow: PendingChildRow = {\n _key: crypto.randomUUID(),\n _dirty: true,\n [positionField]: maxPosition + 1,\n };\n // Pre-fill from quick_add.defaults first, then field-level defaults.\n const quickDefaults = config.quick_add?.defaults ?? {};\n for (const col of editableColumns) {\n const field = childEntity.fields[col];\n if (!field) continue;\n if (quickDefaults[col] !== undefined) {\n newRow[col] = quickDefaults[col];\n } else if (field.default !== undefined) {\n newRow[col] = field.default;\n } else if (field.type === \"bool\") {\n newRow[col] = false;\n }\n }\n onChange([...rows, newRow]);\n }, [rows, onChange, editableColumns, childEntity, config.quick_add?.defaults, positionField]);\n\n const handleDeleteRow = useCallback(\n (rowKey: string) => {\n const updated = rows.map((row) =>\n row._key === rowKey ? { ...row, _deleted: true } : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleUndoDelete = useCallback(\n (rowKey: string) => {\n const updated = rows.map((row) =>\n row._key === rowKey ? { ...row, _deleted: false } : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n const { active, over } = event;\n if (!over || active.id === over.id) return;\n\n // Reorder non-deleted rows.\n const nonDeleted = rows.filter((r) => !r._deleted);\n const deleted = rows.filter((r) => r._deleted);\n\n const oldIndex = nonDeleted.findIndex((r) => r._key === String(active.id));\n const newIndex = nonDeleted.findIndex((r) => r._key === String(over.id));\n if (oldIndex === -1 || newIndex === -1) return;\n\n // Move the row.\n const reordered = [...nonDeleted];\n const [moved] = reordered.splice(oldIndex, 1);\n reordered.splice(newIndex, 0, moved);\n\n // Re-assign sequential position values and mark dirty only if position changed.\n const withPositions = reordered.map((row, index) => ({\n ...row,\n [positionField]: index,\n _dirty: row[positionField] !== index ? true : row._dirty,\n }));\n\n // Append deleted rows at the end (they'll be excluded from payload).\n onChange([...withPositions, ...deleted]);\n },\n [rows, onChange, positionField],\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTableElement>) => {\n const target = e.target as HTMLElement;\n const cell = target.closest(\"td\");\n if (!cell) return;\n const row = cell.closest(\"tr\");\n if (!row) return;\n const tbody = row.closest(\"tbody\");\n if (!tbody) return;\n\n const cellIndex = Array.from(row.cells).indexOf(cell as HTMLTableCellElement);\n const rowIndex = Array.from(tbody.rows).indexOf(row as HTMLTableRowElement);\n\n if (e.key === \"Tab\") {\n const direction = e.shiftKey ? -1 : 1;\n const allRows = Array.from(tbody.rows);\n let nextRow = rowIndex;\n let nextCell = cellIndex + direction;\n\n while (nextRow >= 0 && nextRow < allRows.length) {\n if (nextCell >= 0 && nextCell < allRows[nextRow].cells.length) {\n const nextTd = allRows[nextRow].cells[nextCell];\n const input = nextTd.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (input) {\n e.preventDefault();\n input.focus();\n return;\n }\n nextCell += direction;\n } else {\n nextRow += direction;\n nextCell = direction > 0 ? 0 : (allRows[nextRow]?.cells.length ?? 1) - 1;\n }\n }\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n const allRows = Array.from(tbody.rows);\n if (rowIndex < allRows.length - 1) {\n const nextTd = allRows[rowIndex + 1].cells[cellIndex];\n const input = nextTd?.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (input) input.focus();\n } else {\n handleAddRow();\n requestAnimationFrame(() => {\n const newRows = tbody.querySelectorAll(\"tr\");\n const lastRow = newRows[newRows.length - 1];\n if (lastRow) {\n const firstInput = lastRow.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (firstInput) firstInput.focus();\n }\n });\n }\n } else if (e.key === \"Escape\") {\n (target as HTMLElement).blur?.();\n }\n },\n [handleAddRow],\n );\n\n return (\n <div>\n <div className=\"overflow-x-auto\">\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleDragEnd}\n >\n <table ref={tableRef} className=\"w-full text-sm\" onKeyDown={handleKeyDown}>\n <thead>\n <tr className=\"border-b\">\n <th className=\"h-8 w-8 px-1\" />\n {visibleColumns.map((col) => {\n const field = childEntity.fields[col];\n return (\n <th\n key={col}\n className=\"h-8 px-3 text-left align-middle font-medium text-[var(--muted-foreground)]\"\n >\n {field ? fieldDisplayName(field, col, schema.entities) : col}\n </th>\n );\n })}\n <th className=\"h-8 w-10 px-2\" />\n </tr>\n </thead>\n <SortableContext items={rowIds} strategy={verticalListSortingStrategy}>\n <tbody>\n {rows.map((row) => (\n <SortableRow\n key={row._key}\n row={row}\n columns={visibleColumns}\n editableColumns={editableColumns}\n displayOnlyColumns={displayOnlyColumns}\n childEntity={childEntity}\n validationErrors={validationErrors}\n refs={refs}\n onCellChange={handleCellChange}\n onDelete={handleDeleteRow}\n onUndoDelete={handleUndoDelete}\n />\n ))}\n </tbody>\n </SortableContext>\n </table>\n </DndContext>\n </div>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"mt-2 text-[var(--muted-foreground)]\"\n onClick={handleAddRow}\n >\n <Plus className=\"h-4 w-4 mr-1\" />\n Add row\n </Button>\n </div>\n );\n}\n\n// SortableRow wraps a table row with drag-and-drop support.\ninterface SortableRowProps {\n row: PendingChildRow;\n columns: string[];\n editableColumns: string[];\n displayOnlyColumns: Set<string>;\n childEntity: Entity;\n validationErrors?: Record<string, string[]>;\n refs?: RefsMap;\n onCellChange: (rowKey: string, fieldName: string, value: unknown) => void;\n onDelete: (rowKey: string) => void;\n onUndoDelete: (rowKey: string) => void;\n}\n\nfunction SortableRow({\n row,\n columns,\n editableColumns,\n displayOnlyColumns,\n childEntity,\n validationErrors,\n refs,\n onCellChange,\n onDelete,\n onUndoDelete,\n}: SortableRowProps) {\n const isDeleted = !!row._deleted;\n const rowErrors = validationErrors?.[row._key];\n\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: row._key, disabled: isDeleted });\n\n const style = {\n transform: CSS.Translate.toString(transform),\n transition,\n zIndex: isDragging ? 10 : undefined,\n opacity: isDragging ? 0.5 : undefined,\n };\n\n return (\n <tr\n ref={setNodeRef}\n style={style}\n className={`border-b last:border-0 ${isDeleted ? \"opacity-50\" : \"\"}`}\n >\n <td className=\"px-1 py-1 align-middle w-8\">\n {!isDeleted && (\n <button\n type=\"button\"\n className=\"cursor-grab active:cursor-grabbing p-1 text-[var(--muted-foreground)] hover:text-[var(--foreground)]\"\n {...attributes}\n {...listeners}\n >\n <GripVertical className=\"h-4 w-4\" />\n </button>\n )}\n </td>\n {columns.map((col) => {\n const field = childEntity.fields[col];\n const hasError = rowErrors?.includes(col);\n const isDisplayOnly = displayOnlyColumns.has(col);\n const isEditable = editableColumns.includes(col);\n\n if (isDeleted || isDisplayOnly || !isEditable) {\n return (\n <td\n key={col}\n className={`px-3 py-2 align-middle ${isDeleted ? \"line-through\" : \"\"}`}\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"display\",\n record: row as Record<string, unknown>,\n refs,\n })\n : String(row[col] ?? \"\")}\n </td>\n );\n }\n\n return (\n <td\n key={col}\n className={`px-1 py-1 align-middle ${hasError ? \"ring-1 ring-inset ring-[var(--destructive)] rounded\" : \"\"}`}\n title={hasError ? `${col} is required` : undefined}\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"edit\",\n onChange: (val) => onCellChange(row._key, col, val),\n record: row as Record<string, unknown>,\n refs,\n })\n : String(row[col] ?? \"\")}\n </td>\n );\n })}\n <td className=\"px-2 py-1 align-middle\">\n {isDeleted ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7\"\n onClick={() => onUndoDelete(row._key)}\n title=\"Undo delete\"\n >\n <Undo2 className=\"h-4 w-4\" />\n </Button>\n ) : (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 text-[var(--muted-foreground)] hover:text-[var(--destructive)]\"\n onClick={() => onDelete(row._key)}\n title=\"Delete row\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n )}\n </td>\n </tr>\n );\n}\n","import type { LayoutNode, Schema } from \"@/types/schema\";\nimport { resolveChildConfig, findChildRelation, type ResolvedChildConfig } from \"@/lib/child-config\";\nimport type { LayoutContext } from \"./LayoutRenderer\";\nimport { ChildrenTable } from \"./ChildrenTable\";\nimport { ChildrenList } from \"./ChildrenList\";\nimport { ChildrenCards } from \"./ChildrenCards\";\nimport { ChildrenTimeline } from \"./ChildrenTimeline\";\nimport { EditableChildrenTable } from \"./EditableChildrenTable\";\nimport { DraggableChildrenTable } from \"./DraggableChildrenTable\";\n\ninterface ChildrenBlockProps {\n node: LayoutNode;\n ctx: LayoutContext;\n}\n\nexport interface ChildDisplayProps {\n config: ResolvedChildConfig;\n parentEntity: string;\n parentId: string;\n schema: Schema;\n}\n\n// ChildrenBlock resolves the child config using the three-layer precedence\n// algorithm and dispatches to the appropriate display mode component.\n// In edit mode, dispatches to EditableChildrenTable for table-mode children\n// when editable is true and the child entity is not readonly.\nexport function ChildrenBlock({ node, ctx }: ChildrenBlockProps) {\n const childCode = node.children;\n if (!childCode) return null;\n\n // For non-new records, children cannot be loaded until the parent record exists.\n // For new records in edit mode, we show the editable table with pending data.\n if (ctx.isNew && ctx.mode !== \"edit\") return null;\n\n const relation = findChildRelation(ctx.entity, childCode);\n if (!relation) {\n return (\n <div className=\"text-sm text-[var(--muted-foreground)] py-2\">\n Unknown child relation: {childCode}\n </div>\n );\n }\n\n const childEntity = ctx.schema.entities[relation.entity];\n if (!childEntity) {\n return (\n <div className=\"text-sm text-[var(--muted-foreground)] py-2\">\n Entity not found: {relation.entity}\n </div>\n );\n }\n\n const config = resolveChildConfig(relation, childEntity, node);\n\n // In edit mode, dispatch to EditableChildrenTable for table-mode children\n // when editable is true and the child entity is not readonly.\n if (\n ctx.mode === \"edit\" &&\n config.editable &&\n !childEntity.readonly &&\n config.mode === \"table\" &&\n ctx.pendingChildren !== undefined &&\n ctx.onChildrenChange\n ) {\n const pendingRows = ctx.pendingChildren[childCode] ?? [];\n const validationErrors = ctx.childValidationErrors?.[childCode];\n const TableComponent = config.position_field\n ? DraggableChildrenTable\n : EditableChildrenTable;\n return (\n <TableComponent\n config={config}\n childEntity={childEntity}\n schema={ctx.schema}\n rows={pendingRows}\n onChange={(rows) => ctx.onChildrenChange!(childCode, rows)}\n validationErrors={validationErrors}\n refs={ctx.refs}\n />\n );\n }\n\n // For new records not in editable table mode, nothing to show.\n if (ctx.isNew) return null;\n\n const displayProps: ChildDisplayProps = {\n config,\n parentEntity: ctx.entityCode,\n parentId: ctx.recordId,\n schema: ctx.schema,\n };\n\n switch (config.mode) {\n case \"table\":\n return <ChildrenTable {...displayProps} />;\n case \"list\":\n return <ChildrenList {...displayProps} />;\n case \"cards\":\n return <ChildrenCards {...displayProps} />;\n case \"timeline\":\n return <ChildrenTimeline {...displayProps} />;\n default:\n return <ChildrenTable {...displayProps} />;\n }\n}\n","import { useInfiniteQuery } from \"@tanstack/react-query\";\nimport { apiFetch } from \"@/api/client\";\nimport type { V2ListResponse } from \"@/types/api\";\nimport { ENTITY_CHILDREN_KEY } from \"./useChildrenData\";\n\n/**\n * useAssociatedData fetches associated (non-aggregate) child entity records\n * with cursor-based pagination, search, and filter support.\n *\n * Uses useInfiniteQuery so that \"Load more\" accumulates pages rather than\n * replacing data. The query key is compatible with the SSE invalidation\n * predicate (index 0 = ENTITY_CHILDREN_KEY, index 3 = child entity code).\n */\nexport function useAssociatedData(\n parentEntity: string,\n parentId: string,\n entityCode: string,\n foreignKey: string,\n sort?: string,\n limit?: number,\n search?: string,\n filters?: Record<string, string>,\n) {\n // Stable serialization of filters for query key identity.\n const stableFilters = filters\n ? JSON.stringify(Object.entries(filters).sort())\n : undefined;\n\n return useInfiniteQuery({\n queryKey: [\n ENTITY_CHILDREN_KEY,\n parentEntity,\n parentId,\n entityCode,\n sort,\n limit,\n search,\n stableFilters,\n ],\n queryFn: ({ pageParam }) => {\n const params = new URLSearchParams();\n // Build JSON filter array: FK constraint + any additional filters.\n const filterNodes: Array<{ field: string; op: string; value: unknown }> = [\n { field: foreignKey, op: \"eq\", value: parentId },\n ];\n if (filters) {\n for (const [field, value] of Object.entries(filters)) {\n if (value && value !== \"__all__\") {\n filterNodes.push({ field, op: \"eq\", value });\n }\n }\n }\n params.set(\"filters\", JSON.stringify(filterNodes));\n if (sort) params.set(\"sort\", sort);\n if (limit) params.set(\"limit\", String(limit));\n if (search) params.set(\"search\", search);\n if (pageParam) params.set(\"after\", pageParam);\n return apiFetch<V2ListResponse>(\n `/api/data/${entityCode}?${params.toString()}`,\n );\n },\n getNextPageParam: (lastPage) =>\n lastPage.meta?.has_more ? lastPage.meta.cursor : undefined,\n initialPageParam: undefined as string | undefined,\n enabled:\n !!parentEntity && !!parentId && !!entityCode && !!foreignKey,\n });\n}\n","import { useMemo } from \"react\";\nimport { Search } from \"lucide-react\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { useEntity } from \"@/hooks/useEntity\";\nimport { useEntityData } from \"@/hooks/useEntityData\";\nimport { fieldDisplayName, loc } from \"@/types/schema\";\nimport type { Entity, EntityField } from \"@/types/schema\";\n\ninterface AssociatedToolbarProps {\n entity: Entity;\n searchable?: boolean;\n filterFields?: string[];\n searchValue: string;\n onSearchChange: (value: string) => void;\n filters: Record<string, string>;\n onFilterChange: (field: string, value: string) => void;\n allEntities?: Record<string, Entity>;\n}\n\nexport function AssociatedToolbar({\n entity,\n searchable,\n filterFields,\n searchValue,\n onSearchChange,\n filters,\n onFilterChange,\n allEntities,\n}: AssociatedToolbarProps) {\n const hasSearch = searchable === true;\n const hasFilters = filterFields && filterFields.length > 0;\n\n if (!hasSearch && !hasFilters) return null;\n\n return (\n <div className=\"flex items-center gap-2 mb-2\">\n {hasSearch && (\n <div className=\"relative flex-1 max-w-[200px]\">\n <Search className=\"absolute left-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-[var(--muted-foreground)]\" />\n <Input\n placeholder=\"Search...\"\n value={searchValue}\n onChange={(e) => onSearchChange(e.target.value)}\n className=\"pl-7 h-8 text-sm\"\n />\n </div>\n )}\n {hasFilters &&\n filterFields.map((filterField) => {\n const field = entity.fields[filterField];\n if (!field) return null;\n const currentVal = filters[filterField] ?? \"__all__\";\n const label = fieldDisplayName(field, filterField, allEntities);\n\n if (field.type === \"ref\" && field.ref?.entity) {\n return (\n <RefFilterDropdown\n key={filterField}\n field={field}\n label={label}\n value={currentVal}\n onChange={(v) => onFilterChange(filterField, v)}\n />\n );\n }\n\n if (!field.values) return null;\n return (\n <Select\n key={filterField}\n value={currentVal}\n onValueChange={(v) => onFilterChange(filterField, v)}\n >\n <SelectTrigger className=\"w-[140px] h-8 text-sm\">\n <SelectValue placeholder={label} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__all__\">All {label}</SelectItem>\n {field.values.map((v) => (\n <SelectItem key={v.code} value={v.code}>\n {loc(v.name)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n })}\n </div>\n );\n}\n\nfunction RefFilterDropdown({\n field,\n label,\n value,\n onChange,\n}: {\n field: EntityField;\n label: string;\n value: string;\n onChange: (value: string) => void;\n}) {\n const refEntity = useEntity(field.ref?.entity);\n const displayField =\n field.display?.ref_display_field ?? refEntity?.display?.display_field;\n const pk = useMemo(\n () =>\n refEntity\n ? Object.entries(refEntity.fields).find(([, f]) => f.primary)?.[0] ??\n \"id\"\n : \"id\",\n [refEntity],\n );\n\n const { data: response } = useEntityData(field.ref?.entity, {\n per_page: 200,\n sort: displayField ? `${displayField}:asc` : undefined,\n });\n const options = response?.data ?? [];\n\n const resolveDisplay = (val: unknown): string => {\n if (val == null) return \"-\";\n if (typeof val === \"object\" && !Array.isArray(val)) {\n const first = Object.values(val as Record<string, unknown>)[0];\n return first != null ? String(first) : \"-\";\n }\n return String(val);\n };\n\n return (\n <Select value={value} onValueChange={onChange}>\n <SelectTrigger className=\"w-[140px] h-8 text-sm\">\n <SelectValue placeholder={label} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__all__\">All {label}</SelectItem>\n {options.map((r) => {\n const id = String(r[pk]);\n const optLabel = displayField\n ? resolveDisplay(r[displayField] ?? id)\n : id;\n return (\n <SelectItem key={id} value={id}>\n {optLabel}\n </SelectItem>\n );\n })}\n </SelectContent>\n </Select>\n );\n}\n","import { useState, useCallback, useRef, useMemo, useEffect } from \"react\";\nimport { Plus, Trash2, Check, X, Loader2 } from \"lucide-react\";\nimport { fieldDisplayName, loc } from \"@/types/schema\";\nimport type { LayoutNode, Entity } from \"@/types/schema\";\nimport { renderField } from \"@/components/fields\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport { Button } from \"@/components/ui/button\";\nimport { useChildrenData } from \"@/hooks/useChildrenData\";\nimport { useAssociatedData } from \"@/hooks/useAssociatedData\";\nimport { updateEntity, createEntity, deleteEntity } from \"@/api/data\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { ENTITY_CHILDREN_KEY } from \"@/hooks/useChildrenData\";\nimport { ConfirmDialog } from \"@/components/shared/ConfirmDialog\";\nimport { AssociatedToolbar } from \"./AssociatedToolbar\";\nimport type { LayoutContext } from \"./LayoutRenderer\";\nimport type { Refs } from \"@/types/api\";\n\n// Per-row state for merge-debounce saving.\ninterface AssociatedRowState {\n buffer: Record<string, unknown>; // accumulated dirty fields\n ver: number; // monotonic counter, incremented on every cell change\n saving: boolean; // true while PATCH is in flight\n error?: string; // last save error (cleared on next successful save)\n}\n\ninterface AssociatedBlockProps {\n node: LayoutNode;\n ctx: LayoutContext;\n}\n\n// AssociatedBlock renders a filtered list of an associated entity (independent entity\n// with a FK ref field pointing back to the parent entity). Unlike ChildrenBlock,\n// associated entities are not aggregate children - they have independent lifecycles.\n// Supports inline editing: click-to-edit cells, add/delete rows with immediate saves.\n// When searchable or filters are configured, renders a toolbar and uses cursor-based pagination.\n// Server-side ordering only: set `sort:` on the layout node (e.g. `sort: created_at:desc`).\n// Manual drag-reorder via `position_field` is not supported on associated blocks - it is\n// semantically broken under pagination and prohibitively expensive under per-row save.\n// Use `children:` if you need manual ordering.\nexport function AssociatedBlock({ node, ctx }: AssociatedBlockProps) {\n const assocCode = node.associated;\n if (!assocCode) return null;\n if (ctx.isNew) return null;\n\n const assocEntity = ctx.schema.entities[assocCode];\n if (!assocEntity) {\n return (\n <div className=\"text-sm text-[var(--muted-foreground)] py-2\">\n Entity not found: {assocCode}\n </div>\n );\n }\n\n // Auto-discover FK: find the ref field on the associated entity that points to the parent entity.\n let fkField: string | null = null;\n for (const [fieldName, field] of Object.entries(assocEntity.fields)) {\n if (field.ref?.entity === ctx.entityCode) {\n fkField = fieldName;\n break;\n }\n }\n\n if (!fkField) {\n return (\n <div className=\"text-sm text-[var(--muted-foreground)] py-2\">\n No FK found for {assocCode} -&gt; {ctx.entityCode}\n </div>\n );\n }\n\n // Determine columns: use node.columns override or infer from field_order.\n const columns = node.columns && node.columns.length > 0\n ? node.columns.filter((col) => {\n if (col === fkField) return false;\n const field = assocEntity.fields[col];\n return !!field;\n })\n : (assocEntity.field_order ?? Object.keys(assocEntity.fields)).filter(\n (col) => {\n if (col === fkField) return false;\n const field = assocEntity.fields[col];\n if (!field) return false;\n if (field.primary) return false;\n if (field.display?.is_listable === false) return false;\n return true;\n },\n );\n\n // Resolve editable: node.editable overrides, default true.\n // Entity readonly forces read-only.\n const editable = assocEntity.readonly ? false : (node.editable !== false);\n\n const label = loc(assocEntity.display?.name_plural) || loc(assocEntity.display?.name) || assocCode;\n\n // Determine if toolbar features are enabled.\n const hasToolbar = node.searchable === true || (node.filters && node.filters.length > 0);\n\n return (\n <div>\n <h3 className=\"text-sm font-medium text-[var(--muted-foreground)] mb-2\">{label}</h3>\n {hasToolbar ? (\n <PaginatedAssociatedTable\n entityCode={assocCode}\n entity={assocEntity}\n parentEntity={ctx.entityCode}\n parentId={ctx.recordId}\n foreignKey={fkField}\n columns={columns}\n editable={editable}\n ctx={ctx}\n searchable={node.searchable}\n filterFields={node.filters}\n sort={node.sort}\n />\n ) : (\n <SimpleAssociatedTable\n entityCode={assocCode}\n entity={assocEntity}\n parentEntity={ctx.entityCode}\n parentId={ctx.recordId}\n foreignKey={fkField}\n columns={columns}\n editable={editable}\n ctx={ctx}\n sort={node.sort}\n />\n )}\n </div>\n );\n}\n\n// SimpleAssociatedTable uses the original useChildrenData hook (no search/filter/pagination).\ninterface SimpleTableProps {\n entityCode: string;\n entity: Entity;\n parentEntity: string;\n parentId: string;\n foreignKey: string;\n columns: string[];\n editable: boolean;\n ctx: LayoutContext;\n sort?: string;\n}\n\nfunction SimpleAssociatedTable({\n entityCode,\n entity,\n parentEntity,\n parentId,\n foreignKey,\n columns,\n editable,\n ctx,\n sort,\n}: SimpleTableProps) {\n const queryClient = useQueryClient();\n const { data: response, isLoading, isError } = useChildrenData(\n parentEntity,\n parentId,\n entityCode,\n foreignKey,\n sort,\n );\n const rows = response?.data ?? [];\n const refs = response?.$refs;\n\n const invalidateQuery = useCallback(() => {\n queryClient.invalidateQueries({\n queryKey: [ENTITY_CHILDREN_KEY, parentEntity, parentId, entityCode],\n });\n }, [queryClient, parentEntity, parentId, entityCode]);\n\n return (\n <AssociatedTableInner\n entityCode={entityCode}\n entity={entity}\n parentId={parentId}\n foreignKey={foreignKey}\n columns={columns}\n editable={editable}\n ctx={ctx}\n rows={rows}\n refs={refs}\n isLoading={isLoading}\n isError={isError}\n invalidateQuery={invalidateQuery}\n />\n );\n}\n\n// PaginatedAssociatedTable uses useAssociatedData with search/filter/pagination support.\ninterface PaginatedTableProps extends SimpleTableProps {\n searchable?: boolean;\n filterFields?: string[];\n}\n\nfunction PaginatedAssociatedTable({\n entityCode,\n entity,\n parentEntity,\n parentId,\n foreignKey,\n columns,\n editable,\n ctx,\n searchable,\n filterFields,\n sort,\n}: PaginatedTableProps) {\n const queryClient = useQueryClient();\n\n // Search and filter state.\n const [searchValue, setSearchValue] = useState(\"\");\n const [debouncedSearch, setDebouncedSearch] = useState(\"\");\n const [filters, setFilters] = useState<Record<string, string>>({});\n const searchTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n // Debounce search input.\n useEffect(() => {\n if (searchTimerRef.current) clearTimeout(searchTimerRef.current);\n searchTimerRef.current = setTimeout(() => {\n setDebouncedSearch(searchValue);\n }, 300);\n return () => {\n if (searchTimerRef.current) clearTimeout(searchTimerRef.current);\n };\n }, [searchValue]);\n\n const handleFilterChange = useCallback((field: string, value: string) => {\n setFilters((prev) => {\n if (value === \"__all__\") {\n const { [field]: _, ...rest } = prev;\n return rest;\n }\n return { ...prev, [field]: value };\n });\n }, []);\n\n // Active filters for the API call.\n const activeFilters = useMemo(() => {\n return Object.keys(filters).length > 0 ? filters : undefined;\n }, [filters]);\n\n const {\n data: infiniteData,\n isLoading,\n isError,\n hasNextPage,\n fetchNextPage,\n isFetchingNextPage,\n } = useAssociatedData(\n parentEntity,\n parentId,\n entityCode,\n foreignKey,\n sort,\n undefined, // limit\n debouncedSearch || undefined,\n activeFilters,\n );\n\n // Flatten pages into a single rows array and merge refs.\n const { rows, refs } = useMemo(() => {\n if (!infiniteData?.pages) return { rows: [] as Record<string, unknown>[], refs: undefined as Refs | undefined };\n const allRows: Record<string, unknown>[] = [];\n let mergedRefs: Refs | undefined;\n for (const page of infiniteData.pages) {\n allRows.push(...page.data);\n if (page.$refs) {\n if (!mergedRefs) {\n mergedRefs = { ...page.$refs };\n } else {\n for (const [entityKey, records] of Object.entries(page.$refs)) {\n mergedRefs[entityKey] = { ...mergedRefs[entityKey], ...records };\n }\n }\n }\n }\n return { rows: allRows, refs: mergedRefs };\n }, [infiniteData]);\n\n const invalidateQuery = useCallback(() => {\n queryClient.invalidateQueries({\n predicate: (query) => {\n const key = query.queryKey;\n return key[0] === ENTITY_CHILDREN_KEY && key[3] === entityCode;\n },\n });\n }, [queryClient, entityCode]);\n\n return (\n <div>\n <AssociatedToolbar\n entity={entity}\n searchable={searchable}\n filterFields={filterFields}\n searchValue={searchValue}\n onSearchChange={setSearchValue}\n filters={filters}\n onFilterChange={handleFilterChange}\n allEntities={ctx.schema.entities}\n />\n <AssociatedTableInner\n entityCode={entityCode}\n entity={entity}\n parentId={parentId}\n foreignKey={foreignKey}\n columns={columns}\n editable={editable}\n ctx={ctx}\n rows={rows}\n refs={refs}\n isLoading={isLoading}\n isError={isError}\n invalidateQuery={invalidateQuery}\n />\n {hasNextPage && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"mt-1 text-[var(--muted-foreground)]\"\n onClick={() => fetchNextPage()}\n disabled={isFetchingNextPage}\n >\n {isFetchingNextPage ? (\n <Loader2 className=\"h-4 w-4 mr-1 animate-spin\" />\n ) : null}\n Load more\n </Button>\n )}\n </div>\n );\n}\n\n// AssociatedTableInner is the shared table rendering logic used by both simple and paginated modes.\ninterface TableInnerProps {\n entityCode: string;\n entity: Entity;\n parentId: string;\n foreignKey: string;\n columns: string[];\n editable: boolean;\n ctx: LayoutContext;\n rows: Record<string, unknown>[];\n refs?: Refs;\n isLoading: boolean;\n isError: boolean;\n invalidateQuery: () => void;\n}\n\nfunction AssociatedTableInner({\n entityCode,\n entity,\n parentId,\n foreignKey,\n columns,\n editable,\n ctx,\n rows,\n refs,\n isLoading,\n isError,\n invalidateQuery,\n}: TableInnerProps) {\n // Editable columns: exclude FK, auto, primary.\n const editableColumns = useMemo(() => {\n if (!editable) return new Set<string>();\n return new Set(\n columns.filter((col) => {\n if (col === foreignKey) return false;\n const field = entity.fields[col];\n if (!field) return false;\n if (field.auto || field.primary) return false;\n return true;\n }),\n );\n }, [columns, foreignKey, entity.fields, editable]);\n\n // Per-row edit state: which cell is active (click-to-edit).\n const [activeCell, setActiveCell] = useState<{ rowId: string; col: string } | null>(null);\n // Per-row merge-debounce state.\n const [rowStates, setRowStates] = useState<Record<string, AssociatedRowState>>({});\n const rowStatesRef = useRef(rowStates);\n rowStatesRef.current = rowStates;\n const debounceTimers = useRef<Record<string, ReturnType<typeof setTimeout>>>({});\n\n // Clean up debounce timers on unmount.\n useEffect(() => {\n const timers = debounceTimers.current;\n return () => {\n for (const t of Object.values(timers)) clearTimeout(t);\n };\n }, []);\n\n // Draft row state for \"Add row\" flow.\n const [draftRow, setDraftRow] = useState<Record<string, unknown> | null>(null);\n const [draftErrors, setDraftErrors] = useState<string[]>([]);\n const [draftSaving, setDraftSaving] = useState(false);\n\n // Delete confirmation state.\n const [deleteConfirm, setDeleteConfirm] = useState<{ show: boolean; rowId: string; label: string } | null>(null);\n const [deletingIds, setDeletingIds] = useState<Set<string>>(new Set());\n\n // Flush a row's buffer as a single PATCH.\n const flushRow = useCallback(\n async (rowId: string, buffer: Record<string, unknown>, sentVer: number) => {\n setRowStates((prev) => ({\n ...prev,\n [rowId]: { ...prev[rowId], saving: true, error: undefined },\n }));\n try {\n await updateEntity(entityCode, rowId, buffer);\n setRowStates((prev) => {\n const current = prev[rowId];\n if (!current) return prev;\n // Drop stale response: if user made more edits, don't clear buffer.\n if (current.ver > sentVer) {\n return { ...prev, [rowId]: { ...current, saving: false } };\n }\n // Response is current: clear buffer.\n const { [rowId]: _, ...rest } = prev;\n return rest;\n });\n invalidateQuery();\n } catch (err) {\n const msg = err instanceof Error ? err.message : \"Save failed\";\n setRowStates((prev) => ({\n ...prev,\n [rowId]: { ...prev[rowId], saving: false, error: msg },\n }));\n }\n },\n [entityCode, invalidateQuery],\n );\n\n // Handle cell value change with merge-debounce.\n const handleCellChange = useCallback(\n (rowId: string, fieldName: string, value: unknown) => {\n setRowStates((prev) => {\n const current = prev[rowId] ?? { buffer: {}, ver: 0, saving: false };\n const nextVer = current.ver + 1;\n return {\n ...prev,\n [rowId]: {\n ...current,\n buffer: { ...current.buffer, [fieldName]: value },\n ver: nextVer,\n },\n };\n });\n // Reset debounce timer.\n if (debounceTimers.current[rowId]) {\n clearTimeout(debounceTimers.current[rowId]);\n }\n debounceTimers.current[rowId] = setTimeout(() => {\n const current = rowStatesRef.current[rowId];\n if (current && Object.keys(current.buffer).length > 0) {\n flushRow(rowId, { ...current.buffer }, current.ver);\n }\n }, 500);\n },\n [flushRow],\n );\n\n // Handle adding a new draft row.\n const handleStartDraft = useCallback(() => {\n const draft: Record<string, unknown> = {};\n // Pre-fill FK to parent.\n draft[foreignKey] = parentId;\n // Pre-fill field-level defaults, then bool fallback.\n for (const col of columns) {\n const field = entity.fields[col];\n if (!field) continue;\n if (field.default !== undefined) {\n draft[col] = field.default;\n } else if (field.type === \"bool\") {\n draft[col] = false;\n }\n }\n setDraftRow(draft);\n setDraftErrors([]);\n }, [foreignKey, parentId, columns, entity.fields]);\n\n // Validate and confirm the draft row.\n const handleConfirmDraft = useCallback(async () => {\n if (!draftRow) return;\n // Client-side required field validation.\n const errors: string[] = [];\n for (const col of columns) {\n const field = entity.fields[col];\n if (!field || !field.required) continue;\n if (field.auto || field.primary) continue;\n if (col === foreignKey) continue;\n const val = draftRow[col];\n if (val == null || val === \"\") {\n errors.push(col);\n }\n }\n if (errors.length > 0) {\n setDraftErrors(errors);\n return;\n }\n setDraftSaving(true);\n try {\n await createEntity(entityCode, draftRow);\n setDraftRow(null);\n setDraftErrors([]);\n invalidateQuery();\n } catch (err) {\n const msg = err instanceof Error ? err.message : \"Create failed\";\n setDraftErrors([`_error:${msg}`]);\n } finally {\n setDraftSaving(false);\n }\n }, [draftRow, columns, entity.fields, foreignKey, entityCode, invalidateQuery]);\n\n // Handle delete row with confirmation.\n const handleDeleteRow = useCallback(\n async (rowId: string) => {\n setDeleteConfirm(null);\n setDeletingIds((prev) => new Set(prev).add(rowId));\n try {\n await deleteEntity(entityCode, rowId);\n invalidateQuery();\n } catch {\n // On error, just remove from deleting set - row stays visible.\n } finally {\n setDeletingIds((prev) => {\n const next = new Set(prev);\n next.delete(rowId);\n return next;\n });\n }\n },\n [entityCode, invalidateQuery],\n );\n\n if (isError) {\n return <div className=\"text-sm text-[var(--destructive)] py-2\">Failed to load.</div>;\n }\n\n if (isLoading) {\n return (\n <div className=\"space-y-2 py-2\">\n <Skeleton className=\"h-8 w-full\" />\n <Skeleton className=\"h-8 w-full\" />\n </div>\n );\n }\n\n const showEmpty = rows.length === 0 && !draftRow;\n\n return (\n <div>\n {showEmpty && !editable && (\n <div className=\"text-sm text-[var(--muted-foreground)] py-4\">\n No records yet.\n </div>\n )}\n {(!showEmpty || editable) && (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b\">\n {columns.map((col) => {\n const field = entity.fields[col];\n return (\n <th\n key={col}\n className=\"h-8 px-3 text-left align-middle font-medium text-[var(--muted-foreground)]\"\n >\n {field ? fieldDisplayName(field, col, ctx.schema.entities) : col}\n </th>\n );\n })}\n {editable && <th className=\"h-8 w-10 px-2\" />}\n </tr>\n </thead>\n <tbody>\n {rows.map((row) => {\n const rowId = String((row as Record<string, unknown>)[\"id\"] ?? \"\");\n const isDeleting = deletingIds.has(rowId);\n const rowState = rowStates[rowId];\n return (\n <AssociatedRow\n key={rowId}\n rowId={rowId}\n row={row}\n entity={entity}\n columns={columns}\n editableColumns={editableColumns}\n editable={editable}\n isDeleting={isDeleting}\n activeCell={activeCell}\n setActiveCell={setActiveCell}\n rowState={rowState}\n onCellChange={handleCellChange}\n onDeleteClick={(id) => {\n const displayField = entity.display?.display_field;\n const label = displayField ? String(row[displayField] ?? \"\") : \"\";\n setDeleteConfirm({ show: true, rowId: id, label });\n }}\n refs={refs}\n />\n );\n })}\n {draftRow && (\n <DraftRow\n draftRow={draftRow}\n entity={entity}\n columns={columns}\n editableColumns={editableColumns}\n foreignKey={foreignKey}\n draftErrors={draftErrors}\n draftSaving={draftSaving}\n onChange={(field, value) =>\n setDraftRow((prev) => (prev ? { ...prev, [field]: value } : prev))\n }\n onConfirm={handleConfirmDraft}\n onCancel={() => {\n setDraftRow(null);\n setDraftErrors([]);\n }}\n refs={refs}\n />\n )}\n </tbody>\n </table>\n </div>\n )}\n {editable && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"mt-2 text-[var(--muted-foreground)]\"\n onClick={handleStartDraft}\n disabled={!!draftRow}\n >\n <Plus className=\"h-4 w-4 mr-1\" />\n Add row\n </Button>\n )}\n {deleteConfirm && (\n <ConfirmDialog\n open={deleteConfirm.show}\n onOpenChange={(open) => !open && setDeleteConfirm(null)}\n title=\"Delete record\"\n description={\n deleteConfirm.label\n ? `Are you sure you want to delete \"${deleteConfirm.label}\"?`\n : \"Are you sure you want to delete this record?\"\n }\n confirmLabel=\"Delete\"\n onConfirm={() => handleDeleteRow(deleteConfirm.rowId)}\n destructive\n />\n )}\n </div>\n );\n}\n\n// AssociatedRow renders a single data row with click-to-edit support.\ninterface AssociatedRowProps {\n rowId: string;\n row: Record<string, unknown>;\n entity: Entity;\n columns: string[];\n editableColumns: Set<string>;\n editable: boolean;\n isDeleting: boolean;\n activeCell: { rowId: string; col: string } | null;\n setActiveCell: (cell: { rowId: string; col: string } | null) => void;\n rowState?: AssociatedRowState;\n onCellChange: (rowId: string, fieldName: string, value: unknown) => void;\n onDeleteClick: (rowId: string) => void;\n refs?: Refs;\n}\n\nfunction AssociatedRow({\n rowId,\n row,\n entity,\n columns,\n editableColumns,\n editable,\n isDeleting,\n activeCell,\n setActiveCell,\n rowState,\n onCellChange,\n onDeleteClick,\n refs,\n}: AssociatedRowProps) {\n // Merge buffer values over server data for display while editing.\n const displayRow = useMemo(() => {\n if (!rowState || Object.keys(rowState.buffer).length === 0) return row;\n return { ...row, ...rowState.buffer };\n }, [row, rowState]);\n\n return (\n <tr\n className={`border-b last:border-0 hover:bg-[var(--muted)]/50 ${isDeleting ? \"opacity-50\" : \"\"}`}\n >\n {columns.map((col) => {\n const field = entity.fields[col];\n const isEditable = editableColumns.has(col);\n const isActive = activeCell?.rowId === rowId && activeCell?.col === col;\n\n if (isActive && isEditable) {\n return (\n <td\n key={col}\n className=\"px-1 py-1 align-middle\"\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: displayRow[col],\n mode: \"edit\",\n onChange: (val) => onCellChange(rowId, col, val),\n record: displayRow,\n refs,\n })\n : String(displayRow[col] ?? \"\")}\n </td>\n );\n }\n\n return (\n <td\n key={col}\n className={`px-3 py-2 align-middle ${isEditable ? \"cursor-pointer\" : \"\"}`}\n onClick={\n isEditable && !isDeleting\n ? () => setActiveCell({ rowId, col })\n : undefined\n }\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: displayRow[col],\n mode: \"display\",\n record: displayRow,\n refs,\n })\n : String(displayRow[col] ?? \"\")}\n </td>\n );\n })}\n {editable && (\n <td className=\"px-2 py-1 align-middle\">\n <div className=\"flex items-center gap-1\">\n {rowState?.saving && (\n <Loader2 className=\"h-3 w-3 animate-spin text-[var(--muted-foreground)]\" />\n )}\n {rowState?.error && (\n <span className=\"text-xs text-[var(--destructive)]\" title={rowState.error}>!</span>\n )}\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 text-[var(--muted-foreground)] hover:text-[var(--destructive)]\"\n onClick={() => onDeleteClick(rowId)}\n disabled={isDeleting}\n title=\"Delete row\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n </td>\n )}\n </tr>\n );\n}\n\n// DraftRow renders the inline draft for new row creation.\ninterface DraftRowProps {\n draftRow: Record<string, unknown>;\n entity: Entity;\n columns: string[];\n editableColumns: Set<string>;\n foreignKey: string;\n draftErrors: string[];\n draftSaving: boolean;\n onChange: (field: string, value: unknown) => void;\n onConfirm: () => void;\n onCancel: () => void;\n refs?: Refs;\n}\n\nfunction DraftRow({\n draftRow,\n entity,\n columns,\n editableColumns,\n foreignKey,\n draftErrors,\n draftSaving,\n onChange,\n onConfirm,\n onCancel,\n refs,\n}: DraftRowProps) {\n const apiError = draftErrors.find((e) => e.startsWith(\"_error:\"));\n const fieldErrors = new Set(draftErrors.filter((e) => !e.startsWith(\"_error:\")));\n\n return (\n <tr className=\"border-b last:border-0 border-dashed bg-[var(--muted)]/30\">\n {columns.map((col) => {\n const field = entity.fields[col];\n const isEditable = editableColumns.has(col) && col !== foreignKey;\n const hasError = fieldErrors.has(col);\n\n if (!isEditable) {\n return (\n <td key={col} className=\"px-3 py-2 align-middle text-[var(--muted-foreground)]\">\n {field?.auto ? \"-\" : String(draftRow[col] ?? \"\")}\n </td>\n );\n }\n\n return (\n <td\n key={col}\n className={`px-1 py-1 align-middle ${hasError ? \"ring-1 ring-inset ring-[var(--destructive)] rounded\" : \"\"}`}\n title={hasError ? `${col} is required` : undefined}\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: draftRow[col],\n mode: \"edit\",\n onChange: (val) => onChange(col, val),\n record: draftRow,\n refs,\n })\n : String(draftRow[col] ?? \"\")}\n </td>\n );\n })}\n <td className=\"px-2 py-1 align-middle\">\n <div className=\"flex items-center gap-1\">\n {apiError && (\n <span className=\"text-xs text-[var(--destructive)]\" title={apiError.slice(7)}>!</span>\n )}\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 text-[var(--primary)]\"\n onClick={onConfirm}\n disabled={draftSaving}\n title=\"Confirm\"\n >\n {draftSaving ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Check className=\"h-4 w-4\" />}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 text-[var(--muted-foreground)]\"\n onClick={onCancel}\n disabled={draftSaving}\n title=\"Cancel\"\n >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n </td>\n </tr>\n );\n}\n","import { fieldDisplayName } from \"@/types/schema\";\nimport type { LayoutField } from \"@/types/schema\";\nimport { renderField } from \"@/components/fields\";\nimport { ActionButton } from \"@/components/shared/ActionButton\";\nimport { cn } from \"@/lib/utils\";\nimport type { LayoutContext } from \"./LayoutRenderer\";\n\ninterface FieldsBlockProps {\n fields: LayoutField[];\n ctx: LayoutContext;\n}\n\n// FieldsBlock renders a list of fields without section chrome (no card, no\n// header). Useful for header-style field blocks or inline field groups.\n// When ctx.columns is 1, renders label above value (stacked, full width).\n// When ctx.columns is 2 (default), renders label beside value (side-by-side).\n// Per-field screen-scoped action buttons (LayoutField.actions) render as\n// icon-size buttons to the right of the field value, in display mode only.\nexport function FieldsBlock({ fields, ctx }: FieldsBlockProps) {\n const { entity, entityCode, record, mode, onFieldChange, schema } = ctx;\n const columns = ctx.columns ?? 2;\n // When columns=1 and there's only one field, the section header already\n // serves as label - skip the redundant field label.\n const hideLabels = columns === 1 && fields.length === 1;\n\n return (\n <div className={cn(\n \"grid gap-x-6 gap-y-3\",\n columns === 1 ? \"grid-cols-1\" : \"grid-cols-1 md:grid-cols-2\",\n )}>\n {fields.map((layoutField) => {\n const fieldName = layoutField.name;\n const field = entity.fields[fieldName];\n if (!field) return null;\n const value = record[fieldName];\n const hasActions = mode === \"display\" && layoutField.actions && layoutField.actions.length > 0;\n return (\n <div\n key={fieldName}\n className={columns === 1 ? \"flex flex-col gap-1\" : \"flex flex-col md:flex-row gap-1\"}\n >\n {!hideLabels && (\n <div className={cn(\n \"text-sm text-[var(--muted-foreground)]\",\n columns === 2 && \"md:w-40 md:pt-0.5\",\n )}>\n {fieldDisplayName(field, fieldName, schema.entities)}\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-start gap-1\">\n <div className=\"flex-1 min-w-0\">\n {renderField({\n field,\n fieldName,\n value,\n mode,\n onChange: onFieldChange\n ? (v: unknown) => onFieldChange(fieldName, v)\n : undefined,\n record,\n refs: ctx.refs,\n })}\n </div>\n {hasActions && (\n <div className=\"flex items-center gap-1 shrink-0\">\n {layoutField.actions!.map((action, i) => (\n <ActionButton\n key={i}\n actionCode={`${fieldName}.action[${i}]`}\n action={action}\n entityCode={entityCode}\n row={record}\n variant=\"ghost\"\n size=\"icon\"\n />\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n","import { useCallback, useEffect, useRef } from \"react\";\nimport { renderField } from \"@/components/fields\";\nimport { loc, propertyToField } from \"@/types/schema\";\nimport type { LayoutNode } from \"@/types/schema\";\nimport type { LayoutContext } from \"./LayoutRenderer\";\n\ninterface PropertiesBlockProps {\n node: LayoutNode;\n ctx: LayoutContext;\n}\n\n// Types where onChange fires on every keystroke and needs debouncing.\nconst DEBOUNCE_TYPES = new Set([\"string\", \"text\", \"int\", \"float\", \"decimal\", \"email\", \"url\"]);\nconst DEBOUNCE_MS = 500;\n\n// PropertiesBlock renders object properties using the same rich field renderers as entity fields.\nexport function PropertiesBlock({ node, ctx }: PropertiesBlockProps) {\n const { entity, objectProperties, onSetProperty, isNew, mode, refs } = ctx;\n const propertyDefs = entity.properties ?? {};\n\n // A brand-new record (pre-create) has no properties to render — the row\n // doesn't exist yet in the DB. In all other cases render the property\n // values; in display mode they're read-only, in edit mode they need\n // onSetProperty to propagate changes (gated per-property below).\n if (isNew) return null;\n\n // node.properties is true (all) or an array of property codes (subset).\n const filter: string[] | true = node.properties === true ? true : (node.properties as string[]);\n\n // When filter is an array, preserve its explicit order; otherwise sort alphabetically.\n const entries: [string, import(\"@/types/schema\").PropertyDef][] = filter === true\n ? Object.entries(propertyDefs).sort(([a], [b]) => a.localeCompare(b))\n : (filter as string[])\n .filter((code) => propertyDefs[code] != null)\n .map((code) => [code, propertyDefs[code]]);\n\n if (entries.length === 0) return null;\n\n return (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-3\">\n {entries.map(([propCode, prop]) => {\n const propVal = objectProperties?.find((p) => p.property_code === propCode);\n const field = propertyToField(prop);\n // Force display mode when the outer page has no write callback\n // (readonly entity, or view mode on a detail page) — even if the\n // property itself is writable.\n const effectiveMode = (prop.readonly || !onSetProperty) ? \"display\" : mode;\n\n return (\n <DebouncedProperty\n key={propCode}\n propCode={propCode}\n prop={prop}\n field={field}\n value={propVal?.value}\n mode={effectiveMode}\n onSetProperty={onSetProperty}\n refs={refs}\n />\n );\n })}\n </div>\n );\n}\n\n// DebouncedProperty wraps a single property field with optional debounce for text-like types.\n// onSetProperty is optional — omit it (display-mode / read-only containers) and the field\n// renders without an onChange handler.\nfunction DebouncedProperty({\n propCode,\n prop,\n field,\n value,\n mode,\n onSetProperty,\n refs,\n}: {\n propCode: string;\n prop: { name: import(\"@/types/schema\").LocalizedString; display?: { name: import(\"@/types/schema\").LocalizedString }; type: string };\n field: import(\"@/types/schema\").EntityField;\n value: unknown;\n mode: \"display\" | \"edit\";\n onSetProperty?: (code: string, value: unknown) => void;\n refs?: import(\"@/components/fields\").RefsMap;\n}) {\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (timerRef.current) clearTimeout(timerRef.current);\n };\n }, []);\n\n const onChange = useCallback(\n (v: unknown) => {\n if (!onSetProperty) return;\n if (DEBOUNCE_TYPES.has(prop.type)) {\n if (timerRef.current) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => onSetProperty(propCode, v), DEBOUNCE_MS);\n } else {\n onSetProperty(propCode, v);\n }\n },\n [propCode, prop.type, onSetProperty],\n );\n\n return (\n <div className=\"flex flex-col md:flex-row gap-1\">\n <div className=\"md:w-40 md:pt-0.5 text-sm text-[var(--muted-foreground)]\">\n {loc(prop.display?.name ?? prop.name)}\n </div>\n <div className=\"flex-1 min-w-0\">\n {renderField({\n field,\n fieldName: propCode,\n value,\n mode,\n onChange: mode === \"edit\" ? onChange : undefined,\n refs,\n })}\n </div>\n </div>\n );\n}\n","import { Badge } from \"@/components/ui/badge\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { loc } from \"@/types/schema\";\nimport type { StatusGroupDef } from \"@/types/schema\";\nimport type { StatusInfo } from \"@/types/api\";\n\ninterface StatusGroupsDisplayProps {\n statusGroups: Record<string, StatusGroupDef>;\n objectStatuses: StatusInfo[] | undefined;\n onSetStatus: (groupCode: string, statusCode: string) => void;\n isPending: boolean;\n mode?: \"display\" | \"edit\";\n}\n\n// StatusGroupsDisplay renders status group selectors with colored badges.\n// In display mode: read-only badges. In edit mode: interactive dropdowns.\nexport function StatusGroupsDisplay({\n statusGroups,\n objectStatuses,\n onSetStatus,\n isPending,\n mode = \"edit\",\n}: StatusGroupsDisplayProps) {\n return (\n <div className=\"flex flex-wrap items-center gap-4\">\n {Object.entries(statusGroups).map(([sgCode, sg]) => {\n const current = objectStatuses?.find((s) => s.group_code === sgCode);\n const currentCode = current?.status_code;\n const currentStatus = currentCode ? sg.statuses.find((s) => s.code === currentCode) : undefined;\n\n // Display mode: read-only badge\n if (mode === \"display\") {\n return (\n <div key={sgCode} className=\"flex items-center gap-2\">\n <span className=\"text-sm text-[var(--muted-foreground)]\">{loc(sg.name)}:</span>\n {currentStatus ? (\n <Badge\n className=\"text-xs\"\n style={{\n backgroundColor: currentStatus.color || undefined,\n color: currentStatus.color ? \"#fff\" : undefined,\n }}\n >\n {loc(currentStatus.name)}\n </Badge>\n ) : (\n <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>\n )}\n </div>\n );\n }\n\n // Edit mode: interactive dropdown\n const available = sg.transitions && currentCode\n ? sg.statuses.filter(\n (s) =>\n s.code === currentCode ||\n (sg.transitions![currentCode]?.includes(s.code) ?? false),\n )\n : sg.statuses;\n\n return (\n <div key={sgCode} className=\"flex items-center gap-2\">\n <span className=\"text-sm text-[var(--muted-foreground)]\">{loc(sg.name)}:</span>\n <Select\n value={currentCode ?? \"\"}\n onValueChange={(statusCode) => onSetStatus(sgCode, statusCode)}\n disabled={isPending}\n >\n <SelectTrigger className=\"w-[180px]\">\n <SelectValue>\n {currentStatus ? (\n <Badge\n className=\"text-xs\"\n style={{\n backgroundColor: currentStatus.color || undefined,\n color: currentStatus.color ? \"#fff\" : undefined,\n }}\n >\n {loc(currentStatus.name)}\n </Badge>\n ) : (\n \"Select...\"\n )}\n </SelectValue>\n </SelectTrigger>\n <SelectContent>\n {available.map((s) => (\n <SelectItem key={s.code} value={s.code}>\n <div className=\"flex items-center gap-2\">\n {s.color && (\n <span\n className=\"w-2.5 h-2.5 rounded-full inline-block\"\n style={{ backgroundColor: s.color }}\n />\n )}\n {loc(s.name)}\n </div>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n );\n })}\n </div>\n );\n}\n","import { StatusGroupsDisplay } from \"@/components/shared/StatusGroupsDisplay\";\nimport type { LayoutNode } from \"@/types/schema\";\nimport type { LayoutContext } from \"./LayoutRenderer\";\n\nconst noop = () => {};\n\ninterface StatusesBlockProps {\n node: LayoutNode;\n ctx: LayoutContext;\n}\n\n// StatusesBlock renders status group selectors for a `statuses: true` layout node.\n// Filters to a subset of status groups if the node value is an array of group codes.\nexport function StatusesBlock({ node, ctx }: StatusesBlockProps) {\n const { entity, objectStatuses, onSetStatus, isStatusPending, isNew } = ctx;\n const statusGroups = entity.status_groups ?? {};\n\n if (isNew) return null;\n\n // node.statuses is true (all groups) or an array of group codes (subset).\n const filter: string[] | true = node.statuses === true ? true : (node.statuses as string[]);\n\n const filtered = Object.fromEntries(\n Object.entries(statusGroups).filter(\n ([code]) => filter === true || (filter as string[]).includes(code),\n ),\n );\n\n if (Object.keys(filtered).length === 0) return null;\n\n return (\n <StatusGroupsDisplay\n statusGroups={filtered}\n objectStatuses={objectStatuses}\n onSetStatus={onSetStatus ?? noop}\n isPending={isStatusPending ?? false}\n mode={ctx.mode}\n />\n );\n}\n","import type { Entity, LayoutNode, Schema } from \"@/types/schema\";\nimport type { StatusInfo, PropertyValue } from \"@/types/api\";\nimport { LayoutRow } from \"./LayoutRow\";\nimport { LayoutColumn } from \"./LayoutColumn\";\nimport { LayoutTabs } from \"./LayoutTabs\";\nimport { SectionBlock } from \"./SectionBlock\";\nimport { ChildrenBlock } from \"./ChildrenBlock\";\nimport { AssociatedBlock } from \"./AssociatedBlock\";\nimport { FieldsBlock } from \"./FieldsBlock\";\nimport { PropertiesBlock } from \"./PropertiesBlock\";\nimport { StatusesBlock } from \"./StatusesBlock\";\n\nimport type { RefsMap } from \"@/components/fields\";\n\n// PendingChildRow represents a single child row in the pending edit state.\n// Used for direct (aggregate) children during parent edit mode.\nexport interface PendingChildRow {\n _key: string; // stable React key (id for existing, nanoid() for new)\n _deleted?: boolean; // marked for deletion (shown with strikethrough, excluded from save)\n _dirty?: boolean; // has any field been modified since edit mode started\n [field: string]: unknown;\n}\n\n// LayoutContext carries the parent record context needed by all layout nodes.\nexport interface LayoutContext {\n schema: Schema;\n entity: Entity;\n entityCode: string;\n recordId: string;\n record: Record<string, unknown>;\n isNew: boolean;\n mode: \"display\" | \"edit\";\n onFieldChange?: (field: string, value: unknown) => void;\n // $refs from the detail response (entity -> id -> record).\n refs?: RefsMap;\n // Section-level column count override for FieldsBlock (1 = stacked, 2 = side-by-side).\n columns?: number;\n // Properties and statuses state - required for `properties` and `statuses` leaf nodes.\n objectProperties?: PropertyValue[];\n onSetProperty?: (propertyCode: string, value: unknown) => void;\n isPropertyPending?: boolean;\n objectStatuses?: StatusInfo[];\n onSetStatus?: (groupCode: string, statusCode: string) => void;\n isStatusPending?: boolean;\n // Children editing (direct/aggregate children only).\n // undefined = no edits to any children yet; skip $children in payload.\n pendingChildren?: Record<string, PendingChildRow[]>;\n onChildrenChange?: (childCode: string, rows: PendingChildRow[]) => void;\n // Validation errors keyed by childCode -> rowKey -> fieldNames with errors.\n childValidationErrors?: Record<string, Record<string, string[]>>;\n}\n\ninterface LayoutRendererProps {\n nodes: LayoutNode[];\n ctx: LayoutContext;\n}\n\n// LayoutRenderer renders an array of layout nodes, dispatching each to the\n// appropriate component based on which kind field is set.\nexport function LayoutRenderer({ nodes, ctx }: LayoutRendererProps) {\n return (\n <>\n {nodes.map((node, i) => (\n <LayoutNodeRenderer key={i} node={node} ctx={ctx} />\n ))}\n </>\n );\n}\n\ninterface LayoutNodeRendererProps {\n node: LayoutNode;\n ctx: LayoutContext;\n}\n\n// LayoutNodeRenderer dispatches a single node to the right component.\nexport function LayoutNodeRenderer({ node, ctx }: LayoutNodeRendererProps) {\n // Containers\n if (node.row) {\n return <LayoutRow config={node.row} ctx={ctx} />;\n }\n if (node.column) {\n return <LayoutColumn config={node.column} node={node} ctx={ctx} />;\n }\n if (node.tabs) {\n return <LayoutTabs config={node.tabs} ctx={ctx} />;\n }\n if (node.section) {\n return <SectionBlock config={node.section} ctx={ctx} />;\n }\n if (node.children) {\n return <ChildrenBlock node={node} ctx={ctx} />;\n }\n if (node.associated) {\n return <AssociatedBlock node={node} ctx={ctx} />;\n }\n if (node.fields) {\n return <FieldsBlock fields={node.fields} ctx={ctx} />;\n }\n if (node.properties != null) {\n return <PropertiesBlock node={node} ctx={ctx} />;\n }\n if (node.statuses != null) {\n return <StatusesBlock node={node} ctx={ctx} />;\n }\n\n return null;\n}\n\n// getNodeKind returns the kind string for a layout node, used for testing and debugging.\nexport function getNodeKind(node: LayoutNode): string | null {\n if (node.row) return \"row\";\n if (node.column) return \"column\";\n if (node.tabs) return \"tabs\";\n if (node.section) return \"section\";\n if (node.children) return \"children\";\n if (node.associated) return \"associated\";\n if (node.fields) return \"fields\";\n if (node.properties != null) return \"properties\";\n if (node.statuses != null) return \"statuses\";\n return null;\n}\n","import type { Schema } from \"@/types/schema\";\nimport type { PendingChildRow } from \"@/components/detail-layout/LayoutRenderer\";\n\n// collectFKFields returns the set of FK field names for a given child entity\n// by scanning all parent entities' children relations.\nfunction collectFKFields(childCode: string, schema: Schema): Set<string> {\n const fks = new Set<string>();\n for (const entity of Object.values(schema.entities)) {\n if (!entity.children) continue;\n for (const rel of entity.children) {\n if (rel.entity === childCode && rel.foreign_key) {\n const fkArr = Array.isArray(rel.foreign_key) ? rel.foreign_key : [rel.foreign_key];\n for (const fk of fkArr) {\n fks.add(fk);\n }\n }\n }\n }\n return fks;\n}\n\n// validatePendingChildren checks all non-deleted rows across all child codes\n// against their entity's required fields. Returns a map of validation errors:\n// { childCode: { rowKey: [fieldName, ...] } }\n// Empty object = no errors.\nexport function validatePendingChildren(\n pendingChildren: Record<string, PendingChildRow[]> | undefined,\n schema: Schema | undefined,\n): Record<string, Record<string, string[]>> {\n if (!pendingChildren || !schema) return {};\n\n const errors: Record<string, Record<string, string[]>> = {};\n\n for (const [childCode, rows] of Object.entries(pendingChildren)) {\n const childEntity = schema.entities[childCode];\n if (!childEntity) continue;\n\n // FK fields are auto-injected server-side, skip them.\n const fkFields = collectFKFields(childCode, schema);\n\n // Find required fields (non-auto, non-primary, non-FK).\n const requiredFields: string[] = [];\n for (const [fieldName, field] of Object.entries(childEntity.fields)) {\n if (field.required && !field.auto && !field.primary && !fkFields.has(fieldName)) {\n requiredFields.push(fieldName);\n }\n }\n if (requiredFields.length === 0) continue;\n\n for (const row of rows) {\n if (row._deleted) continue;\n\n const missingFields: string[] = [];\n for (const fieldName of requiredFields) {\n const val = row[fieldName];\n if (val == null || val === \"\") {\n missingFields.push(fieldName);\n }\n }\n if (missingFields.length > 0) {\n if (!errors[childCode]) errors[childCode] = {};\n errors[childCode][row._key] = missingFields;\n }\n }\n }\n\n return errors;\n}\n","import { useState, useMemo, useCallback, useEffect, useRef } from \"react\";\nimport { useParams, useNavigate, useLocation, useSearchParams } from \"react-router-dom\";\nimport { Save, X, Trash2, RotateCcw, AlertTriangle } from \"lucide-react\";\nimport { formatOffsetTimestamp } from \"@/lib/timestamp\";\nimport { Button } from \"@/components/ui/button\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport { useEntityItem } from \"@/hooks/useEntityItem\";\nimport { useCreateEntity, useUpdateEntity, useDeleteEntity, useRestoreEntity } from \"@/hooks/useMutations\";\nimport type { StatusInfo, PropertyValue } from \"@/types/api\";\nimport { PageHeader } from \"@/components/shared/PageHeader\";\nimport { DetailSkeleton } from \"@/components/shared/LoadingSkeleton\";\nimport { ConfirmDialog } from \"@/components/shared/ConfirmDialog\";\nimport { ActionButton } from \"@/components/shared/ActionButton\";\nimport { AssociationTabs } from \"@/components/shared/AssociationTabs\";\nimport { useTabStore } from \"@/stores/tabs\";\nimport { getScreenActions, getActionsByVisibility, evaluateConditions } from \"@/lib/actions\";\nimport { loc, getPrimaryKeyFields, extractPkValues, pkValuesToId } from \"@/types/schema\";\nimport type { LocalizedString, PkValues } from \"@/types/schema\";\nimport { LayoutRenderer, type LayoutContext, type PendingChildRow } from \"@/components/detail-layout\";\nimport { StatusGroupsDisplay } from \"@/components/shared/StatusGroupsDisplay\";\nimport { validatePendingChildren } from \"@/lib/children-validation\";\n\nconst noop = () => {};\n\n// Deep comparison of two arrays of plain objects for detecting children changes.\nfunction arraysEqual(a: Record<string, unknown>[], b: Record<string, unknown>[]): boolean {\n if (a.length !== b.length) return false;\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\ninterface SmartDetailPageProps {\n screenCode: string;\n}\n\nexport function SmartDetailPage({ screenCode }: SmartDetailPageProps) {\n const { id: urlId } = useParams<{ id: string }>();\n const navigate = useNavigate();\n const [searchParams, setSearchParams] = useSearchParams();\n const { data: schema } = useSchema();\n const selfUser = useAuthStore((s) => s.user);\n\n const screen = schema?.screens[screenCode];\n const entity = screen?.entity ? schema?.entities[screen.entity] : undefined;\n const entityCode = screen?.entity;\n\n // Self screens use the authenticated user's ID instead of URL param.\n const isSelf = screen?.self === true;\n const id = isSelf ? selfUser?.id : urlId;\n\n const isNew = !isSelf && id === \"new\";\n\n // Compute PK values for the API call.\n const pkValues: PkValues | string | undefined = useMemo(() => {\n if (!id || isNew) return undefined;\n if (!entity) return id;\n const pkFields = getPrimaryKeyFields(entity);\n if (pkFields.length === 1) {\n return { [pkFields[0]]: id };\n }\n // For composite PK, the URL id is pipe-separated: \"val1|val2\"\n const parts = id.split(\"|\");\n const values: PkValues = {};\n for (let i = 0; i < pkFields.length; i++) {\n values[pkFields[i]] = parts[i] ?? \"\";\n }\n return values;\n }, [id, isNew, entity]);\n\n const pkCacheKey = useMemo(() => {\n if (!pkValues) return undefined;\n if (typeof pkValues === \"string\") return pkValues;\n return pkValuesToId(pkValues);\n }, [pkValues]);\n\n const { data: itemResponse, isLoading } = useEntityItem(entityCode, pkValues);\n\n const createMutation = useCreateEntity(entityCode ?? \"\");\n const updateMutation = useUpdateEntity(entityCode ?? \"\");\n const deleteMutation = useDeleteEntity(entityCode ?? \"\");\n const restoreMutation = useRestoreEntity(entityCode ?? \"\");\n\n // $statuses and $properties are enriched inline on the record by\n // handlers/data.go:getByPKValues. Reading them directly from the\n // entity-item query result avoids a second round-trip AND an old bug\n // where the detail page fired GET /api/data/{entity}/{id} - a path\n // that does not exist and silently 404'd, leaving status/property\n // dropdowns blank even though the data was already in hand. See\n // TestGetByPKEnrichment for the backend contract.\n const hasStatusGroups = Object.keys(entity?.status_groups ?? {}).length > 0;\n const itemData = itemResponse?.data as Record<string, unknown> | undefined;\n const statuses = (itemData?.[\"$statuses\"] as StatusInfo[] | undefined);\n const objectProperties = (itemData?.[\"$properties\"] as PropertyValue[] | undefined);\n const openInEdit = searchParams.get(\"edit\") === \"true\";\n const [editing, setEditing] = useState(isNew || openInEdit);\n const [formData, setFormData] = useState<Record<string, unknown>>({});\n const [pendingStatuses, setPendingStatuses] = useState<Record<string, string>>({});\n const [pendingProperties, setPendingProperties] = useState<Record<string, unknown>>({});\n const [pendingChildren, setPendingChildren] = useState<Record<string, PendingChildRow[]> | undefined>(undefined);\n // Snapshot of $children at the time edit mode was entered, used to detect actual changes on save.\n const [childrenSnapshot, setChildrenSnapshot] = useState<Record<string, Record<string, unknown>[]> | undefined>(undefined);\n const [deleteConfirm, setDeleteConfirm] = useState<{ show: boolean; confirmation?: string }>({ show: false });\n\n // Sidebar resize: use a ref for live DOM updates during drag to avoid\n // re-rendering the entire component tree on every mousemove. Commit to\n // React state only on mouseup.\n const [sidebarW, setSidebarW] = useState(() => {\n const w = parseInt(screen?.sidebar_width || \"380\", 10);\n return isNaN(w) ? 380 : w;\n });\n const sidebarRef = useRef<HTMLDivElement>(null);\n const sidebarDrag = useRef<{ startX: number; startW: number } | null>(null);\n const onSidebarDragStart = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n const el = sidebarRef.current;\n if (!el) return;\n const startW = el.offsetWidth;\n sidebarDrag.current = { startX: e.clientX, startW };\n const onMove = (ev: MouseEvent) => {\n if (!sidebarDrag.current) return;\n const delta = sidebarDrag.current.startX - ev.clientX;\n const next = Math.max(280, Math.min(800, sidebarDrag.current.startW + delta));\n el.style.width = `${next}px`;\n };\n const onUp = () => {\n if (sidebarDrag.current && el) {\n setSidebarW(parseInt(el.style.width, 10) || sidebarDrag.current.startW);\n }\n sidebarDrag.current = null;\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n };\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n },\n [],\n );\n\n // Record data from API\n const record = itemResponse?.data as Record<string, unknown> | undefined;\n // Extract $refs from the record (detail responses embed refs inside the data object).\n const recordRefs = record?.[\"$refs\"] as Record<string, Record<string, Record<string, unknown>>> | undefined;\n\n // Soft-delete detection: if entity has soft_delete and the column is non-null, the record is deleted.\n const hasSoftDelete = !!entity?.soft_delete;\n const isRecordDeleted = hasSoftDelete && record != null && record[entity!.soft_delete!] != null;\n\n // Tab tracking: ensure this page has a tab and update title when record loads.\n const location = useLocation();\n const { openTab, updateTabTitle, findTabByPathname } = useTabStore();\n useEffect(() => {\n if (!entity || isSelf) return;\n const pathname = location.pathname;\n const tabName = loc(screen?.display?.name) || loc(entity.display.name);\n const tabIcon = screen?.display?.icon || entity.display.icon;\n const existing = findTabByPathname(pathname);\n if (!existing) {\n openTab({\n pathname,\n search: \"\",\n title: isNew ? `New ${tabName}` : tabName,\n icon: tabIcon,\n closable: true,\n });\n }\n }, [location.pathname, screen?.display?.name?.en, entity?.display.name?.en, screen?.display?.icon, entity?.display.icon, isNew, isSelf]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n if (!record || !entity || isSelf) return;\n const tab = findTabByPathname(location.pathname);\n if (tab) {\n const dfKey = entity.display?.display_field;\n const rawVal = dfKey ? record[dfKey] : undefined;\n const resolvedVal =\n rawVal && typeof rawVal === \"object\" && !Array.isArray(rawVal)\n ? loc(rawVal as LocalizedString)\n : rawVal;\n const displayTitle = resolvedVal\n ? String(resolvedVal)\n : (loc(screen?.display?.name) || loc(entity.display.name));\n updateTabTitle(tab.id, displayTitle);\n }\n }, [record, entity?.display.name?.en, entity?.display.display_field, location.pathname, isSelf]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Editable fields (non-auto, non-primary)\n const editableFields = useMemo(() => {\n if (!entity) return new Set<string>();\n const editable = new Set<string>();\n for (const [name, field] of Object.entries(entity.fields)) {\n if (!field.auto && !field.primary) {\n editable.add(name);\n }\n }\n return editable;\n }, [entity]);\n\n // Handle ?edit=true URL param: enter edit mode and populate form data.\n // Handles both initial mount and already-mounted tab receiving the param.\n useEffect(() => {\n if (!openInEdit || !record || editableFields.size === 0) return;\n // Enter edit mode if not already editing\n if (!editing) setEditing(true);\n // Populate form data if empty (avoid clobbering in-progress edits)\n if (Object.keys(formData).length === 0) {\n const data: Record<string, unknown> = {};\n editableFields.forEach((name) => {\n data[name] = record[name] ?? \"\";\n });\n setFormData(data);\n }\n // Always clean the param from URL\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.delete(\"edit\");\n return next;\n }, { replace: true });\n }, [openInEdit, record, editableFields]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Initialize pendingChildren for new records (isNew starts in edit mode).\n useEffect(() => {\n if (!isNew || !entity?.children || entity.children.length === 0) return;\n if (pendingChildren !== undefined) return; // already initialized\n setPendingChildren({});\n setChildrenSnapshot({});\n }, [isNew, entity?.children]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Initialize form data when entering edit mode or when record loads\n const startEditing = useCallback(() => {\n if (record) {\n const data: Record<string, unknown> = {};\n editableFields.forEach((name) => {\n data[name] = record[name] ?? \"\";\n });\n setFormData(data);\n }\n // Initialize pendingChildren from the detail response's $children.\n const serverChildren = record?.[\"$children\"] as Record<string, Record<string, unknown>[]> | undefined;\n if (serverChildren && Object.keys(serverChildren).length > 0) {\n const pending: Record<string, PendingChildRow[]> = {};\n for (const [childCode, rows] of Object.entries(serverChildren)) {\n pending[childCode] = rows.map((row) => ({\n ...row,\n _key: String(row.id ?? crypto.randomUUID()),\n }));\n }\n setPendingChildren(pending);\n setChildrenSnapshot(serverChildren);\n } else if (entity?.children && entity.children.length > 0) {\n // Entity has children but none exist yet - initialize empty so the UI can add rows.\n setPendingChildren({});\n setChildrenSnapshot({});\n }\n setEditing(true);\n }, [record, editableFields, entity?.children]);\n\n const cancelEditing = useCallback(() => {\n if (isNew) {\n const listRoute = screen?.route?.replace(\"/:id\", \"\") ?? \"/\";\n navigate(listRoute);\n } else {\n setEditing(false);\n setFormData({});\n setPendingStatuses({});\n setPendingProperties({});\n setPendingChildren(undefined);\n setChildrenSnapshot(undefined);\n }\n }, [isNew, screen, navigate]);\n\n const handleFieldChange = useCallback((fieldName: string, value: unknown) => {\n setFormData((prev) => ({ ...prev, [fieldName]: value }));\n }, []);\n\n // Find the list screen route for back navigation\n const listRoute = useMemo(() => {\n if (!screen?.route) return \"/\";\n // /leads/:id -> /leads\n const parts = screen.route.split(\"/\");\n parts.pop(); // Remove :id\n return parts.join(\"/\") || \"/\";\n }, [screen]);\n\n const listRouteExists = useMemo(() => {\n if (!schema?.screens || !listRoute || listRoute === \"/\") return false;\n return Object.values(schema.screens).some((s) => s.route === listRoute);\n }, [schema, listRoute]);\n\n const handleSave = useCallback(() => {\n if (!entityCode) return;\n\n // Build payload with only changed fields (lighter payloads, less churn).\n const payload: Record<string, unknown> = {};\n if (isNew) {\n // Only include non-empty fields to preserve schema defaults for unset fields.\n for (const [key, val] of Object.entries(formData)) {\n if (val !== \"\" && val !== null && val !== undefined) {\n payload[key] = val;\n }\n }\n } else {\n // Only send fields that actually changed.\n for (const [key, val] of Object.entries(formData)) {\n const original = record?.[key];\n // Treat null/undefined/empty-string as equivalent to avoid spurious writes.\n const normalizedVal = val === \"\" ? null : val;\n const normalizedOrig = original === \"\" || original === undefined ? null : original;\n if (normalizedVal !== normalizedOrig) {\n payload[key] = val;\n }\n }\n }\n // Include $statuses only if any status was changed.\n if (Object.keys(pendingStatuses).length > 0) {\n payload[\"$statuses\"] = Object.entries(pendingStatuses).map(\n ([groupCode, statusCode]) => ({ status_group_code: groupCode, status_code: statusCode }),\n );\n }\n // Include $properties only if any property was changed.\n if (Object.keys(pendingProperties).length > 0) {\n payload[\"$properties\"] = Object.entries(pendingProperties).map(\n ([propertyCode, value]) => ({ property_code: propertyCode, value }),\n );\n }\n // Include $children only for child codes with actual changes.\n if (pendingChildren) {\n const childrenPayload: Record<string, Record<string, unknown>[]> = {};\n for (const [childCode, rows] of Object.entries(pendingChildren)) {\n // Filter out deleted rows, strip meta fields.\n const cleaned = rows\n .filter((r) => !r._deleted)\n .map((r) => {\n const { _key, _deleted, _dirty, ...fields } = r;\n return fields;\n });\n // Compare against snapshot to detect actual changes.\n const original = childrenSnapshot?.[childCode] ?? [];\n if (isNew || !arraysEqual(cleaned, original)) {\n childrenPayload[childCode] = cleaned;\n }\n }\n if (Object.keys(childrenPayload).length > 0) {\n payload[\"$children\"] = childrenPayload;\n }\n }\n\n // Skip save if nothing changed.\n if (!isNew && Object.keys(payload).length === 0) {\n setEditing(false);\n setPendingStatuses({});\n setPendingProperties({});\n setPendingChildren(undefined);\n setChildrenSnapshot(undefined);\n return;\n }\n\n const clearPending = () => {\n setEditing(false);\n setPendingStatuses({});\n setPendingProperties({});\n setPendingChildren(undefined);\n setChildrenSnapshot(undefined);\n // No need to invalidate - useUpdateEntity.onSuccess uses the PATCH response\n // to update item, status, and property caches directly.\n };\n\n if (isNew) {\n createMutation.mutate(payload, {\n onSuccess: (response) => {\n const newRecord = response.data as Record<string, unknown>;\n const newPkValues = entity ? extractPkValues(entity, newRecord) : {};\n const newId = pkValuesToId(newPkValues);\n if (newId) {\n navigate(`${listRoute}/${encodeURIComponent(newId)}`, { replace: true });\n } else {\n navigate(listRoute, { replace: true });\n }\n clearPending();\n },\n });\n } else if (pkValues) {\n updateMutation.mutate(\n { pkValues, data: payload },\n { onSuccess: clearPending },\n );\n }\n }, [isNew, id, entityCode, formData, pendingStatuses, pendingProperties, pendingChildren, childrenSnapshot, createMutation, updateMutation, entity, navigate, listRoute, record]);\n\n const handleChildrenChange = useCallback((childCode: string, rows: PendingChildRow[]) => {\n setPendingChildren((prev) => ({ ...(prev ?? {}), [childCode]: rows }));\n }, []);\n\n const handleDelete = useCallback(() => {\n if (!pkValues || isNew) return;\n deleteMutation.mutate(pkValues, {\n onSuccess: () => navigate(listRoute, { replace: true }),\n });\n }, [pkValues, isNew, deleteMutation, navigate, listRoute]);\n\n const handleRestore = useCallback(() => {\n if (!pkValues || isNew) return;\n restoreMutation.mutate(pkValues);\n }, [pkValues, isNew, restoreMutation]);\n\n // Compute validation errors for direct children (required field checks).\n const childValidationErrors = useMemo(\n () => validatePendingChildren(pendingChildren, schema),\n [pendingChildren, schema],\n );\n const hasChildErrors = Object.keys(childValidationErrors).length > 0;\n\n if (!screen || !entity) return null;\n if (!isNew && isLoading) return <DetailSkeleton />;\n if (!isNew && !record) {\n return (\n <div className=\"p-6\">\n <PageHeader title=\"Not Found\" backTo={listRouteExists ? listRoute : undefined} />\n <p className=\"text-[var(--muted-foreground)]\">Record not found.</p>\n </div>\n );\n }\n\n const entityDisplay = entity.display;\n // Screen display name overrides entity name (e.g. custom detail screens).\n const detailName = loc(screen.display?.name) || loc(entityDisplay.name);\n const displayFieldKey = entity.display?.display_field;\n const rawDisplayValue = displayFieldKey ? record?.[displayFieldKey] : undefined;\n // Handle multilang fields (JSONB objects like {\"en\": \"...\", \"ru\": \"...\"}).\n const displayValue =\n rawDisplayValue && typeof rawDisplayValue === \"object\" && !Array.isArray(rawDisplayValue)\n ? loc(rawDisplayValue as LocalizedString)\n : rawDisplayValue;\n const title = isNew\n ? `New ${detailName}`\n : displayValue ? String(displayValue) : detailName;\n\n const isSaving = createMutation.isPending || updateMutation.isPending;\n\n // When screen.actions is defined, use only those; otherwise fall back to visibility.\n // Detail-page header actions = anything declaring visibility:[detail].\n // The platform loader assigns this canonical slot to scope:single and\n // scope:global actions automatically, so legacy schemas keep working.\n // (Previously a separate filter excluded scope:batch from detail; now the\n // visibility array is the single source of truth — if a schema author wants\n // a batch-capable action on the detail page too, they declare list_toolbar\n // AND detail in visibility.)\n const hasExplicitActions = screen.actions !== undefined;\n const headerActions = hasExplicitActions\n ? getScreenActions(entity.actions, screen.actions, \"detail\", schema?.actions)\n : getActionsByVisibility(entity.actions, \"detail\");\n\n const layoutCtx: LayoutContext = {\n schema: schema!,\n entity,\n entityCode: entityCode!,\n recordId: pkCacheKey ?? id ?? \"\",\n record: editing ? { ...(record ?? {}), ...formData } : (record ?? {}),\n isNew,\n mode: editing ? \"edit\" : \"display\",\n onFieldChange: editing ? handleFieldChange : undefined,\n refs: recordRefs,\n objectProperties: (() => {\n const base = objectProperties ?? [];\n if (!editing || Object.keys(pendingProperties).length === 0) return base.length > 0 ? base : undefined;\n const merged = base.map((p) =>\n pendingProperties[p.property_code] !== undefined\n ? { ...p, value: pendingProperties[p.property_code] }\n : p,\n );\n for (const [code, value] of Object.entries(pendingProperties)) {\n if (!base.some((p) => p.property_code === code)) {\n merged.push({ property_code: code, name: {}, type: \"string\", value });\n }\n }\n return merged;\n })(),\n onSetProperty: (isNew || entity?.readonly)\n ? undefined\n : editing\n ? (propertyCode, value) => setPendingProperties((prev) => ({ ...prev, [propertyCode]: value }))\n : undefined,\n isPropertyPending: false,\n // In edit mode, merge pending status changes into displayed statuses and\n // store changes locally (saved atomically on Save, discarded on Cancel).\n objectStatuses: (() => {\n const base = statuses ?? [];\n if (!editing || Object.keys(pendingStatuses).length === 0) return base.length > 0 ? base : undefined;\n // Merge: replace matching groups, keep others.\n const merged = base.map((s) =>\n pendingStatuses[s.group_code] !== undefined\n ? { ...s, status_code: pendingStatuses[s.group_code] }\n : s,\n );\n // Add groups that aren't in base yet (new status set for first time).\n for (const [gc, sc] of Object.entries(pendingStatuses)) {\n if (!base.some((s) => s.group_code === gc)) {\n merged.push({ group_code: gc, status_code: sc, status_name: {}, set_at: new Date().toISOString() });\n }\n }\n return merged;\n })(),\n onSetStatus: (isNew || entity?.readonly)\n ? undefined\n : editing\n ? (groupCode, statusCode) => setPendingStatuses((prev) => ({ ...prev, [groupCode]: statusCode }))\n : undefined,\n isStatusPending: false,\n // Children editing context for direct (aggregate) children.\n pendingChildren: editing ? pendingChildren : undefined,\n onChildrenChange: editing ? handleChildrenChange : undefined,\n childValidationErrors: editing ? childValidationErrors : undefined,\n };\n\n const hasSidebar = screen.sidebar && screen.sidebar.length > 0;\n\n const headerEl = (\n <PageHeader\n title={title}\n backTo={isSelf || !listRouteExists ? undefined : listRoute}\n actions={\n isRecordDeleted ? (\n <Button onClick={handleRestore} disabled={restoreMutation.isPending}>\n <RotateCcw className=\"w-4 h-4\" />\n {restoreMutation.isPending ? \"Restoring...\" : \"Restore\"}\n </Button>\n ) : editing ? (\n <>\n <Button variant=\"outline\" onClick={cancelEditing} disabled={isSaving}>\n <X className=\"w-4 h-4\" />\n Cancel\n </Button>\n <Button\n onClick={handleSave}\n disabled={isSaving || hasChildErrors}\n title={hasChildErrors ? \"Fix errors in child rows\" : undefined}\n >\n <Save className=\"w-4 h-4\" />\n {isSaving ? \"Saving...\" : \"Save\"}\n </Button>\n </>\n ) : (\n <>\n {!isNew && id && headerActions.map(({ code, action }) => {\n if (action.type === \"edit\") {\n const conditionsMet = record ? evaluateConditions(action.conditions, record) : true;\n return (\n <Button key={code} variant=\"outline\" onClick={startEditing} disabled={!conditionsMet}>\n {loc(action.display?.name) || \"Edit\"}\n </Button>\n );\n }\n if (action.type === \"delete\" && !isSelf) {\n const conditionsMet = record ? evaluateConditions(action.conditions, record) : true;\n return (\n <Button\n key={code}\n variant=\"outline\"\n onClick={() => setDeleteConfirm({ show: true, confirmation: loc(action.confirmation) || undefined })}\n disabled={!conditionsMet}\n className=\"text-[var(--destructive)] hover:text-[var(--destructive)]\"\n >\n <Trash2 className=\"w-4 h-4\" />\n {loc(action.display?.name) || \"Delete\"}\n </Button>\n );\n }\n return (\n <ActionButton\n key={code}\n actionCode={code}\n action={action}\n entityCode={entityCode}\n objectIds={action.scope !== \"global\" ? [id] : undefined}\n row={record}\n variant=\"outline\"\n />\n );\n })}\n {!hasExplicitActions && !entity?.readonly && (\n <Button variant=\"outline\" onClick={startEditing}>\n Edit\n </Button>\n )}\n {!hasExplicitActions && !isNew && !isSelf && !entity?.readonly && (\n <Button\n variant=\"outline\"\n onClick={() => setDeleteConfirm({ show: true })}\n className=\"text-[var(--destructive)] hover:text-[var(--destructive)]\"\n >\n <Trash2 className=\"w-4 h-4\" />\n Delete\n </Button>\n )}\n </>\n )\n }\n />\n );\n\n const deletedBanner = isRecordDeleted && (\n <div className=\"flex items-center gap-2 px-4 py-3 mb-4 rounded-md border border-[var(--destructive)]/30 bg-[var(--destructive)]/10 text-sm text-[var(--destructive)]\">\n <AlertTriangle className=\"w-4 h-4 shrink-0\" />\n <span>\n This record was deleted on{\" \"}\n {formatOffsetTimestamp(String(record![entity.soft_delete!]))}\n </span>\n </div>\n );\n\n const statusesEl = hasStatusGroups && !isNew && !(screen.items && screen.items.length > 0) && (\n <div className=\"mb-4\">\n <StatusGroupsDisplay\n statusGroups={entity.status_groups ?? {}}\n objectStatuses={layoutCtx.objectStatuses}\n onSetStatus={entity?.readonly ? noop : editing\n ? (groupCode, statusCode) => setPendingStatuses((prev) => ({ ...prev, [groupCode]: statusCode }))\n : noop\n }\n isPending={false}\n mode={editing && !entity?.readonly ? \"edit\" : \"display\"}\n />\n </div>\n );\n\n const mainContent = (\n <>\n {screen.items && screen.items.length > 0 && (record || isNew) && schema && (\n <LayoutRenderer nodes={screen.items} ctx={layoutCtx} />\n )}\n {!isNew && id && entityCode && entity.associations && Object.keys(entity.associations).length > 0 && schema && (\n <AssociationTabs entityCode={entityCode} recordId={pkCacheKey ?? id ?? \"\"} associations={entity.associations} schema={schema} />\n )}\n {!isNew && record && (\n <div className=\"flex gap-6 px-1 py-2 text-xs text-[var(--muted-foreground)]\">\n {record.created_at != null && (\n <span>Created: {formatOffsetTimestamp(String(record.created_at))}</span>\n )}\n {record.updated_at != null && (\n <span>Updated: {formatOffsetTimestamp(String(record.updated_at))}</span>\n )}\n </div>\n )}\n </>\n );\n\n const deleteDialog = (\n <ConfirmDialog\n open={deleteConfirm.show}\n onOpenChange={(open) => !open && setDeleteConfirm({ show: false })}\n title={`Delete ${detailName}`}\n description={\n deleteConfirm.confirmation\n ? deleteConfirm.confirmation\n : hasSoftDelete\n ? `Are you sure you want to delete this ${detailName.toLowerCase()}? It can be restored later by an admin.`\n : `Are you sure you want to delete this ${detailName.toLowerCase()}? This action cannot be undone.`\n }\n confirmLabel=\"Delete\"\n onConfirm={handleDelete}\n destructive\n />\n );\n\n // Sidebar layout: two fully independent panes separated by resize handle.\n // Left pane: header + statuses + scrollable sections (entity details)\n // Right pane: sidebar content (e.g. activities) - completely separate, own header\n if (hasSidebar) {\n return (\n <div className=\"h-full flex overflow-hidden\">\n {/* Left pane - entity details */}\n <div className=\"flex-1 min-w-0 flex flex-col h-full\">\n {/* Sticky header (title + Edit/Delete) */}\n <div className=\"shrink-0 px-6 pt-6 pb-2\">\n {headerEl}\n {deletedBanner}\n {statusesEl}\n </div>\n {/* Scrollable content */}\n <div className=\"flex-1 min-h-0 overflow-y-auto px-6 pb-6 space-y-4\">\n {mainContent}\n </div>\n </div>\n {/* Resize handle - full height separator */}\n <div\n className=\"shrink-0 w-1 cursor-col-resize hover:bg-[var(--primary)]/20 active:bg-[var(--primary)]/30 transition-colors\"\n onMouseDown={onSidebarDragStart}\n />\n {/* Right pane - sidebar (activities etc.) */}\n <div ref={sidebarRef} className=\"shrink-0 h-full\" style={{ width: `${sidebarW}px` }}>\n {(record || isNew) && schema && (\n <LayoutRenderer nodes={screen.sidebar!} ctx={layoutCtx} />\n )}\n </div>\n {deleteDialog}\n </div>\n );\n }\n\n // Standard layout (no sidebar): sticky header + scrollable content\n return (\n <div className=\"h-full flex flex-col overflow-hidden\">\n <div className=\"shrink-0 px-6 pt-6 pb-2\">\n {headerEl}\n {deletedBanner}\n {statusesEl}\n </div>\n <div className=\"flex-1 min-h-0 overflow-y-auto px-6 pb-6 space-y-4\">\n {mainContent}\n </div>\n {deleteDialog}\n </div>\n );\n}\n\n","// NOTE: there is no separate \"get statuses\" API call. $statuses is enriched\n// inline on GET /api/data/{entity}?<pk>=<value> by handlers/data.go:getByPKValues.\n// Callers read record.$statuses directly from the useEntityItem query result.\n// See TestGetByPKEnrichment in the Go integration tests for the contract.\nimport { apiFetch } from \"./client\";\nimport type { StatusInfo } from \"@/types/api\";\n\nexport async function setObjectStatus(\n entity: string,\n id: string,\n groupCode: string,\n statusCode: string,\n note?: string,\n): Promise<StatusInfo> {\n const statusEntry: Record<string, unknown> = {\n status_group_code: groupCode,\n status_code: statusCode,\n };\n if (note != null) statusEntry.note = note;\n\n const results = await apiFetch<Record<string, unknown>[]>(\n `/api/data/${entity}`,\n {\n method: \"PATCH\",\n body: JSON.stringify([{ id, $statuses: [statusEntry] }]),\n },\n );\n const row = results[0];\n const statuses = (row?.[\"$statuses\"] ?? []) as StatusInfo[];\n return statuses.find((s) => s.group_code === groupCode) ?? statuses[0];\n}\n","// NOTE: there is no useObjectStatuses hook. $statuses is enriched inline\n// on the row returned by useEntityItem - read `record.$statuses` directly.\n// See api/status.ts and TestGetByPKEnrichment for the contract.\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { toast } from \"sonner\";\nimport * as statusApi from \"@/api/status\";\n\nexport function useSetStatus(entity: string | undefined, id: string | undefined) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({ groupCode, statusCode, note }: { groupCode: string; statusCode: string; note?: string }) =>\n statusApi.setObjectStatus(entity!, id!, groupCode, statusCode, note),\n onSuccess: () => {\n // $statuses rides the entity-item query response - invalidate it\n // (not a separate \"object-status\" cache key, which no longer exists).\n queryClient.invalidateQueries({\n queryKey: [\"entity-item\", entity],\n });\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n","// NOTE: there is no separate \"get properties\" API call. $properties is enriched\n// inline on GET /api/data/{entity}?<pk>=<value> by handlers/data.go:getByPKValues.\n// Callers read record.$properties directly from the useEntityItem query result.\n// See TestGetByPKEnrichment in the Go integration tests for the contract.\nimport { apiFetch } from \"./client\";\nimport type { PropertyValue } from \"@/types/api\";\n\nexport async function setObjectProperty(\n entity: string,\n id: string,\n propertyCode: string,\n value: unknown,\n): Promise<PropertyValue> {\n const results = await apiFetch<Record<string, unknown>[]>(\n `/api/data/${entity}`,\n {\n method: \"PATCH\",\n body: JSON.stringify([{ id, $properties: [{ property_code: propertyCode, value }] }]),\n },\n );\n const row = results[0];\n const props = (row?.[\"$properties\"] ?? []) as PropertyValue[];\n return props.find((p) => p.property_code === propertyCode) ?? props[0];\n}\n\nexport async function deleteObjectProperty(\n entity: string,\n id: string,\n propertyCode: string,\n): Promise<void> {\n await apiFetch(\n `/api/data/${entity}`,\n {\n method: \"PATCH\",\n body: JSON.stringify([{ id, $properties: [{ property_code: propertyCode, value: null }] }]),\n },\n );\n}\n","// NOTE: there is no useObjectProperties hook. $properties is enriched inline\n// on the row returned by useEntityItem - read `record.$properties` directly.\n// See api/properties.ts and TestGetByPKEnrichment for the contract.\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { toast } from \"sonner\";\nimport * as propsApi from \"@/api/properties\";\n\nexport function useSetProperty(entity: string | undefined, id: string | undefined) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({ propertyCode, value }: { propertyCode: string; value: unknown }) =>\n propsApi.setObjectProperty(entity!, id!, propertyCode, value),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: [\"entity-item\", entity],\n });\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n\nexport function useDeleteProperty(entity: string | undefined, id: string | undefined) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (propertyCode: string) =>\n propsApi.deleteObjectProperty(entity!, id!, propertyCode),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: [\"entity-item\", entity],\n });\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n","import { useState, useMemo, useCallback, useEffect, useRef } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\nimport { Search, Pencil, Save, X } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { useEntityData } from \"@/hooks/useEntityData\";\nimport { useEntityItem } from \"@/hooks/useEntityItem\";\nimport { useUpdateEntity } from \"@/hooks/useMutations\";\nimport { useSetStatus } from \"@/hooks/useObjectStatus\";\nimport { useSetProperty } from \"@/hooks/useProperties\";\nimport type { StatusInfo, PropertyValue } from \"@/types/api\";\nimport { useDebounce } from \"@/hooks/useDebounce\";\nimport {\n type FilterNode,\n eqFilter,\n removeFilter,\n setFiltersInURL,\n parseFiltersFromURL,\n} from \"@/lib/filters\";\nimport { useTabStore } from \"@/stores/tabs\";\nimport { renderField } from \"@/components/fields\";\nimport { DetailSkeleton } from \"@/components/shared/LoadingSkeleton\";\nimport { LayoutRenderer, type LayoutContext } from \"@/components/detail-layout\";\nimport { cn } from \"@/lib/utils\";\nimport { toast } from \"sonner\";\nimport { loc, fieldDisplayName } from \"@/types/schema\";\nimport type { Entity, Schema, LayoutNode } from \"@/types/schema\";\n\ninterface SmartRecordListPageProps {\n screenCode: string;\n}\n\ntype RowData = Record<string, unknown>;\n\nexport function SmartRecordListPage({ screenCode }: SmartRecordListPageProps) {\n const [searchParams, setSearchParams] = useSearchParams();\n const { data: schema } = useSchema();\n\n const screen = schema?.screens[screenCode];\n const entity = screen?.entity ? schema?.entities[screen.entity] : undefined;\n const entityCode = screen?.entity;\n\n // Tab tracking\n const { openTab } = useTabStore();\n useEffect(() => {\n if (screen?.route && entity) {\n const tabName = loc(screen.display?.name) || loc(entity.display.name_plural);\n const tabIcon = screen.display?.icon || entity.display.icon;\n openTab({\n pathname: screen.route,\n search: searchParams.toString(),\n title: tabName,\n icon: tabIcon,\n closable: true,\n });\n }\n }, [screen?.route, screen?.display?.name?.en, entity?.display.name_plural?.en]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Selected record ID from URL\n const selectedId = searchParams.get(\"selected\") ?? null;\n\n // Search\n const searchValue = searchParams.get(\"search\") ?? \"\";\n const debouncedSearch = useDebounce(searchValue, 300);\n\n // Sort\n const sortParam = searchParams.get(\"sort\") ?? screen?.sort_default ?? \"\";\n\n // Parse JSON filters from URL.\n const filterNodes = useMemo(() => {\n const raw = searchParams.get(\"filters\");\n if (!raw) return undefined;\n try {\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed) && parsed.length > 0 ? parsed : undefined;\n } catch { return undefined; }\n }, [searchParams]);\n\n // Fetch list with higher per_page for panel-style browsing\n const { data: listResponse, isLoading: listLoading } = useEntityData(entityCode, {\n page: 1,\n per_page: 200,\n sort: sortParam || undefined,\n search: debouncedSearch || undefined,\n filters: filterNodes,\n });\n\n const records = listResponse?.data ?? [];\n const listRefs = listResponse?.$refs;\n\n const pkField = useMemo(\n () => entity?.field_order?.find((f) => entity.fields[f]?.primary) ?? \"id\",\n [entity],\n );\n\n const selectRecord = useCallback(\n (id: string | null) => {\n setSearchParams(\n (prev) => {\n const next = new URLSearchParams(prev);\n if (id) next.set(\"selected\", id);\n else next.delete(\"selected\");\n return next;\n },\n { replace: true },\n );\n },\n [setSearchParams],\n );\n\n const updateSearch = useCallback(\n (value: string) => {\n setSearchParams(\n (prev) => {\n const next = new URLSearchParams(prev);\n if (value) next.set(\"search\", value);\n else next.delete(\"search\");\n return next;\n },\n { replace: true },\n );\n },\n [setSearchParams],\n );\n\n const updateFilter = useCallback(\n (field: string, value: string) => {\n setSearchParams(\n (prev) => {\n const next = new URLSearchParams(prev);\n const current = parseFiltersFromURL(prev);\n let updated: FilterNode[];\n if (value && value !== \"__all__\") {\n updated = [...removeFilter(current, field), eqFilter(field, value)];\n } else {\n updated = removeFilter(current, field);\n }\n setFiltersInURL(updated, next);\n return next;\n },\n { replace: true },\n );\n },\n [setSearchParams],\n );\n\n // Resizable panel\n const listResizable = screen?.list_resizable ?? false;\n const containerRef = useRef<HTMLDivElement>(null);\n const [panelWidth, setPanelWidth] = useState<number | null>(null);\n const isDragging = useRef(false);\n\n // Resolve initial width once the container mounts.\n // The effect includes `entity` in deps so it re-fires after the early-return guard\n // passes and the container div actually mounts (making containerRef.current available).\n const listWidthRaw = screen?.list_width;\n useEffect(() => {\n if (!listResizable || panelWidth !== null) return;\n const container = containerRef.current;\n if (!container) return;\n if (listWidthRaw && listWidthRaw.endsWith(\"%\")) {\n const pct = parseFloat(listWidthRaw) / 100;\n setPanelWidth(Math.round(container.getBoundingClientRect().width * pct));\n } else if (listWidthRaw) {\n setPanelWidth(parseInt(listWidthRaw, 10) || 320);\n } else {\n setPanelWidth(320);\n }\n // entity is included to re-fire after the early return guard passes and the div mounts.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [listResizable, listWidthRaw, panelWidth, entity]);\n\n // Store cleanup fn so we can call it on unmount if drag is in-flight.\n const dragCleanup = useRef<(() => void) | null>(null);\n\n useEffect(() => {\n return () => { dragCleanup.current?.(); };\n }, []);\n\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n e.preventDefault();\n isDragging.current = true;\n const startX = e.clientX;\n const startWidth = panelWidth ?? 320;\n\n const onMouseMove = (ev: MouseEvent) => {\n if (!isDragging.current) return;\n const containerWidth = containerRef.current?.getBoundingClientRect().width ?? window.innerWidth;\n const minWidth = 200;\n const maxWidth = containerWidth - 300;\n const newWidth = Math.max(minWidth, Math.min(maxWidth, startWidth + ev.clientX - startX));\n setPanelWidth(newWidth);\n };\n\n const cleanup = () => {\n isDragging.current = false;\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", cleanup);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n dragCleanup.current = null;\n };\n\n document.body.style.cursor = \"col-resize\";\n document.body.style.userSelect = \"none\";\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", cleanup);\n dragCleanup.current = cleanup;\n }, [panelWidth]);\n\n if (!schema || !screen || !entity) return null;\n\n const listColumns =\n screen.columns ??\n entity.field_order\n .filter(\n (f) =>\n !entity.fields[f]?.primary &&\n !entity.fields[f]?.auto &&\n entity.fields[f]?.display?.is_listable !== false,\n )\n .slice(0, 4);\n\n const activeFilterCount = filterNodes?.length ?? 0;\n\n return (\n <div ref={containerRef} className=\"flex h-full overflow-hidden\">\n {/* Left panel - list */}\n <div\n className={cn(\"flex-none flex flex-col overflow-hidden\", !listResizable && \"border-r\")}\n style={{ width: listResizable && panelWidth !== null ? panelWidth : (screen.list_width ?? \"320px\") }}\n >\n {/* Toolbar */}\n <div className=\"p-3 space-y-2 border-b\">\n <div className=\"relative\">\n <Search className=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n className=\"pl-8 h-9 text-sm\"\n placeholder={`Search ${loc(entity.display.name_plural)}...`}\n value={searchValue}\n onChange={(e) => updateSearch(e.target.value)}\n />\n </div>\n {screen.filters && screen.filters.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5\">\n {screen.filters.map((filterField) => {\n const fieldDef = entity.fields[filterField];\n if (!fieldDef?.values) return null;\n const activeNode = filterNodes?.find(\n (n) => n.field === filterField && n.op === \"eq\",\n );\n const currentValue = (activeNode?.value as string) ?? \"__all__\";\n return (\n <Select\n key={filterField}\n value={currentValue}\n onValueChange={(v) => updateFilter(filterField, v)}\n >\n <SelectTrigger className=\"h-7 text-xs px-2 w-auto min-w-[90px]\">\n <SelectValue\n placeholder={fieldDisplayName(fieldDef, filterField, schema.entities)}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__all__\">\n All {fieldDisplayName(fieldDef, filterField, schema.entities)}\n </SelectItem>\n {fieldDef.values.map((v) => (\n <SelectItem key={v.code} value={v.code}>\n {loc(v.name)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n })}\n </div>\n )}\n <div className=\"flex items-center justify-between text-xs text-muted-foreground\">\n <span>\n {listLoading\n ? \"Loading...\"\n : `${records.length} ${loc(entity.display.name_plural)}`}\n </span>\n {activeFilterCount > 0 && (\n <button\n className=\"text-primary underline\"\n onClick={() =>\n setSearchParams(\n (prev) => {\n const next = new URLSearchParams(prev);\n next.delete(\"filters\");\n return next;\n },\n { replace: true },\n )\n }\n >\n Clear filters\n </button>\n )}\n </div>\n </div>\n\n {/* Records */}\n <div className=\"flex-1 overflow-y-auto\">\n {listLoading ? (\n <div className=\"p-3 space-y-2\">\n {Array.from({ length: 8 }).map((_, i) => (\n <div key={i} className=\"h-12 rounded bg-muted animate-pulse\" />\n ))}\n </div>\n ) : records.length === 0 ? (\n <div className=\"p-8 text-center text-sm text-muted-foreground\">No records found</div>\n ) : (\n records.map((record) => (\n <RecordListRow\n key={String(record[pkField] ?? \"\")}\n record={record}\n entity={entity}\n columns={listColumns}\n pkField={pkField}\n refs={listRefs}\n isSelected={record[pkField] === selectedId}\n onClick={() => selectRecord(String(record[pkField] ?? \"\"))}\n />\n ))\n )}\n </div>\n </div>\n\n {/* Resize handle */}\n {listResizable && (\n <div\n className=\"flex-none w-1 cursor-col-resize hover:bg-[var(--border)] active:bg-[var(--border)] transition-colors\"\n onMouseDown={handleMouseDown}\n />\n )}\n\n {/* Right panel - detail */}\n <div className=\"flex-1 min-w-0 overflow-hidden\">\n {selectedId ? (\n <RecordDetailPanel\n key={selectedId}\n entityCode={entityCode!}\n recordId={selectedId}\n items={screen.items}\n schema={schema}\n entity={entity}\n />\n ) : (\n <div className=\"flex items-center justify-center h-full text-muted-foreground\">\n <p className=\"text-sm\">Select a {loc(entity.display.name)} to view details</p>\n </div>\n )}\n </div>\n </div>\n );\n}\n\n// --- RecordListRow ---\n\ninterface RecordListRowProps {\n record: RowData;\n entity: Entity;\n columns: string[];\n pkField: string;\n refs?: Record<string, Record<string, Record<string, unknown>>>;\n isSelected: boolean;\n onClick: () => void;\n}\n\nfunction RecordListRow({\n record,\n entity,\n columns,\n pkField: _pkField,\n refs,\n isSelected,\n onClick,\n}: RecordListRowProps) {\n const primaryCol = columns[0];\n const secondaryCol = columns[1];\n const badgeCols = columns.slice(2, 4);\n\n return (\n <button\n className={cn(\n \"w-full text-left px-3 py-2.5 border-b hover:bg-accent/50 transition-colors\",\n isSelected && \"bg-accent border-l-2 border-l-primary\",\n )}\n onClick={onClick}\n >\n {primaryCol && (\n <div className=\"text-sm font-medium truncate\">\n {renderField({\n field: entity.fields[primaryCol],\n fieldName: primaryCol,\n value: record[primaryCol],\n mode: \"display\",\n record,\n refs,\n })}\n </div>\n )}\n <div className=\"flex items-center gap-1.5 mt-0.5\">\n {secondaryCol && (\n <div className=\"text-xs text-muted-foreground truncate flex-1\">\n {renderField({\n field: entity.fields[secondaryCol],\n fieldName: secondaryCol,\n value: record[secondaryCol],\n mode: \"display\",\n record,\n refs,\n })}\n </div>\n )}\n <div className=\"flex items-center gap-1 flex-shrink-0\">\n {badgeCols.map(\n (col) =>\n record[col] != null && (\n <div key={col} className=\"text-xs\">\n {renderField({\n field: entity.fields[col],\n fieldName: col,\n value: record[col],\n mode: \"display\",\n record,\n refs,\n })}\n </div>\n ),\n )}\n </div>\n </div>\n </button>\n );\n}\n\n// --- RecordDetailPanel ---\n\ninterface RecordDetailPanelProps {\n entityCode: string;\n recordId: string;\n items?: LayoutNode[];\n schema: Schema;\n entity: Entity;\n}\n\nfunction RecordDetailPanel({\n entityCode,\n recordId,\n items,\n schema,\n entity,\n}: RecordDetailPanelProps) {\n const { data: itemResponse, isLoading } = useEntityItem(entityCode, recordId);\n const updateMutation = useUpdateEntity(entityCode);\n\n const [editing, setEditing] = useState(false);\n const [formData, setFormData] = useState<Record<string, unknown>>({});\n\n const record = itemResponse?.data as Record<string, unknown> | undefined;\n\n // $statuses and $properties ride the entity-item query response -\n // handlers/data.go:getByPKValues enriches the row. See SmartDetailPage\n // for the same pattern and the TestGetByPKEnrichment contract test.\n const statuses = record?.[\"$statuses\"] as StatusInfo[] | undefined;\n const objectProperties = record?.[\"$properties\"] as PropertyValue[] | undefined;\n const setStatusMutation = useSetStatus(entityCode, recordId);\n const setPropertyMutation = useSetProperty(entityCode, recordId);\n\n const editableFields = useMemo(() => {\n const editable = new Set<string>();\n for (const [name, field] of Object.entries(entity.fields)) {\n if (!field.auto && !field.primary) editable.add(name);\n }\n return editable;\n }, [entity]);\n\n const startEditing = useCallback(() => {\n if (record) {\n const data: Record<string, unknown> = {};\n editableFields.forEach((name) => {\n data[name] = record[name] ?? \"\";\n });\n setFormData(data);\n }\n setEditing(true);\n }, [record, editableFields]);\n\n const cancelEditing = useCallback(() => {\n setEditing(false);\n setFormData({});\n }, []);\n\n const handleSave = useCallback(() => {\n updateMutation.mutate(\n { pkValues: recordId, data: formData },\n {\n onSuccess: () => {\n setEditing(false);\n setFormData({});\n toast.success(\"Saved\");\n },\n onError: () => toast.error(\"Failed to save\"),\n },\n );\n }, [updateMutation, recordId, formData]);\n\n const handleFieldChange = useCallback((field: string, value: unknown) => {\n setFormData((prev) => ({ ...prev, [field]: value }));\n }, []);\n\n if (isLoading) return <DetailSkeleton />;\n if (!record) return null;\n\n // Resolve display title from display_field or first non-system field\n const dfKey = entity.display?.display_field;\n const rawTitle = dfKey ? record[dfKey] : record[entity.field_order[0]];\n const displayTitle =\n rawTitle != null && typeof rawTitle !== \"object\" ? String(rawTitle) : loc(entity.display.name);\n\n const recordRefs = record?.[\"$refs\"] as Record<string, Record<string, Record<string, unknown>>> | undefined;\n\n const ctx: LayoutContext = {\n schema,\n entity,\n entityCode,\n recordId,\n record: editing ? { ...record, ...formData } : record,\n isNew: false,\n mode: editing ? \"edit\" : \"display\",\n onFieldChange: editing ? handleFieldChange : undefined,\n refs: recordRefs,\n objectProperties: objectProperties ?? undefined,\n onSetProperty: entity.readonly ? undefined : (code, val) => setPropertyMutation.mutate({ propertyCode: code, value: val }),\n isPropertyPending: setPropertyMutation.isPending,\n objectStatuses: statuses ?? undefined,\n onSetStatus: entity.readonly ? undefined : (groupCode, statusCode) => setStatusMutation.mutate({ groupCode, statusCode }),\n isStatusPending: setStatusMutation.isPending,\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b sticky top-0 bg-background z-10\">\n <h2 className=\"text-sm font-semibold truncate\">{displayTitle}</h2>\n <div className=\"flex items-center gap-1.5\">\n {!entity.readonly && (editing ? (\n <>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={cancelEditing}\n className=\"h-7 text-xs gap-1\"\n >\n <X className=\"h-3 w-3\" />\n Cancel\n </Button>\n <Button\n size=\"sm\"\n onClick={handleSave}\n disabled={updateMutation.isPending}\n className=\"h-7 text-xs gap-1\"\n >\n <Save className=\"h-3 w-3\" />\n {updateMutation.isPending ? \"Saving...\" : \"Save\"}\n </Button>\n </>\n ) : (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={startEditing}\n className=\"h-7 text-xs gap-1\"\n >\n <Pencil className=\"h-3 w-3\" />\n Edit\n </Button>\n ))}\n </div>\n </div>\n\n {/* Body */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\n {items && items.length > 0 ? (\n <LayoutRenderer nodes={items} ctx={ctx} />\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n No layout configured. Add <code>items:</code> to the screen definition.\n </p>\n )}\n </div>\n </div>\n );\n}\n","import { Component, type ErrorInfo, type ReactNode } from \"react\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface Props {\n children: ReactNode;\n /** Optional fallback UI. Defaults to a centered error card with retry button. */\n fallback?: ReactNode;\n}\n\ninterface State {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * Catches JavaScript errors in child components and renders a fallback UI\n * instead of crashing the entire app.\n */\nexport class ErrorBoundary extends Component<Props, State> {\n constructor(props: Props) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): State {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo) {\n console.error(\"[ErrorBoundary]\", error, info.componentStack);\n }\n\n handleRetry = () => {\n this.setState({ hasError: false, error: null });\n };\n\n render() {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n\n return (\n <div className=\"flex items-center justify-center min-h-[200px] p-8\">\n <div className=\"text-center space-y-4 max-w-md\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n Something went wrong\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {this.state.error?.message || \"An unexpected error occurred.\"}\n </p>\n <Button variant=\"outline\" onClick={this.handleRetry}>\n Try again\n </Button>\n </div>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n","import type { ThemeDef } from \"@/types/schema\";\n\n// Maps ThemeDef field names to CSS custom property names.\nconst TOKEN_MAP: Record<string, string> = {\n background: \"--background\",\n foreground: \"--foreground\",\n card: \"--card\",\n card_foreground: \"--card-foreground\",\n popover: \"--popover\",\n popover_foreground: \"--popover-foreground\",\n primary: \"--primary\",\n primary_foreground: \"--primary-foreground\",\n secondary: \"--secondary\",\n secondary_foreground: \"--secondary-foreground\",\n muted: \"--muted\",\n muted_foreground: \"--muted-foreground\",\n accent: \"--accent\",\n accent_foreground: \"--accent-foreground\",\n destructive: \"--destructive\",\n destructive_foreground: \"--destructive-foreground\",\n border: \"--border\",\n input: \"--input\",\n ring: \"--ring\",\n sidebar: \"--sidebar\",\n sidebar_foreground: \"--sidebar-foreground\",\n sidebar_border: \"--sidebar-border\",\n sidebar_accent: \"--sidebar-accent\",\n sidebar_muted: \"--sidebar-muted\",\n radius: \"--radius\",\n};\n\n// All CSS variable names managed by the theme system.\nexport const THEME_TOKENS = Object.values(TOKEN_MAP);\n\n// Converts a ThemeDef from the schema into a CSS variable map.\nexport function themeDefToTokens(def: ThemeDef): Record<string, string> {\n const tokens: Record<string, string> = {};\n for (const [field, cssVar] of Object.entries(TOKEN_MAP)) {\n const value = (def as Record<string, unknown>)[field];\n if (typeof value === \"string\" && value) {\n tokens[cssVar] = value;\n }\n }\n // Track the base theme for backward compat (.dark class).\n if (def.extends) {\n tokens[\"--_base\"] = def.extends;\n }\n return tokens;\n}\n","import { create } from \"zustand\";\nimport { THEME_TOKENS } from \"@/lib/theme-utils\";\n\ntype ThemeTokens = Record<string, string>;\n\ninterface ThemeState {\n // The user's selection: \"light\", \"dark\", \"system\", or a custom theme name.\n selectedTheme: string;\n // The resolved theme after system preference detection.\n effectiveTheme: string;\n // Custom themes from schema (name -> CSS variable map).\n availableThemes: Record<string, ThemeTokens>;\n setTheme: (name: string) => void;\n setAvailableThemes: (themes: Record<string, ThemeTokens>) => void;\n}\n\nconst STORAGE_KEY = \"declarion-theme\";\n\nfunction getSystemPreference(): \"light\" | \"dark\" {\n if (typeof window === \"undefined\") return \"dark\";\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\";\n}\n\nfunction resolveEffective(selected: string): string {\n if (selected === \"system\") return getSystemPreference();\n return selected;\n}\n\nfunction applyTheme(themeName: string, customThemes: Record<string, ThemeTokens>) {\n const html = document.documentElement;\n\n // Remove old .dark class.\n html.classList.remove(\"dark\");\n\n // Set data-theme attribute for CSS selectors.\n html.setAttribute(\"data-theme\", themeName);\n\n // Clear any previously applied custom CSS properties.\n clearCustomProperties(html);\n\n // Apply CSS variables for custom themes.\n const tokens = customThemes[themeName];\n if (tokens) {\n for (const [key, value] of Object.entries(tokens)) {\n if (key.startsWith(\"--_\")) continue; // skip internal metadata\n html.style.setProperty(key, value);\n }\n // Backward compat: add .dark class for dark-based themes (prose-invert etc.).\n const base = tokens[\"--_base\"];\n if (base === \"dark\" || themeName === \"dark\") {\n html.classList.add(\"dark\");\n }\n } else if (themeName === \"dark\") {\n // Built-in dark theme.\n html.classList.add(\"dark\");\n }\n}\n\nfunction clearCustomProperties(el: HTMLElement) {\n for (const name of THEME_TOKENS) {\n el.style.removeProperty(name);\n }\n}\n\nfunction getInitialTheme(): string {\n if (typeof window === \"undefined\") return \"light\";\n return localStorage.getItem(STORAGE_KEY) || \"light\";\n}\n\nconst initialSelected = getInitialTheme();\nconst initialEffective = resolveEffective(initialSelected);\n\n// Apply immediately on module load (prevents FOUC).\nif (typeof window !== \"undefined\") {\n applyTheme(initialEffective, {});\n}\n\nexport const useThemeStore = create<ThemeState>((set, get) => ({\n selectedTheme: initialSelected,\n effectiveTheme: initialEffective,\n availableThemes: {},\n setTheme: (name) => {\n const effective = resolveEffective(name);\n localStorage.setItem(STORAGE_KEY, name);\n applyTheme(effective, get().availableThemes);\n set({ selectedTheme: name, effectiveTheme: effective });\n },\n setAvailableThemes: (themes) => {\n set({ availableThemes: themes });\n // Re-apply current theme in case it's a custom one that just loaded.\n const { effectiveTheme } = get();\n applyTheme(effectiveTheme, themes);\n },\n}));\n\n// Listen for OS preference changes when \"system\" is selected.\nif (typeof window !== \"undefined\") {\n window.matchMedia(\"(prefers-color-scheme: dark)\").addEventListener(\"change\", () => {\n const state = useThemeStore.getState();\n if (state.selectedTheme === \"system\") {\n const effective = getSystemPreference();\n applyTheme(effective, state.availableThemes);\n useThemeStore.setState({ effectiveTheme: effective });\n }\n });\n}\n","import type { ComponentType } from \"react\";\n\nconst registry = new Map<string, ComponentType>();\n\nexport function registerScreen(code: string, component: ComponentType): void {\n registry.set(code, component);\n}\n\nexport function getRegisteredScreen(code: string): ComponentType | undefined {\n return registry.get(code);\n}\n","import { useEffect, useMemo, type ReactNode } from \"react\";\nimport { BrowserRouter, Routes, Route, Navigate } from \"react-router-dom\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { Toaster } from \"sonner\";\nimport { Layout } from \"@/components/layout/Layout\";\nimport { LoginPage } from \"@/components/pages/LoginPage\";\nimport { SignupPage } from \"@/components/pages/SignupPage\";\nimport { SSOCallbackPage } from \"@/components/pages/SSOCallbackPage\";\nimport { NotFoundPage } from \"@/components/pages/NotFoundPage\";\nimport { AdminCatalogPage } from \"@/components/pages/AdminCatalogPage\";\nimport { SmartListPage } from \"@/components/pages/SmartListPage\";\nimport { SmartDetailPage } from \"@/components/pages/SmartDetailPage\";\nimport { SmartRecordListPage } from \"@/components/pages/SmartRecordListPage\";\nimport { ErrorBoundary } from \"@/components/shared/ErrorBoundary\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { useThemeStore } from \"@/stores/theme\";\nimport { themeDefToTokens } from \"@/lib/theme-utils\";\nimport { getRegisteredScreen } from \"@/stores/screen-registry\";\n\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 5 * 60 * 1000,\n retry: 1,\n },\n },\n});\n\nfunction useDynamicRoutes(): { routes: ReactNode[]; defaultRoute: string | null } {\n const { data: schema } = useSchema();\n\n const routes = useMemo<ReactNode[]>(() => {\n if (!schema) return [];\n\n const out: ReactNode[] = [];\n for (const [code, screen] of Object.entries(schema.screens)) {\n if (screen.type === \"list\") {\n out.push(\n <Route\n key={code}\n path={screen.route}\n element={<ErrorBoundary><SmartListPage screenCode={code} /></ErrorBoundary>}\n />,\n );\n continue;\n }\n if (screen.type === \"detail\") {\n out.push(\n <Route\n key={code}\n path={screen.route}\n element={<ErrorBoundary><SmartDetailPage screenCode={code} /></ErrorBoundary>}\n />,\n );\n continue;\n }\n if (screen.type === \"record_list\") {\n out.push(\n <Route\n key={code}\n path={screen.route}\n element={<ErrorBoundary><SmartRecordListPage screenCode={code} /></ErrorBoundary>}\n />,\n );\n continue;\n }\n if (screen.type === \"custom\") {\n const CustomComponent = screen.component\n ? getRegisteredScreen(screen.component)\n : undefined;\n if (CustomComponent) {\n out.push(\n <Route\n key={code}\n path={screen.route}\n element={<ErrorBoundary><CustomComponent /></ErrorBoundary>}\n />,\n );\n }\n }\n }\n return out;\n }, [schema]);\n\n const defaultRoute = useMemo(() => {\n if (!schema?.navigation) return null;\n for (const node of schema.navigation) {\n if (node.screen) {\n const screen = schema.screens[node.screen];\n if (screen) return screen.route;\n }\n if (node.items) {\n for (const child of node.items) {\n if (child.screen) {\n const screen = schema.screens[child.screen];\n if (screen) return screen.route;\n }\n }\n }\n }\n return null;\n }, [schema]);\n\n return { routes, defaultRoute };\n}\n\nfunction AppRoutes() {\n const initialize = useAuthStore((s) => s.initialize);\n const { data: schema } = useSchema();\n const setAvailableThemes = useThemeStore((s) => s.setAvailableThemes);\n const { routes, defaultRoute } = useDynamicRoutes();\n\n useEffect(() => {\n initialize();\n }, [initialize]);\n\n // Wire YAML-defined themes to the theme store once schema loads.\n // Use JSON serialization as a stable dependency to avoid re-applying on every refetch.\n const themesJson = schema?.themes ? JSON.stringify(schema.themes) : null;\n useEffect(() => {\n if (!themesJson || !schema?.themes) return;\n const converted: Record<string, Record<string, string>> = {};\n for (const [name, def] of Object.entries(schema.themes)) {\n converted[name] = themeDefToTokens(def);\n }\n setAvailableThemes(converted);\n }, [themesJson, setAvailableThemes]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <Routes>\n <Route path=\"/login\" element={<LoginPage />} />\n <Route path=\"/login/sso-callback\" element={<SSOCallbackPage />} />\n <Route path=\"/signup\" element={<SignupPage />} />\n <Route element={<Layout />}>\n {defaultRoute && (\n <Route index element={<Navigate to={defaultRoute} replace />} />\n )}\n {routes}\n <Route path=\"/admin/catalog\" element={<AdminCatalogPage />} />\n <Route path=\"*\" element={<NotFoundPage />} />\n </Route>\n </Routes>\n );\n}\n\nexport function App() {\n return (\n <ErrorBoundary>\n <QueryClientProvider client={queryClient}>\n <BrowserRouter>\n <AppRoutes />\n <Toaster richColors position=\"top-right\" toastOptions={{ className: \"select-text\" }} />\n </BrowserRouter>\n </QueryClientProvider>\n </ErrorBoundary>\n );\n}\n","// TODO(T1): EntityClient is the v2 convenience layer built alongside the existing v1\n// hooks (useEntityData, useEntityItem, useMutations). The v1 hooks will be migrated to\n// use EntityClient internally over time. Until then, both layers coexist.\n//\n// TODO(T6): No tests exist for the v2 SDK yet. Unit tests are needed for EntityClient\n// methods, attachHelpers immutability, RefCache merge semantics, and URL building.\nimport { apiFetch } from \"./client\";\nimport type {\n Refs,\n V2ListParams,\n V2ListResponse,\n V2Meta,\n V2StatusInstance,\n V2PropertyInstance,\n EnrichedRow,\n} from \"@/types/api\";\n\n// ---------------------------------------------------------------------------\n// Helpers attached to returned rows\n// ---------------------------------------------------------------------------\n\n/** Find a status by group code on an enriched row. */\nfunction findStatus(\n row: EnrichedRow,\n groupCode: string,\n): V2StatusInstance | undefined {\n return row.$statuses?.find((s) => s.group_code === groupCode);\n}\n\n/** Find a property by code on an enriched row. */\nfunction findProperty(\n row: EnrichedRow,\n propertyCode: string,\n): V2PropertyInstance | undefined {\n return row.$properties?.find((p) => p.property_code === propertyCode);\n}\n\n/**\n * Attach $status() and $property() convenience helpers to a row.\n * Returns a shallow copy - never mutates the input (which may be a\n * TanStack Query cache entry where mutation breaks change detection).\n */\nfunction attachHelpers<T extends Record<string, unknown>>(\n row: T & EnrichedRow,\n): T & EnrichedRow & RowHelpers {\n const enriched = { ...row } as T & EnrichedRow & RowHelpers;\n enriched.$status = (groupCode: string) => findStatus(enriched, groupCode);\n enriched.$property = (propertyCode: string) => findProperty(enriched, propertyCode);\n return enriched;\n}\n\n/** Helper methods injected onto enriched rows. */\nexport interface RowHelpers {\n $status(groupCode: string): V2StatusInstance | undefined;\n $property(propertyCode: string): V2PropertyInstance | undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Ref cache - merges $refs across pages\n// ---------------------------------------------------------------------------\n\n/** Normalized ref cache that merges $refs across multiple responses. */\nexport class RefCache {\n private cache: Refs = {};\n\n /** Merge incoming refs into the cache. */\n merge(refs: Refs | undefined): void {\n if (!refs) return;\n for (const entityCode of Object.keys(refs)) {\n if (!this.cache[entityCode]) {\n this.cache[entityCode] = {};\n }\n const incoming = refs[entityCode];\n for (const id of Object.keys(incoming)) {\n // Newer data wins - shallow merge per ref object.\n this.cache[entityCode][id] = {\n ...this.cache[entityCode][id],\n ...incoming[id],\n };\n }\n }\n }\n\n /** Get a snapshot of all cached refs. */\n all(): Refs {\n return this.cache;\n }\n\n /** Look up a single ref by entity code and id. */\n get(entityCode: string, id: string): Record<string, unknown> | undefined {\n return this.cache[entityCode]?.[id];\n }\n\n /** Clear the cache. */\n clear(): void {\n this.cache = {};\n }\n}\n\n// ---------------------------------------------------------------------------\n// URL builder\n// ---------------------------------------------------------------------------\n\nfunction buildV2ListUrl(entity: string, params: V2ListParams): string {\n const url = new URL(`/api/data/${entity}`, window.location.origin);\n\n if (params.select && params.select.length > 0) {\n url.searchParams.set(\"select\", params.select.join(\",\"));\n }\n if (params.expand && params.expand.length > 0) {\n url.searchParams.set(\"expand\", params.expand.join(\",\"));\n }\n if (params.sort) url.searchParams.set(\"sort\", params.sort);\n if (params.search) url.searchParams.set(\"search\", params.search);\n if (params.limit) url.searchParams.set(\"limit\", String(params.limit));\n if (params.after) url.searchParams.set(\"after\", params.after);\n if (params.include_deleted) url.searchParams.set(\"include_deleted\", \"true\");\n\n if (params.filters && params.filters.length > 0) {\n url.searchParams.set(\"filters\", JSON.stringify(params.filters));\n }\n\n return url.pathname + url.search;\n}\n\n// ---------------------------------------------------------------------------\n// EntityClient<T>\n// ---------------------------------------------------------------------------\n\n/**\n * Generic, type-safe client for a single entity's v2 API.\n *\n * Single-item methods wrap arrays and unwrap the first result.\n * Bulk methods pass arrays through directly.\n *\n * All write responses return enriched rows with $refs, $statuses, etc.\n */\nexport class EntityClient<T extends Record<string, unknown> = Record<string, unknown>> {\n readonly entity: string;\n readonly refs: RefCache;\n\n constructor(entity: string, refCache?: RefCache) {\n this.entity = entity;\n this.refs = refCache ?? new RefCache();\n }\n\n // ---- Read ----------------------------------------------------------------\n\n /** Get a single record by ID. Returns the full object with all sub-resources. */\n async get(id: string): Promise<T & EnrichedRow & RowHelpers> {\n const res = await apiFetch<{ data: T & EnrichedRow }>(\n `/api/data/${this.entity}/${id}`,\n );\n return attachHelpers(res.data);\n }\n\n /** List records with cursor-based pagination, field selection, and expansion. */\n async list(\n params: V2ListParams = {},\n ): Promise<{ data: (T & RowHelpers)[]; meta: V2Meta; $refs: Refs }> {\n const res = await apiFetch<V2ListResponse<T & EnrichedRow>>(\n buildV2ListUrl(this.entity, params),\n );\n\n // Merge response-level $refs into the cache.\n this.refs.merge(res.$refs);\n\n const data = res.data.map((row) => attachHelpers(row));\n return { data, meta: res.meta, $refs: this.refs.all() };\n }\n\n // ---- Create --------------------------------------------------------------\n\n /** Create a single record. Wraps in array, returns unwrapped result. */\n async create(\n item: Partial<T> & Record<string, unknown>,\n ): Promise<T & EnrichedRow & RowHelpers> {\n const results = await this.createMany([item]);\n return results[0];\n }\n\n /** Create multiple records in one request. */\n async createMany(\n items: (Partial<T> & Record<string, unknown>)[],\n ): Promise<(T & EnrichedRow & RowHelpers)[]> {\n const res = await apiFetch<(T & EnrichedRow)[]>(\n `/api/data/${this.entity}`,\n { method: \"POST\", body: JSON.stringify(items) },\n );\n return res.map((row) => attachHelpers(row));\n }\n\n // ---- Update --------------------------------------------------------------\n\n /** Update a single record. Wraps in array, returns unwrapped result. */\n async update(\n id: string,\n data: Partial<T> & Record<string, unknown>,\n ): Promise<T & EnrichedRow & RowHelpers> {\n const results = await this.updateMany([{ id, ...data }]);\n return results[0];\n }\n\n /** Update multiple records in one request. Each item must include its id. */\n async updateMany(\n items: (Partial<T> & Record<string, unknown> & { id: string })[],\n ): Promise<(T & EnrichedRow & RowHelpers)[]> {\n const res = await apiFetch<(T & EnrichedRow)[]>(\n `/api/data/${this.entity}`,\n { method: \"PATCH\", body: JSON.stringify(items) },\n );\n return res.map((row) => attachHelpers(row));\n }\n\n // ---- Delete --------------------------------------------------------------\n\n /** Delete a single record by ID. */\n async delete(id: string): Promise<void> {\n await this.deleteMany([id]);\n }\n\n /** Delete multiple records in one request. Returns the count of deleted records. */\n async deleteMany(ids: string[]): Promise<{ count: number }> {\n return apiFetch<{ count: number }>(\n `/api/data/${this.entity}/delete`,\n { method: \"POST\", body: JSON.stringify(ids) },\n );\n }\n\n // ---- Restore -------------------------------------------------------------\n\n /** Restore a single soft-deleted record by ID. */\n async restore(id: string): Promise<void> {\n await this.restoreMany([id]);\n }\n\n /** Restore multiple soft-deleted records. Returns the count of restored records. */\n async restoreMany(ids: string[]): Promise<{ count: number }> {\n return apiFetch<{ count: number }>(\n `/api/data/${this.entity}/restore`,\n { method: \"POST\", body: JSON.stringify(ids) },\n );\n }\n\n // ---- Upsert --------------------------------------------------------------\n\n /** Upsert a single record. Wraps in array, returns unwrapped result. */\n async upsert(\n item: Partial<T> & Record<string, unknown>,\n uniqueFields: string[],\n ): Promise<T & EnrichedRow & RowHelpers> {\n const results = await this.upsertMany([item], uniqueFields);\n return results[0];\n }\n\n /** Upsert multiple records. Existing matches (by unique_fields) are updated. */\n async upsertMany(\n items: (Partial<T> & Record<string, unknown>)[],\n uniqueFields: string[],\n ): Promise<(T & EnrichedRow & RowHelpers)[]> {\n const uf = encodeURIComponent(uniqueFields.join(\",\"));\n const res = await apiFetch<(T & EnrichedRow)[]>(\n `/api/data/${this.entity}?unique_fields=${uf}`,\n { method: \"POST\", body: JSON.stringify(items) },\n );\n return res.map((row) => attachHelpers(row));\n }\n}\n\n/**\n * Create an EntityClient for the given entity code.\n * Optionally share a RefCache across multiple clients.\n *\n * NOTE(T5): Each call creates a new EntityClient (and a new RefCache if none is\n * provided). For cross-page ref accumulation, callers should create a persistent\n * RefCache instance and pass it to every entityClient() call, e.g. via React\n * context or a module-level singleton.\n */\nexport function entityClient<T extends Record<string, unknown> = Record<string, unknown>>(\n entity: string,\n refCache?: RefCache,\n): EntityClient<T> {\n return new EntityClient<T>(entity, refCache);\n}\n","import { apiFetch } from \"./client\";\nimport type {\n DataResponse,\n PublicParam,\n ResolvedParam,\n} from \"@/types/api\";\n\nexport async function fetchPublicParams(): Promise<PublicParam[]> {\n const res = await apiFetch<DataResponse<PublicParam[]>>(\"/api/params/public\");\n return res.data;\n}\n\nexport async function fetchParam(code: string): Promise<ResolvedParam> {\n const res = await apiFetch<DataResponse<ResolvedParam>>(\n `/api/params/${encodeURIComponent(code)}`,\n );\n return res.data;\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { fetchPublicParams, fetchParam } from \"@/api/params\";\n\nexport function usePublicParams() {\n return useQuery({\n queryKey: [\"params-public\"],\n queryFn: fetchPublicParams,\n staleTime: 5 * 60 * 1000,\n });\n}\n\nexport function useResolvedParam(code: string) {\n return useQuery({\n queryKey: [\"params\", code],\n queryFn: () => fetchParam(code),\n enabled: !!code,\n staleTime: 5 * 60 * 1000,\n });\n}\n","import { useMemo, useCallback } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\n\n/**\n * useColumns manages visible columns via URL `columns` param.\n * Falls back to screen defaults when no URL param is set.\n */\nexport function useColumns(\n availableColumns: string[],\n defaultColumns: string[],\n) {\n const [searchParams, setSearchParams] = useSearchParams();\n\n const visibleColumns = useMemo<string[]>(() => {\n const raw = searchParams.get(\"columns\");\n if (raw) {\n const fromURL = raw.split(\",\").filter(Boolean);\n // Intersect with available pool (drop stale column refs).\n return fromURL.filter((c) => availableColumns.includes(c));\n }\n return defaultColumns.length > 0 ? defaultColumns : availableColumns;\n }, [searchParams, availableColumns, defaultColumns]);\n\n const setColumns = useCallback(\n (cols: string[]) => {\n const next = new URLSearchParams(searchParams);\n if (cols.length === 0 || arraysEqual(cols, defaultColumns)) {\n next.delete(\"columns\"); // reset to defaults\n } else {\n next.set(\"columns\", cols.join(\",\"));\n }\n setSearchParams(next);\n },\n [searchParams, setSearchParams, defaultColumns],\n );\n\n const resetToDefaults = useCallback(() => {\n const next = new URLSearchParams(searchParams);\n next.delete(\"columns\");\n setSearchParams(next);\n }, [searchParams, setSearchParams]);\n\n const showAll = useCallback(() => {\n setColumns(availableColumns);\n }, [availableColumns, setColumns]);\n\n const isColumnVisible = useCallback(\n (col: string) => visibleColumns.includes(col),\n [visibleColumns],\n );\n\n const toggleColumn = useCallback(\n (col: string) => {\n if (visibleColumns.includes(col)) {\n // Don't allow hiding last column.\n if (visibleColumns.length <= 1) return;\n setColumns(visibleColumns.filter((c) => c !== col));\n } else {\n setColumns([...visibleColumns, col]);\n }\n },\n [visibleColumns, setColumns],\n );\n\n return {\n visibleColumns,\n availableColumns,\n setColumns,\n resetToDefaults,\n showAll,\n isColumnVisible,\n toggleColumn,\n };\n}\n\nfunction arraysEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n return a.every((v, i) => v === b[i]);\n}\n"],"names":["cn","inputs","twMerge","clsx","ApiError","status","message","code","index","__publicField","flatActionBody","args","refreshPromise","refreshAccessToken","init","res","retryAfter","r","ensureRefresh","defaultPersistentAuthFailureHandler","onPersistentAuthFailure","apiFetch","path","options","headers","body","retryHeaders","retryRes","retryBody","refreshErr","callHandler","fetchSchema","useSchema","useQuery","EXCLUDED_ROUTES","useTabStore","create","set","get","tab","existing","t","id","newTab","s","state","idx","remaining","nextActive","activeId","overId","oldIdx","newIdx","tabs","moved","pathname","title","search","useTabNavigate","navigate","useNavigate","openTab","switchTab","findTabByPathname","useCallback","opts","iconCache","loadIcon","name","cached","importFn","dynamicIconImports","LazyIcon","lazy","DynamicIcon","props","Icon","useMemo","jsx","Suspense","DETAIL_SCREEN_NONE","loc","ls","lang","fieldDisplayName","field","fieldName","entities","explicit","_a","_b","refEntity","entityName","_c","propertyToField","prop","baseName","display","getPrimaryKeyFields","entity","extractPkValues","record","fields","values","f","pkValuesToId","pkValues","vals","Sidebar","collapsed","setCollapsed","useState","collapsedSections","setCollapsedSections","location","useLocation","schema","tabNavigate","nodes","branding","appName","appInitial","accentColor","findFirstLeaf","items","node","found","toggleSection","prev","isActive","route","jsxs","first","screen","ChevronDown","item","active","ChevronRight","ChevronLeft","checkSetup","login","email","password","signup","displayName","getMe","listTenants","switchTenant","tenantId","logout","listSSOProviders","tenantCode","ssoAuthorizeUrl","slug","redirect","params","qs","useAuthStore","user","tenant","tenants","logoutApi","useAuth","isAuthenticated","isLoading","activeTenant","setUser","setTenants","storeLogout","queryClient","useQueryClient","loginMutation","useMutation","authApi.login","result","authApi.listTenants","err","toast","signupMutation","authApi.signup","switchTenantMutation","authApi.switchTenant","DropdownMenu","DropdownMenuPrimitive","DropdownMenuTrigger","DropdownMenuSubTrigger","React","className","inset","children","ref","DropdownMenuSubContent","DropdownMenuContent","sideOffset","DropdownMenuItem","DropdownMenuCheckboxItem","checked","Check","DropdownMenuRadioItem","Circle","DropdownMenuLabel","DropdownMenuSeparator","buttonVariants","cva","Button","variant","size","asChild","Slot","TopBar","isSwitchingTenant","initials","n","canSwitch","ChevronsUpDown","Fragment","LogOut","SortableTab","isOnly","onSwitch","onClose","attributes","listeners","setNodeRef","transform","transition","isDragging","useSortable","style","CSS","e","X","TabBar","activeTabId","closeTab","reorderTabs","sensors","useSensors","useSensor","PointerSensor","tabIds","handleSwitch","handleClose","_e","nextIdx","next","handleDragEnd","event","over","DndContext","closestCenter","SortableContext","horizontalListSortingStrategy","streamEvents","signal","reader","decoder","buffer","currentEvent","currentData","done","value","lines","line","parsed","ENTITY_CHILDREN_KEY","useChildrenData","parentEntity","parentId","childCode","foreignKey","sort","limit","fkArr","idArr","filters","fk","i","MAX_RECONNECT_DELAY","BASE_DELAY","COALESCE_WINDOW_MS","invalidateForEntityChanges","events","ev","mutated","query","key","useSSE","abortRef","useRef","useEffect","mounted","attempt","pending","flushTimer","flush","batch","scheduleFlush","connect","controller","delay","jitter","Layout","intended","redirectParam","Outlet","Input","type","labelVariants","Label","LabelPrimitive","Card","CardHeader","CardTitle","CardDescription","CardContent","CardFooter","LoginPage","searchParams","useSearchParams","isLoginPending","setEmail","setPassword","rawRedirect","redirectTo","ssoError","setupStatus","ssoProviders","handleSubmit","hasProviders","provider","Link","SignupPage","isSignupPending","setDisplayName","SSOCallbackPage","NotFoundPage","PageHeader","backTo","actions","handleBack","ArrowLeft","badgeVariants","Badge","color","colorStyle","AdminCatalogPage","activeTab","setActiveTab","HandlersTab","ActionsTab","allHandlers","h","entityCode","a","b","handler","HandlerCard","expanded","setExpanded","paramCode","param","ParamRow","allActions","action","grouped","groups","group","ActionCard","v","buildListUrl","url","listEntities","getEntity","createEntity","data","updateEntity","pkFields","deleteEntity","restoreEntity","buildActionBody","ids","executeAction","resolveAssociation","useEntityData","prevQuery","useCreateEntity","useUpdateEntity","_result","_variables","useDeleteEntity","_pkValues","useRestoreEntity","useExecuteAction","actionCode","useDebounce","debounced","setDebounced","timer","CopyButton","copied","setCopied","handleCopy","iconSize","Copy","StringField","mode","onChange","text","Textarea","remarkPlugins","remarkBreaks","TextField","widget","rendered","Markdown","rows","Select","SelectPrimitive","SelectValue","SelectTrigger","SelectScrollUpButton","ChevronUp","SelectScrollDownButton","SelectContent","position","SelectItem","SelectLabel","SelectSeparator","NULL_SENTINEL","EnumField","current","showClearOption","currentValue","EmailField","str","FAVICON_BASE","SAFE_PROTOCOLS","LONG_TLD","looksLikeTLD","label","looksLikeHostname","candidate","labels","normalizeUrl","raw","schemeMatch","scheme","afterColon","port","parseDomain","href","isValidUrl","UrlField","errorDomain","setErrorDomain","isLink","domain","showFavicon","linkText","ExternalLink","formatTimestamp","isDateOnly","d","offsetMatch","isUTC","date","tz","sign","hours","minutes","offsetMs","localMs","localDate","extractTzAbbrev","m","minPart","toInputValue","y","mo","mi","TimestampField","hasTz","formatted","tzAbbrev","inputValue","BoolField","formatDecimalString","trimmed","negative","abs","intPart","fracPart","formattedInt","numFormatter","NumberField","isMoney","isDecimal","units","unitSuffix","staticUnit","displayUnit","num","useEntity","resolveDisplay","val","RefField","refs","refEntityCode","displayField","_d","pk","response","optionsLoading","displayValue","strVal","entityRefs","refRecord","match","currentId","hasCurrentInOptions","JsonEditor","JsonEditorFallback","JsonField","parseLangMap","MultilangField","languages","langMap","displayVal","handleLangChange","updated","k","MultilangTextField","StructureField","structDef","StructureArrayRenderer","StructureObjectRenderer","obj","fieldOrder","fieldValue","renderField","handleFieldChange","handleItemChange","itemValue","handleAdd","handleRemove","_","Trash2","Plus","SECRET_SENTINEL","SecretField","showValue","setShowValue","setInputValue","isUpdate","hasExistingValue","handleChange","EyeOff","Eye","PasswordField","revealed","setRevealed","toStringArray","StringArrayField","draft","setDraft","addItem","removeItem","handleKeyDown","toIntArray","IntArrayField","fieldRenderers","Renderer","EmptyState","icon","description","Skeleton","TableSkeleton","cols","j","DetailSkeleton","AlertDialog","AlertDialogPrimitive","AlertDialogPortal","AlertDialogOverlay","AlertDialogContent","AlertDialogHeader","AlertDialogFooter","AlertDialogTitle","AlertDialogDescription","AlertDialogAction","AlertDialogCancel","ConfirmDialog","open","onOpenChange","confirmLabel","onConfirm","destructive","Dialog","DialogPrimitive","DialogPortal","DialogOverlay","DialogContent","DialogHeader","DialogFooter","DialogTitle","DialogDescription","ROW_PREFILL_RE","resolveParamDefault","row","paramToEntityField","ActionDialog","actionName","onSubmit","isPending","paramEntries","order","buildInitialFormData","initial","formData","setFormData","handleOpenChange","isOpen","paramName","ActionConfirmDialog","ActionResultDialog","DisplayFieldRow","evaluateConditions","conditions","cond","rowStatus","evaluateFieldCondition","fieldVal","op","isTruthy","compareValues","fieldStr","condStr","getActionsByVisibility","visibility","getScreenActions","entityActions","screenActionCodes","fallbackVisibility","globalActions","actionHasParams","isAssociationAction","findListScreenForEntity","regions","registerFieldRegion","region","getFieldRegion","interpolate","template","ctx","_match","resolvePath","parts","root","rest","acc","regionName","executeUISteps","steps","step","runStep","msg","target","splitPath","kind","dot","isUIAction","ActionButton","objectIds","onSuccess","onBatchStart","onBatchError","onBatchPartial","showDialog","setShowDialog","showConfirm","setShowConfirm","navigating","setNavigating","displayResult","setDisplayResult","executeMutation","isAssociation","hasParams","hasConfirmation","conditionsMet","isBatchEmpty","isSingleInvalid","handleAssociationNavigate","assocCode","targetScreen","targetEntity","qualifiedActionCode","actionIds","handleActionSuccess","closeDialog","handleClick","handleConfirm","handleDialogSubmit","RowActionItem","objectId","BatchActionProgress","count","isSuccess","isError","isPartial","Loader2","CheckCircle2","AlertTriangle","XCircle","NO_VALUE_OPS","OP_LABELS","parseFiltersFromURL","setFiltersInURL","hasOrGroups","flatFieldConditions","countActiveFilters","eqFilter","removeFilter","cleaned","useFilters","setSearchParams","activeCount","setFilters","newFilters","clearFilters","FilterChips","onRemove","onClearAll","onChipClick","fieldLabel","gi","formatValue","FilterChip","fieldNodes","onClick","FilterDrawer","onApply","availableFields","showFieldPicker","setShowFieldPicker","isOrMode","activeFields","addCondition","fieldCode","meta","defaultOp","updateCondition","updates","removeCondition","addOrGroup","currentConditions","otherNodes","handleApply","filteredOr","g","handleReset","Filter","FilterRow","OrGroupEditor","newGroups","newDraft","FieldPicker","onUpdate","isNoValue","opt","ni","firstAvailable","onSelect","onCancel","setSearch","filtered","ColumnPicker","availableColumns","visibleColumns","onToggle","onReset","onShowAll","columnLabel","c","setOpen","Columns3","col","isVisible","RotateCcw","ViewSwitcher","views","activeViewId","isDirty","onSave","onSaveAs","onSetDefault","activeView","systemViews","personalViews","sharedViews","ViewOption","Save","isDefault","isShared","_onSetDefault","Star","Globe","useScreen","screenCode","useViews","userId","dbResponse","isOwn","resolveDetailHref","list","allScreens","SmartListPage","deleteState","setDeleteState","rowSelection","setRowSelection","batchState","setBatchState","filterDrawerOpen","setFilterDrawerOpen","jsonFilters","filterCount","setJsonFilters","allViews","toolbarActions","rowActions","hasExplicitRowActions","hasBatchActions","hasSoftDelete","canViewDeleted","p","includeDeleted","updateTabSearch","tabName","tabIcon","page","searchValue","sortParam","debouncedSearch","visibleCols","expand","allCols","deleteMutation","sorting","dir","pkField","refsRef","columns","tbl","colKey","groupCode","statusMap","statuses","def","propCode","propDef","width","getValue","hasDefaultActions","editHref","MoreHorizontal","Pencil","table","useReactTable","getCoreRowModel","updater","selectedIds","tag","input","parentRef","rowVirtualizer","useVirtualizer","updateSearch","toggleIncludeDeleted","goToPage","hasRowDetailTarget","handleRowClick","firstCol","tabTitle","handleDelete","results","failed","succeededIds","entityDisplay","screenName","screenIcon","_f","rawIds","isDisabled","successIds","succeeded","view","Search","gc","pc","_g","headerGroup","header","canSort","sorted","flexRender","ArrowUp","ArrowDown","ArrowUpDown","_h","virtualRow","isDeleted","cell","_i","buildFilterFieldMeta","filterFields","ops","fieldTypeToOperators","formatOffsetTimestamp","useEntityItem","cacheKey","AssociationTabs","recordId","associations","assocEntries","activeKey","activeAssoc","assoc","AssociationContent","assocKey","association","assocResult","resolving","targetEntityCode","targetIds","filterIds","listResponse","loadingRecords","handleViewAll","PX_PATTERN","parseSizeValue","pxMatch","intVal","LayoutRow","config","gap","resizable","stack_below","stackPx","stacked","setStacked","containerRef","el","observer","entries","entry","flexSizes","setFlexSizes","dragging","getInitialSizes","w","onDragStart","sizes","onMove","totalWidth","delta","totalFlex","flexDelta","newSizes","onUp","heightStyle","parseHeight","itemStyle","LayoutNodeRenderer","flexValue","minWidth","maxWidth","flex","height","LayoutColumn","getTabLabel","childRelation","childEntity","getTabIcon","LayoutTabs","SectionBlock","defaultCollapsed","childCtx","LayoutRenderer","resolveChildConfig","relation","screenNode","resolveField","inferName","inferColumns","inferSort","posField","timelineSource","inferTimelineFields","cardsSource","quickAdd","screenOverride","entityDefault","autoDefault","findPrimaryKey","fkSet","tc","inferTimeField","inferFirstFieldOfType","inferFirstFieldOfTypes","inferDirectionField","inferIntentField","direction","intent","types","pks","findChildRelation","buildQuickAddPayload","fieldValues","defaults","isQuickAddReady","requiredFields","toBareLocalNow","now","min","useQuickAdd","setValues","qa0","ce","initialValues","mutate","error","reset","payload","qa","resetValues","normalizedParentId","isReady","QuickAddForm","ChildrenTable","quickAddForm","rowIdx","ChildrenList","subCols","ChildrenCards","cardsConfig","headerField","badgeField","colCount","gridClass","detailFields","QUICK_ENTRY_REGION","MIN_HEIGHT","DEFAULT_HEIGHT","MAX_HEIGHT","TimelineComposer","setHeight","valuesRef","handleFieldChangeRef","fieldNodesRef","contentField","topFields","bottomFields","renderMetaField","ChildrenTimeline","timeline","scroll","autoScroll","scrollRef","hasAutoScrolled","prevRowCount","isInitialLoad","hasNewRows","editingId","setEditingId","editableFields","rowId","TimelineEntry","isEditing","onStartEdit","onCancelEdit","onSaved","invalidate","updateMut","deleteMut","startEdit","timeField","typeField","summaryField","authorField","directionField","intentField","DirectionChip","outbound","isOutbound","ArrowUpRight","ArrowDownLeft","EditableChildrenTable","validationErrors","tableRef","editableColumns","displayOnlyColumns","handleCellChange","rowKey","handleAddRow","newRow","quickDefaults","handleDeleteRow","handleUndoDelete","tbody","cellIndex","rowIndex","allRows","nextRow","nextCell","nextTd","newRows","lastRow","firstInput","rowErrors","hasError","isDisplayOnly","Undo2","DraggableChildrenTable","positionField","rowIds","maxPosition","max","pos","nonDeleted","deleted","oldIndex","newIndex","reordered","withPositions","verticalListSortingStrategy","SortableRow","onCellChange","onDelete","onUndoDelete","GripVertical","isEditable","ChildrenBlock","pendingRows","TableComponent","displayProps","useAssociatedData","stableFilters","useInfiniteQuery","pageParam","filterNodes","lastPage","AssociatedToolbar","searchable","onSearchChange","onFilterChange","allEntities","hasSearch","hasFilters","filterField","currentVal","RefFilterDropdown","optLabel","AssociatedBlock","assocEntity","fkField","editable","hasToolbar","PaginatedAssociatedTable","SimpleAssociatedTable","invalidateQuery","AssociatedTableInner","setSearchValue","setDebouncedSearch","searchTimerRef","handleFilterChange","activeFilters","infiniteData","hasNextPage","fetchNextPage","isFetchingNextPage","mergedRefs","entityKey","records","activeCell","setActiveCell","rowStates","setRowStates","rowStatesRef","debounceTimers","timers","draftRow","setDraftRow","draftErrors","setDraftErrors","draftSaving","setDraftSaving","deleteConfirm","setDeleteConfirm","deletingIds","setDeletingIds","flushRow","sentVer","nextVer","handleStartDraft","handleConfirmDraft","errors","showEmpty","isDeleting","rowState","AssociatedRow","DraftRow","onDeleteClick","displayRow","apiError","fieldErrors","FieldsBlock","onFieldChange","hideLabels","layoutField","hasActions","DEBOUNCE_TYPES","DEBOUNCE_MS","PropertiesBlock","objectProperties","onSetProperty","isNew","propertyDefs","filter","propVal","effectiveMode","DebouncedProperty","timerRef","StatusGroupsDisplay","statusGroups","objectStatuses","onSetStatus","sgCode","sg","currentCode","currentStatus","available","statusCode","noop","StatusesBlock","isStatusPending","collectFKFields","fks","rel","validatePendingChildren","pendingChildren","fkFields","missingFields","arraysEqual","SmartDetailPage","urlId","useParams","selfUser","isSelf","pkCacheKey","itemResponse","createMutation","updateMutation","restoreMutation","hasStatusGroups","itemData","openInEdit","editing","setEditing","pendingStatuses","setPendingStatuses","pendingProperties","setPendingProperties","setPendingChildren","childrenSnapshot","setChildrenSnapshot","sidebarW","setSidebarW","sidebarRef","sidebarDrag","onSidebarDragStart","startW","recordRefs","isRecordDeleted","updateTabTitle","dfKey","rawVal","resolvedVal","displayTitle","startEditing","serverChildren","cancelEditing","listRoute","listRouteExists","handleSave","original","propertyCode","childrenPayload","_key","_deleted","_dirty","clearPending","newRecord","newPkValues","newId","handleChildrenChange","handleRestore","childValidationErrors","hasChildErrors","detailName","displayFieldKey","rawDisplayValue","isSaving","hasExplicitActions","headerActions","layoutCtx","base","merged","sc","hasSidebar","headerEl","deletedBanner","statusesEl","mainContent","deleteDialog","setObjectStatus","note","statusEntry","useSetStatus","statusApi.setObjectStatus","setObjectProperty","deleteObjectProperty","useSetProperty","propsApi.setObjectProperty","useDeleteProperty","propsApi.deleteObjectProperty","SmartRecordListPage","selectedId","listLoading","listRefs","selectRecord","updateFilter","listResizable","panelWidth","setPanelWidth","listWidthRaw","container","pct","dragCleanup","handleMouseDown","startX","startWidth","onMouseMove","containerWidth","newWidth","cleanup","listColumns","activeFilterCount","fieldDef","activeNode","RecordListRow","RecordDetailPanel","_pkField","isSelected","primaryCol","secondaryCol","badgeCols","setStatusMutation","setPropertyMutation","rawTitle","ErrorBoundary","Component","info","TOKEN_MAP","THEME_TOKENS","themeDefToTokens","tokens","cssVar","STORAGE_KEY","getSystemPreference","resolveEffective","selected","applyTheme","themeName","customThemes","html","clearCustomProperties","getInitialTheme","initialSelected","initialEffective","useThemeStore","effective","themes","effectiveTheme","registry","registerScreen","component","getRegisteredScreen","QueryClient","useDynamicRoutes","routes","out","Route","CustomComponent","defaultRoute","child","AppRoutes","initialize","setAvailableThemes","themesJson","converted","Routes","Navigate","App","QueryClientProvider","BrowserRouter","Toaster","findStatus","findProperty","attachHelpers","enriched","RefCache","incoming","buildV2ListUrl","EntityClient","refCache","uniqueFields","uf","entityClient","fetchPublicParams","fetchParam","usePublicParams","useResolvedParam","useColumns","defaultColumns","setColumns","resetToDefaults","showAll","isColumnVisible","toggleColumn"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/lib/utils.ts","../src/types/api.ts","../src/api/client.ts","../src/api/schema.ts","../src/hooks/useSchema.ts","../src/stores/tabs.ts","../src/hooks/useTabNavigate.ts","../src/components/shared/DynamicIcon.tsx","../src/types/schema.ts","../src/components/layout/Sidebar.tsx","../src/api/auth.ts","../src/stores/auth.ts","../src/hooks/useAuth.ts","../src/components/ui/dropdown-menu.tsx","../src/components/ui/button.tsx","../src/components/layout/TopBar.tsx","../src/components/layout/TabBar.tsx","../src/api/events.ts","../src/hooks/useChildrenData.ts","../src/hooks/useSSE.ts","../src/components/layout/Layout.tsx","../src/components/ui/input.tsx","../src/components/ui/label.tsx","../src/components/ui/card.tsx","../src/components/pages/LoginPage.tsx","../src/components/pages/SignupPage.tsx","../src/components/pages/SSOCallbackPage.tsx","../src/components/pages/NotFoundPage.tsx","../src/components/shared/PageHeader.tsx","../src/components/ui/badge.tsx","../src/components/pages/AdminCatalogPage.tsx","../src/api/data.ts","../src/hooks/useEntityData.ts","../src/hooks/useMutations.ts","../src/hooks/useDebounce.ts","../src/components/shared/CopyButton.tsx","../src/components/fields/StringField.tsx","../src/components/ui/textarea.tsx","../src/components/fields/TextField.tsx","../src/components/ui/select.tsx","../src/components/fields/EnumField.tsx","../src/components/fields/EmailField.tsx","../src/components/fields/UrlField.tsx","../src/components/fields/TimestampField.tsx","../src/components/fields/BoolField.tsx","../src/components/fields/NumberField.tsx","../src/hooks/useEntity.ts","../src/components/fields/RefField.tsx","../src/components/fields/JsonField.tsx","../src/components/fields/MultilangField.tsx","../src/components/fields/MultilangTextField.tsx","../src/components/fields/StructureField.tsx","../src/components/fields/SecretField.tsx","../src/components/fields/PasswordField.tsx","../src/components/fields/StringArrayField.tsx","../src/components/fields/IntArrayField.tsx","../src/components/fields/index.tsx","../src/components/shared/EmptyState.tsx","../src/components/ui/skeleton.tsx","../src/components/shared/LoadingSkeleton.tsx","../src/components/ui/alert-dialog.tsx","../src/components/shared/ConfirmDialog.tsx","../src/components/ui/dialog.tsx","../src/lib/field-regions.ts","../src/lib/ui-actions.ts","../src/components/shared/ActionDialog.tsx","../src/components/shared/ActionConfirmDialog.tsx","../src/components/shared/ActionResultDialog.tsx","../src/lib/actions.ts","../src/components/shared/ActionButton.tsx","../src/components/shared/RowActionItem.tsx","../src/components/shared/BatchActionProgress.tsx","../src/lib/filters.ts","../src/hooks/useFilters.ts","../src/components/filters/FilterChips.tsx","../src/components/filters/FilterDrawer.tsx","../src/components/columns/ColumnPicker.tsx","../src/components/views/ViewSwitcher.tsx","../src/hooks/useScreen.ts","../src/hooks/useViews.ts","../src/components/pages/SmartListPage.tsx","../src/lib/timestamp.ts","../src/hooks/useEntityItem.ts","../src/components/shared/AssociationTabs.tsx","../src/lib/size-value.ts","../src/components/detail-layout/LayoutRow.tsx","../src/components/detail-layout/LayoutColumn.tsx","../src/components/detail-layout/LayoutTabs.tsx","../src/components/detail-layout/SectionBlock.tsx","../src/lib/child-config.ts","../src/lib/quick-add.ts","../src/components/detail-layout/useQuickAdd.ts","../src/components/detail-layout/QuickAddForm.tsx","../src/components/detail-layout/ChildrenTable.tsx","../src/components/detail-layout/ChildrenList.tsx","../src/components/detail-layout/ChildrenCards.tsx","../src/components/detail-layout/TimelineComposer.tsx","../src/components/detail-layout/ChildrenTimeline.tsx","../src/components/detail-layout/EditableChildrenTable.tsx","../src/components/detail-layout/DraggableChildrenTable.tsx","../src/components/detail-layout/ChildrenBlock.tsx","../src/hooks/useAssociatedData.ts","../src/components/detail-layout/AssociatedToolbar.tsx","../src/components/detail-layout/AssociatedBlock.tsx","../src/components/detail-layout/FieldsBlock.tsx","../src/components/detail-layout/PropertiesBlock.tsx","../src/components/shared/StatusGroupsDisplay.tsx","../src/components/detail-layout/StatusesBlock.tsx","../src/components/detail-layout/LayoutRenderer.tsx","../src/lib/children-validation.ts","../src/components/pages/SmartDetailPage.tsx","../src/api/status.ts","../src/hooks/useObjectStatus.ts","../src/api/properties.ts","../src/hooks/useProperties.ts","../src/components/pages/SmartRecordListPage.tsx","../src/components/shared/ErrorBoundary.tsx","../src/lib/theme-utils.ts","../src/stores/theme.ts","../src/stores/screen-registry.ts","../src/app.tsx","../src/api/entities.ts","../src/api/params.ts","../src/hooks/useParams.ts","../src/hooks/useColumns.ts"],"sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import type { LocalizedString } from \"./schema\";\n\nexport interface ListMeta {\n total: number;\n page: number;\n per_page: number;\n total_pages: number;\n}\n\nexport interface ListResponse<T = Record<string, unknown>> {\n data: T[];\n meta: ListMeta;\n $refs?: Record<string, Record<string, Record<string, unknown>>>;\n}\n\nexport interface DataResponse<T = Record<string, unknown>> {\n data: T;\n}\n\nexport interface ApiErrorBody {\n error: {\n message: string;\n code: string;\n field?: string;\n };\n /** Bulk operation item index (present on validation errors for array requests). */\n index?: number;\n}\n\nexport class ApiError extends Error {\n status: number;\n code: string;\n /** Bulk operation item index (present on validation errors for array requests). */\n index?: number;\n\n constructor(status: number, message: string, code: string, index?: number) {\n super(message);\n this.name = \"ApiError\";\n this.status = status;\n this.code = code;\n this.index = index;\n }\n}\n\nexport interface Tenant {\n id: string;\n code: string;\n name: string;\n role: string;\n}\n\nexport interface AuthUser {\n id: string;\n email: string;\n display_name: string;\n is_active: boolean;\n roles: string[];\n permissions?: string[];\n tenant?: Tenant;\n created_at: string;\n updated_at: string;\n}\n\nexport interface LoginResponse {\n expires_at: string;\n user: AuthUser;\n tenant?: Tenant;\n}\n\nexport interface CheckSetupResponse {\n needs_setup: boolean;\n}\n\nexport interface StatusInfo {\n group_code: string;\n status_code: string;\n status_name: LocalizedString;\n color?: string;\n set_by?: string;\n set_at: string;\n note?: string;\n}\n\nexport interface PropertyValue {\n property_code: string;\n name: LocalizedString;\n type: string;\n value: unknown;\n}\n\nexport interface PublicParam {\n code: string;\n name: LocalizedString;\n type: string;\n category: string;\n description?: LocalizedString;\n value: unknown;\n}\n\nexport interface ResolvedParam {\n code: string;\n name: LocalizedString;\n type: string;\n category?: string;\n description?: LocalizedString;\n value: unknown;\n source: \"object\" | \"user\" | \"role\" | \"tenant\" | \"env\" | \"yaml\" | \"none\";\n}\n\nexport interface ParamOverride {\n param_code: string;\n value: unknown;\n}\n\nexport interface SSOProvider {\n name: string;\n slug: string;\n}\n\nexport interface ListParams {\n page?: number;\n per_page?: number;\n sort?: string;\n search?: string;\n /** JSON filter nodes (recursive AND/OR tree). */\n filters?: FilterNodeParam[];\n include_deleted?: boolean;\n expand?: string[];\n screen?: string;\n}\n\n/** Minimal filter node type for API params (matches backend FilterNode). */\nexport interface FilterNodeParam {\n field?: string;\n op?: string;\n value?: unknown;\n or?: FilterNodeParam[][];\n and?: FilterNodeParam[];\n}\n\n// ---------------------------------------------------------------------------\n// v2 API types - bulk operations, cursor pagination, sub-resource shapes\n// ---------------------------------------------------------------------------\n\n/** Cursor-based pagination metadata returned by v2 List. */\nexport interface V2Meta {\n total: number;\n limit: number;\n has_more: boolean;\n cursor?: string;\n}\n\n/**\n * Refs map: keyed by entity code (or $-prefixed virtual entity code),\n * then by record ID, then field values.\n * Example: { company: { \"uuid-1\": { id: \"uuid-1\", name: \"Acme\" } } }\n */\nexport type Refs = Record<string, Record<string, Record<string, unknown>>>;\n\n/** Per-row status instance. */\nexport interface V2StatusInstance {\n group_code: string;\n status_code: string;\n status_name?: Record<string, string>;\n color?: string;\n set_at?: string;\n set_by?: string;\n note?: string;\n}\n\n/** Per-row property instance. */\nexport interface V2PropertyInstance {\n property_code: string;\n value: unknown;\n updated_at?: string;\n updated_by?: string;\n}\n\n/** Per-row parameter override. */\nexport interface V2ParamInstance {\n param_code: string;\n value: unknown;\n}\n\n/** v2 List response with cursor pagination and response-level $refs. */\nexport interface V2ListResponse<T = Record<string, unknown>> {\n data: T[];\n meta: V2Meta;\n $refs?: Refs;\n}\n\n/** v2 List query parameters. */\nexport interface V2ListParams {\n select?: string[];\n expand?: string[];\n sort?: string;\n search?: string;\n filters?: FilterNodeParam[];\n limit?: number;\n after?: string;\n include_deleted?: boolean;\n}\n\n/** Per-field resolved display unit codes. */\nexport type Units = Record<string, string>;\n\n/** A row enriched with $-prefixed sub-resources (as returned by Get or write responses). */\nexport interface EnrichedRow extends Record<string, unknown> {\n $refs?: Refs;\n $statuses?: V2StatusInstance[];\n $properties?: V2PropertyInstance[];\n $params?: V2ParamInstance[];\n $children?: Record<string, Record<string, unknown>[]>;\n $units?: Units;\n}\n","import { ApiError, type ApiErrorBody } from \"@/types/api\";\n\n// The access and refresh tokens live in httpOnly cookies managed entirely by\n// the backend (__Host-declarion-access-token, __Host-declarion-refresh-token).\n// The browser attaches them automatically on every request when\n// credentials: \"include\" is set. JavaScript cannot read these cookies, which\n// is the whole point - an XSS cannot exfiltrate the session.\n//\n// The backend collapsed every auth/SSO/api-key endpoint into the generic\n// handler dispatcher at POST /api/actions/{code}. `callHandler` below is\n// the single entry point from the frontend; every wrapper in api/auth.ts\n// etc. uses it. `apiFetch` is kept for the handful of platform endpoints\n// that still live at named URLs (schema, data CRUD, params, etc.).\n\n// POST /api/actions/{code} bodies are flat: the handler's params sit at\n// the top level. Global handlers (auth.*, etc.) pass their args as-is.\nconst flatActionBody = (args: unknown) =>\n JSON.stringify(args ?? {});\n\nlet refreshPromise: Promise<void> | null = null;\n\n// refreshAccessToken stays on raw fetch (NOT apiFetch / callHandler) to\n// avoid recursion: apiFetch's 401 retry path waits on refreshPromise, so\n// if the refresh call itself went through apiFetch it would deadlock.\nasync function refreshAccessToken(): Promise<void> {\n const init: RequestInit = {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"Content-Type\": \"application/json\" },\n body: flatActionBody({}),\n };\n const res = await fetch(\"/api/actions/auth.refresh\", init);\n\n // Grace-period replay: backend says retry shortly.\n if (res.status === 429) {\n const retryAfter = parseInt(res.headers.get(\"Retry-After\") || \"1\", 10);\n await new Promise((r) => setTimeout(r, retryAfter * 1000));\n const retryRes = await fetch(\"/api/actions/auth.refresh\", init);\n if (!retryRes.ok) {\n throw new Error(\"refresh failed after retry\");\n }\n return;\n }\n\n if (!res.ok) {\n throw new Error(\"refresh failed\");\n }\n}\n\nexport async function ensureRefresh(): Promise<void> {\n if (refreshPromise) return refreshPromise;\n refreshPromise = refreshAccessToken().finally(() => {\n refreshPromise = null;\n });\n return refreshPromise;\n}\n\n// Handler invoked when a persistent 401 requires sending the user back to\n// the login flow. Injected (not hardcoded) so tests can substitute a spy\n// and non-browser consumers (e.g. a worker) can route the signal their own\n// way. Default implementation assigns window.location.href — same behavior\n// as before this was extracted.\ntype PersistentAuthFailureHandler = () => void;\n\nconst defaultPersistentAuthFailureHandler: PersistentAuthFailureHandler = () => {\n if (typeof window === \"undefined\") return;\n if (\n window.location.pathname.startsWith(\"/login\") ||\n window.location.pathname.startsWith(\"/signup\")\n ) {\n return;\n }\n window.location.href = \"/login\";\n};\n\nlet onPersistentAuthFailure: PersistentAuthFailureHandler =\n defaultPersistentAuthFailureHandler;\n\n/** Replace the handler invoked on persistent 401. Intended for tests\n * and non-browser consumers. Returns the previous handler so callers\n * can restore it if needed. */\nexport function setPersistentAuthFailureHandler(\n h: PersistentAuthFailureHandler,\n): PersistentAuthFailureHandler {\n const prev = onPersistentAuthFailure;\n onPersistentAuthFailure = h;\n return prev;\n}\n\nexport async function apiFetch<T>(\n path: string,\n options: RequestInit = {},\n): Promise<T> {\n const headers = new Headers(options.headers);\n\n if (!headers.has(\"Content-Type\") && options.body) {\n headers.set(\"Content-Type\", \"application/json\");\n }\n\n const res = await fetch(path, { ...options, headers, credentials: \"include\" });\n\n if (res.status === 204) {\n return undefined as T;\n }\n\n if (!res.ok) {\n let message = \"Request failed\";\n let code = \"UNKNOWN\";\n let index: number | undefined;\n\n try {\n const body = (await res.json()) as ApiErrorBody;\n message = body.error.message;\n code = body.error.code;\n if (body.index != null) index = body.index;\n } catch {\n // Ignore JSON parse errors\n }\n\n // 401 with a refresh hint: attempt exactly one silent refresh + retry.\n if (res.status === 401 && (code === \"TOKEN_REFRESH_NEEDED\" || code === \"UNAUTHORIZED\")) {\n try {\n await ensureRefresh();\n const retryHeaders = new Headers(options.headers);\n if (!retryHeaders.has(\"Content-Type\") && options.body) {\n retryHeaders.set(\"Content-Type\", \"application/json\");\n }\n const retryRes = await fetch(path, {\n ...options,\n headers: retryHeaders,\n credentials: \"include\",\n });\n if (retryRes.status === 204) {\n return undefined as T;\n }\n if (!retryRes.ok) {\n onPersistentAuthFailure();\n const retryBody = (await retryRes\n .json()\n .catch(() => ({ error: { message: \"Request failed\", code: \"UNKNOWN\" } }))) as ApiErrorBody;\n throw new ApiError(retryRes.status, retryBody.error.message, retryBody.error.code, retryBody.index);\n }\n return retryRes.json() as Promise<T>;\n } catch (refreshErr) {\n if (refreshErr instanceof ApiError) {\n throw refreshErr;\n }\n onPersistentAuthFailure();\n throw new ApiError(401, message, code, index);\n }\n }\n\n // Session revoked or other 401 - redirect to login.\n if (res.status === 401) {\n onPersistentAuthFailure();\n }\n\n console.error(`[API ${res.status}] ${code}: ${message}`);\n throw new ApiError(res.status, message, code, index);\n }\n\n return res.json() as Promise<T>;\n}\n\n// Action endpoint response envelope. The actions dispatcher always wraps\n// successful handler results as { status: \"success\", result: <data>, ... }.\ninterface ActionEnvelope<R> {\n status: string;\n result: R;\n audit_operation_id?: string;\n object_count?: number;\n}\n\n// callHandler is the single entry point for every auth/SSO/api-key\n// operation. It POSTs to /api/actions/{code} with a flat body (handler\n// params at the top level) and unwraps the result envelope, so callers\n// see the handler's return type directly.\n//\n// Cookie side effects (login/signup/refresh/switch_tenant) are set by the\n// backend via the HTTPCustomizer interface on *auth.LoginResult; the\n// browser stores them automatically because `credentials: \"include\"` is\n// already set by apiFetch. Frontend does not need any special handling.\nexport async function callHandler<R = unknown>(\n code: string,\n args: unknown = {},\n): Promise<R> {\n const env = await apiFetch<ActionEnvelope<R>>(\n `/api/actions/${encodeURIComponent(code)}`,\n {\n method: \"POST\",\n body: flatActionBody(args),\n },\n );\n return env.result;\n}\n","import { apiFetch } from \"./client\";\nimport type { Schema } from \"@/types/schema\";\n\nexport async function fetchSchema(): Promise<Schema> {\n return apiFetch<Schema>(\"/api/schema\");\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { fetchSchema } from \"@/api/schema\";\n\nexport function useSchema() {\n return useQuery({\n queryKey: [\"schema\"],\n queryFn: fetchSchema,\n staleTime: Infinity,\n });\n}\n","import { create } from \"zustand\";\n\nexport interface TabItem {\n id: string;\n pathname: string;\n search: string;\n title: string;\n icon?: string;\n closable: boolean;\n}\n\ninterface TabState {\n tabs: TabItem[];\n activeTabId: string | null;\n\n openTab: (tab: Omit<TabItem, \"id\">) => string;\n closeTab: (id: string) => void;\n switchTab: (id: string) => void;\n reorderTabs: (activeId: string, overId: string) => void;\n findTabByPathname: (pathname: string) => TabItem | undefined;\n updateTabTitle: (id: string, title: string) => void;\n updateTabSearch: (id: string, search: string) => void;\n}\n\n// Routes that should not create tabs.\nconst EXCLUDED_ROUTES = [\"/login\", \"/signup\"];\n\nexport const useTabStore = create<TabState>((set, get) => ({\n tabs: [],\n activeTabId: null,\n\n openTab: (tab) => {\n if (EXCLUDED_ROUTES.includes(tab.pathname)) {\n return \"\";\n }\n\n const state = get();\n // If a tab with the same pathname already exists, switch to it.\n const existing = state.tabs.find((t) => t.pathname === tab.pathname);\n if (existing) {\n set({ activeTabId: existing.id });\n return existing.id;\n }\n\n const id = crypto.randomUUID();\n const newTab: TabItem = { ...tab, id };\n set((s) => ({\n tabs: [...s.tabs, newTab],\n activeTabId: id,\n }));\n return id;\n },\n\n closeTab: (id) => {\n const state = get();\n const idx = state.tabs.findIndex((t) => t.id === id);\n if (idx === -1) return;\n\n const tab = state.tabs[idx];\n if (!tab.closable) return;\n\n // Prevent closing the very last tab — always keep at least one.\n if (state.tabs.length === 1) return;\n\n const remaining = state.tabs.filter((t) => t.id !== id);\n let nextActive = state.activeTabId;\n\n if (state.activeTabId === id) {\n if (remaining.length === 0) {\n nextActive = null;\n } else if (idx < remaining.length) {\n // Switch to the tab at the same index (right neighbor).\n nextActive = remaining[idx].id;\n } else {\n // Switch to the last tab (left neighbor).\n nextActive = remaining[remaining.length - 1].id;\n }\n }\n\n set({ tabs: remaining, activeTabId: nextActive });\n },\n\n switchTab: (id) => {\n set({ activeTabId: id });\n },\n\n reorderTabs: (activeId, overId) => {\n set((s) => {\n const oldIdx = s.tabs.findIndex((t) => t.id === activeId);\n const newIdx = s.tabs.findIndex((t) => t.id === overId);\n if (oldIdx === -1 || newIdx === -1 || oldIdx === newIdx) return s;\n const tabs = [...s.tabs];\n const [moved] = tabs.splice(oldIdx, 1);\n tabs.splice(newIdx, 0, moved);\n return { tabs };\n });\n },\n\n findTabByPathname: (pathname) => {\n return get().tabs.find((t) => t.pathname === pathname);\n },\n\n updateTabTitle: (id, title) => {\n set((s) => ({\n tabs: s.tabs.map((t) => (t.id === id ? { ...t, title } : t)),\n }));\n },\n\n updateTabSearch: (id, search) => {\n set((s) => ({\n tabs: s.tabs.map((t) => (t.id === id ? { ...t, search } : t)),\n }));\n },\n}));\n","import { useCallback } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { useTabStore } from \"@/stores/tabs\";\n\ninterface TabNavigateOptions {\n title?: string;\n icon?: string;\n search?: string;\n replace?: boolean;\n}\n\nexport function useTabNavigate() {\n const navigate = useNavigate();\n const { openTab, switchTab, findTabByPathname } = useTabStore();\n\n const tabNavigate = useCallback(\n (pathname: string, opts?: TabNavigateOptions) => {\n // Check if tab exists for this pathname.\n const existing = findTabByPathname(pathname);\n if (existing) {\n switchTab(existing.id);\n navigate(\n { pathname, search: opts?.search },\n { replace: opts?.replace },\n );\n return;\n }\n\n // Open new tab.\n openTab({\n pathname,\n search: opts?.search ?? \"\",\n title: opts?.title ?? pathname,\n icon: opts?.icon,\n closable: true,\n });\n navigate(\n { pathname, search: opts?.search },\n { replace: opts?.replace },\n );\n },\n [navigate, openTab, switchTab, findTabByPathname],\n );\n\n return tabNavigate;\n}\n","import { lazy, Suspense, useMemo } from \"react\";\nimport type { LucideProps } from \"lucide-react\";\nimport dynamicIconImports from \"lucide-react/dynamicIconImports\";\n\ntype IconName = keyof typeof dynamicIconImports;\n\nconst iconCache = new Map<\n string,\n React.LazyExoticComponent<React.ComponentType<LucideProps>>\n>();\n\nfunction loadIcon(name: string) {\n const cached = iconCache.get(name);\n if (cached) return cached;\n\n const importFn = dynamicIconImports[name as IconName];\n if (!importFn) return null;\n\n const LazyIcon = lazy(importFn) as React.LazyExoticComponent<\n React.ComponentType<LucideProps>\n >;\n iconCache.set(name, LazyIcon);\n return LazyIcon;\n}\n\ninterface DynamicIconProps extends LucideProps {\n name: string;\n}\n\nexport function DynamicIcon({ name, ...props }: DynamicIconProps) {\n const Icon = useMemo(() => loadIcon(name), [name]);\n\n if (!Icon) return null;\n\n return (\n <Suspense fallback={<div className=\"w-4 h-4\" />}>\n <Icon {...props} />\n </Suspense>\n );\n}\n","export type LocalizedString = Record<string, string>;\n\n/**\n * Reserved sentinel value for Screen.detail_screen (list screens). Disables\n * row-click navigation even when the entity declares a canonical detail. Paired\n * with Go's engine.DetailScreenNone - keep the literal \"none\" in sync.\n */\nexport const DETAIL_SCREEN_NONE = \"none\";\n\nexport function loc(ls: LocalizedString | undefined, lang = \"en\"): string {\n if (!ls) return \"\";\n return ls[lang] ?? Object.values(ls)[0] ?? \"\";\n}\n\n// fieldDisplayName resolves a field's display label.\n// For ref fields without an explicit display.name, falls back to the\n// referenced entity's singular name (e.g. organization_id → \"Organization\").\nexport function fieldDisplayName(\n field: EntityField,\n fieldName: string,\n entities?: Record<string, Entity>,\n): string {\n const explicit = loc(field.display?.name);\n if (explicit) return explicit;\n if (field.type === \"ref\" && field.ref?.entity && entities) {\n const refEntity = entities[field.ref.entity];\n if (refEntity) {\n const entityName = loc(refEntity.display?.name);\n if (entityName) return entityName;\n }\n }\n return fieldName;\n}\n\nexport interface RefDisplay {\n field: string;\n}\n\nexport interface RefConfig {\n entity: string;\n field?: string; // lookup column on target entity (default: primary key)\n display?: RefDisplay;\n fields?: string[];\n}\n\nexport interface UnitConfig {\n storage: string;\n display?: string;\n}\n\nexport interface EntityField {\n type: string;\n required?: boolean;\n primary?: boolean;\n auto?: boolean;\n timezone?: string;\n precision?: number;\n scale?: number;\n unit?: UnitConfig;\n default?: unknown;\n display?: {\n name: LocalizedString;\n width?: number;\n widget?: string;\n is_listable?: boolean;\n is_filterable?: boolean;\n ref_display_field?: string;\n span?: number | \"full\";\n };\n values?: Array<{ code: string; name: LocalizedString; description?: LocalizedString; color?: string }>;\n enum?: string;\n ref?: RefConfig;\n structure?: string;\n array?: boolean;\n // copyable exposes a plain copy-to-clipboard icon next to the value in display mode.\n // Dumb by design: copies the field value as-is, no side effects.\n copyable?: boolean;\n}\n\nexport interface StructureDef {\n name: LocalizedString;\n description?: LocalizedString;\n fields: Record<string, EntityField>;\n field_order: string[];\n}\n\nexport type ChildDisplayMode = \"table\" | \"timeline\" | \"list\" | \"cards\";\n\nexport interface TimelineConfig {\n type_field?: string;\n time_field?: string;\n summary_field?: string;\n content_field?: string;\n author_field?: string;\n direction_field?: string;\n intent_field?: string;\n scroll?: boolean;\n auto_scroll?: \"none\" | \"bottom\" | \"top\";\n}\n\nexport interface CardsConfig {\n columns_count?: number;\n header_field?: string;\n badge_field?: string;\n}\n\nexport interface ChildQuickAdd {\n fields: string[];\n defaults?: Record<string, unknown>;\n placeholder?: LocalizedString;\n}\n\nexport interface ChildDisplay {\n name: LocalizedString;\n icon?: string;\n mode?: ChildDisplayMode;\n columns?: string[];\n sort?: string;\n limit?: number;\n timeline?: TimelineConfig;\n cards?: CardsConfig;\n editable?: boolean;\n searchable?: boolean;\n filters?: string[];\n position_field?: string;\n}\n\nexport interface ChildRelation {\n entity: string;\n foreign_key: string | string[];\n display?: ChildDisplay;\n quick_add?: ChildQuickAdd;\n}\n\nexport interface StatusDef {\n code: string;\n name: LocalizedString;\n description?: LocalizedString;\n color?: string;\n is_final?: boolean;\n}\n\nexport interface StatusGroupDef {\n name: LocalizedString;\n description?: LocalizedString;\n is_main?: boolean;\n initial: string;\n statuses: StatusDef[];\n transitions?: Record<string, string[]>;\n}\n\nexport interface PropertyDef {\n name: LocalizedString;\n description?: LocalizedString;\n type: string;\n display?: EntityField[\"display\"];\n values?: EntityField[\"values\"];\n enum?: string;\n ref?: RefConfig;\n structure?: string;\n readonly?: boolean;\n}\n\n// propertyToField converts a PropertyDef to an EntityField for use with renderField().\n// Merges prop.name as fallback display name; prop.display.name wins if set.\nexport function propertyToField(prop: PropertyDef): EntityField {\n const baseName = prop.name;\n const display = prop.display\n ? { ...prop.display, name: prop.display.name ?? baseName }\n : { name: baseName };\n return {\n type: prop.type,\n display,\n values: prop.values,\n ref: prop.ref,\n structure: prop.structure,\n };\n}\n\nexport interface EnumDef {\n name: LocalizedString;\n description?: LocalizedString;\n values: Array<{ code: string; name: LocalizedString; description?: LocalizedString; color?: string }>;\n}\n\nexport interface ParameterDef {\n name: LocalizedString;\n description?: LocalizedString;\n type: string;\n default?: unknown;\n is_public?: boolean;\n category?: string;\n}\n\nexport interface AssociationDisplay {\n name?: LocalizedString;\n icon?: string;\n}\n\nexport interface AssociationDef {\n target: string;\n display?: AssociationDisplay;\n source: string;\n code: string;\n}\n\nexport interface Entity {\n table: string;\n primary_key?: string[];\n virtual?: boolean;\n readonly?: boolean;\n default_timezone?: string;\n display: {\n name: LocalizedString;\n name_plural: LocalizedString;\n description?: LocalizedString;\n icon: string;\n display_field?: string;\n };\n fields: Record<string, EntityField>;\n field_order: string[];\n soft_delete?: string;\n tenant_key?: string;\n children?: ChildRelation[];\n status_groups?: Record<string, StatusGroupDef>;\n properties?: Record<string, PropertyDef>;\n search_fields?: string[];\n actions?: Record<string, Action>;\n handlers?: Record<string, HandlerDef>;\n associations?: Record<string, AssociationDef>;\n detail_screen?: string; // Canonical detail screen for records of this entity. Required when any detail screen targets the entity.\n}\n\n// getPrimaryKeyFields returns the ordered list of primary key field names.\n// Checks entity.primary_key first (composite PK), falls back to scanning\n// fields for field.primary (single PK), defaults to [\"id\"].\nexport function getPrimaryKeyFields(entity: Entity): string[] {\n if (entity.primary_key && entity.primary_key.length > 0) {\n return entity.primary_key;\n }\n for (const name of entity.field_order) {\n if (entity.fields[name]?.primary) return [name];\n }\n return [\"id\"];\n}\n\n// PkValues is a map of PK field names to their string values.\nexport type PkValues = Record<string, string>;\n\n// extractPkValues extracts PK field values from a record.\nexport function extractPkValues(entity: Entity, record: Record<string, unknown>): PkValues {\n const fields = getPrimaryKeyFields(entity);\n const values: PkValues = {};\n for (const f of fields) {\n values[f] = String(record[f] ?? \"\");\n }\n return values;\n}\n\n// pkValuesToId converts PK values to a single string identifier for use as\n// cache keys, React keys, etc. For single PK returns the value directly.\n// For composite PK joins with \"|\".\nexport function pkValuesToId(pkValues: PkValues): string {\n const vals = Object.values(pkValues);\n if (vals.length === 1) return vals[0];\n return vals.join(\"|\");\n}\n\n// isCompositePk returns true if the entity has more than one PK field.\nexport function isCompositePk(entity: Entity): boolean {\n return getPrimaryKeyFields(entity).length > 1;\n}\n\nexport type SizeValue = string; // integer weight (as string), \"<n>px\", \"auto\", \"fill\"\n\nexport interface SectionNode {\n name: LocalizedString;\n items: LayoutNode[];\n collapsed?: boolean;\n columns?: number; // 1 or 2 (default: 2)\n}\n\nexport interface RowConfig {\n items: LayoutNode[];\n gap?: number;\n resizable?: boolean;\n stack_below?: number | \"never\";\n width?: SizeValue;\n height?: SizeValue;\n}\n\nexport interface ColumnConfig {\n items: LayoutNode[];\n gap?: number;\n width?: SizeValue;\n height?: SizeValue;\n}\n\nexport interface TabsConfig {\n items: LayoutNode[];\n}\n\n// LayoutField is one entry in a screen's `fields:` layout block, carrying\n// the field name and any screen-scoped overrides (e.g. inline action buttons).\n// YAML also accepts a bare string, which the server normalizes to { name }.\nexport interface LayoutField {\n name: string;\n actions?: Action[];\n}\n\nexport interface LayoutNode {\n // Container kinds (exactly one, or none if leaf).\n row?: RowConfig;\n column?: ColumnConfig;\n tabs?: TabsConfig;\n\n section?: SectionNode;\n\n // Leaf kinds.\n children?: string;\n associated?: string; // associated entity code (independent entity with FK back)\n properties?: true | string[];\n statuses?: true | string[];\n fields?: LayoutField[];\n\n // Sizing (valid when nested inside row or column).\n width?: SizeValue;\n height?: SizeValue;\n min_width?: string;\n max_width?: string;\n\n // Child-override keys (only valid when children is set).\n label?: LocalizedString;\n icon?: string;\n mode?: ChildDisplayMode;\n columns?: string[];\n sort?: string;\n limit?: number;\n quick_add?: ChildQuickAdd;\n timeline?: TimelineConfig;\n cards?: CardsConfig;\n editable?: boolean;\n searchable?: boolean;\n filters?: string[];\n position_field?: string;\n}\n\nexport interface Screen {\n type: \"list\" | \"detail\" | \"custom\" | \"record_list\";\n entity?: string;\n route: string;\n component?: string;\n display?: {\n name: LocalizedString;\n icon: string;\n };\n columns?: string[];\n default_columns?: string[]; // Subset visible initially. Omit = all visible.\n filters?: string[];\n default_filters?: string[]; // Subset shown initially in filter panel. Omit = empty.\n search_fields?: string[];\n sort_default?: string;\n actions?: string[];\n row_actions?: string[];\n items?: LayoutNode[];\n sidebar?: LayoutNode[]; // right sidebar layout (always visible, independent of tabs)\n sidebar_width?: string; // sidebar CSS width (default: \"380px\")\n self?: boolean;\n list_width?: string; // record_list: CSS width of the left list panel (e.g. \"50%\", \"400px\")\n list_resizable?: boolean; // record_list: enable drag-to-resize the list panel\n // list only: tri-valued.\n // absent -> inherit entity.detail_screen\n // \"none\" -> explicit opt-out (row-click disabled)\n // any code -> override with that detail screen\n detail_screen?: string;\n fixed_filters?: Record<string, unknown>; // backend-injected WHERE clauses\n views?: ViewDefinition[]; // System views (presets) from DSL, read-only\n}\n\n/** System view (preset) defined in screen YAML. Read-only. */\nexport interface ViewDefinition {\n code: string;\n name: LocalizedString;\n icon?: string;\n filters?: Array<{ field: string; op: string; value?: unknown }>;\n columns?: string[];\n sort?: string;\n}\n\nexport interface NavNode {\n screen?: string;\n name?: LocalizedString;\n icon?: string;\n items?: NavNode[];\n}\n\nexport interface HandlerParamDisplay {\n name?: LocalizedString;\n description?: LocalizedString;\n widget?: string;\n}\n\nexport interface HandlerParam {\n type?: string;\n required?: boolean;\n default?: unknown;\n hidden?: boolean;\n enum?: string;\n values?: Array<{ code: string; name: LocalizedString; description?: LocalizedString; color?: string }>;\n ref?: string;\n display?: HandlerParamDisplay;\n /**\n * Narrows the param's option set. Values may be literals or templates\n * using the ui_steps interpolation vocabulary (e.g. \"{{params.other}}\").\n * Semantics are type-specific: for type=\"status\", a \"status_group\" key\n * selects the group whose statuses are offered.\n */\n filter?: Record<string, string>;\n}\n\nexport interface ActionCondition {\n status?: string[];\n field?: string;\n op?: string;\n value?: unknown;\n}\n\nexport interface UISetFieldStep {\n target: string;\n value: string;\n}\n\nexport interface UIShowToastStep {\n kind?: \"success\" | \"error\" | \"info\";\n message: string;\n}\n\n// UIStep is a tagged union - exactly one variant field is set per step.\nexport interface UIStep {\n copy_to_clipboard?: string;\n set_field?: UISetFieldStep;\n focus_field?: string;\n show_toast?: UIShowToastStep;\n}\n\nexport interface Action {\n handler?: string;\n type?: string;\n association?: string;\n entity?: string;\n display: {\n name: LocalizedString;\n icon: string;\n };\n visibility?: string[];\n confirmation?: LocalizedString;\n conditions?: ActionCondition[];\n resolved_params?: Record<string, HandlerParam>;\n resolved_param_order?: string[];\n /**\n * Default values of params marked hidden+default by the action. The UI\n * seeds formData with these so filter templates resolve references to\n * prefilled siblings (e.g. \"{{params.status_group}}\") and so the\n * submission payload includes them. Not rendered in the modal.\n */\n resolved_hidden_defaults?: Record<string, unknown>;\n ui_steps?: UIStep[];\n}\n\nexport interface LanguageDef {\n code: string;\n name: LocalizedString;\n}\n\nexport interface HandlerDef {\n code: string;\n type: string;\n entity?: string;\n display?: {\n name?: LocalizedString;\n icon?: string;\n };\n params?: Record<string, HandlerParam>;\n param_order?: string[];\n success_event?: string;\n}\n\nexport interface Branding {\n app_name?: string;\n app_logo?: string;\n app_initial?: string;\n accent_color?: string;\n}\n\nexport interface ThemeDef {\n extends?: string;\n background?: string;\n foreground?: string;\n card?: string;\n card_foreground?: string;\n popover?: string;\n popover_foreground?: string;\n primary?: string;\n primary_foreground?: string;\n secondary?: string;\n secondary_foreground?: string;\n muted?: string;\n muted_foreground?: string;\n accent?: string;\n accent_foreground?: string;\n destructive?: string;\n destructive_foreground?: string;\n border?: string;\n input?: string;\n ring?: string;\n sidebar?: string;\n sidebar_foreground?: string;\n sidebar_border?: string;\n sidebar_accent?: string;\n sidebar_muted?: string;\n radius?: string;\n}\n\nexport interface Schema {\n languages: LanguageDef[];\n structures: Record<string, StructureDef>;\n entities: Record<string, Entity>;\n screens: Record<string, Screen>;\n navigation: NavNode[];\n actions: Record<string, Action>;\n handlers?: Record<string, HandlerDef>;\n enums: Record<string, EnumDef>;\n parameters: Record<string, ParameterDef>;\n branding?: Branding;\n themes?: Record<string, ThemeDef>;\n}\n","import { useState } from \"react\";\nimport { useLocation } from \"react-router-dom\";\nimport { ChevronLeft, ChevronRight, ChevronDown } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { useTabNavigate } from \"@/hooks/useTabNavigate\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\nimport { loc, type NavNode } from \"@/types/schema\";\n\nexport function Sidebar() {\n const [collapsed, setCollapsed] = useState(false);\n const [collapsedSections, setCollapsedSections] = useState<Record<number, boolean>>({});\n const location = useLocation();\n const { data: schema } = useSchema();\n const tabNavigate = useTabNavigate();\n\n const nodes = schema?.navigation ?? [];\n const branding = schema?.branding;\n const appName = branding?.app_name || \"Declarion\";\n const appInitial = branding?.app_initial || appName.charAt(0);\n const accentColor = branding?.accent_color || \"#4f46e5\";\n\n function findFirstLeaf(items: NavNode[]): NavNode | undefined {\n for (const node of items) {\n if (node.screen) return node;\n if (node.items) {\n const found = findFirstLeaf(node.items);\n if (found) return found;\n }\n }\n return undefined;\n }\n\n function toggleSection(idx: number) {\n setCollapsedSections((prev) => ({ ...prev, [idx]: !prev[idx] }));\n }\n\n function isActive(route: string) {\n return location.pathname === route || location.pathname.startsWith(route + \"/\");\n }\n\n return (\n <aside\n className={cn(\n \"flex flex-col bg-[var(--sidebar)] text-[var(--sidebar-foreground)] border-r border-[var(--sidebar-border)] transition-all duration-200\",\n collapsed ? \"w-16\" : \"w-60\",\n )}\n >\n {/* Brand */}\n <div className=\"flex items-center h-14 px-4 border-b border-[var(--sidebar-border)]\">\n <button\n onClick={() => {\n const first = findFirstLeaf(nodes);\n const screen = first?.screen ? schema?.screens[first.screen] : undefined;\n if (screen && first) {\n tabNavigate(screen.route, {\n title: loc(first.name),\n icon: first.icon,\n });\n }\n }}\n className=\"flex items-center gap-2 overflow-hidden\"\n >\n {branding?.app_logo ? (\n <img src={branding.app_logo} alt={appName} className=\"w-8 h-8 rounded-lg shrink-0\" />\n ) : (\n <div className=\"w-8 h-8 rounded-lg flex items-center justify-center shrink-0\" style={{ backgroundColor: accentColor }}>\n <span className=\"text-white font-bold text-sm\">{appInitial}</span>\n </div>\n )}\n {!collapsed && (\n <span className=\"font-semibold text-sm whitespace-nowrap\">\n {appName}\n </span>\n )}\n </button>\n </div>\n\n {/* Navigation */}\n <nav className=\"flex-1 py-4 px-2 space-y-4 overflow-y-auto\">\n {nodes.map((node, idx) =>\n node.items ? (\n // Branch node — collapsible section\n <div key={idx}>\n {!collapsed && (\n <button\n onClick={() => toggleSection(idx)}\n className=\"flex items-center justify-between w-full px-3 mb-1 text-[10px] font-semibold uppercase tracking-wider text-[var(--sidebar-muted)] hover:text-[var(--sidebar-foreground)] transition-colors\"\n >\n <span>{loc(node.name)}</span>\n <ChevronDown\n className={cn(\n \"w-3 h-3 transition-transform\",\n collapsedSections[idx] && \"-rotate-90\",\n )}\n />\n </button>\n )}\n {!collapsedSections[idx] && (\n <div className=\"space-y-0.5\">\n {node.items.map((item) => {\n if (!item.screen) return null;\n const screen = schema?.screens[item.screen];\n if (!screen) return null;\n const route = screen.route;\n const active = isActive(route);\n\n return (\n <button\n key={item.screen}\n onClick={() =>\n tabNavigate(route, {\n title: loc(item.name),\n icon: item.icon,\n })\n }\n className={cn(\n \"flex items-center gap-3 px-3 py-2 rounded-md text-sm transition-colors w-full text-left\",\n active\n ? \"bg-[var(--sidebar-accent)] text-[var(--sidebar-foreground)]\"\n : \"text-[var(--sidebar-muted)] hover:bg-[var(--sidebar-accent)]/50 hover:text-[var(--sidebar-foreground)]\",\n )}\n title={collapsed ? loc(item.name) : undefined}\n >\n {item.icon && <DynamicIcon name={item.icon} className=\"w-4 h-4 shrink-0\" />}\n {!collapsed && <span>{loc(item.name)}</span>}\n </button>\n );\n })}\n </div>\n )}\n </div>\n ) : node.screen ? (\n // Top-level leaf node (screen without section)\n (() => {\n const screen = schema?.screens[node.screen];\n if (!screen) return null;\n const route = screen.route;\n const active = isActive(route);\n return (\n <button\n key={node.screen}\n onClick={() =>\n tabNavigate(route, {\n title: loc(node.name),\n icon: node.icon,\n })\n }\n className={cn(\n \"flex items-center gap-3 px-3 py-2 rounded-md text-sm transition-colors w-full text-left\",\n active\n ? \"bg-[var(--sidebar-accent)] text-[var(--sidebar-foreground)]\"\n : \"text-[var(--sidebar-muted)] hover:bg-[var(--sidebar-accent)]/50 hover:text-[var(--sidebar-foreground)]\",\n )}\n title={collapsed ? loc(node.name) : undefined}\n >\n {node.icon && <DynamicIcon name={node.icon} className=\"w-4 h-4 shrink-0\" />}\n {!collapsed && <span>{loc(node.name)}</span>}\n </button>\n );\n })()\n ) : null,\n )}\n </nav>\n\n {/* Collapse toggle */}\n <button\n onClick={() => setCollapsed(!collapsed)}\n className=\"flex items-center justify-center h-10 border-t border-[var(--sidebar-border)] text-[var(--sidebar-muted)] hover:text-[var(--sidebar-foreground)] transition-colors\"\n >\n {collapsed ? (\n <ChevronRight className=\"w-4 h-4\" />\n ) : (\n <ChevronLeft className=\"w-4 h-4\" />\n )}\n </button>\n </aside>\n );\n}\n","import { callHandler } from \"./client\";\nimport type {\n CheckSetupResponse,\n LoginResponse,\n AuthUser,\n Tenant,\n SSOProvider,\n} from \"@/types/api\";\n\n// Every auth endpoint now dispatches through POST /api/actions/{code}.\n// The shared callHandler helper in client.ts wraps the envelope and\n// returns the typed handler result directly. Cookies are set by the\n// backend via the HTTPCustomizer interface on *auth.LoginResult, so the\n// client-side wrappers never see tokens - they return user + tenant only.\n\nexport async function checkSetup(): Promise<CheckSetupResponse> {\n return callHandler<CheckSetupResponse>(\"auth.check_setup\");\n}\n\nexport async function login(\n email: string,\n password: string,\n): Promise<LoginResponse> {\n return callHandler<LoginResponse>(\"auth.login\", { email, password });\n}\n\nexport async function signup(\n email: string,\n password: string,\n displayName: string,\n): Promise<LoginResponse> {\n return callHandler<LoginResponse>(\"auth.signup\", {\n email,\n password,\n display_name: displayName,\n });\n}\n\n// auth.me returns { ...user, tenant? } per MeResult. The AuthUser type\n// on the frontend already reflects that shape.\nexport async function getMe(): Promise<AuthUser> {\n return callHandler<AuthUser>(\"auth.me\");\n}\n\n// auth.list_tenants returns { tenants: [...] } from ListTenantsResult.\nexport async function listTenants(): Promise<Tenant[]> {\n const result = await callHandler<{ tenants: Tenant[] }>(\"auth.list_tenants\");\n return result.tenants;\n}\n\nexport async function switchTenant(tenantId: string): Promise<LoginResponse> {\n return callHandler<LoginResponse>(\"auth.switch_tenant\", {\n tenant_id: tenantId,\n });\n}\n\nexport async function createTenant(code: string, name: string): Promise<Tenant> {\n return callHandler<Tenant>(\"auth.create_tenant\", { code, name });\n}\n\nexport async function logout(): Promise<void> {\n await callHandler(\"auth.logout\");\n}\n\n// sso_provider.list is a global handler with AllowUnauthenticated - used\n// on the login page before the user has a session.\nexport async function listSSOProviders(tenantCode?: string): Promise<SSOProvider[]> {\n const result = await callHandler<{ providers: SSOProvider[] }>(\n \"sso_provider.list\",\n tenantCode ? { tenant_code: tenantCode } : {},\n );\n return result.providers;\n}\n\nexport function ssoAuthorizeUrl(\n slug: string,\n tenantCode?: string,\n redirect?: string,\n): string {\n const params = new URLSearchParams();\n if (tenantCode) params.set(\"tenant\", tenantCode);\n if (redirect) params.set(\"redirect\", redirect);\n const qs = params.toString();\n return `/api/auth/sso/authorize/${encodeURIComponent(slug)}${qs ? `?${qs}` : \"\"}`;\n}\n","import { create } from \"zustand\";\nimport type { AuthUser, Tenant } from \"@/types/api\";\nimport { getMe, listTenants, logout as logoutApi } from \"@/api/auth\";\n\ninterface AuthState {\n user: AuthUser | null;\n isAuthenticated: boolean;\n isLoading: boolean;\n activeTenant: Tenant | null;\n tenants: Tenant[];\n initialize: () => Promise<void>;\n setUser: (user: AuthUser, tenant?: Tenant) => void;\n setTenants: (tenants: Tenant[]) => void;\n setActiveTenant: (tenant: Tenant) => void;\n logout: () => Promise<void>;\n}\n\nexport const useAuthStore = create<AuthState>((set) => ({\n user: null,\n isAuthenticated: false,\n isLoading: true,\n activeTenant: null,\n tenants: [],\n\n initialize: async () => {\n // Session lives in httpOnly cookies the JS cannot see. Probe auth.me\n // (dispatched via POST /api/actions/auth.me) with the cookie attached;\n // 401 means unauthenticated.\n try {\n const user = await getMe();\n const tenant = user.tenant ?? null;\n\n let tenants: Tenant[] = [];\n try {\n tenants = await listTenants();\n } catch {\n // Non-critical - user may only have one tenant.\n }\n\n set({\n user,\n isAuthenticated: true,\n isLoading: false,\n activeTenant: tenant,\n tenants,\n });\n } catch {\n set({ user: null, isAuthenticated: false, isLoading: false });\n }\n },\n\n setUser: (user: AuthUser, tenant?: Tenant) => {\n set({\n user,\n isAuthenticated: true,\n isLoading: false,\n activeTenant: tenant ?? null,\n });\n },\n\n setTenants: (tenants: Tenant[]) => {\n set({ tenants });\n },\n\n setActiveTenant: (tenant: Tenant) => {\n set({ activeTenant: tenant });\n },\n\n logout: async () => {\n try {\n await logoutApi();\n } catch {\n // Best-effort - clear local state regardless.\n }\n set({\n user: null,\n isAuthenticated: false,\n activeTenant: null,\n tenants: [],\n });\n },\n}));\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useNavigate } from \"react-router-dom\";\nimport { toast } from \"sonner\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport * as authApi from \"@/api/auth\";\n\nexport function useAuth() {\n const {\n user,\n isAuthenticated,\n isLoading,\n activeTenant,\n tenants,\n setUser,\n setTenants,\n logout: storeLogout,\n } = useAuthStore();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n\n const loginMutation = useMutation({\n mutationFn: ({ email, password }: { email: string; password: string }) =>\n authApi.login(email, password),\n onSuccess: (result) => {\n setUser(result.user, result.tenant);\n // Fetch tenants in background after login.\n authApi.listTenants().then(setTenants).catch(() => {});\n navigate(\"/\");\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n\n const signupMutation = useMutation({\n mutationFn: ({\n email,\n password,\n displayName,\n }: {\n email: string;\n password: string;\n displayName: string;\n }) => authApi.signup(email, password, displayName),\n onSuccess: (result) => {\n setUser(result.user, result.tenant);\n authApi.listTenants().then(setTenants).catch(() => {});\n navigate(\"/\");\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n\n const switchTenantMutation = useMutation({\n mutationFn: (tenantId: string) => authApi.switchTenant(tenantId),\n onSuccess: (result) => {\n // Update user (roles may differ per tenant) + tenant. The new access\n // cookie is set by the backend; the browser picks it up on the next request.\n setUser(result.user, result.tenant);\n // Invalidate all queries - tenant context changed (data, statuses, properties, etc.).\n queryClient.invalidateQueries();\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n\n const logout = async () => {\n await storeLogout();\n queryClient.clear();\n navigate(\"/login\");\n };\n\n return {\n user,\n isAuthenticated,\n isLoading,\n activeTenant,\n tenants,\n login: loginMutation.mutate,\n signup: signupMutation.mutate,\n switchTenant: switchTenantMutation.mutate,\n logout,\n isLoginPending: loginMutation.isPending,\n isSignupPending: signupMutation.isPending,\n isSwitchingTenant: switchTenantMutation.isPending,\n };\n}\n","import * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { Check, ChevronRight, Circle } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\nconst DropdownMenu = DropdownMenuPrimitive.Root;\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group;\nconst DropdownMenuPortal = DropdownMenuPrimitive.Portal;\nconst DropdownMenuSub = DropdownMenuPrimitive.Sub;\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;\n\nconst DropdownMenuSubTrigger = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n }\n>(({ className, inset, children, ...props }, ref) => (\n <DropdownMenuPrimitive.SubTrigger\n ref={ref}\n className={cn(\n \"flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-[var(--accent)] data-[state=open]:bg-[var(--accent)] [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n inset && \"pl-8\",\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRight className=\"ml-auto\" />\n </DropdownMenuPrimitive.SubTrigger>\n));\nDropdownMenuSubTrigger.displayName =\n DropdownMenuPrimitive.SubTrigger.displayName;\n\nconst DropdownMenuSubContent = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.SubContent\n ref={ref}\n className={cn(\n \"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-[var(--popover)] p-1 text-[var(--popover-foreground)] shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className,\n )}\n {...props}\n />\n));\nDropdownMenuSubContent.displayName =\n DropdownMenuPrimitive.SubContent.displayName;\n\nconst DropdownMenuContent = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-[var(--popover)] p-1 text-[var(--popover-foreground)] shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n));\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;\n\nconst DropdownMenuItem = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-[var(--accent)] focus:text-[var(--accent-foreground)] data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0\",\n inset && \"pl-8\",\n className,\n )}\n {...props}\n />\n));\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;\n\nconst DropdownMenuCheckboxItem = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n <DropdownMenuPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n \"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-[var(--accent)] focus:text-[var(--accent-foreground)] data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n));\nDropdownMenuCheckboxItem.displayName =\n DropdownMenuPrimitive.CheckboxItem.displayName;\n\nconst DropdownMenuRadioItem = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n <DropdownMenuPrimitive.RadioItem\n ref={ref}\n className={cn(\n \"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-[var(--accent)] focus:text-[var(--accent-foreground)] data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Circle className=\"h-2 w-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n));\nDropdownMenuRadioItem.displayName =\n DropdownMenuPrimitive.RadioItem.displayName;\n\nconst DropdownMenuLabel = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Label\n ref={ref}\n className={cn(\n \"px-2 py-1.5 text-sm font-semibold\",\n inset && \"pl-8\",\n className,\n )}\n {...props}\n />\n));\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;\n\nconst DropdownMenuSeparator = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-[var(--muted)]\", className)}\n {...props}\n />\n));\nDropdownMenuSeparator.displayName =\n DropdownMenuPrimitive.Separator.displayName;\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) {\n return (\n <span\n className={cn(\"ml-auto text-xs tracking-widest opacity-60\", className)}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuGroup,\n DropdownMenuPortal,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuRadioGroup,\n};\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/utils\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default:\n \"bg-[var(--primary)] text-[var(--primary-foreground)] hover:bg-[var(--primary)]/90\",\n destructive:\n \"bg-[var(--destructive)] text-[var(--destructive-foreground)] hover:bg-[var(--destructive)]/90\",\n outline:\n \"border border-[var(--input)] bg-[var(--background)] hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]\",\n secondary:\n \"bg-[var(--secondary)] text-[var(--secondary-foreground)] hover:bg-[var(--secondary)]/80\",\n ghost:\n \"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]\",\n link: \"text-[var(--primary)] underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"h-9 w-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n","import { LogOut, ChevronsUpDown } from \"lucide-react\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport { useAuth } from \"@/hooks/useAuth\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { Button } from \"@/components/ui/button\";\n\nexport function TopBar() {\n const user = useAuthStore((s) => s.user);\n const { logout, activeTenant, tenants, switchTenant, isSwitchingTenant } =\n useAuth();\n\n const initials = user?.display_name\n ? user.display_name\n .split(\" \")\n .map((n) => n[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2)\n : user?.email?.[0]?.toUpperCase() ?? \"U\";\n\n const canSwitch = tenants.length > 1;\n\n return (\n <header className=\"flex items-center justify-between h-14 px-6 border-b border-[var(--border)] bg-[var(--background)]\">\n <div className=\"flex items-center gap-3\">\n {activeTenant && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n disabled={!canSwitch || isSwitchingTenant}\n >\n {activeTenant.name}\n {canSwitch && (\n <ChevronsUpDown className=\"w-3.5 h-3.5 opacity-50\" />\n )}\n </Button>\n </DropdownMenuTrigger>\n {canSwitch && (\n <DropdownMenuContent align=\"start\">\n {tenants.map((t) => (\n <DropdownMenuItem\n key={t.id}\n onClick={() => switchTenant(t.id)}\n className={\n t.id === activeTenant?.id ? \"font-medium\" : undefined\n }\n >\n {t.name}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n )}\n </DropdownMenu>\n )}\n </div>\n <div className=\"flex items-center gap-3\">\n {user && (\n <>\n <span className=\"text-sm text-[var(--muted-foreground)] hidden sm:inline\">\n {user.email}\n </span>\n <div className=\"w-8 h-8 rounded-full bg-[var(--muted)] flex items-center justify-center\">\n <span className=\"text-xs font-medium text-[var(--muted-foreground)]\">\n {initials}\n </span>\n </div>\n <button\n onClick={logout}\n className=\"p-2 rounded-md text-[var(--muted-foreground)] hover:text-[var(--foreground)] transition-colors\"\n title=\"Sign out\"\n >\n <LogOut className=\"w-4 h-4\" />\n </button>\n </>\n )}\n </div>\n </header>\n );\n}\n","import { useCallback, useMemo } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport {\n DndContext,\n closestCenter,\n PointerSensor,\n useSensor,\n useSensors,\n type DragEndEvent,\n} from \"@dnd-kit/core\";\nimport {\n SortableContext,\n horizontalListSortingStrategy,\n useSortable,\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { X } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { useTabStore, type TabItem } from \"@/stores/tabs\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\n\nfunction SortableTab({\n tab,\n isActive,\n isOnly,\n onSwitch,\n onClose,\n}: {\n tab: TabItem;\n isActive: boolean;\n isOnly: boolean;\n onSwitch: (id: string, pathname: string, search: string) => void;\n onClose: (e: React.MouseEvent, id: string) => void;\n}) {\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: tab.id });\n\n const style = {\n transform: CSS.Translate.toString(transform),\n transition,\n zIndex: isDragging ? 10 : undefined,\n opacity: isDragging ? 0.5 : undefined,\n };\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n {...attributes}\n {...listeners}\n onClick={() => onSwitch(tab.id, tab.pathname, tab.search)}\n className={cn(\n \"flex items-center gap-1.5 px-3 h-7 rounded text-xs whitespace-nowrap max-w-[180px] select-none\",\n isActive\n ? \"bg-[var(--muted)] text-[var(--foreground)]\"\n : \"text-[var(--muted-foreground)] hover:bg-[var(--muted)]/50 hover:text-[var(--foreground)]\",\n )}\n >\n {tab.icon && (\n <DynamicIcon name={tab.icon} className=\"w-3 h-3 shrink-0\" />\n )}\n <span className=\"truncate\">{tab.title}</span>\n {tab.closable && !isOnly && (\n <span\n role=\"button\"\n onPointerDown={(e) => e.stopPropagation()}\n onClick={(e) => {\n e.stopPropagation();\n onClose(e, tab.id);\n }}\n className=\"ml-1 p-0.5 rounded hover:bg-[var(--border)] shrink-0\"\n >\n <X className=\"w-3 h-3\" />\n </span>\n )}\n </div>\n );\n}\n\nexport function TabBar() {\n const navigate = useNavigate();\n const { tabs, activeTabId, switchTab, closeTab, reorderTabs } =\n useTabStore();\n\n // distance: 5 separates click (< 5px) from drag (>= 5px).\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),\n );\n\n const tabIds = useMemo(() => tabs.map((t) => t.id), [tabs]);\n\n const handleSwitch = useCallback(\n (id: string, pathname: string, search: string) => {\n switchTab(id);\n navigate({ pathname, search: search || undefined });\n },\n [switchTab, navigate],\n );\n\n const handleClose = useCallback(\n (_e: React.MouseEvent, id: string) => {\n const state = useTabStore.getState();\n const idx = state.tabs.findIndex((t) => t.id === id);\n const isActive = state.activeTabId === id;\n\n closeTab(id);\n\n if (isActive) {\n const remaining = state.tabs.filter((t) => t.id !== id);\n if (remaining.length > 0) {\n const nextIdx = idx < remaining.length ? idx : remaining.length - 1;\n const next = remaining[nextIdx];\n navigate({\n pathname: next.pathname,\n search: next.search || undefined,\n });\n }\n }\n },\n [closeTab, navigate],\n );\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n const { active, over } = event;\n if (over && active.id !== over.id) {\n reorderTabs(String(active.id), String(over.id));\n }\n },\n [reorderTabs],\n );\n\n if (tabs.length === 0) return null;\n\n const isOnly = tabs.length === 1;\n\n return (\n <div className=\"flex items-center gap-0.5 h-9 px-2 border-t border-[var(--border)] bg-[var(--background)] overflow-x-auto shrink-0\">\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleDragEnd}\n >\n <SortableContext\n items={tabIds}\n strategy={horizontalListSortingStrategy}\n >\n {tabs.map((tab) => (\n <SortableTab\n key={tab.id}\n tab={tab}\n isActive={tab.id === activeTabId}\n isOnly={isOnly}\n onSwitch={handleSwitch}\n onClose={handleClose}\n />\n ))}\n </SortableContext>\n </DndContext>\n </div>\n );\n}\n","export type SSEEvent =\n | {\n type: \"entity_changed\";\n entity: string;\n ids: string[];\n action: \"created\" | \"updated\" | \"deleted\" | \"restored\";\n }\n | { type: \"session_refresh\" };\n\nexport async function* streamEvents(\n signal?: AbortSignal,\n): AsyncGenerator<SSEEvent> {\n const res = await fetch(\"/api/events\", { credentials: \"include\", signal });\n\n if (!res.ok || !res.body) {\n throw new Error(`SSE connection failed: ${res.status}`);\n }\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let currentEvent = \"\";\n let currentData = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"event: \")) {\n currentEvent = line.slice(7);\n } else if (line.startsWith(\"data: \")) {\n currentData = line.slice(6);\n } else if (line === \"\" && currentEvent) {\n try {\n if (currentEvent === \"session_refresh\") {\n yield { type: \"session_refresh\" };\n } else if (currentEvent === \"entity_changed\" && currentData) {\n const parsed = JSON.parse(currentData) as {\n entity: string;\n ids: string[];\n action: \"created\" | \"updated\" | \"deleted\" | \"restored\";\n };\n yield {\n type: \"entity_changed\",\n entity: parsed.entity,\n ids: parsed.ids,\n action: parsed.action,\n };\n }\n } catch {\n // Ignore parse errors\n }\n currentEvent = \"\";\n currentData = \"\";\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { apiFetch } from \"@/api/client\";\nimport type { ListResponse } from \"@/types/api\";\n\n// ENTITY_CHILDREN_KEY is the single source of truth for the query key prefix\n// used by all child entity queries. useSSE, QuickAddForm, TimelineComposer,\n// and SmartDetailPage must all use this constant to stay in sync.\nexport const ENTITY_CHILDREN_KEY = \"entity-children\" as const;\n\n// useChildrenData fetches child entity records for a parent record.\n// Extracted as a shared hook so all child display components can reuse it.\n// Uses the standard list endpoint with a filter on the foreign key field(s).\nexport function useChildrenData(\n parentEntity: string,\n parentId: string,\n childCode: string,\n foreignKey: string | string[],\n sort?: string,\n limit?: number,\n) {\n return useQuery({\n queryKey: [ENTITY_CHILDREN_KEY, parentEntity, parentId, childCode, sort, limit],\n queryFn: () => {\n const params = new URLSearchParams();\n // Build filters: single FK uses parentId directly, composite FK splits parentId by \"|\".\n const fkArr = Array.isArray(foreignKey) ? foreignKey : [foreignKey];\n const idArr = fkArr.length > 1 ? parentId.split(\"|\") : [parentId];\n const filters = fkArr.map((fk, i) => ({ field: fk, op: \"eq\", value: idArr[i] }));\n params.set(\"filters\", JSON.stringify(filters));\n if (sort) params.set(\"sort\", sort);\n if (limit) params.set(\"limit\", String(limit));\n return apiFetch<ListResponse>(\n `/api/data/${childCode}?${params.toString()}`,\n );\n },\n enabled: !!parentEntity && !!parentId && !!childCode && !!foreignKey,\n });\n}\n","import { useEffect, useRef } from \"react\";\nimport { useQueryClient, type QueryClient } from \"@tanstack/react-query\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport { streamEvents } from \"@/api/events\";\nimport { ensureRefresh } from \"@/api/client\";\nimport { ENTITY_CHILDREN_KEY } from \"@/hooks/useChildrenData\";\n\nconst MAX_RECONNECT_DELAY = 30000;\nconst BASE_DELAY = 1000;\n\n// COALESCE_WINDOW_MS groups entity_changed events into a single invalidation\n// per entity-per-window. A bulk upsert of 1000 rows produces ~2000 SSE events\n// server-side (audit_change + audit_operation per write); without coalescing,\n// React Query refires one HTTP fetch per event, saturating the UI and the\n// server's rate limiter. 50ms is short enough to feel real-time and long\n// enough to absorb a typical bulk-write burst.\nconst COALESCE_WINDOW_MS = 50;\n\ntype EntityAction = \"created\" | \"updated\" | \"deleted\" | \"restored\";\n\ninterface EntityChangedEvent {\n entity: string;\n action: EntityAction;\n}\n\n// invalidateForEntityChanges deduplicates a batch of entity_changed events\n// and fires the minimum set of React Query invalidations. Per entity:\n// - always invalidate the list query and matching child queries;\n// - additionally invalidate cached detail views if any event for that\n// entity is a mutation (update/delete/restore) — create events don't\n// need detail invalidation because a new row has no cached detail yet.\n// Exported so useSSE can call it and tests can exercise it directly.\nexport function invalidateForEntityChanges(\n queryClient: QueryClient,\n events: EntityChangedEvent[],\n): void {\n if (events.length === 0) return;\n\n const entities = new Map<string, { mutated: boolean }>();\n for (const ev of events) {\n const prev = entities.get(ev.entity);\n const mutated =\n ev.action === \"updated\" ||\n ev.action === \"deleted\" ||\n ev.action === \"restored\";\n entities.set(ev.entity, { mutated: (prev?.mutated ?? false) || mutated });\n }\n\n for (const [entity, state] of entities) {\n queryClient.invalidateQueries({ queryKey: [\"entity-data\", entity] });\n\n queryClient.invalidateQueries({\n predicate: (query) => {\n const key = query.queryKey;\n return key[0] === ENTITY_CHILDREN_KEY && key[3] === entity;\n },\n });\n\n if (state.mutated) {\n queryClient.invalidateQueries({ queryKey: [\"entity-item\", entity] });\n }\n }\n}\n\nexport function useSSE() {\n const isAuthenticated = useAuthStore((s) => s.isAuthenticated);\n const queryClient = useQueryClient();\n const abortRef = useRef<AbortController | null>(null);\n\n useEffect(() => {\n if (!isAuthenticated) return;\n\n let mounted = true;\n let attempt = 0;\n\n const pending: EntityChangedEvent[] = [];\n let flushTimer: ReturnType<typeof setTimeout> | null = null;\n\n const flush = () => {\n flushTimer = null;\n if (pending.length === 0) return;\n const batch = pending.splice(0, pending.length);\n invalidateForEntityChanges(queryClient, batch);\n };\n\n const scheduleFlush = () => {\n if (flushTimer !== null) return;\n flushTimer = setTimeout(flush, COALESCE_WINDOW_MS);\n };\n\n async function connect() {\n while (mounted) {\n const controller = new AbortController();\n abortRef.current = controller;\n\n try {\n for await (const event of streamEvents(controller.signal)) {\n if (!mounted) break;\n\n // Reset backoff on successful event.\n attempt = 0;\n\n if (event.type === \"session_refresh\") {\n // Permissions changed - refresh token and reconnect.\n try {\n await ensureRefresh();\n } catch {\n // Refresh failed - reconnect will use new token or fail.\n }\n break; // Break to reconnect with new token.\n }\n\n if (event.type === \"entity_changed\") {\n pending.push({ entity: event.entity, action: event.action });\n scheduleFlush();\n }\n }\n } catch (err) {\n if (!mounted) break;\n if (err instanceof DOMException && err.name === \"AbortError\") break;\n }\n\n // Exponential backoff with 50% jitter.\n if (mounted) {\n const delay = Math.min(BASE_DELAY * Math.pow(2, attempt), MAX_RECONNECT_DELAY);\n const jitter = delay * 0.5 * Math.random();\n await new Promise((r) => setTimeout(r, delay + jitter));\n attempt++;\n }\n }\n }\n\n connect();\n\n return () => {\n mounted = false;\n abortRef.current?.abort();\n if (flushTimer !== null) {\n clearTimeout(flushTimer);\n flushTimer = null;\n }\n if (pending.length > 0) {\n invalidateForEntityChanges(queryClient, pending.splice(0, pending.length));\n }\n };\n }, [isAuthenticated, queryClient]);\n}\n","import { useEffect } from \"react\";\nimport { Outlet, useNavigate, useLocation } from \"react-router-dom\";\nimport { Sidebar } from \"./Sidebar\";\nimport { TopBar } from \"./TopBar\";\nimport { TabBar } from \"./TabBar\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport { useSSE } from \"@/hooks/useSSE\";\n\nexport function Layout() {\n const { isAuthenticated, isLoading } = useAuthStore();\n const navigate = useNavigate();\n const location = useLocation();\n\n // SSE connection for real-time updates\n useSSE();\n\n useEffect(() => {\n if (!isLoading && !isAuthenticated) {\n // Preserve the intended URL so we can redirect back after login.\n const intended = location.pathname + location.search;\n const redirectParam = intended && intended !== \"/\" ? `?redirect=${encodeURIComponent(intended)}` : \"\";\n navigate(`/login${redirectParam}`, { replace: true });\n }\n }, [isLoading, isAuthenticated, navigate, location.pathname, location.search]);\n\n if (isLoading) {\n return (\n <div className=\"flex h-screen items-center justify-center bg-[var(--background)]\">\n <div className=\"text-[var(--muted-foreground)]\">Loading...</div>\n </div>\n );\n }\n\n if (!isAuthenticated) {\n return null;\n }\n\n return (\n <div className=\"flex h-screen overflow-hidden bg-[var(--background)]\">\n <Sidebar />\n <div className=\"flex flex-col flex-1 overflow-hidden\">\n <TopBar />\n <main className=\"flex-1 overflow-auto\">\n <Outlet />\n </main>\n <TabBar />\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nconst Input = React.forwardRef<\n HTMLInputElement,\n React.InputHTMLAttributes<HTMLInputElement>\n>(({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-9 w-full rounded-md border border-[var(--input)] bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-[var(--foreground)] placeholder:text-[var(--muted-foreground)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[var(--ring)] disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n});\nInput.displayName = \"Input\";\n\nexport { Input };\n","import * as React from \"react\";\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/utils\";\n\nconst labelVariants = cva(\n \"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\",\n);\n\nconst Label = React.forwardRef<\n React.ComponentRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &\n VariantProps<typeof labelVariants>\n>(({ className, ...props }, ref) => (\n <LabelPrimitive.Root\n ref={ref}\n className={cn(labelVariants(), className)}\n {...props}\n />\n));\nLabel.displayName = LabelPrimitive.Root.displayName;\n\nexport { Label };\n","import * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nconst Card = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n \"rounded-xl border bg-[var(--card)] text-[var(--card-foreground)] shadow-sm\",\n className,\n )}\n {...props}\n />\n));\nCard.displayName = \"Card\";\n\nconst CardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"flex flex-col space-y-1.5 p-6\", className)}\n {...props}\n />\n));\nCardHeader.displayName = \"CardHeader\";\n\nconst CardTitle = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"font-semibold leading-none tracking-tight\", className)}\n {...props}\n />\n));\nCardTitle.displayName = \"CardTitle\";\n\nconst CardDescription = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"text-sm text-[var(--muted-foreground)]\", className)}\n {...props}\n />\n));\nCardDescription.displayName = \"CardDescription\";\n\nconst CardContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"p-6 pt-0\", className)} {...props} />\n));\nCardContent.displayName = \"CardContent\";\n\nconst CardFooter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"flex items-center p-6 pt-0\", className)}\n {...props}\n />\n));\nCardFooter.displayName = \"CardFooter\";\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };\n","import { useState, useEffect, type FormEvent } from \"react\";\nimport { useNavigate, useSearchParams, Link } from \"react-router-dom\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { toast } from \"sonner\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Card, CardContent, CardHeader, CardTitle, CardDescription } from \"@/components/ui/card\";\nimport { useAuth } from \"@/hooks/useAuth\";\nimport { checkSetup, listSSOProviders, ssoAuthorizeUrl } from \"@/api/auth\";\nimport type { SSOProvider } from \"@/types/api\";\n\nexport function LoginPage() {\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const { login, isLoginPending, isAuthenticated } = useAuth();\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const rawRedirect = searchParams.get(\"redirect\") || \"/\";\n const redirectTo = rawRedirect.startsWith(\"/\") && !rawRedirect.startsWith(\"//\") ? rawRedirect : \"/\";\n const ssoError = searchParams.get(\"sso_error\");\n\n const { data: setupStatus } = useQuery({\n queryKey: [\"check-setup\"],\n queryFn: checkSetup,\n });\n\n const { data: ssoProviders } = useQuery<SSOProvider[]>({\n queryKey: [\"sso-providers\"],\n queryFn: () => listSSOProviders(),\n staleTime: 60_000,\n });\n\n useEffect(() => {\n if (setupStatus?.needs_setup) {\n navigate(\"/signup\", { replace: true });\n }\n }, [setupStatus, navigate]);\n\n useEffect(() => {\n if (isAuthenticated) {\n navigate(redirectTo, { replace: true });\n }\n }, [isAuthenticated, navigate, redirectTo]);\n\n useEffect(() => {\n if (ssoError) {\n toast.error(ssoError);\n }\n }, [ssoError]);\n\n function handleSubmit(e: FormEvent) {\n e.preventDefault();\n login({ email, password });\n }\n\n const hasProviders = ssoProviders && ssoProviders.length > 0;\n\n return (\n <div className=\"flex min-h-screen items-center justify-center bg-[var(--background)] px-4\">\n <Card className=\"w-full max-w-sm\">\n <CardHeader className=\"text-center\">\n <div className=\"mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-xl bg-[var(--primary)]\">\n <span className=\"text-lg font-bold text-[var(--primary-foreground)]\">D</span>\n </div>\n <CardTitle className=\"text-2xl\">Sign in</CardTitle>\n <CardDescription>Enter your credentials to continue</CardDescription>\n </CardHeader>\n <CardContent>\n {hasProviders && (\n <div className=\"space-y-2 mb-4\">\n {ssoProviders.map((provider) => (\n <Button\n key={provider.slug}\n variant=\"outline\"\n className=\"w-full\"\n asChild\n >\n <a href={ssoAuthorizeUrl(provider.slug, undefined, redirectTo)}>\n Sign in with {provider.name}\n </a>\n </Button>\n ))}\n <div className=\"relative my-4\">\n <div className=\"absolute inset-0 flex items-center\">\n <span className=\"w-full border-t\" />\n </div>\n <div className=\"relative flex justify-center text-xs uppercase\">\n <span className=\"bg-[var(--card)] px-2 text-[var(--muted-foreground)]\">\n or continue with email\n </span>\n </div>\n </div>\n </div>\n )}\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"email\">Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"you@example.com\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n autoFocus\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"password\">Password</Label>\n <Input\n id=\"password\"\n type=\"password\"\n placeholder=\"Enter your password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n required\n />\n </div>\n <Button type=\"submit\" className=\"w-full\" disabled={isLoginPending}>\n {isLoginPending ? \"Signing in...\" : \"Sign in\"}\n </Button>\n </form>\n <p className=\"mt-4 text-center text-sm text-[var(--muted-foreground)]\">\n First time?{\" \"}\n <Link to=\"/signup\" className=\"text-[var(--primary)] hover:underline\">\n Create account\n </Link>\n </p>\n </CardContent>\n </Card>\n </div>\n );\n}\n","import { useState, useEffect, type FormEvent } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Card, CardContent, CardHeader, CardTitle, CardDescription } from \"@/components/ui/card\";\nimport { useAuth } from \"@/hooks/useAuth\";\nimport { checkSetup } from \"@/api/auth\";\n\nexport function SignupPage() {\n const navigate = useNavigate();\n const { signup, isSignupPending, isAuthenticated } = useAuth();\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [displayName, setDisplayName] = useState(\"\");\n\n const { data: setupStatus } = useQuery({\n queryKey: [\"check-setup\"],\n queryFn: checkSetup,\n });\n\n useEffect(() => {\n if (setupStatus && !setupStatus.needs_setup) {\n navigate(\"/login\", { replace: true });\n }\n }, [setupStatus, navigate]);\n\n useEffect(() => {\n if (isAuthenticated) {\n navigate(\"/\", { replace: true });\n }\n }, [isAuthenticated, navigate]);\n\n function handleSubmit(e: FormEvent) {\n e.preventDefault();\n signup({ email, password, displayName });\n }\n\n return (\n <div className=\"flex min-h-screen items-center justify-center bg-[var(--background)] px-4\">\n <Card className=\"w-full max-w-sm\">\n <CardHeader className=\"text-center\">\n <div className=\"mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-xl bg-[var(--primary)]\">\n <span className=\"text-lg font-bold text-[var(--primary-foreground)]\">D</span>\n </div>\n <CardTitle className=\"text-2xl\">Create account</CardTitle>\n <CardDescription>Set up the first admin account</CardDescription>\n </CardHeader>\n <CardContent>\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"displayName\">Name</Label>\n <Input\n id=\"displayName\"\n type=\"text\"\n placeholder=\"Your name\"\n value={displayName}\n onChange={(e) => setDisplayName(e.target.value)}\n required\n autoFocus\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"email\">Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"you@example.com\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"password\">Password</Label>\n <Input\n id=\"password\"\n type=\"password\"\n placeholder=\"Min 8 characters\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n required\n minLength={8}\n />\n </div>\n <Button type=\"submit\" className=\"w-full\" disabled={isSignupPending}>\n {isSignupPending ? \"Creating...\" : \"Create account\"}\n </Button>\n </form>\n </CardContent>\n </Card>\n </div>\n );\n}\n","import { useEffect } from \"react\";\nimport { useNavigate, useSearchParams } from \"react-router-dom\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport { getMe, listTenants } from \"@/api/auth\";\n\nexport function SSOCallbackPage() {\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const { setUser, setTenants } = useAuthStore();\n\n useEffect(() => {\n // The backend has already set the __Host- session cookies on the SSO\n // callback response. All we need to do is hydrate the store by\n // dispatching auth.me (the browser sends the cookie automatically).\n const rawRedirect = searchParams.get(\"redirect\") || \"/\";\n const redirect =\n rawRedirect.startsWith(\"/\") && !rawRedirect.startsWith(\"//\") ? rawRedirect : \"/\";\n\n getMe()\n .then((user) => {\n setUser(user, user.tenant);\n listTenants().then(setTenants).catch(() => {});\n navigate(redirect, { replace: true });\n })\n .catch(() => {\n navigate(\"/login?sso_error=authentication+failed\", { replace: true });\n });\n }, [navigate, searchParams, setUser, setTenants]);\n\n return (\n <div className=\"flex min-h-screen items-center justify-center\">\n <p className=\"text-[var(--muted-foreground)]\">Completing sign in...</p>\n </div>\n );\n}\n","import { Link } from \"react-router-dom\";\nimport { Button } from \"@/components/ui/button\";\n\nexport function NotFoundPage() {\n return (\n <div className=\"flex h-full items-center justify-center\">\n <div className=\"text-center\">\n <h1 className=\"text-6xl font-bold text-[var(--muted-foreground)]\">404</h1>\n <p className=\"mt-2 text-lg text-[var(--muted-foreground)]\">Page not found</p>\n <Button asChild variant=\"outline\" className=\"mt-6\">\n <Link to=\"/\">Go home</Link>\n </Button>\n </div>\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { ArrowLeft } from \"lucide-react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { Button } from \"@/components/ui/button\";\nimport { useTabStore } from \"@/stores/tabs\";\n\ninterface PageHeaderProps {\n title: string;\n backTo?: string;\n actions?: ReactNode;\n}\n\nexport function PageHeader({ title, backTo, actions }: PageHeaderProps) {\n const navigate = useNavigate();\n const { switchTab, findTabByPathname } = useTabStore();\n\n function handleBack() {\n if (!backTo) return;\n const tab = findTabByPathname(backTo);\n if (tab) {\n switchTab(tab.id);\n }\n navigate(backTo);\n }\n\n return (\n <div className=\"flex items-center justify-between mb-6\">\n <div className=\"flex items-center gap-3\">\n {backTo && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={handleBack}\n >\n <ArrowLeft className=\"w-4 h-4\" />\n </Button>\n )}\n <h1 className=\"text-2xl font-semibold\">{title}</h1>\n </div>\n {actions && <div className=\"flex items-center gap-2\">{actions}</div>}\n </div>\n );\n}\n","import { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/utils\";\n\nconst badgeVariants = cva(\n \"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-[var(--ring)] focus:ring-offset-2\",\n {\n variants: {\n variant: {\n default:\n \"border-transparent bg-[var(--primary)] text-[var(--primary-foreground)]\",\n secondary:\n \"border-transparent bg-[var(--secondary)] text-[var(--secondary-foreground)]\",\n destructive:\n \"border-transparent bg-[var(--destructive)] text-[var(--destructive-foreground)]\",\n outline: \"text-[var(--foreground)]\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n },\n);\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof badgeVariants> {\n color?: string;\n}\n\nfunction Badge({ className, variant, color, style, ...props }: BadgeProps) {\n const colorStyle = color\n ? {\n backgroundColor: color + \"1a\",\n color: color,\n borderColor: color + \"33\",\n ...style,\n }\n : style;\n\n return (\n <div\n className={cn(badgeVariants({ variant: color ? undefined : variant }), className)}\n style={colorStyle}\n {...props}\n />\n );\n}\n\nexport { Badge, badgeVariants };\n","import { useState, useMemo } from \"react\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { PageHeader } from \"@/components/shared/PageHeader\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\nimport { loc } from \"@/types/schema\";\nimport type { Action, HandlerDef, HandlerParam } from \"@/types/schema\";\n\ntype Tab = \"handlers\" | \"actions\";\n\nexport function AdminCatalogPage() {\n const { data: schema } = useSchema();\n const [activeTab, setActiveTab] = useState<Tab>(\"handlers\");\n\n if (!schema) return null;\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"px-6 pt-6\">\n <PageHeader title=\"Handler & Action Catalog\" />\n <div className=\"flex gap-2 mb-4\">\n <Button\n variant={activeTab === \"handlers\" ? \"default\" : \"outline\"}\n size=\"sm\"\n onClick={() => setActiveTab(\"handlers\")}\n >\n Handlers\n </Button>\n <Button\n variant={activeTab === \"actions\" ? \"default\" : \"outline\"}\n size=\"sm\"\n onClick={() => setActiveTab(\"actions\")}\n >\n Actions\n </Button>\n </div>\n </div>\n <div className=\"flex-1 overflow-auto px-6 pb-6\">\n {activeTab === \"handlers\" && <HandlersTab schema={schema} />}\n {activeTab === \"actions\" && <ActionsTab schema={schema} />}\n </div>\n </div>\n );\n}\n\nfunction HandlersTab({ schema }: { schema: NonNullable<ReturnType<typeof useSchema>[\"data\"]> }) {\n const allHandlers = useMemo(() => {\n const result: Array<{ code: string; handler: HandlerDef; entity?: string }> = [];\n\n // Top-level handlers.\n if (schema.handlers) {\n for (const [code, h] of Object.entries(schema.handlers)) {\n result.push({ code, handler: h });\n }\n }\n\n // Entity-scoped handlers.\n for (const [entityCode, entity] of Object.entries(schema.entities)) {\n if (entity.handlers) {\n for (const [code, h] of Object.entries(entity.handlers as Record<string, HandlerDef>)) {\n result.push({ code: `${entityCode}.${code}`, handler: h, entity: entityCode });\n }\n }\n }\n\n return result.sort((a, b) => a.code.localeCompare(b.code));\n }, [schema]);\n\n return (\n <div className=\"space-y-3\">\n <p className=\"text-sm text-[var(--muted-foreground)]\">\n {allHandlers.length} handlers registered (view-only - source of truth is code/YAML)\n </p>\n <div className=\"grid gap-3\">\n {allHandlers.map(({ code, handler, entity }) => (\n <HandlerCard key={code} code={code} handler={handler} entity={entity} />\n ))}\n </div>\n </div>\n );\n}\n\nfunction HandlerCard({ code, handler, entity }: { code: string; handler: HandlerDef; entity?: string }) {\n const [expanded, setExpanded] = useState(false);\n const displayName = handler.display?.name ? loc(handler.display.name) : code;\n\n return (\n <div className=\"border border-[var(--border)] rounded-lg p-4\">\n <div className=\"flex items-center justify-between cursor-pointer\" onClick={() => setExpanded(!expanded)}>\n <div className=\"flex items-center gap-3\">\n {handler.display?.icon && <DynamicIcon name={handler.display.icon} className=\"w-4 h-4 text-[var(--muted-foreground)]\" />}\n <div>\n <span className=\"font-mono text-sm font-medium\">{code}</span>\n {displayName !== code && (\n <span className=\"ml-2 text-sm text-[var(--muted-foreground)]\">{displayName}</span>\n )}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Badge variant=\"outline\">{handler.type}</Badge>\n {entity && <Badge variant=\"secondary\">{entity}</Badge>}\n {handler.success_event && <Badge variant=\"secondary\">event: {handler.success_event}</Badge>}\n </div>\n </div>\n {expanded && handler.params && Object.keys(handler.params).length > 0 && (\n <div className=\"mt-3 border-t border-[var(--border)] pt-3\">\n <p className=\"text-xs font-medium text-[var(--muted-foreground)] mb-2\">Parameters</p>\n <div className=\"space-y-1\">\n {(handler.param_order || Object.keys(handler.params)).map((paramCode) => {\n const param = handler.params![paramCode];\n if (!param) return null;\n return <ParamRow key={paramCode} code={paramCode} param={param} />;\n })}\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction ParamRow({ code, param }: { code: string; param: HandlerParam }) {\n const displayName = param.display?.name ? loc(param.display.name) : undefined;\n return (\n <div className=\"flex items-center gap-3 text-sm py-1\">\n <span className=\"font-mono text-xs w-32 shrink-0\">{code}</span>\n <Badge variant=\"outline\" className=\"text-xs\">{param.type || \"string\"}</Badge>\n {param.required && <Badge variant=\"destructive\" className=\"text-xs\">required</Badge>}\n {param.hidden && <Badge variant=\"secondary\" className=\"text-xs\">hidden</Badge>}\n {param.default != null && (\n <span className=\"text-xs text-[var(--muted-foreground)]\">default: {String(param.default)}</span>\n )}\n {displayName && (\n <span className=\"text-xs text-[var(--muted-foreground)]\">{displayName}</span>\n )}\n </div>\n );\n}\n\nfunction ActionsTab({ schema }: { schema: NonNullable<ReturnType<typeof useSchema>[\"data\"]> }) {\n const allActions = useMemo(() => {\n const result: Array<{ code: string; action: Action; entity?: string }> = [];\n\n // Global actions.\n if (schema.actions) {\n for (const [code, action] of Object.entries(schema.actions)) {\n result.push({ code, action });\n }\n }\n\n // Entity-scoped actions.\n for (const [entityCode, entity] of Object.entries(schema.entities)) {\n if (entity.actions) {\n for (const [code, action] of Object.entries(entity.actions)) {\n result.push({ code: `${entityCode}.${code}`, action, entity: entityCode });\n }\n }\n }\n\n return result.sort((a, b) => a.code.localeCompare(b.code));\n }, [schema]);\n\n // Group by entity.\n const grouped = useMemo(() => {\n const groups: Record<string, typeof allActions> = {};\n for (const item of allActions) {\n const key = item.entity || \"(global)\";\n if (!groups[key]) groups[key] = [];\n groups[key].push(item);\n }\n return Object.entries(groups).sort(([a], [b]) => a.localeCompare(b));\n }, [allActions]);\n\n return (\n <div className=\"space-y-4\">\n <p className=\"text-sm text-[var(--muted-foreground)]\">\n {allActions.length} actions defined (view-only - source of truth is code/YAML)\n </p>\n {grouped.map(([group, actions]) => (\n <div key={group}>\n <h3 className=\"text-sm font-medium mb-2 text-[var(--foreground)]\">{group}</h3>\n <div className=\"grid gap-2\">\n {actions.map(({ code, action }) => (\n <ActionCard key={code} code={code} action={action} />\n ))}\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction ActionCard({ code, action }: { code: string; action: Action }) {\n const displayName = loc(action.display?.name);\n return (\n <div className=\"border border-[var(--border)] rounded-lg p-3 flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n {action.display?.icon && <DynamicIcon name={action.display.icon} className=\"w-4 h-4 text-[var(--muted-foreground)]\" />}\n <div>\n <span className=\"font-mono text-sm\">{code}</span>\n {displayName && displayName !== code && (\n <span className=\"ml-2 text-sm text-[var(--muted-foreground)]\">{displayName}</span>\n )}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n {action.type && <Badge variant=\"outline\">{action.type}</Badge>}\n {action.handler && (\n <span className=\"text-xs text-[var(--muted-foreground)] font-mono\">handler: {action.handler}</span>\n )}\n {action.visibility && action.visibility.length > 0 && (\n <div className=\"flex gap-1\">\n {action.visibility.map((v) => (\n <Badge key={v} variant=\"outline\" className=\"text-xs\">{v}</Badge>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { apiFetch } from \"./client\";\nimport type { ListParams, ListResponse, DataResponse } from \"@/types/api\";\nimport type { PkValues } from \"@/types/schema\";\n\nfunction buildListUrl(entity: string, params: ListParams): string {\n const url = new URL(`/api/data/${entity}`, window.location.origin);\n\n if (params.page) url.searchParams.set(\"page\", String(params.page));\n if (params.per_page) url.searchParams.set(\"per_page\", String(params.per_page));\n if (params.sort) url.searchParams.set(\"sort\", params.sort);\n if (params.search) url.searchParams.set(\"search\", params.search);\n\n if (params.filters && params.filters.length > 0) {\n url.searchParams.set(\"filters\", JSON.stringify(params.filters));\n }\n\n if (params.include_deleted) {\n url.searchParams.set(\"include_deleted\", \"true\");\n }\n\n if (params.expand) {\n for (const e of params.expand) {\n url.searchParams.append(\"expand\", e);\n }\n }\n\n if (params.screen) url.searchParams.set(\"screen\", params.screen);\n\n return url.pathname + url.search;\n}\n\nexport async function listEntities(\n entity: string,\n params: ListParams = {},\n): Promise<ListResponse> {\n return apiFetch<ListResponse>(buildListUrl(entity, params));\n}\n\n// getEntity fetches a single record by primary key values.\n// Accepts either a PkValues object (composite PK support) or a plain string\n// (backward compat for single-PK entities - sent as query param `id=<value>`).\nexport async function getEntity(\n entity: string,\n pkValues: PkValues | string,\n): Promise<DataResponse> {\n const params = new URLSearchParams();\n if (typeof pkValues === \"string\") {\n params.set(\"id\", pkValues);\n } else {\n for (const [key, value] of Object.entries(pkValues)) {\n params.set(key, value);\n }\n }\n return apiFetch<DataResponse>(`/api/data/${entity}?${params.toString()}`);\n}\n\nexport async function createEntity(\n entity: string,\n data: Record<string, unknown>,\n): Promise<DataResponse> {\n const results = await apiFetch<Record<string, unknown>[]>(`/api/data/${entity}`, {\n method: \"POST\",\n body: JSON.stringify([data]),\n });\n return { data: results[0] };\n}\n\n// updateEntity sends a PATCH with PK fields included in the body item.\n// Accepts either a PkValues object (composite PK) or a plain string id\n// (backward compat - sent as { id: <value> }).\nexport async function updateEntity(\n entity: string,\n pkValues: PkValues | string,\n data: Record<string, unknown>,\n): Promise<DataResponse> {\n const pkFields = typeof pkValues === \"string\" ? { id: pkValues } : pkValues;\n const results = await apiFetch<Record<string, unknown>[]>(`/api/data/${entity}`, {\n method: \"PATCH\",\n body: JSON.stringify([{ ...pkFields, ...data }]),\n });\n return { data: results[0] };\n}\n\n// deleteEntity sends a POST /delete with PK fields in the body items.\n// Accepts either a PkValues object (composite PK) or a plain string id.\nexport async function deleteEntity(\n entity: string,\n pkValues: PkValues | string,\n): Promise<void> {\n const item = typeof pkValues === \"string\" ? { id: pkValues } : pkValues;\n await apiFetch(`/api/data/${entity}/delete`, {\n method: \"POST\",\n body: JSON.stringify([item]),\n });\n}\n\n// restoreEntity sends a POST /restore with PK fields in the body items.\n// Accepts either a PkValues object (composite PK) or a plain string id.\nexport async function restoreEntity(\n entity: string,\n pkValues: PkValues | string,\n): Promise<void> {\n const item = typeof pkValues === \"string\" ? { id: pkValues } : pkValues;\n await apiFetch(`/api/data/${entity}/restore`, {\n method: \"POST\",\n body: JSON.stringify([item]),\n });\n}\n\n/**\n * Action request body is flat: top-level keys are handler params. The only\n * reserved control key is `_ids` (array of object IDs for single/batch\n * scope). The server resolves entity from the action's registration; the\n * URL code is fully qualified (\"entity.action\" for entity-scoped,\n * \"action\" for global).\n */\nexport type ActionExecuteRequest = Record<string, unknown>;\n\nexport interface ActionExecuteResponse {\n status: string;\n result?: unknown;\n audit_operation_id?: string;\n object_count?: number;\n /** IDs that succeeded (batch_mode: each responses). */\n success?: string[];\n}\n\n/**\n * Build a flat action body from handler params + optional object IDs.\n * Promotes `ids` to the reserved `_ids` key. Throws if a caller passes a\n * param literally named `_ids` (collision with the reserved control key).\n */\nexport function buildActionBody(\n params: Record<string, unknown> | undefined,\n ids?: string[] | undefined,\n): ActionExecuteRequest {\n const body: Record<string, unknown> = { ...(params ?? {}) };\n if (\"_ids\" in body) {\n throw new Error('handler param \"_ids\" collides with reserved key');\n }\n if (ids !== undefined) {\n body._ids = ids;\n }\n return body;\n}\n\n/**\n * Invoke an action. The URL `code` must be fully qualified for\n * entity-scoped actions (e.g. `lead.archive`). For global actions it's the\n * action code on its own (e.g. `auth.login`).\n */\nexport async function executeAction(\n code: string,\n body: ActionExecuteRequest,\n): Promise<ActionExecuteResponse> {\n return apiFetch<ActionExecuteResponse>(`/api/actions/${code}`, {\n method: \"POST\",\n body: JSON.stringify(body),\n });\n}\n\nexport interface AssociationResponse {\n target_entity: string;\n ids: string[];\n count: number;\n}\n\nexport async function resolveAssociation(\n code: string,\n ids: string[],\n): Promise<AssociationResponse> {\n const params = new URLSearchParams();\n params.set(\"ids\", ids.join(\",\"));\n return apiFetch<AssociationResponse>(`/api/associations/${code}?${params.toString()}`);\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { listEntities } from \"@/api/data\";\nimport type { ListParams } from \"@/types/api\";\n\nexport function useEntityData(entity: string | undefined, params: ListParams) {\n return useQuery({\n queryKey: [\"entity-data\", entity, params],\n queryFn: () => listEntities(entity!, params),\n enabled: !!entity,\n placeholderData: (prev, prevQuery) => {\n // Only reuse previous data within the same entity (pagination/sorting).\n // Cross-entity placeholder causes wrong rows/columns flash.\n const prevEntity = (prevQuery?.queryKey as unknown[])?.[1];\n return prevEntity === entity ? prev : undefined;\n },\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { toast } from \"sonner\";\nimport { createEntity, updateEntity, deleteEntity, restoreEntity, executeAction } from \"@/api/data\";\nimport type { PkValues } from \"@/types/schema\";\nimport { ENTITY_CHILDREN_KEY } from \"@/hooks/useChildrenData\";\n\nimport type { ActionExecuteRequest } from \"@/api/data\";\n\nexport function useCreateEntity(entityCode: string) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (data: Record<string, unknown>) =>\n createEntity(entityCode, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [\"entity-data\", entityCode] });\n toast.success(\"Record created\");\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n\nexport function useUpdateEntity(entityCode: string) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({ pkValues, data }: { pkValues: PkValues | string; data: Record<string, unknown> }) =>\n updateEntity(entityCode, pkValues, data),\n onSuccess: (_result, _variables) => {\n // Invalidate all caches by entity-level prefix. We avoid setQueryData\n // because cache keys use different ID formats across consumers\n // (pkCacheKey \"k=v&...\" vs raw URL id vs \"|\"-joined composite).\n // Prefix invalidation always matches regardless of format.\n queryClient.invalidateQueries({ queryKey: [\"entity-data\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"entity-item\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [ENTITY_CHILDREN_KEY, entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"object-status\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"object-properties\", entityCode] });\n toast.success(\"Record updated\");\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n\nexport function useDeleteEntity(entityCode: string) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (pkValues: PkValues | string) => deleteEntity(entityCode, pkValues),\n onSuccess: (_result, _pkValues) => {\n queryClient.invalidateQueries({ queryKey: [\"entity-data\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"entity-item\", entityCode] });\n toast.success(\"Record deleted\");\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n\nexport function useRestoreEntity(entityCode: string) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (pkValues: PkValues | string) => restoreEntity(entityCode, pkValues),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [\"entity-data\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"entity-item\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"object-status\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"object-properties\", entityCode] });\n toast.success(\"Record restored\");\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n\nexport function useExecuteAction(entityCode?: string) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ actionCode, body }: { actionCode: string; body: ActionExecuteRequest }) => {\n const result = await executeAction(actionCode, body);\n if (result.status === \"error\") {\n throw new Error(\"Action failed for all items\");\n }\n return result;\n },\n onSuccess: (result) => {\n if (entityCode) {\n queryClient.invalidateQueries({ queryKey: [\"entity-data\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"entity-item\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [ENTITY_CHILDREN_KEY, entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"object-status\", entityCode] });\n queryClient.invalidateQueries({ queryKey: [\"object-properties\", entityCode] });\n }\n if (result.status === \"accepted\") {\n toast.success(\"Action started - check audit for progress\");\n } else if (result.status === \"partial\") {\n toast.warning(\"Action partially completed - some items failed or were skipped\");\n } else {\n toast.success(\"Action executed\");\n }\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n","import { useState, useEffect } from \"react\";\n\nexport function useDebounce<T>(value: T, delay: number): T {\n const [debounced, setDebounced] = useState(value);\n\n useEffect(() => {\n const timer = setTimeout(() => setDebounced(value), delay);\n return () => clearTimeout(timer);\n }, [value, delay]);\n\n return debounced;\n}\n","import { useState, useCallback } from \"react\";\nimport { Copy, Check } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface CopyButtonProps {\n value: string;\n title?: string;\n className?: string;\n size?: \"sm\" | \"icon\";\n}\n\n// CopyButton is the single platform-wide control for copy-to-clipboard.\n// Dumb by design: it copies the given value and briefly swaps to a check icon.\n// No side effects, no hooks, no extra behavior. Multi-step workflows must live\n// on a separate action button with ui_steps.\nexport function CopyButton({ value, title, className, size = \"icon\" }: CopyButtonProps) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(async (e: React.MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch {\n // Clipboard API may be unavailable (non-secure context). Swallow:\n // the caller can select text manually.\n }\n }, [value]);\n\n const iconSize = size === \"sm\" ? \"h-3 w-3\" : \"h-4 w-4\";\n const buttonClass = size === \"sm\" ? \"h-6 w-6\" : \"h-8 w-8\";\n\n return (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className={`${buttonClass} shrink-0 ${className ?? \"\"}`}\n onClick={handleCopy}\n title={title ?? \"Copy to clipboard\"}\n >\n {copied ? (\n <Check className={`${iconSize} text-green-500`} />\n ) : (\n <Copy className={`${iconSize} text-[var(--muted-foreground)]`} />\n )}\n </Button>\n );\n}\n","import { Input } from \"@/components/ui/input\";\nimport { CopyButton } from \"@/components/shared/CopyButton\";\nimport type { FieldRendererProps } from \"./index\";\n\nexport function StringField({ field, value, mode, onChange }: FieldRendererProps) {\n if (mode === \"display\") {\n const text = String(value ?? \"\");\n if (field.copyable && text) {\n return (\n <span className=\"inline-flex items-center gap-1\">\n <span className=\"text-sm\">{text}</span>\n <CopyButton value={text} size=\"sm\" />\n </span>\n );\n }\n return <span className=\"text-sm\">{text}</span>;\n }\n\n return (\n <Input\n value={String(value ?? \"\")}\n onChange={(e) => onChange?.(e.target.value)}\n />\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nconst Textarea = React.forwardRef<\n HTMLTextAreaElement,\n React.TextareaHTMLAttributes<HTMLTextAreaElement>\n>(({ className, ...props }, ref) => {\n return (\n <textarea\n className={cn(\n \"flex min-h-[60px] w-full rounded-md border border-[var(--input)] bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-[var(--muted-foreground)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[var(--ring)] disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n});\nTextarea.displayName = \"Textarea\";\n\nexport { Textarea };\n","import Markdown from \"react-markdown\";\nimport remarkBreaks from \"remark-breaks\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { CopyButton } from \"@/components/shared/CopyButton\";\nimport type { FieldRendererProps } from \"./index\";\n\nconst remarkPlugins = [remarkBreaks];\n\nexport function TextField({ field, value, mode, onChange }: FieldRendererProps) {\n const widget = field.display?.widget;\n\n if (mode === \"display\") {\n const text = String(value ?? \"\");\n if (!text) return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n\n const rendered = widget === \"markdown\" ? (\n <div className=\"prose prose-sm dark:prose-invert max-w-none break-words overflow-hidden\">\n {/* skipHtml blocks raw HTML injection (script, img onerror, etc.).\n react-markdown v10's defaultUrlTransform blocks javascript: URLs.\n Do not pass urlTransform or allowedElements without security review. */}\n <Markdown skipHtml remarkPlugins={remarkPlugins}>{text}</Markdown>\n </div>\n ) : widget === \"code\" ? (\n <pre className=\"text-sm font-mono bg-[var(--muted)] text-[var(--foreground)] rounded-md border border-[var(--border)] p-4 overflow-x-auto max-h-[600px] overflow-y-auto whitespace-pre\">\n {text}\n </pre>\n ) : (\n <p className=\"text-sm whitespace-pre-wrap break-words\">{text}</p>\n );\n\n if (field.copyable) {\n return (\n <div className=\"group relative\">\n {rendered}\n <div className=\"absolute top-0 right-0 opacity-0 group-hover:opacity-100 transition-opacity\">\n <CopyButton value={text} size=\"sm\" />\n </div>\n </div>\n );\n }\n\n return rendered;\n }\n\n const rows = widget === \"markdown\" || widget === \"code\" ? 10 : 4;\n return (\n <Textarea\n value={String(value ?? \"\")}\n onChange={(e) => onChange?.(e.target.value)}\n rows={rows}\n className=\"resize-y font-mono text-sm\"\n />\n );\n}\n","import * as React from \"react\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { Check, ChevronDown, ChevronUp } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\nconst Select = SelectPrimitive.Root;\nconst SelectGroup = SelectPrimitive.Group;\nconst SelectValue = SelectPrimitive.Value;\n\nconst SelectTrigger = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Trigger\n ref={ref}\n className={cn(\n \"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-[var(--input)] bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-[var(--background)] placeholder:text-[var(--muted-foreground)] focus:outline-none focus:ring-1 focus:ring-[var(--ring)] disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1\",\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDown className=\"h-4 w-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n));\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName;\n\nconst SelectScrollUpButton = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.ScrollUpButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollUpButton\n ref={ref}\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className,\n )}\n {...props}\n >\n <ChevronUp className=\"h-4 w-4\" />\n </SelectPrimitive.ScrollUpButton>\n));\nSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;\n\nconst SelectScrollDownButton = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.ScrollDownButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollDownButton\n ref={ref}\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className,\n )}\n {...props}\n >\n <ChevronDown className=\"h-4 w-4\" />\n </SelectPrimitive.ScrollDownButton>\n));\nSelectScrollDownButton.displayName =\n SelectPrimitive.ScrollDownButton.displayName;\n\nconst SelectContent = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>\n>(({ className, children, position = \"popper\", ...props }, ref) => (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n ref={ref}\n className={cn(\n \"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-[var(--popover)] text-[var(--popover-foreground)] shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className,\n )}\n position={position}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]\",\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n));\nSelectContent.displayName = SelectPrimitive.Content.displayName;\n\nconst SelectItem = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-[var(--accent)] focus:text-[var(--accent-foreground)] data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n));\nSelectItem.displayName = SelectPrimitive.Item.displayName;\n\nconst SelectLabel = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label\n ref={ref}\n className={cn(\"px-2 py-1.5 text-sm font-semibold\", className)}\n {...props}\n />\n));\nSelectLabel.displayName = SelectPrimitive.Label.displayName;\n\nconst SelectSeparator = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-[var(--muted)]\", className)}\n {...props}\n />\n));\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName;\n\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectItem,\n SelectLabel,\n SelectSeparator,\n SelectScrollUpButton,\n SelectScrollDownButton,\n};\n","import { Badge } from \"@/components/ui/badge\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { loc } from \"@/types/schema\";\nimport type { FieldRendererProps } from \"./index\";\n\n// Sentinel for the \"clear / no value\" item in the dropdown. shadcn/ui's\n// SelectItem forbids an empty string as value (it's reserved for the\n// unset state), so we use a unique sentinel that cannot collide with a\n// real enum code and map it back to null on change.\nconst NULL_SENTINEL = \"__declarion_enum_null__\";\n\nexport function EnumField({ field, value, mode, onChange }: FieldRendererProps) {\n const values = field.values ?? [];\n const current = values.find((v) => v.code === value);\n\n if (mode === \"display\") {\n if (!current) {\n return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n }\n return <Badge color={current.color}>{loc(current.name)}</Badge>;\n }\n\n // Non-required enums render a leading \"— None —\" item so users can\n // clear a previously-set value (e.g. activity.intent, which is only\n // valid for specific channel/direction combos and must stay null for\n // everything else). Required enums have no clear option.\n const showClearOption = !field.required;\n const currentValue = value != null && value !== \"\" ? String(value) : NULL_SENTINEL;\n\n return (\n <Select\n value={currentValue}\n onValueChange={(v) => onChange?.(v === NULL_SENTINEL ? null : v)}\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Select...\" />\n </SelectTrigger>\n <SelectContent>\n {showClearOption && (\n <SelectItem value={NULL_SENTINEL}>\n <span className=\"text-[var(--muted-foreground)]\">— None —</span>\n </SelectItem>\n )}\n {values.map((v) => (\n <SelectItem key={v.code} value={v.code}>\n {loc(v.name)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n","import { Input } from \"@/components/ui/input\";\nimport type { FieldRendererProps } from \"./index\";\n\nexport function EmailField({ value, mode, onChange }: FieldRendererProps) {\n const str = String(value ?? \"\");\n\n if (mode === \"display\") {\n if (!str) return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n return (\n <a\n href={`mailto:${str}`}\n className=\"text-sm text-[var(--primary)] hover:underline\"\n >\n {str}\n </a>\n );\n }\n\n return (\n <Input\n type=\"email\"\n value={str}\n onChange={(e) => onChange?.(e.target.value)}\n />\n );\n}\n","import { useState } from \"react\";\nimport { ExternalLink } from \"lucide-react\";\nimport { Input } from \"@/components/ui/input\";\nimport type { FieldRendererProps } from \"./index\";\n\nconst FAVICON_BASE = \"https://www.google.com/s2/favicons\";\nconst SAFE_PROTOCOLS = /^(https?|ftps?|ssh|mailto|tel):/i;\n// Known gTLDs with 4+ characters commonly seen in URLs.\nconst LONG_TLD = /^(info|name|tech|site|cloud|online|store|shop|blog|space|world|link|live|page|zone|life|team|work|host|land|news|wiki|mobi|coop|aero|asia)$/i;\n\n// Checks whether a label looks like a TLD. All 2-3 character all-alpha labels\n// are treated as TLDs (covers ccTLDs like .uk, .de, .ai and short gTLDs like\n// .com, .xyz, .app). Longer labels are checked against a known gTLD list.\nfunction looksLikeTLD(label: string): boolean {\n return /^[a-z]{2,3}$/i.test(label) || LONG_TLD.test(label);\n}\n\nfunction looksLikeHostname(candidate: string): boolean {\n if (!candidate.includes(\".\")) return false;\n const labels = candidate.split(\".\");\n if (labels.length < 3) return true;\n const first = labels[0].toLowerCase();\n // Traditional gTLDs as first label always indicate reverse-DNS (com.google.android)\n if (/^(com|org|net|edu|gov)$/.test(first)) return false;\n // io/app/dev as first label are ambiguous: they're TLDs used in reverse-DNS\n // (io.github.user) but also common subdomain prefixes (app.example.com).\n // Disambiguate by checking the last label: if it looks like a TLD, the name\n // is structured as subdomain.domain.TLD (hostname), not TLD.domain.product.\n if (/^(io|app|dev)$/.test(first)) {\n return looksLikeTLD(labels[labels.length - 1]);\n }\n return true;\n}\n\nfunction normalizeUrl(raw: string): string | null {\n // Allow known-safe protocols through\n if (SAFE_PROTOCOLS.test(raw)) return raw;\n // Check for protocol-like pattern (scheme \":\" per RFC 3986)\n const schemeMatch = raw.match(/^([a-z][a-z0-9+.-]*):/i);\n if (schemeMatch) {\n const scheme = schemeMatch[1];\n const afterColon = raw.slice(schemeMatch[0].length);\n // Port numbers are always digits optionally followed by /, ?, #, or\n // end-of-string. If that pattern matches and the number is a valid TCP\n // port (1-65535), the part before : is likely a hostname. We apply this\n // when the candidate looks like a multi-label hostname (contains a dot)\n // and is NOT a reverse-DNS identifier (com.example.app). Single-label\n // names (sip:1234, minio:9000) are syntactically identical to\n // scheme:argument URIs and are treated as unknown protocols - users can\n // prefix with http:// to disambiguate.\n if (/^\\d+([/?#]|$)/.test(afterColon) && looksLikeHostname(scheme)) {\n const port = parseInt(afterColon, 10);\n if (port >= 1 && port <= 65535) {\n return `https://${raw}`;\n }\n }\n // \"localhost\" is a bare hostname (with or without port)\n if (scheme.toLowerCase() === \"localhost\") {\n return `https://${raw}`;\n }\n // Unknown protocol - reject (includes custom schemes like my.app://open)\n return null;\n }\n // No protocol - bare domain, prepend https://\n return `https://${raw}`;\n}\n\nfunction parseDomain(href: string): string | null {\n try {\n const hostname = new URL(href).hostname.replace(/^www\\./i, \"\");\n return hostname || null;\n } catch {\n return null;\n }\n}\n\nfunction isValidUrl(href: string): boolean {\n try {\n new URL(href);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function UrlField({ field, value, mode, onChange }: FieldRendererProps) {\n const str = String(value ?? \"\");\n const [errorDomain, setErrorDomain] = useState<string | null>(null);\n\n if (mode === \"display\") {\n if (!str) return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n\n const widget = field.display?.widget;\n const isLink = widget === \"link\";\n const href = normalizeUrl(str);\n\n // If the URL uses an unsafe protocol or is not parseable, render as plain text\n if (href == null || !isValidUrl(href)) {\n return <span className=\"text-sm\">{str}</span>;\n }\n\n const domain = parseDomain(href);\n\n // domain widget (default): show favicon + domain name\n // link widget: show full URL, no favicon\n // fallback: if domain parsing fails, show raw value as link\n const showFavicon = !isLink && domain != null && errorDomain !== domain;\n const linkText = isLink ? str : (domain ?? str);\n\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title={str}\n className=\"inline-flex items-center gap-1 text-sm text-[var(--primary)] hover:underline\"\n >\n {showFavicon && (\n <img\n src={`${FAVICON_BASE}?domain=${encodeURIComponent(domain)}&sz=16`}\n alt=\"\"\n width={16}\n height={16}\n loading=\"lazy\"\n className=\"shrink-0\"\n onError={() => setErrorDomain(domain)}\n />\n )}\n {linkText}\n <ExternalLink className=\"w-3 h-3 shrink-0\" />\n </a>\n );\n }\n\n return (\n <Input\n type=\"url\"\n value={str}\n onChange={(e) => onChange?.(e.target.value)}\n placeholder=\"https://\"\n />\n );\n}\n","import { Input } from \"@/components/ui/input\";\nimport type { FieldRendererProps } from \"./index\";\n\n/**\n * Parse an offset-aware ISO timestamp (e.g. \"2026-03-27T14:30:00+03:00\") and\n * format it for display WITHOUT browser-local conversion. When the server\n * returns a timestamp with an offset, we want to show the exact local time the\n * server computed - not the browser's reinterpretation of it.\n *\n * If the value has an explicit offset or Z suffix we use Intl.DateTimeFormat\n * with the timeZone extracted from the offset so the browser doesn't shift the\n * time. For bare datetime strings (no offset) we fall back to simple parsing.\n */\nfunction formatTimestamp(raw: string, isDateOnly: boolean): string {\n if (isDateOnly) {\n // Date-only: just format the date portion.\n const d = new Date(raw + \"T00:00:00\");\n if (isNaN(d.getTime())) return raw;\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n }).format(d);\n }\n\n // Try to extract the IANA-compatible fixed offset from the string so we can\n // tell Intl.DateTimeFormat to use it (prevents browser-local shift).\n const offsetMatch = raw.match(/([+-]\\d{2}:\\d{2})$/);\n const isUTC = raw.endsWith(\"Z\");\n\n if (offsetMatch || isUTC) {\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n\n // Build a formatter that locks to the original offset. For UTC we pass\n // \"UTC\"; for fixed offsets like +03:00 we pass \"Etc/GMT-3\" style (note\n // the sign inversion in Etc/GMT). However, Etc/GMT doesn't handle\n // non-hour offsets well, so for those we fall back to manual formatting.\n let tz: string | undefined;\n if (isUTC) {\n tz = \"UTC\";\n } else if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0);\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n if (minutes === 0) {\n // Etc/GMT sign is inverted: +03:00 -> Etc/GMT-3\n tz = hours === 0 ? \"UTC\" : `Etc/GMT${sign === \"+\" ? \"-\" : \"+\"}${hours}`;\n }\n // For non-zero minute offsets (e.g. +05:30), tz stays undefined\n // and we fall through to manual formatting below.\n }\n\n if (tz) {\n try {\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n timeZone: tz,\n }).format(date);\n } catch {\n // Fall through to manual formatting if the tz string is invalid.\n }\n }\n\n // Manual formatting for non-standard offsets (e.g. +05:30).\n // Parse the offset and compute the local time manually.\n if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0) === \"+\" ? 1 : -1;\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n const offsetMs = sign * (hours * 60 + minutes) * 60 * 1000;\n const localMs = date.getTime() + offsetMs;\n const localDate = new Date(localMs);\n // Format using UTC methods (since we already applied the offset).\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n timeZone: \"UTC\",\n }).format(localDate);\n }\n }\n\n // Bare datetime string or unparseable offset - format via browser locale.\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n }).format(date);\n}\n\n/**\n * Extract a short timezone abbreviation from a timestamp string for display.\n * E.g. \"+03:00\" -> \"UTC+3\", \"Z\" -> \"UTC\", \"+05:30\" -> \"UTC+5:30\".\n */\nfunction extractTzAbbrev(raw: string): string | null {\n if (raw.endsWith(\"Z\")) return \"UTC\";\n const m = raw.match(/([+-]\\d{2}:\\d{2})$/);\n if (!m) return null;\n const sign = m[1].charAt(0);\n const hours = parseInt(m[1].substring(1, 3), 10);\n const minutes = parseInt(m[1].substring(4, 6), 10);\n if (hours === 0 && minutes === 0) return \"UTC\";\n const minPart = minutes > 0 ? `:${String(minutes).padStart(2, \"0\")}` : \"\";\n return `UTC${sign}${hours}${minPart}`;\n}\n\n/**\n * Convert a server-provided offset-aware timestamp to \"YYYY-MM-DDTHH:MM\"\n * for the datetime-local input, preserving the server's local time (not\n * converting to browser local).\n */\nfunction toInputValue(raw: string, isDateOnly: boolean): string {\n const offsetMatch = raw.match(/([+-]\\d{2}:\\d{2})$/);\n const isUTC = raw.endsWith(\"Z\");\n\n if (offsetMatch || isUTC) {\n const date = new Date(raw);\n if (isNaN(date.getTime())) return \"\";\n\n if (isUTC) {\n // UTC: use UTC methods to get the digits.\n const y = date.getUTCFullYear();\n const mo = String(date.getUTCMonth() + 1).padStart(2, \"0\");\n const d = String(date.getUTCDate()).padStart(2, \"0\");\n if (isDateOnly) return `${y}-${mo}-${d}`;\n const h = String(date.getUTCHours()).padStart(2, \"0\");\n const mi = String(date.getUTCMinutes()).padStart(2, \"0\");\n return `${y}-${mo}-${d}T${h}:${mi}`;\n }\n\n // Fixed offset: compute local time manually.\n const sign = offsetMatch![1].charAt(0) === \"+\" ? 1 : -1;\n const hours = parseInt(offsetMatch![1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch![1].substring(4, 6), 10);\n const offsetMs = sign * (hours * 60 + minutes) * 60 * 1000;\n const localMs = date.getTime() + offsetMs;\n const localDate = new Date(localMs);\n const y = localDate.getUTCFullYear();\n const mo = String(localDate.getUTCMonth() + 1).padStart(2, \"0\");\n const d = String(localDate.getUTCDate()).padStart(2, \"0\");\n if (isDateOnly) return `${y}-${mo}-${d}`;\n const h = String(localDate.getUTCHours()).padStart(2, \"0\");\n const mi = String(localDate.getUTCMinutes()).padStart(2, \"0\");\n return `${y}-${mo}-${d}T${h}:${mi}`;\n }\n\n // Bare datetime string - extract digits directly.\n // Format: \"2026-03-27T14:30\" or \"2026-03-27T14:30:00\"\n if (isDateOnly) return raw.slice(0, 10);\n // Take up to minutes precision.\n return raw.slice(0, 16);\n}\n\nexport function TimestampField({ field, value, mode, onChange }: FieldRendererProps) {\n const isDateOnly = field.type === \"date\";\n const hasTz = !!field.timezone;\n\n if (mode === \"display\") {\n if (!value) return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n const raw = String(value);\n const formatted = formatTimestamp(raw, isDateOnly);\n // Show timezone abbreviation when field has timezone config.\n const tzAbbrev = hasTz && !isDateOnly ? extractTzAbbrev(raw) : null;\n return (\n <span className=\"text-sm\">\n {formatted}\n {tzAbbrev && <span className=\"ml-1 text-[var(--muted-foreground)]\">{tzAbbrev}</span>}\n </span>\n );\n }\n\n // Edit mode: convert server value to input format preserving server's local\n // time (not browser local), then send the raw datetime-local value as-is on\n // change. The server handles timezone attachment and UTC conversion.\n let inputValue = \"\";\n if (value) {\n inputValue = toInputValue(String(value), isDateOnly);\n }\n\n return (\n <Input\n type={isDateOnly ? \"date\" : \"datetime-local\"}\n value={inputValue}\n onChange={(e) => {\n if (!e.target.value) {\n onChange?.(null);\n return;\n }\n // Send the raw datetime-local value as-is. The server will interpret\n // this as local time in the field's configured timezone.\n onChange?.(e.target.value);\n }}\n />\n );\n}\n","import type { FieldRendererProps } from \"./index\";\n\nexport function BoolField({ value, mode, onChange }: FieldRendererProps) {\n const checked = Boolean(value);\n\n if (mode === \"display\") {\n return (\n <span className=\"inline-flex items-center gap-1.5 text-sm\">\n <span\n className={`inline-block w-2 h-2 rounded-full ${\n checked ? \"bg-[var(--primary)]\" : \"bg-[var(--muted-foreground)]\"\n }`}\n />\n {checked ? \"Yes\" : \"No\"}\n </span>\n );\n }\n\n return (\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={checked}\n onChange={(e) => onChange?.(e.target.checked)}\n className=\"h-4 w-4 rounded border-[var(--input)] text-[var(--primary)] focus:ring-[var(--ring)]\"\n />\n <span className=\"text-sm\">{checked ? \"Yes\" : \"No\"}</span>\n </label>\n );\n}\n","import { Input } from \"@/components/ui/input\";\nimport type { FieldRendererProps } from \"./index\";\n\n/**\n * Format a decimal string for display using locale-aware grouping.\n * Splits on \".\" to preserve exact decimal places without parseFloat precision loss.\n */\nfunction formatDecimalString(value: string): string {\n const trimmed = value.trim();\n if (trimmed === \"\" || trimmed === \"-\") return trimmed;\n\n const negative = trimmed.startsWith(\"-\");\n const abs = negative ? trimmed.slice(1) : trimmed;\n const [intPart, fracPart] = abs.split(\".\");\n\n let formattedInt: string;\n try {\n formattedInt = new Intl.NumberFormat().format(BigInt(intPart || \"0\"));\n } catch {\n return value; // fallback to raw string on invalid input\n }\n\n let result = negative ? `-${formattedInt}` : formattedInt;\n if (fracPart !== undefined) {\n result += `.${fracPart}`;\n }\n return result;\n}\n\nconst numFormatter = new Intl.NumberFormat();\n\nexport function NumberField({ field, fieldName, value, mode, onChange, record }: FieldRendererProps) {\n const isMoney = field.display?.widget === \"money\";\n const isDecimal = field.type === \"decimal\" || isMoney;\n\n // Resolve unit suffix from $units metadata on the record.\n const units = record?.[\"$units\"] as Record<string, string> | undefined;\n const unitSuffix = units?.[fieldName];\n\n // If no $units metadata, fall back to static unit config from schema.\n const staticUnit = !unitSuffix && field.unit\n ? (field.unit.display || field.unit.storage)\n : undefined;\n // Only show static unit if it doesn't start with $ (dynamic units are resolved in $units).\n const displayUnit = unitSuffix\n || (staticUnit && !staticUnit.startsWith(\"$\") ? staticUnit : undefined);\n\n if (mode === \"display\") {\n if (value == null) return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n\n let formatted: string | null;\n if (isDecimal && typeof value === \"string\") {\n formatted = formatDecimalString(value);\n } else {\n const num = Number(value);\n formatted = isNaN(num) ? null : numFormatter.format(num);\n }\n\n if (formatted == null) return <span className=\"text-sm\">-</span>;\n\n return (\n <span className=\"text-sm tabular-nums\">\n {formatted}\n {displayUnit && <span className=\"text-[var(--muted-foreground)] ml-1\">{displayUnit}</span>}\n </span>\n );\n }\n\n // Edit mode: use text input for decimal to avoid IEEE 754 precision loss.\n if (isDecimal) {\n return (\n <Input\n type=\"text\"\n inputMode=\"decimal\"\n pattern=\"-?\\d*\\.?\\d*\"\n value={value != null ? String(value) : \"\"}\n onChange={(e) => {\n const v = e.target.value;\n if (v === \"\") {\n onChange?.(null);\n } else {\n // Keep as string - do NOT parseFloat. Server expects decimal strings.\n onChange?.(v);\n }\n }}\n />\n );\n }\n\n // int/float: use number input\n return (\n <Input\n type=\"number\"\n step={field.type === \"float\" ? \"0.01\" : \"1\"}\n value={value != null ? String(value) : \"\"}\n onChange={(e) => {\n const v = e.target.value;\n if (v === \"\") {\n onChange?.(null);\n } else {\n onChange?.(field.type === \"int\" ? parseInt(v, 10) : parseFloat(v));\n }\n }}\n />\n );\n}\n","import { useSchema } from \"./useSchema\";\nimport type { Entity } from \"@/types/schema\";\n\nexport function useEntity(entityCode: string | undefined): Entity | undefined {\n const { data: schema } = useSchema();\n if (!schema || !entityCode) return undefined;\n return schema.entities[entityCode];\n}\n","import { useMemo } from \"react\";\nimport { useEntityData } from \"@/hooks/useEntityData\";\nimport { useEntity } from \"@/hooks/useEntity\";\nimport type { FieldRendererProps } from \"./index\";\n\n/** Resolve a display value that may be a plain string or a multilang object. */\nfunction resolveDisplay(val: unknown): string {\n if (val == null) return \"-\";\n if (typeof val === \"object\" && !Array.isArray(val)) {\n const first = Object.values(val)[0];\n return first != null ? String(first) : \"-\";\n }\n return String(val);\n}\n\nexport function RefField({\n field,\n value,\n mode,\n onChange,\n refs,\n}: FieldRendererProps) {\n const refEntityCode = field.ref?.entity;\n const entity = useEntity(refEntityCode);\n\n // Display field: ref.display.field overrides entity.display.display_field.\n const displayField = field.display?.ref_display_field ?? field.ref?.display?.field ?? entity?.display?.display_field;\n const pk = useMemo(\n () =>\n entity\n ? Object.entries(entity.fields).find(([, f]) => f.primary)?.[0] ?? \"id\"\n : \"id\",\n [entity],\n );\n\n // Only fetch ref options in edit mode (display mode uses $refs from the response).\n const { data: response, isLoading: optionsLoading } = useEntityData(mode === \"edit\" ? refEntityCode : undefined, {\n per_page: 200,\n sort: displayField ? `${displayField}:asc` : undefined,\n });\n const options = response?.data ?? [];\n\n // Resolve display value from $refs (list/detail response) or fetched options (edit mode).\n const displayValue = useMemo(() => {\n if (value == null) return \"-\";\n const strVal = String(value);\n\n // Look up from $refs (provided by list or detail response).\n if (refs && refEntityCode) {\n const entityRefs = refs[refEntityCode];\n if (entityRefs) {\n const refRecord = entityRefs[strVal];\n if (refRecord) {\n if (displayField) return resolveDisplay(refRecord[displayField]);\n return strVal;\n }\n }\n }\n\n // Fallback: look up from fetched options (edit mode dropdown data).\n if (displayField && options.length > 0) {\n const match = options.find((r) => String(r[pk]) === strVal);\n if (match) return resolveDisplay(match[displayField] ?? value);\n }\n\n return strVal;\n }, [value, refs, refEntityCode, displayField, options, pk]);\n\n if (mode === \"display\") {\n return <span className=\"text-sm\">{displayValue}</span>;\n }\n\n // While options are loading, show a temporary option with the current display value\n // so the select doesn't jump to \"Select...\".\n const currentId = String(value ?? \"\");\n const hasCurrentInOptions = options.some((r) => String(r[pk]) === currentId);\n\n return (\n <select\n className=\"flex h-9 w-full rounded-md border border-[var(--input)] bg-[var(--background)] px-3 py-1 text-sm text-[var(--foreground)] shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[var(--ring)]\"\n value={currentId}\n onChange={(e) => onChange?.(e.target.value || null)}\n disabled={optionsLoading}\n >\n <option value=\"\">Select...</option>\n {optionsLoading && currentId && (\n <option value={currentId}>{displayValue}</option>\n )}\n {!optionsLoading && currentId && !hasCurrentInOptions && (\n <option value={currentId}>{displayValue}</option>\n )}\n {options.map((r) => {\n const id = String(r[pk]);\n const label = displayField\n ? resolveDisplay(r[displayField] ?? id)\n : id;\n return (\n <option key={id} value={id}>\n {label}\n </option>\n );\n })}\n </select>\n );\n}\n","import { lazy, Suspense } from \"react\";\nimport type { FieldRendererProps } from \"./index\";\n\nconst JsonEditor = lazy(() =>\n import(\"./JsonEditor\").then((m) => ({ default: m.JsonEditor })),\n);\n\nfunction JsonEditorFallback() {\n return (\n <div className=\"h-20 rounded-md border border-[var(--border)] bg-[var(--muted)] animate-pulse\" />\n );\n}\n\nexport function JsonField({ value, mode, onChange }: FieldRendererProps) {\n if (mode === \"display\") {\n if (value == null || (typeof value === \"string\" && !value)) {\n return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n }\n return (\n <Suspense fallback={<JsonEditorFallback />}>\n <JsonEditor value={value} readOnly />\n </Suspense>\n );\n }\n\n return (\n <Suspense fallback={<JsonEditorFallback />}>\n <JsonEditor value={value} onChange={onChange} />\n </Suspense>\n );\n}\n","import { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport type { FieldRendererProps } from \"./index\";\n\ntype LangMap = Record<string, string>;\n\nfunction parseLangMap(value: unknown): LangMap {\n if (value == null) return {};\n if (typeof value === \"object\" && !Array.isArray(value)) {\n return value as LangMap;\n }\n if (typeof value === \"string\") {\n return { en: value };\n }\n return {};\n}\n\nexport function MultilangField({\n value,\n mode,\n onChange,\n}: FieldRendererProps) {\n const { data: schema } = useSchema();\n const languages = schema?.languages?.length\n ? schema.languages\n : [{ code: \"en\", name: { en: \"English\" } }];\n const langMap = parseLangMap(value);\n\n if (mode === \"display\") {\n // Show the first available language value.\n const displayVal =\n Object.values(langMap)[0] ?? \"-\";\n return <span className=\"text-sm\">{displayVal}</span>;\n }\n\n const handleLangChange = (lang: string, text: string) => {\n const updated = { ...langMap, [lang]: text };\n // Remove empty language entries.\n for (const k of Object.keys(updated)) {\n if (!updated[k]) delete updated[k];\n }\n onChange?.(Object.keys(updated).length > 0 ? updated : null);\n };\n\n return (\n <div className=\"space-y-2\">\n {languages.map((lang) => (\n <div key={lang.code} className=\"flex items-center gap-2\">\n <Label className=\"w-8 text-xs text-[var(--muted-foreground)] uppercase shrink-0\">\n {lang.code}\n </Label>\n <Input\n value={langMap[lang.code] ?? \"\"}\n onChange={(e) => handleLangChange(lang.code, e.target.value)}\n placeholder={`Value (${lang.code})`}\n />\n </div>\n ))}\n </div>\n );\n}\n","import { Textarea } from \"@/components/ui/textarea\";\nimport { Label } from \"@/components/ui/label\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport type { FieldRendererProps } from \"./index\";\n\ntype LangMap = Record<string, string>;\n\nfunction parseLangMap(value: unknown): LangMap {\n if (value == null) return {};\n if (typeof value === \"object\" && !Array.isArray(value)) {\n return value as LangMap;\n }\n if (typeof value === \"string\") {\n return { en: value };\n }\n return {};\n}\n\nexport function MultilangTextField({\n value,\n mode,\n onChange,\n}: FieldRendererProps) {\n const { data: schema } = useSchema();\n const languages = schema?.languages?.length\n ? schema.languages\n : [{ code: \"en\", name: { en: \"English\" } }];\n const langMap = parseLangMap(value);\n\n if (mode === \"display\") {\n const displayVal = Object.values(langMap)[0] ?? \"-\";\n return <p className=\"text-sm whitespace-pre-wrap\">{displayVal}</p>;\n }\n\n const handleLangChange = (lang: string, text: string) => {\n const updated = { ...langMap, [lang]: text };\n for (const k of Object.keys(updated)) {\n if (!updated[k]) delete updated[k];\n }\n onChange?.(Object.keys(updated).length > 0 ? updated : null);\n };\n\n return (\n <div className=\"space-y-3\">\n {languages.map((lang) => (\n <div key={lang.code} className=\"space-y-1\">\n <Label className=\"text-xs text-[var(--muted-foreground)] uppercase\">\n {lang.code}\n </Label>\n <Textarea\n value={langMap[lang.code] ?? \"\"}\n onChange={(e) => handleLangChange(lang.code, e.target.value)}\n placeholder={`Value (${lang.code})`}\n rows={4}\n className=\"resize-y\"\n />\n </div>\n ))}\n </div>\n );\n}\n","import { useSchema } from \"@/hooks/useSchema\";\nimport { loc } from \"@/types/schema\";\nimport type { StructureDef } from \"@/types/schema\";\nimport type { FieldRendererProps } from \"./index\";\nimport { renderField } from \"./index\";\nimport { JsonField } from \"./JsonField\";\nimport { Label } from \"@/components/ui/label\";\nimport { Button } from \"@/components/ui/button\";\nimport { Plus, Trash2 } from \"lucide-react\";\n\nexport function StructureField(props: FieldRendererProps) {\n const { field, value, mode, onChange } = props;\n const { data: schema } = useSchema();\n\n const structDef = field.structure\n ? schema?.structures?.[field.structure]\n : undefined;\n\n // Fall back to raw JsonField if structure def not found.\n if (!structDef) {\n return <JsonField {...props} />;\n }\n\n if (field.array) {\n return (\n <StructureArrayRenderer\n structDef={structDef}\n value={value}\n mode={mode}\n onChange={onChange}\n />\n );\n }\n\n return (\n <StructureObjectRenderer\n structDef={structDef}\n value={value}\n mode={mode}\n onChange={onChange}\n />\n );\n}\n\nfunction StructureObjectRenderer({\n structDef,\n value,\n mode,\n onChange,\n}: {\n structDef: StructureDef;\n value: unknown;\n mode: \"display\" | \"edit\";\n onChange?: (value: unknown) => void;\n}) {\n const obj = (typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? value\n : {}) as Record<string, unknown>;\n\n const fieldOrder = structDef.field_order?.length\n ? structDef.field_order\n : Object.keys(structDef.fields);\n\n if (mode === \"display\") {\n const hasAnyValue = fieldOrder.some((key) => obj[key] != null && obj[key] !== \"\");\n if (!hasAnyValue) {\n return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n }\n\n return (\n <div className=\"space-y-2 rounded-md border border-[var(--border)] p-3\">\n {fieldOrder.map((key) => {\n const field = structDef.fields[key];\n if (!field) return null;\n const fieldValue = obj[key];\n if (fieldValue == null) return null;\n\n return (\n <div key={key} className=\"flex items-baseline gap-2\">\n <span className=\"text-xs font-medium text-[var(--muted-foreground)] min-w-[100px] shrink-0\">\n {field.display ? loc(field.display.name) : key}\n </span>\n <div className=\"min-w-0 flex-1\">\n {field.type === \"structure\" && field.structure ? (\n <StructureField\n field={field}\n fieldName={key}\n value={fieldValue}\n mode=\"display\"\n />\n ) : (\n renderField({\n field,\n fieldName: key,\n value: fieldValue,\n mode: \"display\",\n })\n )}\n </div>\n </div>\n );\n })}\n </div>\n );\n }\n\n // Edit mode\n const handleFieldChange = (key: string) => (fieldValue: unknown) => {\n onChange?.({ ...obj, [key]: fieldValue });\n };\n\n return (\n <div className=\"space-y-3 rounded-md border border-[var(--border)] p-3\">\n {fieldOrder.map((key) => {\n const field = structDef.fields[key];\n if (!field) return null;\n\n return (\n <div key={key} className=\"space-y-1\">\n <Label className=\"text-xs\">\n {field.display ? loc(field.display.name) : key}\n {field.required && (\n <span className=\"text-[var(--destructive)] ml-0.5\">*</span>\n )}\n </Label>\n {field.type === \"structure\" && field.structure ? (\n <StructureField\n field={field}\n fieldName={key}\n value={obj[key]}\n mode=\"edit\"\n onChange={handleFieldChange(key)}\n />\n ) : (\n renderField({\n field,\n fieldName: key,\n value: obj[key],\n mode: \"edit\",\n onChange: handleFieldChange(key),\n })\n )}\n </div>\n );\n })}\n </div>\n );\n}\n\nfunction StructureArrayRenderer({\n structDef,\n value,\n mode,\n onChange,\n}: {\n structDef: StructureDef;\n value: unknown;\n mode: \"display\" | \"edit\";\n onChange?: (value: unknown) => void;\n}) {\n const items = Array.isArray(value) ? value : [];\n\n if (mode === \"display\") {\n if (items.length === 0) {\n return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n }\n\n return (\n <div className=\"space-y-2\">\n {items.map((item, idx) => (\n <StructureObjectRenderer\n key={idx}\n structDef={structDef}\n value={item}\n mode=\"display\"\n />\n ))}\n </div>\n );\n }\n\n // Edit mode\n const handleItemChange = (idx: number) => (itemValue: unknown) => {\n const next = [...items];\n next[idx] = itemValue;\n onChange?.(next);\n };\n\n const handleAdd = () => {\n onChange?.([...items, {}]);\n };\n\n const handleRemove = (idx: number) => () => {\n const next = items.filter((_, i) => i !== idx);\n onChange?.(next);\n };\n\n return (\n <div className=\"space-y-2\">\n {items.map((item, idx) => (\n <div key={idx} className=\"relative\">\n <StructureObjectRenderer\n structDef={structDef}\n value={item}\n mode=\"edit\"\n onChange={handleItemChange(idx)}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"absolute top-1 right-1 h-6 w-6 p-0 text-[var(--muted-foreground)] hover:text-[var(--destructive)]\"\n onClick={handleRemove(idx)}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1\"\n onClick={handleAdd}\n >\n <Plus className=\"h-3.5 w-3.5\" />\n Add\n </Button>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { Eye, EyeOff } from \"lucide-react\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport type { FieldRendererProps } from \"./index\";\n\n// The sentinel value returned by the server for non-null secret fields.\n// Must match secrets.SecretSentinel in the Go backend.\nconst SECRET_SENTINEL = \"[SET]\";\n\nexport function SecretField({ value, mode, onChange, record }: FieldRendererProps) {\n const [showValue, setShowValue] = useState(false);\n // track user input separately from the underlying record value\n const [inputValue, setInputValue] = useState(\"\");\n\n const isUpdate = record !== undefined;\n const hasExistingValue =\n value === SECRET_SENTINEL || (typeof value === \"string\" && value !== \"\");\n\n if (mode === \"display\") {\n if (hasExistingValue) {\n return (\n <span className=\"text-sm font-mono text-[var(--muted-foreground)]\">\n {SECRET_SENTINEL}\n </span>\n );\n }\n return (\n <span className=\"text-sm text-[var(--muted-foreground)] italic\">Not set</span>\n );\n }\n\n // Edit mode.\n // On Update: leaving blank preserves the DB value ([SET] is sent).\n // On Create: leaving blank writes NULL.\n const handleChange = (v: string) => {\n setInputValue(v);\n if (isUpdate) {\n // Send the typed value; if blank and there was an existing value, send [SET]\n // to signal \"preserve existing\". If blank and no existing value, send \"\".\n if (v === \"\") {\n onChange?.(hasExistingValue ? SECRET_SENTINEL : \"\");\n } else {\n onChange?.(v);\n }\n } else {\n // Create: blank means NULL\n onChange?.(v);\n }\n };\n\n return (\n <div className=\"flex items-center gap-1\">\n <Input\n type={showValue ? \"text\" : \"password\"}\n value={inputValue}\n placeholder={isUpdate ? \"Leave blank to keep existing value\" : \"Enter value\"}\n onChange={(e) => handleChange(e.target.value)}\n className=\"flex-1\"\n autoComplete=\"new-password\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 shrink-0\"\n onClick={() => setShowValue((v) => !v)}\n title={showValue ? \"Hide value\" : \"Show typed value\"}\n >\n {showValue ? (\n <EyeOff className=\"h-4 w-4\" />\n ) : (\n <Eye className=\"h-4 w-4\" />\n )}\n </Button>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { Eye, EyeOff } from \"lucide-react\";\nimport { Input } from \"@/components/ui/input\";\nimport type { FieldRendererProps } from \"./index\";\n\n// The sentinel value returned by the server for non-null password fields.\n// Must match secrets.SecretSentinel in the Go backend.\nconst SECRET_SENTINEL = \"[SET]\";\n\nexport function PasswordField({ value, mode, onChange, record }: FieldRendererProps) {\n // track user input separately from the underlying record value\n const [inputValue, setInputValue] = useState(\"\");\n // show/hide toggle for the eye icon - defaults to masked (type=password).\n const [revealed, setRevealed] = useState(false);\n\n const isUpdate = record !== undefined;\n const hasExistingValue =\n value === SECRET_SENTINEL || (typeof value === \"string\" && value !== \"\");\n\n if (mode === \"display\") {\n if (hasExistingValue) {\n return (\n <span className=\"text-sm font-mono text-[var(--muted-foreground)]\">\n {SECRET_SENTINEL}\n </span>\n );\n }\n return (\n <span className=\"text-sm text-[var(--muted-foreground)] italic\">Not set</span>\n );\n }\n\n // Edit mode.\n // On Update: leaving blank preserves the DB value ([SET] is sent).\n // On Create: leaving blank writes NULL.\n const handleChange = (v: string) => {\n setInputValue(v);\n if (isUpdate) {\n if (v === \"\") {\n onChange?.(hasExistingValue ? SECRET_SENTINEL : \"\");\n } else {\n onChange?.(v);\n }\n } else {\n onChange?.(v);\n }\n };\n\n // Wrapper positions the eye-toggle absolutely inside the input's right edge.\n // The input gets right-padding so the masked text never overlaps the icon.\n return (\n <div className=\"relative\">\n <Input\n type={revealed ? \"text\" : \"password\"}\n value={inputValue}\n placeholder={isUpdate ? \"Leave blank to keep existing value\" : \"Enter password\"}\n onChange={(e) => handleChange(e.target.value)}\n autoComplete=\"new-password\"\n className=\"pr-9\"\n />\n <button\n type=\"button\"\n onClick={() => setRevealed((r) => !r)}\n aria-label={revealed ? \"Hide password\" : \"Show password\"}\n tabIndex={-1}\n className=\"absolute inset-y-0 right-0 flex items-center pr-2 text-[var(--muted-foreground)] hover:text-[var(--foreground)]\"\n >\n {revealed ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\n </button>\n </div>\n );\n}\n","import { useState, type KeyboardEvent } from \"react\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { X, Plus } from \"lucide-react\";\nimport type { FieldRendererProps } from \"./index\";\n\nfunction toStringArray(value: unknown): string[] {\n if (Array.isArray(value)) return value.filter((v) => v != null).map(String);\n return [];\n}\n\nexport function StringArrayField({ value, mode, onChange }: FieldRendererProps) {\n const items = toStringArray(value);\n const [draft, setDraft] = useState(\"\");\n\n if (mode === \"display\") {\n if (items.length === 0) return <span className=\"text-sm text-muted-foreground\">-</span>;\n return (\n <div className=\"flex flex-wrap gap-1\">\n {items.map((item, i) => (\n <span\n key={i}\n className=\"inline-flex items-center rounded-md bg-secondary px-2 py-0.5 text-xs text-secondary-foreground\"\n >\n {item}\n </span>\n ))}\n </div>\n );\n }\n\n const addItem = () => {\n const trimmed = draft.trim();\n if (!trimmed) return;\n onChange?.([...items, trimmed]);\n setDraft(\"\");\n };\n\n const removeItem = (index: number) => {\n onChange?.(items.filter((_, i) => i !== index));\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n addItem();\n }\n };\n\n return (\n <div className=\"space-y-2\">\n {items.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {items.map((item, i) => (\n <span\n key={i}\n className=\"inline-flex items-center gap-1 rounded-md bg-secondary px-2 py-0.5 text-xs text-secondary-foreground\"\n >\n {item}\n <button\n type=\"button\"\n onClick={() => removeItem(i)}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n </span>\n ))}\n </div>\n )}\n <div className=\"flex gap-1\">\n <Input\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder=\"Add item...\"\n className=\"flex-1\"\n />\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addItem}>\n <Plus className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n}\n","import { useState, type KeyboardEvent } from \"react\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { X, Plus } from \"lucide-react\";\nimport type { FieldRendererProps } from \"./index\";\n\nfunction toIntArray(value: unknown): number[] {\n if (Array.isArray(value)) {\n return value.filter((v) => v != null).map(Number).filter((n) => !isNaN(n));\n }\n return [];\n}\n\nexport function IntArrayField({ value, mode, onChange }: FieldRendererProps) {\n const items = toIntArray(value);\n const [draft, setDraft] = useState(\"\");\n\n if (mode === \"display\") {\n if (items.length === 0) return <span className=\"text-sm text-muted-foreground\">-</span>;\n return (\n <div className=\"flex flex-wrap gap-1\">\n {items.map((item, i) => (\n <span\n key={i}\n className=\"inline-flex items-center rounded-md bg-secondary px-2 py-0.5 text-xs text-secondary-foreground\"\n >\n {item}\n </span>\n ))}\n </div>\n );\n }\n\n const addItem = () => {\n const trimmed = draft.trim();\n if (!trimmed) return;\n const num = Number(trimmed);\n if (isNaN(num) || !Number.isInteger(num)) return;\n onChange?.([...items, num]);\n setDraft(\"\");\n };\n\n const removeItem = (index: number) => {\n onChange?.(items.filter((_, i) => i !== index));\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n addItem();\n }\n };\n\n return (\n <div className=\"space-y-2\">\n {items.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {items.map((item, i) => (\n <span\n key={i}\n className=\"inline-flex items-center gap-1 rounded-md bg-secondary px-2 py-0.5 text-xs text-secondary-foreground\"\n >\n {item}\n <button\n type=\"button\"\n onClick={() => removeItem(i)}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n </span>\n ))}\n </div>\n )}\n <div className=\"flex gap-1\">\n <Input\n type=\"number\"\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder=\"Add number...\"\n className=\"flex-1\"\n />\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addItem}>\n <Plus className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n}\n","import type { EntityField } from \"@/types/schema\";\nimport { StringField } from \"./StringField\";\nimport { TextField } from \"./TextField\";\nimport { EnumField } from \"./EnumField\";\nimport { EmailField } from \"./EmailField\";\nimport { UrlField } from \"./UrlField\";\nimport { TimestampField } from \"./TimestampField\";\nimport { BoolField } from \"./BoolField\";\nimport { NumberField } from \"./NumberField\";\nimport { RefField } from \"./RefField\";\nimport { JsonField } from \"./JsonField\";\nimport { MultilangField } from \"./MultilangField\";\nimport { MultilangTextField } from \"./MultilangTextField\";\nimport { StructureField } from \"./StructureField\";\nimport { SecretField } from \"./SecretField\";\nimport { PasswordField } from \"./PasswordField\";\nimport { StringArrayField } from \"./StringArrayField\";\nimport { IntArrayField } from \"./IntArrayField\";\n\n// RefsMap is the $refs structure from list/detail API responses.\n// Shape: { entityCode: { recordId: { field: value, ... } } }\nexport type RefsMap = Record<string, Record<string, Record<string, unknown>>>;\n\nexport interface FieldRendererProps {\n field: EntityField;\n fieldName: string;\n value: unknown;\n mode: \"display\" | \"edit\";\n onChange?: (value: unknown) => void;\n record?: Record<string, unknown>;\n refs?: RefsMap;\n}\n\ntype FieldRenderer = React.ComponentType<FieldRendererProps>;\n\nconst fieldRenderers: Record<string, FieldRenderer> = {\n string: StringField,\n text: TextField,\n enum: EnumField,\n email: EmailField,\n url: UrlField,\n phone: StringField,\n timestamp: TimestampField,\n date: TimestampField,\n time: TimestampField,\n bool: BoolField,\n int: NumberField,\n float: NumberField,\n decimal: NumberField,\n uuid: StringField,\n ref: RefField,\n json: JsonField,\n tags: StringField,\n string_array: StringArrayField,\n int_array: IntArrayField,\n multilang: MultilangField,\n multilang_text: MultilangTextField,\n structure: StructureField,\n secret: SecretField,\n password: PasswordField,\n};\n\nexport function renderField(props: FieldRendererProps): React.ReactNode {\n // type: json + structure: \"code\" → use StructureField instead of JsonField\n if (props.field.type === \"json\" && props.field.structure) {\n return <StructureField {...props} />;\n }\n // Widget-first dispatch: if display.widget names a known renderer, use it.\n // Lets a handler param declare widget:\"password\" on a type:\"string\" to\n // render with PasswordField without polluting the backend type system.\n // Falls through to type when widget is absent or unknown.\n const widget = props.field.display?.widget;\n if (widget && fieldRenderers[widget]) {\n const Renderer = fieldRenderers[widget];\n return <Renderer {...props} />;\n }\n const Renderer = fieldRenderers[props.field.type] ?? StringField;\n return <Renderer {...props} />;\n}\n\nexport function getFieldRenderer(type: string): FieldRenderer {\n return fieldRenderers[type] ?? StringField;\n}\n\n// hasFieldRenderer reports whether a given key has a registered renderer.\n// Used by callers that want to validate a widget hint before passing it in.\nexport function hasFieldRenderer(key: string): boolean {\n return key in fieldRenderers;\n}\n","import type { ReactNode } from \"react\";\nimport { DynamicIcon } from \"./DynamicIcon\";\n\ninterface EmptyStateProps {\n icon?: string;\n title: string;\n description?: string;\n action?: ReactNode;\n}\n\nexport function EmptyState({ icon, title, description, action }: EmptyStateProps) {\n return (\n <div className=\"flex flex-col items-center justify-center py-16 text-center\">\n {icon && (\n <div className=\"mb-4 rounded-full bg-[var(--muted)] p-4\">\n <DynamicIcon name={icon} className=\"w-8 h-8 text-[var(--muted-foreground)]\" />\n </div>\n )}\n <h3 className=\"text-lg font-medium text-[var(--foreground)]\">{title}</h3>\n {description && (\n <p className=\"mt-1 text-sm text-[var(--muted-foreground)] max-w-sm\">\n {description}\n </p>\n )}\n {action && <div className=\"mt-4\">{action}</div>}\n </div>\n );\n}\n","import { cn } from \"@/lib/utils\";\n\nfunction Skeleton({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn(\n \"animate-pulse rounded-md bg-[var(--muted)]\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Skeleton };\n","import { Skeleton } from \"@/components/ui/skeleton\";\n\nexport function TableSkeleton({ rows = 8, cols = 4 }: { rows?: number; cols?: number }) {\n return (\n <div className=\"space-y-3 p-6\">\n {/* Header */}\n <div className=\"flex gap-4\">\n {Array.from({ length: cols }).map((_, i) => (\n <Skeleton key={i} className=\"h-4 flex-1\" />\n ))}\n </div>\n {/* Rows */}\n {Array.from({ length: rows }).map((_, i) => (\n <div key={i} className=\"flex gap-4\">\n {Array.from({ length: cols }).map((_, j) => (\n <Skeleton key={j} className=\"h-8 flex-1\" />\n ))}\n </div>\n ))}\n </div>\n );\n}\n\nexport function DetailSkeleton() {\n return (\n <div className=\"space-y-6 p-6\">\n <Skeleton className=\"h-8 w-48\" />\n <div className=\"space-y-4\">\n {Array.from({ length: 4 }).map((_, i) => (\n <div key={i} className=\"space-y-2\">\n <Skeleton className=\"h-4 w-24\" />\n <Skeleton className=\"h-9 w-full max-w-md\" />\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\";\nimport { cn } from \"@/lib/utils\";\nimport { buttonVariants } from \"@/components/ui/button\";\n\nconst AlertDialog = AlertDialogPrimitive.Root;\nconst AlertDialogTrigger = AlertDialogPrimitive.Trigger;\nconst AlertDialogPortal = AlertDialogPrimitive.Portal;\n\nconst AlertDialogOverlay = React.forwardRef<\n React.ComponentRef<typeof AlertDialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Overlay\n className={cn(\n \"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n ref={ref}\n />\n));\nAlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;\n\nconst AlertDialogContent = React.forwardRef<\n React.ComponentRef<typeof AlertDialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>\n>(({ className, ...props }, ref) => (\n <AlertDialogPortal>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Content\n ref={ref}\n className={cn(\n \"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-[var(--background)] p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg\",\n className,\n )}\n {...props}\n />\n </AlertDialogPortal>\n));\nAlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;\n\nfunction AlertDialogHeader({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn(\n \"flex flex-col space-y-2 text-center sm:text-left\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogFooter({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n className,\n )}\n {...props}\n />\n );\n}\n\nconst AlertDialogTitle = React.forwardRef<\n React.ComponentRef<typeof AlertDialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Title\n ref={ref}\n className={cn(\"text-lg font-semibold\", className)}\n {...props}\n />\n));\nAlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;\n\nconst AlertDialogDescription = React.forwardRef<\n React.ComponentRef<typeof AlertDialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Description\n ref={ref}\n className={cn(\"text-sm text-[var(--muted-foreground)]\", className)}\n {...props}\n />\n));\nAlertDialogDescription.displayName =\n AlertDialogPrimitive.Description.displayName;\n\nconst AlertDialogAction = React.forwardRef<\n React.ComponentRef<typeof AlertDialogPrimitive.Action>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Action\n ref={ref}\n className={cn(buttonVariants(), className)}\n {...props}\n />\n));\nAlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;\n\nconst AlertDialogCancel = React.forwardRef<\n React.ComponentRef<typeof AlertDialogPrimitive.Cancel>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Cancel\n ref={ref}\n className={cn(\n buttonVariants({ variant: \"outline\" }),\n \"mt-2 sm:mt-0\",\n className,\n )}\n {...props}\n />\n));\nAlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;\n\nexport {\n AlertDialog,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogTrigger,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogAction,\n AlertDialogCancel,\n};\n","import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from \"@/components/ui/alert-dialog\";\n\ninterface ConfirmDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: string;\n description: string;\n confirmLabel?: string;\n onConfirm: () => void;\n destructive?: boolean;\n}\n\nexport function ConfirmDialog({\n open,\n onOpenChange,\n title,\n description,\n confirmLabel = \"Confirm\",\n onConfirm,\n destructive = false,\n}: ConfirmDialogProps) {\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{title}</AlertDialogTitle>\n <AlertDialogDescription>{description}</AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={onConfirm}\n className={destructive ? \"bg-[var(--destructive)] text-[var(--destructive-foreground)] hover:bg-[var(--destructive)]/90\" : \"\"}\n >\n {confirmLabel}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n","import * as React from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { X } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\nconst Dialog = DialogPrimitive.Root;\nconst DialogTrigger = DialogPrimitive.Trigger;\nconst DialogPortal = DialogPrimitive.Portal;\nconst DialogClose = DialogPrimitive.Close;\n\nconst DialogOverlay = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n \"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n />\n));\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;\n\nconst DialogContent = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n className={cn(\n \"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-[var(--background)] p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg\",\n className,\n )}\n {...props}\n >\n {children}\n <DialogPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-[var(--background)] transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-[var(--ring)] focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-[var(--accent)] data-[state=open]:text-[var(--muted-foreground)]\">\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPortal>\n));\nDialogContent.displayName = DialogPrimitive.Content.displayName;\n\nfunction DialogHeader({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn(\n \"flex flex-col space-y-1.5 text-center sm:text-left\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogFooter({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n className,\n )}\n {...props}\n />\n );\n}\n\nconst DialogTitle = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n className={cn(\n \"text-lg font-semibold leading-none tracking-tight\",\n className,\n )}\n {...props}\n />\n));\nDialogTitle.displayName = DialogPrimitive.Title.displayName;\n\nconst DialogDescription = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n className={cn(\"text-sm text-[var(--muted-foreground)]\", className)}\n {...props}\n />\n));\nDialogDescription.displayName = DialogPrimitive.Description.displayName;\n\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogTrigger,\n DialogClose,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n};\n","import { useEffect } from \"react\";\n\n// FieldRegion is an imperative handle for a named region of form fields.\n// Regions register themselves on mount and unregister on unmount. ui_steps\n// reference fields as \"{region}.{field}\" (e.g. \"quick_entry.body\").\nexport interface FieldRegion {\n getField: (fieldName: string) => unknown;\n setField: (fieldName: string, value: unknown) => void;\n focusField: (fieldName: string) => void;\n}\n\n// Module-scope registry. Declarion is a single-app SPA; a module-scope map is\n// simpler than threading context through every tree and matches how toast\n// (sonner) is already consumed.\nconst regions = new Map<string, FieldRegion>();\n\nexport function registerFieldRegion(name: string, region: FieldRegion): () => void {\n regions.set(name, region);\n return () => {\n // Only unregister if still the same instance (remount races).\n if (regions.get(name) === region) regions.delete(name);\n };\n}\n\nexport function getFieldRegion(name: string): FieldRegion | undefined {\n return regions.get(name);\n}\n\n// useFieldRegion is a convenience hook for components to register themselves\n// for the lifetime of the mount. The handle MUST be stable or wrapped in useMemo\n// to avoid re-registration on every render.\nexport function useFieldRegion(name: string, region: FieldRegion): void {\n useEffect(() => registerFieldRegion(name, region), [name, region]);\n}\n","import { toast } from \"sonner\";\nimport { getFieldRegion } from \"./field-regions\";\nimport type { UIStep } from \"@/types/schema\";\n\n// UIActionContext is everything a ui_step sequence may read from.\n// row: current record (populated for row_actions). May be undefined for global actions.\n// params: current action-modal form state, used to resolve {{params.X}} references\n// in HandlerParam.filter templates.\nexport interface UIActionContext {\n row?: Record<string, unknown>;\n params?: Record<string, unknown>;\n}\n\n// interpolate replaces `{{path}}` tokens with values from the context.\n// Supported paths:\n// {{row.FIELD}} - read from ctx.row[FIELD]\n// {{field.REGION.FIELD}} - read from a registered field region\n// {{params.NAME}} - read from ctx.params[NAME] (action modal form state)\n// Unknown tokens are replaced with an empty string. Whitespace around the path\n// inside the braces is ignored.\nexport function interpolate(template: string, ctx: UIActionContext): string {\n return template.replace(/\\{\\{\\s*([^}]+?)\\s*\\}\\}/g, (_match, path: string) => {\n const value = resolvePath(path, ctx);\n return value == null ? \"\" : String(value);\n });\n}\n\nfunction resolvePath(path: string, ctx: UIActionContext): unknown {\n const parts = path.split(\".\");\n if (parts.length < 2) return undefined;\n const [root, ...rest] = parts;\n if (root === \"row\") {\n if (!ctx.row) return undefined;\n return rest.reduce<unknown>((acc, key) => {\n if (acc && typeof acc === \"object\") return (acc as Record<string, unknown>)[key];\n return undefined;\n }, ctx.row);\n }\n if (root === \"field\" && rest.length >= 2) {\n const [regionName, fieldName] = rest;\n const region = getFieldRegion(regionName);\n return region?.getField(fieldName);\n }\n if (root === \"params\") {\n if (!ctx.params) return undefined;\n return rest.reduce<unknown>((acc, key) => {\n if (acc && typeof acc === \"object\") return (acc as Record<string, unknown>)[key];\n return undefined;\n }, ctx.params);\n }\n return undefined;\n}\n\n// executeUISteps runs the step sequence in order. Errors surface as toasts and\n// stop the sequence - a partial execution is preferable to silent failure\n// because the steps mutate client state.\nexport async function executeUISteps(steps: UIStep[], ctx: UIActionContext): Promise<void> {\n for (const step of steps) {\n try {\n await runStep(step, ctx);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n toast.error(`ui_step failed: ${msg}`);\n return;\n }\n }\n}\n\nasync function runStep(step: UIStep, ctx: UIActionContext): Promise<void> {\n if (step.copy_to_clipboard != null) {\n const value = interpolate(step.copy_to_clipboard, ctx);\n await navigator.clipboard.writeText(value);\n return;\n }\n if (step.set_field) {\n const { target, value } = step.set_field;\n const { region, field } = splitPath(target);\n const r = getFieldRegion(region);\n if (!r) throw new Error(`region \"${region}\" not registered`);\n r.setField(field, interpolate(value, ctx));\n return;\n }\n if (step.focus_field) {\n const { region, field } = splitPath(step.focus_field);\n const r = getFieldRegion(region);\n if (!r) throw new Error(`region \"${region}\" not registered`);\n r.focusField(field);\n return;\n }\n if (step.show_toast) {\n const msg = interpolate(step.show_toast.message, ctx);\n const kind = step.show_toast.kind ?? \"info\";\n if (kind === \"success\") toast.success(msg);\n else if (kind === \"error\") toast.error(msg);\n else toast(msg);\n return;\n }\n}\n\nfunction splitPath(path: string): { region: string; field: string } {\n const dot = path.indexOf(\".\");\n if (dot <= 0) throw new Error(`invalid path \"${path}\" (expected \"region.field\")`);\n return { region: path.slice(0, dot), field: path.slice(dot + 1) };\n}\n\n// isUIAction returns true when the action is a client-only ui_steps action.\nexport function isUIAction(action: { ui_steps?: UIStep[]; handler?: string }): boolean {\n return !action.handler && !!action.ui_steps && action.ui_steps.length > 0;\n}\n","import { useState, useCallback, useMemo } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from \"@/components/ui/dialog\";\nimport { Button } from \"@/components/ui/button\";\nimport { Label } from \"@/components/ui/label\";\nimport { renderField } from \"@/components/fields\";\nimport { loc } from \"@/types/schema\";\nimport type {\n Action,\n HandlerParam,\n EntityField,\n StatusDef,\n StatusGroupDef,\n} from \"@/types/schema\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { interpolate } from \"@/lib/ui-actions\";\n\ninterface ActionDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n action: Action;\n actionName: string;\n onSubmit: (params: Record<string, unknown>) => void;\n isPending: boolean;\n /**\n * Target record for default-value prefill via the `$row.<field>` template\n * syntax. When a param default is a string literal `$row.foo`, the dialog\n * substitutes `row.foo` at open time. For batch invocations on a list\n * page, pass the first selected row (or omit - callers that invoke the\n * action without a single-row context simply don't get row prefills).\n *\n * The substitution is client-side only. The server ignores template\n * syntax - it only sees the concrete value the admin submits.\n */\n row?: Record<string, unknown>;\n}\n\n// Regex for the supported prefill syntax: $row.<field>.\n// Matches only bare `$row.foo`, not `$row.foo.bar` (no nesting), not\n// `$user.foo`, not arbitrary expressions. Narrow on purpose - see the plan.\nconst ROW_PREFILL_RE = /^\\$row\\.([a-zA-Z_][a-zA-Z0-9_]*)$/;\n\nfunction resolveParamDefault(\n raw: unknown,\n row: Record<string, unknown> | undefined,\n): unknown {\n if (typeof raw !== \"string\") {\n return raw ?? \"\";\n }\n const match = raw.match(ROW_PREFILL_RE);\n if (!match) {\n return raw;\n }\n const field = match[1];\n if (row && field in row) {\n return row[field] ?? \"\";\n }\n // Template was requested but no row or no such field - fall back to empty.\n // Emits a dev-mode warning; the action dialog must not render \"$row.foo\"\n // literally into a text input.\n if (typeof console !== \"undefined\" && console.warn) {\n console.warn(\n `ActionDialog: prefill template ${raw} could not be resolved; row missing or has no field '${field}'`,\n );\n }\n return \"\";\n}\n\n/**\n * Converts a HandlerParam to an EntityField so we can reuse existing field renderers.\n */\nfunction paramToEntityField(param: HandlerParam): EntityField {\n return {\n type: param.type ?? \"string\",\n required: param.required,\n display: param.display\n ? {\n name: param.display.name ?? {},\n widget: param.display.widget,\n }\n : undefined,\n enum: param.enum,\n values: param.values,\n ref: param.ref ? { entity: param.ref } : undefined,\n };\n}\n\n// resolveFilterValue returns the current literal value for a filter key,\n// interpolating `{{params.X}}` templates against the current form state.\nfunction resolveFilterValue(\n raw: string,\n formData: Record<string, unknown>,\n): string {\n if (!raw.includes(\"{{\")) return raw;\n return interpolate(raw, { params: formData });\n}\n\n// Matches any {{ <path> }} token in a template string. Mirrors the\n// accepting form of `interpolate()` so dependency detection tolerates\n// the same whitespace variants (e.g. \"{{params.x}}\" and \"{{ params.x }}\").\nconst TEMPLATE_TOKEN_RE = /\\{\\{\\s*([^}]+?)\\s*\\}\\}/g;\n\n// referencesParam returns true when a filter template contains a\n// `{{params.<paramName>}}` reference (any whitespace). Used to decide\n// whether a sibling change should clear a dependent field's value.\nfunction referencesParam(template: string, paramName: string): boolean {\n const target = `params.${paramName}`;\n for (const match of template.matchAll(TEMPLATE_TOKEN_RE)) {\n if (match[1] === target) return true;\n }\n return false;\n}\n\ninterface StatusPickerProps {\n param: HandlerParam;\n value: unknown;\n onChange: (v: unknown) => void;\n statusGroups: Record<string, StatusGroupDef> | undefined;\n formData: Record<string, unknown>;\n}\n\n// StatusGroupPicker renders a dropdown of the entity's status_groups.\nfunction StatusGroupPicker({\n param,\n value,\n onChange,\n statusGroups,\n}: StatusPickerProps) {\n const entries = useMemo(\n () => (statusGroups ? Object.entries(statusGroups) : []),\n [statusGroups],\n );\n return (\n <select\n className=\"w-full rounded-md border border-[var(--border)] bg-[var(--background)] px-3 py-2 text-sm\"\n value={typeof value === \"string\" ? value : \"\"}\n onChange={(e) => onChange(e.target.value)}\n required={param.required}\n >\n <option value=\"\" disabled>\n {param.required ? \"Select status group...\" : \"-\"}\n </option>\n {entries.map(([code, group]) => (\n <option key={code} value={code}>\n {loc(group.name) || code}\n </option>\n ))}\n </select>\n );\n}\n\n// StatusPicker renders a dropdown of statuses, narrowed by param.filter.\nfunction StatusPicker({\n param,\n value,\n onChange,\n statusGroups,\n formData,\n}: StatusPickerProps) {\n const statuses: StatusDef[] = useMemo(() => {\n if (!statusGroups) return [];\n const groupKey = param.filter?.[\"status_group\"];\n if (groupKey) {\n const resolved = resolveFilterValue(groupKey, formData);\n if (resolved && statusGroups[resolved]) {\n return statusGroups[resolved].statuses;\n }\n // Filter declared but unresolved (sibling not yet chosen) - empty.\n return [];\n }\n // No filter: flatten all statuses across groups for \"change any status\" UX.\n return Object.values(statusGroups).flatMap((g) => g.statuses);\n }, [statusGroups, param.filter, formData]);\n\n return (\n <select\n className=\"w-full rounded-md border border-[var(--border)] bg-[var(--background)] px-3 py-2 text-sm\"\n value={typeof value === \"string\" ? value : \"\"}\n onChange={(e) => onChange(e.target.value)}\n required={param.required}\n disabled={statuses.length === 0}\n >\n <option value=\"\" disabled>\n {statuses.length === 0 ? \"Select status group first\" : \"Select status...\"}\n </option>\n {statuses.map((s) => (\n <option key={s.code} value={s.code}>\n {loc(s.name) || s.code}\n </option>\n ))}\n </select>\n );\n}\n\nexport function ActionDialog({\n open,\n onOpenChange,\n action,\n actionName,\n onSubmit,\n isPending,\n row,\n}: ActionDialogProps) {\n const { data: schema } = useSchema();\n const params = action.resolved_params ?? {};\n const hiddenDefaults = action.resolved_hidden_defaults ?? {};\n const paramEntries = useMemo(() => {\n const order = action.resolved_param_order;\n if (order && order.length > 0) {\n return order\n .filter((key) => key in params)\n .map((key) => [key, params[key]] as [string, typeof params[string]]);\n }\n return Object.entries(params);\n }, [params, action.resolved_param_order]);\n\n const entityStatusGroups = useMemo(() => {\n if (!action.entity || !schema) return undefined;\n return schema.entities[action.entity]?.status_groups;\n }, [action.entity, schema]);\n\n const buildInitialFormData = useCallback(() => {\n const initial: Record<string, unknown> = { ...hiddenDefaults };\n for (const [key, param] of paramEntries) {\n initial[key] = resolveParamDefault(param.default, row);\n }\n return initial;\n // hiddenDefaults is derived from action; stable across a single open.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [paramEntries, row]);\n\n const [formData, setFormData] = useState<Record<string, unknown>>(\n buildInitialFormData,\n );\n\n // Reset form when dialog opens.\n const handleOpenChange = useCallback(\n (isOpen: boolean) => {\n if (isOpen) {\n setFormData(buildInitialFormData());\n }\n onOpenChange(isOpen);\n },\n [onOpenChange, buildInitialFormData],\n );\n\n const handleFieldChange = useCallback((fieldName: string, value: unknown) => {\n setFormData((prev) => {\n const next = { ...prev, [fieldName]: value };\n // Cascading clear: when a status_group param changes, clear any\n // status param that filters by it so stale selections don't survive.\n // Matches the same whitespace tolerance as `interpolate()` so we\n // don't miss `{{ params.foo }}` variants that the UI accepts.\n for (const [key, param] of Object.entries(params)) {\n if (param.type !== \"status\") continue;\n const filterBy = param.filter?.[\"status_group\"];\n if (!filterBy) continue;\n if (referencesParam(filterBy, fieldName)) {\n next[key] = \"\";\n }\n }\n return next;\n });\n }, [params]);\n\n const handleSubmit = useCallback(() => {\n // Basic client-side validation: check required fields.\n for (const [key, param] of paramEntries) {\n if (param.required) {\n const val = formData[key];\n if (val == null || val === \"\") {\n return; // Don't submit if required field is empty.\n }\n }\n }\n onSubmit(formData);\n }, [formData, paramEntries, onSubmit]);\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogContent className=\"max-w-lg\">\n <DialogHeader>\n <DialogTitle>{actionName}</DialogTitle>\n <DialogDescription>Fill in the parameters below to execute this action.</DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 py-2\">\n {paramEntries.map(([key, param]) => {\n const paramName = loc(param.display?.name) || key;\n const label = (\n <Label>\n {paramName}\n {param.required && (\n <span className=\"text-[var(--destructive)] ml-0.5\">*</span>\n )}\n </Label>\n );\n\n let control: React.ReactNode;\n if (param.type === \"status_group\") {\n control = (\n <StatusGroupPicker\n param={param}\n value={formData[key]}\n onChange={(v) => handleFieldChange(key, v)}\n statusGroups={entityStatusGroups}\n formData={formData}\n />\n );\n } else if (param.type === \"status\") {\n control = (\n <StatusPicker\n param={param}\n value={formData[key]}\n onChange={(v) => handleFieldChange(key, v)}\n statusGroups={entityStatusGroups}\n formData={formData}\n />\n );\n } else {\n const field = paramToEntityField(param);\n control = renderField({\n field,\n fieldName: key,\n value: formData[key],\n mode: \"edit\",\n onChange: (v) => handleFieldChange(key, v),\n });\n }\n\n return (\n <div key={key} className=\"space-y-1.5\">\n {label}\n {control}\n {param.display?.description && (\n <p className=\"text-xs text-[var(--muted-foreground)]\">\n {loc(param.display.description)}\n </p>\n )}\n </div>\n );\n })}\n </div>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => onOpenChange(false)} disabled={isPending}>\n Cancel\n </Button>\n <Button onClick={handleSubmit} disabled={isPending}>\n {isPending ? \"Executing...\" : \"Execute\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n","import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from \"@/components/ui/alert-dialog\";\n\ninterface ActionConfirmDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n actionName: string;\n message: string;\n onConfirm: () => void;\n isPending: boolean;\n}\n\nexport function ActionConfirmDialog({\n open,\n onOpenChange,\n actionName,\n message,\n onConfirm,\n isPending,\n}: ActionConfirmDialogProps) {\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{actionName}</AlertDialogTitle>\n <AlertDialogDescription>{message}</AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isPending}>Cancel</AlertDialogCancel>\n <AlertDialogAction onClick={onConfirm} disabled={isPending}>\n {isPending ? \"Executing...\" : \"Confirm\"}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n","import {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from \"@/components/ui/dialog\";\nimport { Button } from \"@/components/ui/button\";\nimport { CopyButton } from \"./CopyButton\";\n\nexport interface DisplayField {\n label: string;\n value: string;\n copyable?: boolean;\n monospace?: boolean;\n}\n\nexport interface ActionDisplayResult {\n title?: string;\n message?: string;\n fields?: DisplayField[];\n}\n\ninterface ActionResultDialogProps {\n open: boolean;\n onClose: () => void;\n display: ActionDisplayResult;\n}\n\n// ActionResultDialog renders the $display result from a handler action.\n// Requires explicit close (no click-outside, no auto-dismiss) for sensitive data.\nexport function ActionResultDialog({ open, onClose, display }: ActionResultDialogProps) {\n return (\n <Dialog open={open} onOpenChange={(isOpen) => { if (!isOpen) onClose(); }}>\n <DialogContent className=\"max-w-lg\" onInteractOutside={(e) => e.preventDefault()} onEscapeKeyDown={(e) => e.preventDefault()}>\n <DialogHeader>\n <DialogTitle>{display.title ?? \"Action Result\"}</DialogTitle>\n {display.message && (\n <DialogDescription>{display.message}</DialogDescription>\n )}\n </DialogHeader>\n\n {display.fields && display.fields.length > 0 && (\n <div className=\"space-y-3 py-2\">\n {display.fields.map((field, i) => (\n <DisplayFieldRow key={i} field={field} />\n ))}\n </div>\n )}\n\n <DialogFooter>\n <Button onClick={onClose}>Close</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction DisplayFieldRow({ field }: { field: DisplayField }) {\n return (\n <div className=\"space-y-1\">\n <div className=\"text-sm font-medium text-[var(--muted-foreground)]\">\n {field.label}\n </div>\n <div className=\"flex items-center gap-2\">\n <div\n className={`flex-1 rounded-md border bg-[var(--muted)] px-3 py-2 text-sm break-all ${\n field.monospace ? \"font-mono\" : \"\"\n }`}\n >\n {field.value}\n </div>\n {field.copyable && <CopyButton value={field.value} />}\n </div>\n </div>\n );\n}\n","import type { Action, ActionCondition, Schema } from \"@/types/schema\";\n\n/**\n * Evaluates action conditions against row data.\n * Returns true if the action is available (all conditions pass).\n * An action with no conditions is always available.\n */\nexport function evaluateConditions(\n conditions: ActionCondition[] | undefined,\n row: Record<string, unknown>,\n): boolean {\n if (!conditions || conditions.length === 0) return true;\n\n for (const cond of conditions) {\n // Status-based conditions.\n if (cond.status && cond.status.length > 0) {\n const rowStatus = row.status;\n if (typeof rowStatus !== \"string\") return false;\n if (!cond.status.includes(rowStatus)) return false;\n }\n // Field-based conditions with operators.\n if (cond.field) {\n if (!evaluateFieldCondition(cond, row)) return false;\n }\n }\n return true;\n}\n\n/**\n * Evaluates a single field-based condition against row data.\n * Supports operators: eq, ne, gt, gte, lt, lte.\n * Defaults to \"eq\" when op is not specified.\n */\nfunction evaluateFieldCondition(\n cond: ActionCondition,\n row: Record<string, unknown>,\n): boolean {\n const fieldVal = row[cond.field!];\n const op = cond.op || \"eq\";\n\n // Boolean truthiness check: {field: \"is_active\", value: true/false}\n if (typeof cond.value === \"boolean\" && op === \"eq\") {\n return isTruthy(fieldVal) === cond.value;\n }\n\n // Numeric comparison when both values are numbers.\n if (typeof fieldVal === \"number\" && typeof cond.value === \"number\") {\n return compareValues(fieldVal, cond.value, op);\n }\n\n // String comparison (coerce to string).\n const fieldStr = fieldVal == null ? \"\" : String(fieldVal);\n const condStr = cond.value == null ? \"\" : String(cond.value);\n return compareValues(fieldStr, condStr, op);\n}\n\nfunction isTruthy(val: unknown): boolean {\n if (val == null) return false;\n if (typeof val === \"boolean\") return val;\n if (typeof val === \"string\") return val !== \"\";\n if (typeof val === \"number\") return val !== 0;\n return true;\n}\n\nfunction compareValues<T extends number | string>(a: T, b: T, op: string): boolean {\n switch (op) {\n case \"eq\": return a === b;\n case \"ne\": return a !== b;\n case \"gt\": return a > b;\n case \"gte\": return a >= b;\n case \"lt\": return a < b;\n case \"lte\": return a <= b;\n default: return false;\n }\n}\n\n/**\n * Returns actions from an entity whose visibility array contains the given\n * placement. Canonical values: detail | list_row | list_toolbar | app_menu |\n * nav_create | command_palette. Schema validator rejects unknown values at\n * load time so we don't need runtime alias handling here.\n */\nexport function getActionsByVisibility(\n actions: Record<string, Action> | undefined,\n visibility: string,\n): Array<{ code: string; action: Action }> {\n if (!actions) return [];\n return Object.entries(actions)\n .filter(([, action]) => action.visibility?.includes(visibility))\n .map(([code, action]) => ({ code, action }));\n}\n\n/**\n * Returns actions bound to a screen. When the screen defines explicit action/row_action\n * codes, only those are returned (resolved from entity.actions first, then global actions).\n * When no screen binding exists, falls back to visibility-based filtering.\n */\nexport function getScreenActions(\n entityActions: Record<string, Action> | undefined,\n screenActionCodes: string[] | undefined,\n fallbackVisibility: string,\n globalActions?: Record<string, Action>,\n): Array<{ code: string; action: Action }> {\n if (!entityActions && !globalActions) return [];\n if (screenActionCodes !== undefined) {\n return screenActionCodes\n .map((code) => {\n const action = entityActions?.[code] ?? globalActions?.[code];\n return action ? { code, action } : null;\n })\n .filter((item): item is { code: string; action: Action } => item !== null);\n }\n return getActionsByVisibility(entityActions, fallbackVisibility);\n}\n\n/**\n * Checks if an action has parameters that need user input.\n */\nexport function actionHasParams(action: Action): boolean {\n const params = action.resolved_params;\n if (!params) return false;\n return Object.keys(params).length > 0;\n}\n\n/**\n * Builds the full dot-qualified action code for API calls.\n */\nexport function fullActionCode(entityCode: string | undefined, actionCode: string): string {\n if (entityCode) return `${entityCode}.${actionCode}`;\n return actionCode;\n}\n\n/**\n * Checks if an action is an association navigation action.\n */\nexport function isAssociationAction(action: Action): boolean {\n return action.type === \"association\" && !!action.association;\n}\n\n/**\n * Finds the list screen route for a given entity code.\n * Returns the screen route and display info, or undefined if no list screen exists.\n */\nexport function findListScreenForEntity(\n schema: Schema | undefined,\n entityCode: string,\n): { route: string; icon: string } | undefined {\n if (!schema) return undefined;\n for (const screen of Object.values(schema.screens)) {\n if (screen.entity === entityCode && screen.type === \"list\") {\n const entity = schema.entities[entityCode];\n return {\n route: screen.route,\n icon: screen.display?.icon || entity?.display?.icon || \"\",\n };\n }\n }\n return undefined;\n}\n","import { useState, useCallback } from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\nimport { ActionDialog } from \"@/components/shared/ActionDialog\";\nimport { ActionConfirmDialog } from \"@/components/shared/ActionConfirmDialog\";\nimport { ActionResultDialog, type ActionDisplayResult } from \"@/components/shared/ActionResultDialog\";\nimport { useExecuteAction } from \"@/hooks/useMutations\";\nimport { buildActionBody } from \"@/api/data\";\nimport { evaluateConditions, actionHasParams, isAssociationAction, findListScreenForEntity } from \"@/lib/actions\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { useTabNavigate } from \"@/hooks/useTabNavigate\";\nimport { resolveAssociation } from \"@/api/data\";\nimport { toast } from \"sonner\";\nimport { loc } from \"@/types/schema\";\nimport type { Action } from \"@/types/schema\";\nimport { executeUISteps, isUIAction } from \"@/lib/ui-actions\";\n\ninterface ActionButtonProps {\n actionCode: string;\n action: Action;\n entityCode?: string;\n /** Selected object IDs (for single/batch scope). */\n objectIds?: string[];\n /** Current row data for condition evaluation (single row context). */\n row?: Record<string, unknown>;\n /** Variant for the button. */\n variant?: \"default\" | \"outline\" | \"ghost\" | \"secondary\";\n /** Size for the button. */\n size?: \"default\" | \"sm\" | \"icon\";\n /** Called after action execution succeeds. */\n onSuccess?: () => void;\n /** Called when a batch action starts executing. */\n onBatchStart?: (count: number) => void;\n /** Called when a batch action fails. */\n onBatchError?: (count: number) => void;\n /** Called when a batch action partially succeeds (some items failed/skipped). */\n onBatchPartial?: (count: number, successIds?: string[]) => void;\n}\n\nexport function ActionButton({\n actionCode,\n action,\n entityCode,\n objectIds = [],\n row,\n variant = \"outline\",\n size = \"default\",\n onSuccess,\n onBatchStart,\n onBatchError,\n onBatchPartial,\n}: ActionButtonProps) {\n const [showDialog, setShowDialog] = useState(false);\n const [showConfirm, setShowConfirm] = useState(false);\n const [navigating, setNavigating] = useState(false);\n const [displayResult, setDisplayResult] = useState<ActionDisplayResult | null>(null);\n const executeMutation = useExecuteAction(entityCode);\n const { data: schema } = useSchema();\n const tabNavigate = useTabNavigate();\n\n const isAssociation = isAssociationAction(action);\n const hasParams = actionHasParams(action);\n const hasConfirmation = !!action.confirmation && Object.keys(action.confirmation).length > 0;\n\n // Evaluate conditions - if row data is provided and conditions fail, disable button.\n const conditionsMet = row ? evaluateConditions(action.conditions, row) : true;\n\n // Scope-based disable: batch requires >= 1, single requires exactly 1.\n const isBatchEmpty = false;\n const isSingleInvalid = false;\n\n const handleAssociationNavigate = useCallback(async () => {\n if (!action.association || objectIds.length === 0) return;\n setNavigating(true);\n try {\n const assocCode = entityCode ? `${entityCode}.${action.association}` : action.association;\n const result = await resolveAssociation(assocCode, objectIds);\n const targetScreen = findListScreenForEntity(schema, result.target_entity);\n if (!targetScreen) {\n toast.error(`No list screen found for ${result.target_entity}`);\n return;\n }\n const targetEntity = schema?.entities[result.target_entity];\n const displayName = loc(action.display?.name) || result.target_entity;\n if (result.ids.length === 0) {\n toast.info(`No related ${displayName} found`);\n return;\n }\n // Navigate to target entity's list with ID filter.\n const pk = targetEntity?.field_order?.find((f) => targetEntity.fields[f]?.primary) ?? \"id\";\n const search = new URLSearchParams();\n search.set(`filter_${pk}`, result.ids.join(\",\"));\n tabNavigate(targetScreen.route, {\n title: displayName,\n icon: action.display?.icon || targetScreen.icon,\n search: search.toString(),\n });\n onSuccess?.();\n } catch (err) {\n toast.error(err instanceof Error ? err.message : \"Failed to resolve association\");\n } finally {\n setNavigating(false);\n }\n }, [action, entityCode, objectIds, schema, tabNavigate, onSuccess]);\n\n // Fully-qualified URL code: \"entity.action\" for entity-scoped, bare\n // \"action\" for globals. The entityCode prop is only used for cache\n // invalidation, not URL composition.\n const qualifiedActionCode = action.entity ? `${action.entity}.${actionCode}` : actionCode;\n // Only pass _ids when the scope is non-global.\n const actionIds = objectIds.length > 0 ? objectIds : undefined;\n\n // Shared success handler: checks for $display in the result and opens\n // ActionResultDialog instead of firing the regular onSuccess callback.\n const handleActionSuccess = useCallback(\n (result: { status: string; result?: unknown; success?: string[]; audit_operation_id?: string }, closeDialog?: () => void) => {\n closeDialog?.();\n // Async handler: enqueued for background execution.\n if (result.status === \"accepted\") {\n onSuccess?.();\n return;\n }\n // Check if the handler returned a $display result.\n const display = (result.result as Record<string, unknown> | undefined)?.$display as ActionDisplayResult | undefined;\n if (display) {\n setDisplayResult(display);\n return;\n }\n if (result.status === \"partial\") {\n onBatchPartial?.(objectIds.length, result.success);\n } else {\n onSuccess?.();\n }\n },\n [objectIds.length, onSuccess, onBatchPartial],\n );\n\n const handleClick = useCallback(() => {\n if (isUIAction(action)) {\n // Client-only action: run ui_steps sequentially. No server round-trip.\n void executeUISteps(action.ui_steps!, { row }).then(() => onSuccess?.());\n return;\n }\n if (isAssociation) {\n handleAssociationNavigate();\n return;\n }\n if (hasParams) {\n setShowDialog(true);\n } else if (hasConfirmation) {\n setShowConfirm(true);\n } else {\n // Execute immediately.\n onBatchStart?.(objectIds.length);\n executeMutation.mutate(\n { actionCode: qualifiedActionCode, body: buildActionBody(undefined, actionIds) },\n {\n onSuccess: (result) => handleActionSuccess(result),\n onError: () => onBatchError?.(objectIds.length),\n },\n );\n }\n }, [action, row, isAssociation, hasParams, hasConfirmation, qualifiedActionCode, actionIds, objectIds, executeMutation, handleActionSuccess, handleAssociationNavigate, onBatchStart, onBatchError, onSuccess]);\n\n const handleConfirm = useCallback(() => {\n onBatchStart?.(objectIds.length);\n executeMutation.mutate(\n { actionCode: qualifiedActionCode, body: buildActionBody(undefined, actionIds) },\n {\n onSuccess: (result) => handleActionSuccess(result, () => setShowConfirm(false)),\n onError: () => onBatchError?.(objectIds.length),\n },\n );\n }, [qualifiedActionCode, actionIds, objectIds, executeMutation, handleActionSuccess, onBatchStart, onBatchError]);\n\n const handleDialogSubmit = useCallback(\n (params: Record<string, unknown>) => {\n onBatchStart?.(objectIds.length);\n executeMutation.mutate(\n { actionCode: qualifiedActionCode, body: buildActionBody(params, actionIds) },\n {\n onSuccess: (result) => handleActionSuccess(result, () => setShowDialog(false)),\n onError: () => onBatchError?.(objectIds.length),\n },\n );\n },\n [qualifiedActionCode, actionIds, objectIds, executeMutation, handleActionSuccess, onBatchStart, onBatchError],\n );\n\n const displayName = loc(action.display?.name);\n const icon = action.display?.icon;\n\n return (\n <>\n <Button\n variant={variant}\n size={size}\n onClick={handleClick}\n disabled={!conditionsMet || isBatchEmpty || isSingleInvalid || executeMutation.isPending || navigating}\n title={displayName}\n aria-label={displayName}\n >\n {icon && <DynamicIcon name={icon} className=\"w-4 h-4\" />}\n {size !== \"icon\" && displayName}\n </Button>\n\n {hasParams && (\n <ActionDialog\n open={showDialog}\n onOpenChange={setShowDialog}\n action={action}\n actionName={displayName}\n onSubmit={handleDialogSubmit}\n isPending={executeMutation.isPending}\n row={row}\n />\n )}\n\n {hasConfirmation && (\n <ActionConfirmDialog\n open={showConfirm}\n onOpenChange={setShowConfirm}\n actionName={displayName}\n message={loc(action.confirmation)}\n onConfirm={handleConfirm}\n isPending={executeMutation.isPending}\n />\n )}\n\n {displayResult && (\n <ActionResultDialog\n open={!!displayResult}\n onClose={() => {\n setDisplayResult(null);\n onSuccess?.();\n }}\n display={displayResult}\n />\n )}\n </>\n );\n}\n","import { useState, useCallback } from \"react\";\nimport { DropdownMenuItem } from \"@/components/ui/dropdown-menu\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\nimport { ActionDialog } from \"@/components/shared/ActionDialog\";\nimport { ActionConfirmDialog } from \"@/components/shared/ActionConfirmDialog\";\nimport { useExecuteAction } from \"@/hooks/useMutations\";\nimport { evaluateConditions, actionHasParams, isAssociationAction, findListScreenForEntity } from \"@/lib/actions\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { useTabNavigate } from \"@/hooks/useTabNavigate\";\nimport { resolveAssociation, buildActionBody } from \"@/api/data\";\nimport { toast } from \"sonner\";\nimport { loc } from \"@/types/schema\";\nimport type { Action } from \"@/types/schema\";\n\ninterface RowActionItemProps {\n actionCode: string;\n action: Action;\n entityCode?: string;\n objectId: string;\n row: Record<string, unknown>;\n onSuccess?: () => void;\n}\n\nexport function RowActionItem({\n actionCode,\n action,\n entityCode,\n objectId,\n row,\n onSuccess,\n}: RowActionItemProps) {\n const [showDialog, setShowDialog] = useState(false);\n const [showConfirm, setShowConfirm] = useState(false);\n const executeMutation = useExecuteAction(entityCode);\n const { data: schema } = useSchema();\n const tabNavigate = useTabNavigate();\n\n const isAssociation = isAssociationAction(action);\n const hasParams = actionHasParams(action);\n const hasConfirmation = !!action.confirmation && Object.keys(action.confirmation).length > 0;\n const conditionsMet = evaluateConditions(action.conditions, row);\n\n const displayName = loc(action.display?.name);\n const icon = action.display?.icon;\n\n const handleAssociationNavigate = useCallback(async () => {\n if (!action.association) return;\n try {\n const assocCode = entityCode ? `${entityCode}.${action.association}` : action.association;\n const result = await resolveAssociation(assocCode, [objectId]);\n const targetScreen = findListScreenForEntity(schema, result.target_entity);\n if (!targetScreen) {\n toast.error(`No list screen found for ${result.target_entity}`);\n return;\n }\n const targetEntity = schema?.entities[result.target_entity];\n const name = loc(action.display?.name) || result.target_entity;\n if (result.ids.length === 0) {\n toast.info(`No related ${name} found`);\n return;\n }\n const pk = targetEntity?.field_order?.find((f) => targetEntity.fields[f]?.primary) ?? \"id\";\n const search = new URLSearchParams();\n search.set(`filter_${pk}`, result.ids.join(\",\"));\n tabNavigate(targetScreen.route, {\n title: name,\n icon: action.display?.icon || targetScreen.icon,\n search: search.toString(),\n });\n onSuccess?.();\n } catch (err) {\n toast.error(err instanceof Error ? err.message : \"Failed to resolve association\");\n }\n }, [action, entityCode, objectId, schema, tabNavigate, onSuccess]);\n\n // Use action.entity for the API code (global actions have no entity prefix).\n // The entityCode prop is only used for cache invalidation.\n const qualifiedActionCode = action.entity ? `${action.entity}.${actionCode}` : actionCode;\n\n const handleClick = useCallback(() => {\n if (isAssociation) {\n handleAssociationNavigate();\n return;\n }\n if (hasParams) {\n setShowDialog(true);\n } else if (hasConfirmation) {\n setShowConfirm(true);\n } else {\n executeMutation.mutate(\n { actionCode: qualifiedActionCode, body: buildActionBody(undefined, [objectId]) },\n { onSuccess },\n );\n }\n }, [isAssociation, hasParams, hasConfirmation, qualifiedActionCode, objectId, executeMutation, onSuccess, handleAssociationNavigate]);\n\n const handleConfirm = useCallback(() => {\n executeMutation.mutate(\n { actionCode: qualifiedActionCode, body: buildActionBody(undefined, [objectId]) },\n { onSuccess: () => { setShowConfirm(false); onSuccess?.(); } },\n );\n }, [qualifiedActionCode, objectId, executeMutation, onSuccess]);\n\n const handleDialogSubmit = useCallback(\n (params: Record<string, unknown>) => {\n executeMutation.mutate(\n { actionCode: qualifiedActionCode, body: buildActionBody(params, [objectId]) },\n { onSuccess: () => { setShowDialog(false); onSuccess?.(); } },\n );\n },\n [qualifiedActionCode, objectId, executeMutation, onSuccess],\n );\n\n return (\n <>\n <DropdownMenuItem\n onClick={handleClick}\n disabled={!conditionsMet}\n >\n {icon && <DynamicIcon name={icon} className=\"mr-2 h-4 w-4\" />}\n {displayName}\n </DropdownMenuItem>\n\n {hasParams && (\n <ActionDialog\n open={showDialog}\n onOpenChange={setShowDialog}\n action={action}\n actionName={displayName}\n onSubmit={handleDialogSubmit}\n isPending={executeMutation.isPending}\n />\n )}\n\n {hasConfirmation && (\n <ActionConfirmDialog\n open={showConfirm}\n onOpenChange={setShowConfirm}\n actionName={displayName}\n message={loc(action.confirmation)}\n onConfirm={handleConfirm}\n isPending={executeMutation.isPending}\n />\n )}\n </>\n );\n}\n","import { Loader2, CheckCircle2, XCircle, AlertTriangle } from \"lucide-react\";\n\ninterface BatchActionProgressProps {\n /** Number of items being processed. */\n count: number;\n /** Whether the action is currently executing. */\n isPending: boolean;\n /** Whether the last execution succeeded. */\n isSuccess?: boolean;\n /** Whether the last execution errored. */\n isError?: boolean;\n /** Whether the last execution partially succeeded (some items failed/skipped). */\n isPartial?: boolean;\n}\n\n/**\n * Inline progress indicator for batch actions.\n * Shows selected count, a spinner during execution, and success/error/partial state.\n */\nexport function BatchActionProgress({\n count,\n isPending,\n isSuccess,\n isError,\n isPartial,\n}: BatchActionProgressProps) {\n if (count === 0 && !isPending && !isSuccess && !isError && !isPartial) return null;\n\n return (\n <div className=\"flex items-center gap-2 text-sm text-[var(--muted-foreground)]\">\n {isPending && (\n <>\n <Loader2 className=\"w-4 h-4 animate-spin\" />\n <span>Processing {count} {count === 1 ? \"item\" : \"items\"}...</span>\n </>\n )}\n {!isPending && isSuccess && (\n <>\n <CheckCircle2 className=\"w-4 h-4 text-green-600\" />\n <span>{count} {count === 1 ? \"item\" : \"items\"} processed</span>\n </>\n )}\n {!isPending && isPartial && (\n <>\n <AlertTriangle className=\"w-4 h-4 text-yellow-600\" />\n <span>Partially completed - some items failed or were skipped</span>\n </>\n )}\n {!isPending && isError && (\n <>\n <XCircle className=\"w-4 h-4 text-[var(--destructive)]\" />\n <span>Failed to process {count} {count === 1 ? \"item\" : \"items\"}</span>\n </>\n )}\n {!isPending && !isSuccess && !isError && !isPartial && count > 0 && (\n <span>{count} {count === 1 ? \"item\" : \"items\"} selected</span>\n )}\n </div>\n );\n}\n","/**\n * Filter system types and utilities.\n * One JSON format everywhere: API, URL, DB, frontend state.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** A single node in the recursive filter tree. */\nexport interface FilterNode {\n /** Field condition */\n field?: string;\n op?: FilterOp;\n value?: unknown; // string | number | string[] | number[] | null\n\n /** OR group: each inner array is AND-ed, groups are OR-ed */\n or?: FilterNode[][];\n /** Explicit AND group (rarely needed, top-level is implicit AND) */\n and?: FilterNode[];\n}\n\n/** All supported filter operator codes. */\nexport type FilterOp =\n | \"eq\" | \"not_eq\"\n | \"gt\" | \"gte\" | \"lt\" | \"lte\"\n | \"in\" | \"not_in\" | \"between\"\n | \"contains\" | \"starts_with\"\n | \"is_empty\" | \"is_not_empty\"\n | \"today\" | \"this_week\" | \"this_month\"\n | \"last_7_days\" | \"last_30_days\"\n | \"last_hour\" | \"last_24_hours\";\n\n/** Operators that don't take a value. */\nexport const NO_VALUE_OPS = new Set<FilterOp>([\n \"is_empty\", \"is_not_empty\",\n \"today\", \"this_week\", \"this_month\",\n \"last_7_days\", \"last_30_days\",\n \"last_hour\", \"last_24_hours\",\n]);\n\n/** Human-friendly display names for operators. */\nexport const OP_LABELS: Record<FilterOp, string> = {\n eq: \"is\",\n not_eq: \"is not\",\n gt: \">\",\n gte: \">=\",\n lt: \"<\",\n lte: \"<=\",\n in: \"is any of\",\n not_in: \"is none of\",\n between: \"between\",\n contains: \"contains\",\n starts_with: \"starts with\",\n is_empty: \"is empty\",\n is_not_empty: \"is not empty\",\n today: \"today\",\n this_week: \"this week\",\n this_month: \"this month\",\n last_7_days: \"last 7 days\",\n last_30_days: \"last 30 days\",\n last_hour: \"last hour\",\n last_24_hours: \"last 24 hours\",\n};\n\n// ---------------------------------------------------------------------------\n// URL serialization\n// ---------------------------------------------------------------------------\n\n/** Parse filters from URL search params (JSON `filters` param). */\nexport function parseFiltersFromURL(searchParams: URLSearchParams): FilterNode[] {\n const raw = searchParams.get(\"filters\");\n if (!raw) return [];\n try {\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed) ? parsed : [];\n } catch {\n return [];\n }\n}\n\n/** Write filters to URL search params. */\nexport function setFiltersInURL(\n filters: FilterNode[],\n searchParams: URLSearchParams,\n): void {\n if (filters.length === 0) {\n searchParams.delete(\"filters\");\n } else {\n searchParams.set(\"filters\", JSON.stringify(filters));\n }\n}\n\n// ---------------------------------------------------------------------------\n// API conversion\n// ---------------------------------------------------------------------------\n\n/**\n * Convert FilterNode array to API query params.\n * Uses the JSON `filters` param for the API request.\n */\nexport function filtersToApiParams(filters: FilterNode[]): URLSearchParams {\n const params = new URLSearchParams();\n if (filters.length > 0) {\n params.set(\"filters\", JSON.stringify(filters));\n }\n return params;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Check if the filter tree has any OR groups (needs Level 2 UI). */\nexport function hasOrGroups(nodes: FilterNode[]): boolean {\n return nodes.some((n) => n.or != null);\n}\n\n/** Extract flat field conditions from a FilterNode array (ignoring OR/AND structure). */\nexport function flatFieldConditions(nodes: FilterNode[]): FilterNode[] {\n const result: FilterNode[] = [];\n for (const n of nodes) {\n if (n.field && n.op) {\n result.push(n);\n }\n if (n.or) {\n for (const group of n.or) {\n result.push(...flatFieldConditions(group));\n }\n }\n if (n.and) {\n result.push(...flatFieldConditions(n.and));\n }\n }\n return result;\n}\n\n/** Count active field conditions in the filter tree. */\nexport function countActiveFilters(nodes: FilterNode[]): number {\n return flatFieldConditions(nodes).length;\n}\n\n/** Format a filter node for chip display. */\nexport function formatFilterChip(node: FilterNode): string {\n if (!node.field || !node.op) return \"\";\n const label = OP_LABELS[node.op] || node.op;\n if (NO_VALUE_OPS.has(node.op)) {\n return `${label}`;\n }\n const val = Array.isArray(node.value)\n ? node.value.join(\", \")\n : String(node.value ?? \"\");\n return `${label} ${val}`;\n}\n\n/** Create a simple equality filter node. */\nexport function eqFilter(field: string, value: string): FilterNode {\n return { field, op: \"eq\", value };\n}\n\n/** Remove a filter node by field name, recursing into OR/AND groups. */\nexport function removeFilter(nodes: FilterNode[], field: string): FilterNode[] {\n const result: FilterNode[] = [];\n for (const n of nodes) {\n if (n.field === field) continue;\n if (n.or) {\n const cleaned = n.or\n .map((group) => removeFilter(group, field))\n .filter((group) => group.length > 0);\n if (cleaned.length > 0) result.push({ ...n, or: cleaned });\n continue;\n }\n if (n.and) {\n const cleaned = removeFilter(n.and, field);\n if (cleaned.length > 0) result.push({ ...n, and: cleaned });\n continue;\n }\n result.push(n);\n }\n return result;\n}\n","import { useMemo, useCallback } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\nimport {\n type FilterNode,\n parseFiltersFromURL,\n setFiltersInURL,\n countActiveFilters,\n} from \"@/lib/filters\";\n\n/**\n * useFilters reads/writes the JSON `filters` URL param.\n * URL is the source of truth.\n */\nexport function useFilters() {\n const [searchParams, setSearchParams] = useSearchParams();\n\n const filters = useMemo<FilterNode[]>(\n () => parseFiltersFromURL(searchParams),\n [searchParams],\n );\n\n const activeCount = useMemo(() => countActiveFilters(filters), [filters]);\n\n const setFilters = useCallback(\n (newFilters: FilterNode[]) => {\n const next = new URLSearchParams(searchParams);\n setFiltersInURL(newFilters, next);\n next.set(\"page\", \"1\");\n setSearchParams(next);\n },\n [searchParams, setSearchParams],\n );\n\n const clearFilters = useCallback(() => {\n const next = new URLSearchParams(searchParams);\n next.delete(\"filters\");\n next.set(\"page\", \"1\");\n setSearchParams(next);\n }, [searchParams, setSearchParams]);\n\n return { filters, activeCount, setFilters, clearFilters };\n}\n","import { X } from \"lucide-react\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n type FilterNode,\n hasOrGroups,\n flatFieldConditions,\n OP_LABELS,\n NO_VALUE_OPS,\n} from \"@/lib/filters\";\n\ninterface FilterChipsProps {\n filters: FilterNode[];\n onRemove: (field: string) => void;\n onClearAll: () => void;\n onChipClick?: () => void;\n /** Resolve field name to display label */\n fieldLabel?: (field: string) => string;\n}\n\n/**\n * FilterChips shows active filters as compact chips between toolbar and table.\n * Simple mode: flat chips. OR mode: grouped chips.\n * Zero active filters = hidden (zero height).\n */\nexport function FilterChips({\n filters,\n onRemove,\n onClearAll,\n onChipClick,\n fieldLabel = (f) => f,\n}: FilterChipsProps) {\n if (filters.length === 0) return null;\n\n const isOrMode = hasOrGroups(filters);\n\n if (isOrMode) {\n return (\n <div className=\"flex items-center gap-2 flex-wrap pb-3\">\n {filters.map((node, i) => {\n if (node.or) {\n return (\n <div key={i} className=\"flex items-center gap-1\">\n {node.or.map((group, gi) => (\n <span key={gi} className=\"flex items-center gap-1\">\n {gi > 0 && (\n <span className=\"text-xs text-[var(--muted-foreground)] font-medium px-1\">\n OR\n </span>\n )}\n <Badge\n variant=\"secondary\"\n className=\"cursor-pointer text-xs\"\n onClick={onChipClick}\n >\n {group\n .filter((n) => n.field && n.op)\n .map((n) => `${fieldLabel(n.field!)} ${formatValue(n)}`)\n .join(\" AND \")}\n </Badge>\n </span>\n ))}\n </div>\n );\n }\n if (node.field && node.op) {\n return (\n <FilterChip\n key={`${node.field}-${i}`}\n node={node}\n fieldLabel={fieldLabel}\n onRemove={() => onRemove(node.field!)}\n onClick={onChipClick}\n />\n );\n }\n return null;\n })}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onClearAll}\n className=\"h-6 px-2 text-xs text-[var(--muted-foreground)]\"\n >\n <X className=\"w-3 h-3 mr-1\" />\n Clear all\n </Button>\n </div>\n );\n }\n\n // Simple mode: flat chips.\n const fieldNodes = flatFieldConditions(filters);\n return (\n <div className=\"flex items-center gap-2 flex-wrap pb-3\">\n {fieldNodes.map((node, i) => (\n <FilterChip\n key={`${node.field}-${i}`}\n node={node}\n fieldLabel={fieldLabel}\n onRemove={() => onRemove(node.field!)}\n onClick={onChipClick}\n />\n ))}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onClearAll}\n className=\"h-6 px-2 text-xs text-[var(--muted-foreground)]\"\n >\n <X className=\"w-3 h-3 mr-1\" />\n Clear all\n </Button>\n </div>\n );\n}\n\nfunction FilterChip({\n node,\n fieldLabel,\n onRemove,\n onClick,\n}: {\n node: FilterNode;\n fieldLabel: (f: string) => string;\n onRemove: () => void;\n onClick?: () => void;\n}) {\n return (\n <Badge\n variant=\"secondary\"\n className=\"cursor-pointer text-xs gap-1 pr-1\"\n >\n <span onClick={onClick}>\n {fieldLabel(node.field!)}:{\" \"}\n <span className=\"font-normal\">{formatValue(node)}</span>\n </span>\n <button\n onClick={(e) => {\n e.stopPropagation();\n onRemove();\n }}\n className=\"ml-1 hover:text-[var(--destructive)] rounded-full\"\n >\n <X className=\"w-3 h-3\" />\n </button>\n </Badge>\n );\n}\n\nfunction formatValue(node: FilterNode): string {\n if (!node.op) return \"\";\n const label = OP_LABELS[node.op] || node.op;\n if (NO_VALUE_OPS.has(node.op)) return label;\n const val = Array.isArray(node.value)\n ? node.value.join(\", \")\n : String(node.value ?? \"\");\n return `${label} ${val}`;\n}\n","import { useState, useEffect } from \"react\";\nimport { X, Plus, Filter } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport {\n type FilterNode,\n type FilterOp,\n OP_LABELS,\n NO_VALUE_OPS,\n hasOrGroups,\n} from \"@/lib/filters\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface FilterFieldMeta {\n code: string;\n label: string;\n type: \"string\" | \"enum\" | \"int\" | \"float\" | \"date\" | \"timestamp\" | \"bool\" | \"ref\" | \"status\" | \"property\" | string;\n operators: FilterOp[];\n /** Enum values for enum/status fields. */\n options?: { value: string; label: string; color?: string }[];\n}\n\ninterface FilterDrawerProps {\n open: boolean;\n onClose: () => void;\n filters: FilterNode[];\n onApply: (filters: FilterNode[]) => void;\n availableFields: FilterFieldMeta[];\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * FilterDrawer - right-side panel with progressive disclosure.\n * Level 1: flat AND conditions (default).\n * Level 2: OR groups when \"Add OR group\" is clicked.\n */\nexport function FilterDrawer({\n open,\n onClose,\n filters,\n onApply,\n availableFields,\n}: FilterDrawerProps) {\n // Local state for editing (apply on button click).\n const [draft, setDraft] = useState<FilterNode[]>(filters);\n const [showFieldPicker, setShowFieldPicker] = useState(false);\n\n // Sync draft when filters change externally or drawer opens.\n useEffect(() => {\n if (open) setDraft(filters);\n }, [open, filters]);\n\n if (!open) return null;\n\n const isOrMode = hasOrGroups(draft);\n\n // Active field codes (for hiding in \"Add filter\" picker).\n const activeFields = new Set(\n draft.filter((n) => n.field).map((n) => n.field!),\n );\n\n const addCondition = (fieldCode: string) => {\n const meta = availableFields.find((f) => f.code === fieldCode);\n if (!meta) return;\n const defaultOp = meta.operators[0] || \"eq\";\n setDraft([...draft, { field: fieldCode, op: defaultOp }]);\n setShowFieldPicker(false);\n };\n\n const updateCondition = (index: number, updates: Partial<FilterNode>) => {\n setDraft(draft.map((n, i) => (i === index ? { ...n, ...updates } : n)));\n };\n\n const removeCondition = (index: number) => {\n setDraft(draft.filter((_, i) => i !== index));\n };\n\n const addOrGroup = () => {\n // Convert flat conditions to first OR group, add empty second group.\n const currentConditions = draft.filter((n) => n.field && n.op);\n const otherNodes = draft.filter((n) => !n.field || !n.op);\n setDraft([\n ...otherNodes,\n {\n or: [\n currentConditions.length > 0 ? currentConditions : [],\n [],\n ],\n },\n ]);\n };\n\n const handleApply = () => {\n // Remove empty conditions (without mutating draft in place).\n const cleaned = draft\n .map((n) => {\n if (n.or) {\n const filteredOr = n.or.filter((g) => g.length > 0);\n return filteredOr.length > 0 ? { ...n, or: filteredOr } : null;\n }\n return n.field && n.op ? n : null;\n })\n .filter((n): n is FilterNode => n !== null);\n onApply(cleaned);\n onClose();\n };\n\n const handleReset = () => {\n setDraft([]);\n };\n\n return (\n <div className=\"fixed inset-y-0 right-0 w-[400px] max-w-full bg-[var(--background)] border-l border-[var(--border)] shadow-lg z-50 flex flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-[var(--border)]\">\n <div className=\"flex items-center gap-2\">\n <Filter className=\"w-4 h-4\" />\n <h3 className=\"font-semibold text-sm\">Filters</h3>\n </div>\n <Button variant=\"ghost\" size=\"icon\" onClick={onClose} className=\"h-8 w-8\">\n <X className=\"w-4 h-4\" />\n </Button>\n </div>\n\n {/* Body */}\n <div className=\"flex-1 overflow-auto p-4 space-y-3\">\n {!isOrMode ? (\n // Level 1: flat AND conditions.\n <>\n {draft.map((node, i) => {\n if (!node.field || !node.op) return null;\n const meta = availableFields.find((f) => f.code === node.field);\n if (!meta) return null;\n return (\n <FilterRow\n key={`${node.field}-${i}`}\n node={node}\n meta={meta}\n onUpdate={(updates) => updateCondition(i, updates)}\n onRemove={() => removeCondition(i)}\n />\n );\n })}\n </>\n ) : (\n // Level 2: OR groups.\n draft.map((node, i) => {\n if (!node.or) {\n if (!node.field || !node.op) return null;\n const meta = availableFields.find((f) => f.code === node.field);\n if (!meta) return null;\n return (\n <FilterRow\n key={`${node.field}-${i}`}\n node={node}\n meta={meta}\n onUpdate={(updates) => updateCondition(i, updates)}\n onRemove={() => removeCondition(i)}\n />\n );\n }\n return (\n <OrGroupEditor\n key={`or-${i}`}\n groups={node.or}\n availableFields={availableFields}\n onChange={(newGroups) => {\n const newDraft = [...draft];\n newDraft[i] = { or: newGroups };\n setDraft(newDraft);\n }}\n />\n );\n })\n )}\n\n {/* Add filter / Add OR group buttons */}\n <div className=\"flex items-center gap-2 pt-2\">\n {showFieldPicker ? (\n <FieldPicker\n fields={availableFields}\n activeFields={activeFields}\n onSelect={addCondition}\n onCancel={() => setShowFieldPicker(false)}\n />\n ) : (\n <>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setShowFieldPicker(true)}\n >\n <Plus className=\"w-3 h-3 mr-1\" />\n Add filter\n </Button>\n {!isOrMode && draft.some((n) => n.field) && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={addOrGroup}\n className=\"text-[var(--muted-foreground)]\"\n >\n <Plus className=\"w-3 h-3 mr-1\" />\n Add OR group\n </Button>\n )}\n </>\n )}\n </div>\n </div>\n\n {/* Footer */}\n <div className=\"flex items-center justify-between px-4 py-3 border-t border-[var(--border)]\">\n <Button variant=\"ghost\" size=\"sm\" onClick={handleReset}>\n Reset\n </Button>\n <Button size=\"sm\" onClick={handleApply}>\n Apply\n </Button>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\nfunction FilterRow({\n node,\n meta,\n onUpdate,\n onRemove,\n}: {\n node: FilterNode;\n meta: FilterFieldMeta;\n onUpdate: (updates: Partial<FilterNode>) => void;\n onRemove: () => void;\n}) {\n const isNoValue = NO_VALUE_OPS.has(node.op as FilterOp);\n\n return (\n <div className=\"flex items-center gap-2 group\">\n <span className=\"text-sm font-medium min-w-[100px] truncate\">\n {meta.label}\n </span>\n <Select\n value={node.op}\n onValueChange={(op) => onUpdate({ op: op as FilterOp })}\n >\n <SelectTrigger className=\"w-[130px] h-8 text-xs\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {meta.operators.map((op) => (\n <SelectItem key={op} value={op} className=\"text-xs\">\n {OP_LABELS[op] || op}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n {!isNoValue && (\n meta.options ? (\n <Select\n value={String(node.value ?? \"\")}\n onValueChange={(v) => onUpdate({ value: v })}\n >\n <SelectTrigger className=\"flex-1 h-8 text-xs\">\n <SelectValue placeholder=\"Select...\" />\n </SelectTrigger>\n <SelectContent>\n {meta.options.map((opt) => (\n <SelectItem key={opt.value} value={opt.value} className=\"text-xs\">\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : (\n <Input\n className=\"flex-1 h-8 text-xs\"\n value={String(node.value ?? \"\")}\n onChange={(e) => onUpdate({ value: e.target.value })}\n placeholder=\"Value...\"\n />\n )\n )}\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity\"\n onClick={onRemove}\n >\n <X className=\"w-3 h-3\" />\n </Button>\n </div>\n );\n}\n\nfunction OrGroupEditor({\n groups,\n availableFields,\n onChange,\n}: {\n groups: FilterNode[][];\n availableFields: FilterFieldMeta[];\n onChange: (groups: FilterNode[][]) => void;\n}) {\n return (\n <div className=\"space-y-2\">\n {groups.map((group, gi) => (\n <div key={gi}>\n {gi > 0 && (\n <div className=\"flex items-center gap-2 py-1\">\n <div className=\"flex-1 border-t border-[var(--border)]\" />\n <span className=\"text-xs font-medium text-[var(--muted-foreground)] px-2\">\n OR\n </span>\n <div className=\"flex-1 border-t border-[var(--border)]\" />\n </div>\n )}\n <div className=\"border border-[var(--border)] rounded-md p-3 space-y-2\">\n <div className=\"text-xs text-[var(--muted-foreground)] font-medium mb-2\">\n Match ALL\n </div>\n {group.map((node, ni) => {\n const meta = availableFields.find((f) => f.code === node.field);\n if (!meta) return null;\n return (\n <FilterRow\n key={`${node.field}-${ni}`}\n node={node}\n meta={meta}\n onUpdate={(updates) => {\n const newGroups = groups.map((g, i) =>\n i === gi\n ? g.map((n, j) => (j === ni ? { ...n, ...updates } : n))\n : g,\n );\n onChange(newGroups);\n }}\n onRemove={() => {\n const newGroups = groups.map((g, i) =>\n i === gi ? g.filter((_, j) => j !== ni) : g,\n );\n // Remove empty groups, collapse back to flat if one group.\n onChange(newGroups.filter((g) => g.length > 0));\n }}\n />\n );\n })}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={() => {\n // Placeholder - needs field picker for this group.\n const firstAvailable = availableFields.find(\n (f) => !group.some((n) => n.field === f.code),\n );\n if (firstAvailable) {\n const newGroups = groups.map((g, i) =>\n i === gi\n ? [...g, { field: firstAvailable.code, op: firstAvailable.operators[0] || (\"eq\" as FilterOp) }]\n : g,\n );\n onChange(newGroups);\n }\n }}\n >\n <Plus className=\"w-3 h-3 mr-1\" />\n Add condition\n </Button>\n </div>\n </div>\n ))}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs text-[var(--muted-foreground)]\"\n onClick={() => onChange([...groups, []])}\n >\n <Plus className=\"w-3 h-3 mr-1\" />\n Add OR group\n </Button>\n </div>\n );\n}\n\nfunction FieldPicker({\n fields,\n activeFields,\n onSelect,\n onCancel,\n}: {\n fields: FilterFieldMeta[];\n activeFields: Set<string>;\n onSelect: (code: string) => void;\n onCancel: () => void;\n}) {\n const [search, setSearch] = useState(\"\");\n const filtered = fields.filter(\n (f) =>\n !activeFields.has(f.code) &&\n (search === \"\" || f.label.toLowerCase().includes(search.toLowerCase()) || f.code.toLowerCase().includes(search.toLowerCase())),\n );\n\n return (\n <div className=\"w-full border border-[var(--border)] rounded-md p-2 space-y-2\">\n <Input\n className=\"h-7 text-xs\"\n placeholder=\"Search fields...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n autoFocus\n />\n <div className=\"max-h-[200px] overflow-auto space-y-0.5\">\n {filtered.map((f) => (\n <button\n key={f.code}\n className=\"w-full text-left px-2 py-1 text-xs rounded hover:bg-[var(--muted)] transition-colors\"\n onClick={() => onSelect(f.code)}\n >\n {f.label}\n <span className=\"text-[var(--muted-foreground)] ml-2\">{f.code}</span>\n </button>\n ))}\n {filtered.length === 0 && (\n <div className=\"text-xs text-[var(--muted-foreground)] px-2 py-1\">\n No fields available\n </div>\n )}\n </div>\n <Button variant=\"ghost\" size=\"sm\" className=\"text-xs w-full\" onClick={onCancel}>\n Cancel\n </Button>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { Columns3, Check, RotateCcw } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface ColumnPickerProps {\n availableColumns: string[];\n visibleColumns: string[];\n onToggle: (col: string) => void;\n onReset: () => void;\n onShowAll: () => void;\n /** Resolve column code to display label */\n columnLabel?: (code: string) => string;\n}\n\n/**\n * ColumnPicker - popover-style checklist for toggling column visibility.\n * Drag-reorder deferred to later phase (using @dnd-kit).\n */\nexport function ColumnPicker({\n availableColumns,\n visibleColumns,\n onToggle,\n onReset,\n onShowAll,\n columnLabel = (c) => c,\n}: ColumnPickerProps) {\n const [open, setOpen] = useState(false);\n\n return (\n <div className=\"relative\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setOpen(!open)}\n className=\"h-8\"\n >\n <Columns3 className=\"w-4 h-4 mr-1.5\" />\n Columns\n </Button>\n\n {open && (\n <>\n {/* Backdrop */}\n <div\n className=\"fixed inset-0 z-40\"\n onClick={() => setOpen(false)}\n />\n {/* Popover */}\n <div className=\"absolute right-0 top-full mt-1 w-[250px] bg-[var(--background)] border border-[var(--border)] rounded-md shadow-lg z-50 py-1\">\n <div className=\"max-h-[300px] overflow-auto\">\n {availableColumns.map((col) => {\n const isVisible = visibleColumns.includes(col);\n return (\n <button\n key={col}\n className=\"flex items-center w-full px-3 py-1.5 text-sm hover:bg-[var(--muted)] transition-colors text-left\"\n onClick={() => onToggle(col)}\n >\n <span className=\"w-5 h-5 mr-2 flex items-center justify-center\">\n {isVisible && <Check className=\"w-4 h-4 text-[var(--primary)]\" />}\n </span>\n <span className={isVisible ? \"\" : \"text-[var(--muted-foreground)]\"}>\n {columnLabel(col)}\n </span>\n </button>\n );\n })}\n </div>\n <div className=\"border-t border-[var(--border)] px-2 py-1.5 flex items-center gap-1\">\n <Button variant=\"ghost\" size=\"sm\" className=\"text-xs h-7 flex-1\" onClick={onReset}>\n <RotateCcw className=\"w-3 h-3 mr-1\" />\n Reset\n </Button>\n <Button variant=\"ghost\" size=\"sm\" className=\"text-xs h-7 flex-1\" onClick={onShowAll}>\n Show all\n </Button>\n </div>\n </div>\n </>\n )}\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { ChevronDown, Star, Globe, Save, Plus } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { loc } from \"@/types/schema\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ViewItem {\n /** UUID for DB views, code string for system views */\n id: string;\n name: Record<string, string>;\n icon?: string;\n source: \"system\" | \"personal\" | \"shared\";\n is_default?: boolean;\n filters?: unknown[];\n columns?: string[];\n sort?: string;\n}\n\ninterface ViewSwitcherProps {\n views: ViewItem[];\n activeViewId: string | null;\n isDirty: boolean;\n onSelect: (view: ViewItem) => void;\n onSave?: () => void;\n onSaveAs?: () => void;\n onSetDefault?: (viewId: string) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * ViewSwitcher - dropdown at the top of list pages.\n * Shows system views (presets) + personal/shared DB views.\n * \"Save View\" button appears when dirty.\n */\nexport function ViewSwitcher({\n views,\n activeViewId,\n isDirty,\n onSelect,\n onSave,\n onSaveAs,\n onSetDefault,\n}: ViewSwitcherProps) {\n const [open, setOpen] = useState(false);\n\n const activeView = views.find((v) => v.id === activeViewId);\n const systemViews = views.filter((v) => v.source === \"system\");\n const personalViews = views.filter((v) => v.source === \"personal\");\n const sharedViews = views.filter((v) => v.source === \"shared\");\n\n const displayName = activeView\n ? loc(activeView.name)\n : \"Default view\";\n\n return (\n <div className=\"flex items-center gap-2\">\n <div className=\"relative\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setOpen(!open)}\n className=\"h-8 gap-1.5\"\n >\n {displayName}\n {isDirty && (\n <span className=\"w-2 h-2 rounded-full bg-[var(--primary)]\" />\n )}\n <ChevronDown className=\"w-3 h-3\" />\n </Button>\n\n {open && (\n <>\n <div\n className=\"fixed inset-0 z-40\"\n onClick={() => setOpen(false)}\n />\n <div className=\"absolute left-0 top-full mt-1 w-[280px] bg-[var(--background)] border border-[var(--border)] rounded-md shadow-lg z-50 py-1\">\n {/* Default (no view) */}\n <ViewOption\n label=\"Default view\"\n isActive={!activeViewId}\n onClick={() => {\n onSelect({ id: \"\", name: { en: \"Default\" }, source: \"system\" });\n setOpen(false);\n }}\n />\n\n {systemViews.length > 0 && (\n <>\n <div className=\"px-3 py-1 text-xs text-[var(--muted-foreground)] font-medium\">\n Presets\n </div>\n {systemViews.map((v) => (\n <ViewOption\n key={v.id}\n label={loc(v.name)}\n isActive={activeViewId === v.id}\n onClick={() => {\n onSelect(v);\n setOpen(false);\n }}\n />\n ))}\n </>\n )}\n\n {personalViews.length > 0 && (\n <>\n <div className=\"px-3 py-1 text-xs text-[var(--muted-foreground)] font-medium\">\n My Views\n </div>\n {personalViews.map((v) => (\n <ViewOption\n key={v.id}\n label={loc(v.name)}\n isActive={activeViewId === v.id}\n isDefault={v.is_default}\n onSetDefault={onSetDefault ? () => onSetDefault(v.id) : undefined}\n onClick={() => {\n onSelect(v);\n setOpen(false);\n }}\n />\n ))}\n </>\n )}\n\n {sharedViews.length > 0 && (\n <>\n <div className=\"px-3 py-1 text-xs text-[var(--muted-foreground)] font-medium\">\n Shared\n </div>\n {sharedViews.map((v) => (\n <ViewOption\n key={v.id}\n label={loc(v.name)}\n isActive={activeViewId === v.id}\n isShared\n onClick={() => {\n onSelect(v);\n setOpen(false);\n }}\n />\n ))}\n </>\n )}\n\n {/* Save As button */}\n {onSaveAs && (\n <>\n <div className=\"border-t border-[var(--border)] mt-1 pt-1\">\n <button\n className=\"flex items-center w-full px-3 py-1.5 text-sm hover:bg-[var(--muted)] transition-colors\"\n onClick={() => {\n onSaveAs();\n setOpen(false);\n }}\n >\n <Plus className=\"w-4 h-4 mr-2 text-[var(--muted-foreground)]\" />\n Save as new view...\n </button>\n </div>\n </>\n )}\n </div>\n </>\n )}\n </div>\n\n {/* Save button (when dirty) */}\n {isDirty && activeViewId && onSave && (\n <Button variant=\"outline\" size=\"sm\" className=\"h-8\" onClick={onSave}>\n <Save className=\"w-3 h-3 mr-1\" />\n Save\n </Button>\n )}\n </div>\n );\n}\n\nfunction ViewOption({\n label,\n isActive,\n isDefault,\n isShared,\n onClick,\n onSetDefault: _onSetDefault,\n}: {\n label: string;\n isActive: boolean;\n isDefault?: boolean;\n isShared?: boolean;\n onClick: () => void;\n onSetDefault?: () => void;\n}) {\n return (\n <button\n className={`flex items-center w-full px-3 py-1.5 text-sm hover:bg-[var(--muted)] transition-colors ${\n isActive ? \"bg-[var(--muted)] font-medium\" : \"\"\n }`}\n onClick={onClick}\n >\n <span className=\"flex-1 text-left truncate\">{label}</span>\n {isDefault && (\n <Star className=\"w-3 h-3 text-[var(--primary)] fill-current\" />\n )}\n {isShared && (\n <Globe className=\"w-3 h-3 text-[var(--muted-foreground)]\" />\n )}\n </button>\n );\n}\n","import { useSchema } from \"./useSchema\";\nimport type { Screen } from \"@/types/schema\";\n\nexport function useScreen(screenCode: string | undefined): Screen | undefined {\n const { data: schema } = useSchema();\n if (!schema || !screenCode) return undefined;\n return schema.screens[screenCode];\n}\n","import { useMemo } from \"react\";\nimport { useEntityData } from \"./useEntityData\";\nimport { useScreen } from \"./useScreen\";\nimport type { ViewItem } from \"@/components/views/ViewSwitcher\";\n\n/**\n * useViews fetches DB views for a screen and merges with system views (presets) from DSL.\n * Returns a unified list with source tagging.\n */\nexport function useViews(screenCode: string, userId?: string) {\n const screen = useScreen(screenCode);\n\n // Fetch DB views for this screen (personal + shared).\n const { data: dbResponse } = useEntityData(\"view\", {\n filters: [\n { field: \"screen_code\", op: \"eq\", value: screenCode },\n // Return own views + shared views. The OR ensures visibility.\n ...(userId ? [{ or: [\n [{ field: \"user_id\", op: \"eq\", value: userId }],\n [{ field: \"is_shared\", op: \"eq\", value: \"true\" }],\n ] }] : []),\n ],\n per_page: 100,\n });\n\n const views = useMemo<ViewItem[]>(() => {\n const items: ViewItem[] = [];\n\n // System views (presets from DSL) - always first.\n if (screen?.views) {\n for (const v of screen.views) {\n items.push({\n id: v.code,\n name: v.name,\n icon: v.icon,\n source: \"system\",\n filters: v.filters as unknown[],\n columns: v.columns,\n sort: v.sort,\n });\n }\n }\n\n // DB views (personal + shared).\n if (dbResponse?.data) {\n for (const row of dbResponse.data) {\n const isOwn = userId && String(row.user_id) === userId;\n items.push({\n id: String(row.id),\n name: typeof row.name === \"object\" && row.name !== null ? row.name as Record<string, string> : { en: String(row.name ?? \"\") },\n icon: row.icon as string | undefined,\n source: isOwn ? \"personal\" : \"shared\",\n is_default: row.is_default === true,\n filters: row.filters as unknown[] | undefined,\n columns: row.columns as string[] | undefined,\n sort: row.sort as string | undefined,\n });\n }\n }\n\n return items;\n }, [screen?.views, dbResponse?.data, userId]);\n\n return views;\n}\n","import { useMemo, useRef, useState, useCallback, useEffect } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\nimport {\n useReactTable,\n getCoreRowModel,\n flexRender,\n type ColumnDef,\n type SortingState,\n type RowSelectionState,\n} from \"@tanstack/react-table\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport {\n ChevronLeft,\n ChevronRight,\n Search,\n Plus,\n MoreHorizontal,\n Pencil,\n Trash2,\n ArrowUpDown,\n ArrowUp,\n ArrowDown,\n Eye,\n EyeOff,\n} from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport { useEntityData } from \"@/hooks/useEntityData\";\nimport { useDeleteEntity } from \"@/hooks/useMutations\";\nimport { useDebounce } from \"@/hooks/useDebounce\";\nimport { renderField } from \"@/components/fields\";\nimport { PageHeader } from \"@/components/shared/PageHeader\";\nimport { EmptyState } from \"@/components/shared/EmptyState\";\nimport { TableSkeleton } from \"@/components/shared/LoadingSkeleton\";\nimport { ConfirmDialog } from \"@/components/shared/ConfirmDialog\";\nimport { ActionButton } from \"@/components/shared/ActionButton\";\nimport { RowActionItem } from \"@/components/shared/RowActionItem\";\nimport { BatchActionProgress } from \"@/components/shared/BatchActionProgress\";\nimport { useTabNavigate } from \"@/hooks/useTabNavigate\";\nimport { useTabStore } from \"@/stores/tabs\";\nimport { cn } from \"@/lib/utils\";\nimport { toast } from \"sonner\";\nimport { getScreenActions, evaluateConditions } from \"@/lib/actions\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { loc, fieldDisplayName, DETAIL_SCREEN_NONE } from \"@/types/schema\";\nimport type { EntityField } from \"@/types/schema\";\nimport type { V2StatusInstance, V2PropertyInstance } from \"@/types/api\";\nimport { useFilters } from \"@/hooks/useFilters\";\nimport { removeFilter } from \"@/lib/filters\";\nimport { FilterChips } from \"@/components/filters/FilterChips\";\nimport { FilterDrawer, type FilterFieldMeta } from \"@/components/filters/FilterDrawer\";\nimport { ColumnPicker } from \"@/components/columns/ColumnPicker\";\nimport { ViewSwitcher } from \"@/components/views/ViewSwitcher\";\nimport { useViews } from \"@/hooks/useViews\";\nimport { Filter } from \"lucide-react\";\n\ninterface SmartListPageProps {\n screenCode: string;\n}\n\ntype RowData = Record<string, unknown>;\n\n/**\n * Resolve the target href for a row click on a list screen per the\n * entity-canonical DSL. `list.detail_screen` is tri-valued:\n *\n * absent -> inherit entity.detail_screen\n * DETAIL_SCREEN_NONE (\"none\") -> explicit opt-out (disabled)\n * any other code -> override with that detail screen\n *\n * Resolution:\n * if list.detail_screen === \"none\" -> null (disabled)\n * elif list.detail_screen is set -> use screens[list.detail_screen]\n * elif entity.detail_screen is set -> use screens[entity.detail_screen]\n * else -> null (disabled)\n *\n * Returns null when no navigation target exists; callers MUST render\n * non-interactive rows in that case (no cursor, no click handler).\n */\nexport function resolveDetailHref(\n list: { detail_screen?: string },\n id: string,\n entity: { detail_screen?: string } | undefined,\n allScreens: Record<string, { route?: string }> | undefined,\n): string | null {\n if (list.detail_screen === DETAIL_SCREEN_NONE) return null;\n const code = list.detail_screen ?? entity?.detail_screen;\n if (!code) return null;\n const target = allScreens?.[code];\n if (!target?.route) return null;\n return target.route.replace(\":id\", encodeURIComponent(id));\n}\n\nexport function SmartListPage({ screenCode }: SmartListPageProps) {\n const tabNavigate = useTabNavigate();\n const [searchParams, setSearchParams] = useSearchParams();\n const { data: schema } = useSchema();\n const [deleteState, setDeleteState] = useState<{ ids: string[]; confirmation?: string } | null>(null);\n\n const [rowSelection, setRowSelection] = useState<RowSelectionState>({});\n const [batchState, setBatchState] = useState<{ isPending: boolean; isSuccess: boolean; isError: boolean; isPartial: boolean; count: number }>({ isPending: false, isSuccess: false, isError: false, isPartial: false, count: 0 });\n const [filterDrawerOpen, setFilterDrawerOpen] = useState(false);\n const { filters: jsonFilters, activeCount: filterCount, setFilters: setJsonFilters, clearFilters } = useFilters();\n const user = useAuthStore((s) => s.user);\n const allViews = useViews(screenCode, user?.id);\n\n const screen = schema?.screens[screenCode];\n const entity = screen?.entity ? schema?.entities[screen.entity] : undefined;\n const entityCode = screen?.entity;\n\n // Actions: use screen-bound actions when defined, otherwise fall back to visibility.\n const globalActions = schema?.actions;\n const toolbarActions = useMemo(\n () => getScreenActions(entity?.actions, screen?.actions, \"list_toolbar\", globalActions),\n [entity?.actions, screen?.actions, globalActions],\n );\n const rowActions = useMemo(\n () => getScreenActions(entity?.actions, screen?.row_actions, \"list_row\", globalActions),\n [entity?.actions, screen?.row_actions, globalActions],\n );\n // When the screen explicitly binds row_actions, it controls the full row menu.\n const hasExplicitRowActions = screen?.row_actions !== undefined;\n // Checkboxes appear iff at least one action declares list_toolbar visibility.\n // Schema declares intent; UI follows. No separate selectable: true setting.\n const hasBatchActions = useMemo(\n () => toolbarActions.some((a) => (a.action.visibility ?? []).includes(\"list_toolbar\")),\n [toolbarActions],\n );\n\n // Soft-delete visibility toggle (admin-only).\n const hasSoftDelete = !!entity?.soft_delete;\n const canViewDeleted = hasSoftDelete && (user?.permissions ?? []).some((p) => p === \"feature:view_deleted\" || p === \"feature:*\" || p === \"*\");\n const includeDeleted = canViewDeleted && searchParams.get(\"include_deleted\") === \"true\";\n\n // Ensure this page is tracked as a tab (preserves current search params).\n const { openTab, updateTabSearch, findTabByPathname } = useTabStore();\n useEffect(() => {\n if (screen?.route && entity) {\n const tabName = loc(screen.display?.name) || loc(entity.display.name_plural);\n const tabIcon = screen.display?.icon || entity.display.icon;\n openTab({\n pathname: screen.route,\n search: searchParams.toString(),\n title: tabName,\n icon: tabIcon,\n closable: true,\n });\n }\n }, [screen?.route, screen?.display?.name?.en, entity?.display.name_plural?.en, screen?.display?.icon, entity?.display.icon]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Sync URL search params back to tab store so switching away and back restores the URL.\n useEffect(() => {\n if (!screen?.route) return;\n const tab = findTabByPathname(screen.route);\n if (tab) {\n updateTabSearch(tab.id, searchParams.toString());\n }\n }, [searchParams, screen?.route]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // URL state\n const page = parseInt(searchParams.get(\"page\") ?? \"1\", 10);\n const searchValue = searchParams.get(\"search\") ?? \"\";\n const sortParam = searchParams.get(\"sort\") ?? screen?.sort_default ?? \"\";\n const debouncedSearch = useDebounce(searchValue, 300);\n\n // Visible columns from URL (or screen defaults).\n const visibleCols = useMemo<string[]>(() => {\n const raw = searchParams.get(\"columns\");\n if (raw) return raw.split(\",\").filter(Boolean);\n return screen?.columns ?? [];\n }, [searchParams, screen?.columns]);\n\n // Detect which expand params are needed based on VISIBLE column prefixes.\n // When any expand is requested, $refs must be explicitly included too\n // (the backend disables auto-refs when expand mode is active).\n const expand = useMemo(() => {\n const e: string[] = [];\n // Check both the screen pool and visible columns for $status/$property.\n const allCols = [...(screen?.columns ?? []), ...visibleCols];\n if (allCols.some((c) => c.startsWith(\"$status.\"))) e.push(\"statuses\");\n if (allCols.some((c) => c.startsWith(\"$property.\"))) e.push(\"properties\");\n if (e.length > 0) e.unshift(\"refs\");\n return e.length > 0 ? e : undefined;\n }, [screen?.columns, visibleCols]);\n\n // Data fetching - prefer JSON filters over legacy format.\n const { data: response, isLoading, isError } = useEntityData(entityCode, {\n page,\n per_page: 50,\n sort: sortParam || undefined,\n search: debouncedSearch || undefined,\n filters: jsonFilters.length > 0 ? jsonFilters : undefined,\n include_deleted: includeDeleted || undefined,\n expand,\n screen: screen?.fixed_filters ? screenCode : undefined,\n });\n\n const deleteMutation = useDeleteEntity(entityCode ?? \"\");\n\n // Parse sort state from URL\n const sorting: SortingState = useMemo(() => {\n if (!sortParam) return [];\n const [field, dir] = sortParam.split(\":\");\n return [{ id: field, desc: dir === \"desc\" }];\n }, [sortParam]);\n\n // Primary key field name.\n const pkField = useMemo(\n () => entity?.field_order?.find((f) => entity.fields[f]?.primary) ?? \"id\",\n [entity],\n );\n\n const refs = response?.$refs;\n // Use a ref so the cell render function always reads the latest $refs\n // without adding it to the useMemo deps (which would re-create columns on every fetch).\n const refsRef = useRef(refs);\n refsRef.current = refs;\n\n // Build columns from visible columns (URL state or screen defaults).\n const columns = useMemo<ColumnDef<RowData>[]>(() => {\n if (visibleCols.length === 0 || !entity) return [];\n\n const cols: ColumnDef<RowData>[] = [];\n\n // Checkbox column for batch selection.\n if (hasBatchActions) {\n cols.push({\n id: \"_select\",\n header: ({ table: tbl }) => (\n <input\n type=\"checkbox\"\n className=\"accent-[var(--primary)]\"\n checked={tbl.getIsAllRowsSelected()}\n onChange={tbl.getToggleAllRowsSelectedHandler()}\n />\n ),\n size: 36,\n cell: ({ row }) => (\n <input\n type=\"checkbox\"\n className=\"accent-[var(--primary)]\"\n checked={row.getIsSelected()}\n onChange={row.getToggleSelectedHandler()}\n />\n ),\n });\n }\n\n // Data columns (use visible columns from URL state, not full screen.columns pool).\n for (const colKey of visibleCols) {\n // Status group column: $status.pipeline\n if (colKey.startsWith(\"$status.\")) {\n const groupCode = colKey.slice(8);\n const group = entity.status_groups?.[groupCode];\n if (!group) continue;\n const statusMap = new Map(group.statuses.map((s) => [s.code, s]));\n cols.push({\n id: colKey,\n header: loc(group.name) || groupCode,\n size: 140,\n cell: ({ row }) => {\n const statuses = (row.original as Record<string, unknown>)[\"$statuses\"] as V2StatusInstance[] | undefined;\n const match = statuses?.find((s) => s.group_code === groupCode);\n if (!match) return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n const def = statusMap.get(match.status_code);\n return (\n <Badge color={def?.color}>{loc(def?.name) || match.status_code}</Badge>\n );\n },\n });\n continue;\n }\n\n // Property column: $property.clickup_task_id\n if (colKey.startsWith(\"$property.\")) {\n const propCode = colKey.slice(10);\n const propDef = entity.properties?.[propCode];\n if (!propDef) continue;\n cols.push({\n id: colKey,\n header: loc(propDef.name) || propCode,\n size: 150,\n enableSorting: false,\n cell: ({ row }) => {\n const props = (row.original as Record<string, unknown>)[\"$properties\"] as V2PropertyInstance[] | undefined;\n const match = props?.find((p) => p.property_code === propCode);\n if (!match || match.value == null) return <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>;\n return <span className=\"text-sm\">{String(match.value)}</span>;\n },\n });\n continue;\n }\n\n // Regular field column\n const field = entity.fields[colKey];\n if (!field) continue;\n const displayName = fieldDisplayName(field, colKey, schema?.entities);\n const width = field.display?.width;\n cols.push({\n id: colKey,\n accessorKey: colKey,\n header: displayName,\n size: width ?? 150,\n cell: ({ getValue, row }) =>\n renderField({\n field,\n fieldName: colKey,\n value: getValue(),\n mode: \"display\",\n record: row.original,\n refs: refsRef.current,\n }),\n });\n }\n\n // Actions column (dropdown) - only show when there are items to display.\n const hasDefaultActions = !hasExplicitRowActions && !entity?.readonly;\n if (hasDefaultActions || rowActions.length > 0) {\n cols.push({\n id: \"_actions\",\n header: \"\",\n size: 48,\n cell: ({ row }) => {\n const id = String(row.original[pkField] ?? \"\");\n const editHref = resolveDetailHref(screen!, id, entity, schema?.screens);\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\">\n <MoreHorizontal className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {hasDefaultActions && (\n <>\n {editHref && (\n <DropdownMenuItem\n onClick={() =>\n tabNavigate(editHref, {\n title: loc(entity!.display.name),\n icon: entity!.display.icon,\n search: \"edit=true\",\n })\n }\n >\n <Pencil className=\"mr-2 h-4 w-4\" />\n Edit\n </DropdownMenuItem>\n )}\n <DropdownMenuItem\n onClick={() => setDeleteState({ ids: [id] })}\n className=\"text-[var(--destructive)]\"\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n Delete\n </DropdownMenuItem>\n {rowActions.length > 0 && <DropdownMenuSeparator />}\n </>\n )}\n {rowActions.map(({ code, action }) => {\n if (action.type === \"edit\") {\n const conditionsMet = evaluateConditions(action.conditions, row.original);\n if (!editHref) return null;\n return (\n <DropdownMenuItem\n key={code}\n disabled={!conditionsMet}\n onClick={() =>\n tabNavigate(editHref, {\n title: loc(entity!.display.name),\n icon: entity!.display.icon,\n search: \"edit=true\",\n })\n }\n >\n <Pencil className=\"mr-2 h-4 w-4\" />\n {loc(action.display?.name) || \"Edit\"}\n </DropdownMenuItem>\n );\n }\n if (action.type === \"delete\") {\n const conditionsMet = evaluateConditions(action.conditions, row.original);\n return (\n <DropdownMenuItem\n key={code}\n disabled={!conditionsMet}\n onClick={() => setDeleteState({ ids: [id], confirmation: loc(action.confirmation) || undefined })}\n className=\"text-[var(--destructive)]\"\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n {loc(action.display?.name) || \"Delete\"}\n </DropdownMenuItem>\n );\n }\n return (\n <RowActionItem\n key={code}\n actionCode={code}\n action={action}\n entityCode={entityCode}\n objectId={id}\n row={row.original}\n />\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n },\n });\n }\n\n return cols;\n }, [screen, entity, visibleCols, tabNavigate, hasBatchActions, rowActions, hasExplicitRowActions, entityCode, pkField]);\n\n const data = response?.data ?? [];\n const meta = response?.meta;\n\n const table = useReactTable({\n data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n manualSorting: true,\n manualPagination: true,\n state: { sorting, rowSelection },\n onSortingChange: (updater) => {\n const next = typeof updater === \"function\" ? updater(sorting) : updater;\n const params = new URLSearchParams(searchParams);\n if (next.length === 0) {\n params.delete(\"sort\");\n } else {\n const s = next[0];\n params.set(\"sort\", `${s.id}:${s.desc ? \"desc\" : \"asc\"}`);\n }\n params.set(\"page\", \"1\");\n setSearchParams(params);\n },\n onRowSelectionChange: setRowSelection,\n getRowId: (row) => String(row[pkField] ?? \"\"),\n rowCount: meta?.total ?? 0,\n });\n\n // Selected IDs for batch actions.\n const selectedIds = useMemo(\n () => Object.keys(rowSelection).filter((k) => rowSelection[k]),\n [rowSelection],\n );\n\n // Clear selection after data changes (page, search, sort, or filter change).\n useEffect(() => {\n setRowSelection({});\n }, [page, debouncedSearch, sortParam, jsonFilters]);\n\n // Keyboard shortcuts: / = focus search, f = open filter drawer, Escape = close drawer.\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n // Skip when typing in an input/textarea/select.\n const tag = (e.target as HTMLElement)?.tagName;\n if (tag === \"INPUT\" || tag === \"TEXTAREA\" || tag === \"SELECT\") {\n if (e.key === \"Escape\") {\n (e.target as HTMLElement).blur();\n setFilterDrawerOpen(false);\n }\n return;\n }\n if (e.key === \"/\" && !e.metaKey && !e.ctrlKey) {\n e.preventDefault();\n const input = document.querySelector<HTMLInputElement>('[placeholder*=\"Search\"]');\n input?.focus();\n }\n if (e.key === \"f\" && !e.metaKey && !e.ctrlKey) {\n e.preventDefault();\n setFilterDrawerOpen((prev) => !prev);\n }\n if (e.key === \"Escape\") {\n setFilterDrawerOpen(false);\n }\n };\n document.addEventListener(\"keydown\", handler);\n return () => document.removeEventListener(\"keydown\", handler);\n }, []);\n\n // Auto-clear batch success/error/partial state after a few seconds.\n useEffect(() => {\n if (batchState.isSuccess || batchState.isError || batchState.isPartial) {\n const timer = setTimeout(() => setBatchState({ isPending: false, isSuccess: false, isError: false, isPartial: false, count: 0 }), 3000);\n return () => clearTimeout(timer);\n }\n }, [batchState.isSuccess, batchState.isError, batchState.isPartial]);\n\n // Virtual scroll\n const parentRef = useRef<HTMLDivElement>(null);\n const { rows } = table.getRowModel();\n\n const rowVirtualizer = useVirtualizer({\n count: rows.length,\n getScrollElement: () => parentRef.current,\n estimateSize: () => 48,\n overscan: 10,\n });\n\n // URL state helpers\n const updateSearch = useCallback(\n (value: string) => {\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n if (value) {\n next.set(\"search\", value);\n } else {\n next.delete(\"search\");\n }\n next.set(\"page\", \"1\");\n return next;\n });\n },\n [setSearchParams],\n );\n\n const toggleIncludeDeleted = useCallback(() => {\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n if (next.get(\"include_deleted\")) {\n next.delete(\"include_deleted\");\n } else {\n next.set(\"include_deleted\", \"true\");\n }\n next.set(\"page\", \"1\");\n return next;\n });\n }, [setSearchParams]);\n\n const goToPage = useCallback(\n (p: number) => {\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.set(\"page\", String(p));\n return next;\n });\n },\n [setSearchParams],\n );\n\n const hasRowDetailTarget = useMemo(() => {\n if (!screen || !entity) return false;\n return resolveDetailHref(screen, \"_\", entity, schema?.screens) !== null;\n }, [screen, entity, schema?.screens]);\n\n const handleRowClick = useCallback(\n (row: RowData) => {\n if (!entity || !screen) return;\n const pk = entity.field_order?.find((f) => entity.fields[f]?.primary);\n const id = pk ? String(row[pk] ?? \"\") : \"\";\n if (!id) return;\n const href = resolveDetailHref(screen, id, entity, schema?.screens);\n if (!href) return; // no detail target; row is non-interactive\n // Determine a display title for the tab from the first visible column value.\n const firstCol = screen.columns?.find(\n (c) => !c.startsWith(\"$status.\") && !c.startsWith(\"$property.\"),\n );\n const tabTitle = firstCol\n ? String(row[firstCol] ?? loc(entity.display.name))\n : loc(entity.display.name);\n const icon = screen.display?.icon || entity.display.icon;\n tabNavigate(href, {\n title: tabTitle,\n icon,\n });\n },\n [entity, screen, schema, tabNavigate],\n );\n\n const handleDelete = useCallback(async () => {\n if (!deleteState || deleteState.ids.length === 0) return;\n setDeleteState(null);\n const results = await Promise.allSettled(\n deleteState.ids.map((id) => deleteMutation.mutateAsync(id)),\n );\n const failed = results.filter((r) => r.status === \"rejected\").length;\n if (failed === 0) {\n setRowSelection({});\n } else if (failed < deleteState.ids.length) {\n // Remove successfully deleted IDs from selection to prevent stale retries.\n const succeededIds = new Set(\n deleteState.ids.filter((_, i) => results[i].status === \"fulfilled\"),\n );\n setRowSelection((prev) => {\n const next: RowSelectionState = {};\n for (const [key, val] of Object.entries(prev)) {\n if (!succeededIds.has(key)) next[key] = val;\n }\n return next;\n });\n toast.warning(`${failed} of ${deleteState.ids.length} deletes failed`);\n }\n }, [deleteState, deleteMutation]);\n\n if (!screen || !entity) return null;\n\n const entityDisplay = entity.display;\n // Screen display name takes priority over entity display name (supports multiple screens per entity).\n const screenName = loc(screen.display?.name) || loc(entityDisplay.name);\n const screenIcon = screen.display?.icon || entityDisplay.icon;\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"px-6 pt-6\">\n <PageHeader\n title={screenName}\n actions={\n <>\n {hasBatchActions && (\n <BatchActionProgress\n count={(batchState.isPending || batchState.isSuccess || batchState.isError || batchState.isPartial) ? batchState.count : selectedIds.length}\n isPending={batchState.isPending}\n isSuccess={batchState.isSuccess}\n isError={batchState.isError}\n isPartial={batchState.isPartial}\n />\n )}\n {toolbarActions.map(({ code, action }) => {\n if (action.type === \"create\") {\n if (entity?.readonly) return null;\n return (\n <Button key={code} onClick={() => tabNavigate(`${screen.route}/new`, { title: `New ${loc(entityDisplay.name)}`, icon: screenIcon })}>\n <Plus className=\"w-4 h-4\" />\n {loc(action.display?.name) || `New ${loc(entityDisplay.name)}`}\n </Button>\n );\n }\n if (action.type === \"delete\") {\n // Filter selected IDs by conditions when the action defines them.\n const rawIds = selectedIds;\n const ids = action.conditions && action.conditions.length > 0\n ? rawIds.filter((id) => {\n const row = data.find((r) => String(r[pkField] ?? \"\") === id);\n return row ? evaluateConditions(action.conditions, row) : false;\n })\n : rawIds;\n const isDisabled = ids.length === 0;\n return (\n <Button\n key={code}\n variant=\"outline\"\n onClick={() => setDeleteState({ ids, confirmation: loc(action.confirmation) || undefined })}\n disabled={isDisabled}\n className=\"text-[var(--destructive)] hover:text-[var(--destructive)]\"\n >\n <Trash2 className=\"w-4 h-4\" />\n {loc(action.display?.name) || \"Delete\"}\n </Button>\n );\n }\n if (action.type === \"edit\") {\n // Edit in toolbar is not a standard pattern; render as no-op.\n return null;\n }\n return (\n <ActionButton\n key={code}\n actionCode={code}\n action={action}\n entityCode={entityCode}\n objectIds={selectedIds}\n variant=\"outline\"\n onSuccess={() => { setRowSelection({}); setBatchState({ isPending: false, isSuccess: true, isError: false, isPartial: false, count: selectedIds.length }); }}\n onBatchStart={(count: number) => setBatchState({ isPending: true, isSuccess: false, isError: false, isPartial: false, count })}\n onBatchError={(count: number) => setBatchState({ isPending: false, isSuccess: false, isError: true, isPartial: false, count })}\n onBatchPartial={(count: number, successIds?: string[]) => {\n setBatchState({ isPending: false, isSuccess: false, isError: false, isPartial: true, count });\n if (successIds && successIds.length > 0) {\n const succeeded = new Set(successIds);\n setRowSelection((prev) => {\n const next: RowSelectionState = {};\n for (const [key, val] of Object.entries(prev)) {\n if (!succeeded.has(key)) next[key] = val;\n }\n return next;\n });\n }\n }}\n />\n );\n })}\n {screen.actions === undefined && !entity?.readonly && (\n <Button onClick={() => tabNavigate(`${screen.route}/new`, { title: `New ${loc(entityDisplay.name)}`, icon: screenIcon })}>\n <Plus className=\"w-4 h-4\" />\n New {loc(entityDisplay.name)}\n </Button>\n )}\n </>\n }\n />\n\n {/* Toolbar: view switcher + search + filter + columns + soft-delete */}\n <div className=\"flex items-center gap-3 mb-2\">\n {/* View switcher */}\n <ViewSwitcher\n views={allViews}\n activeViewId={searchParams.get(\"view\")}\n isDirty={false}\n onSelect={(view) => {\n if (!view.id) {\n // Default view - clear all view params.\n const next = new URLSearchParams();\n if (searchParams.get(\"search\")) next.set(\"search\", searchParams.get(\"search\")!);\n setSearchParams(next);\n return;\n }\n const next = new URLSearchParams(searchParams);\n next.set(\"view\", view.id);\n if (view.filters && Array.isArray(view.filters) && view.filters.length > 0) {\n next.set(\"filters\", JSON.stringify(view.filters));\n }\n if (view.columns && view.columns.length > 0) {\n next.set(\"columns\", view.columns.join(\",\"));\n }\n if (view.sort) {\n next.set(\"sort\", view.sort);\n }\n next.set(\"page\", \"1\");\n setSearchParams(next);\n }}\n />\n\n <div className=\"relative flex-1 max-w-sm\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--muted-foreground)]\" />\n <Input\n placeholder={`Search ${screenName.toLowerCase()}...`}\n value={searchValue}\n onChange={(e) => updateSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n\n <Button\n variant={filterCount > 0 ? \"secondary\" : \"outline\"}\n size=\"sm\"\n onClick={() => setFilterDrawerOpen(true)}\n className=\"h-8\"\n >\n <Filter className=\"w-4 h-4 mr-1.5\" />\n Filters\n {filterCount > 0 && (\n <Badge variant=\"secondary\" className=\"ml-1.5 h-5 min-w-[20px] px-1 text-xs\">\n {filterCount}\n </Badge>\n )}\n </Button>\n\n <ColumnPicker\n availableColumns={screen.columns ?? []}\n visibleColumns={visibleCols}\n onToggle={(col) => {\n const next = new URLSearchParams(searchParams);\n const current = visibleCols.includes(col)\n ? visibleCols.filter((c) => c !== col)\n : [...visibleCols, col];\n if (current.length === 0) return; // keep at least 1\n next.set(\"columns\", current.join(\",\"));\n setSearchParams(next);\n }}\n onReset={() => {\n const next = new URLSearchParams(searchParams);\n next.delete(\"columns\");\n setSearchParams(next);\n }}\n onShowAll={() => {\n const next = new URLSearchParams(searchParams);\n next.set(\"columns\", (screen.columns ?? []).join(\",\"));\n setSearchParams(next);\n }}\n columnLabel={(c) => {\n if (c.startsWith(\"$status.\")) {\n const gc = c.slice(8);\n const g = entity.status_groups?.[gc];\n return g ? (loc(g.name) || gc) : c;\n }\n if (c.startsWith(\"$property.\")) {\n const pc = c.slice(10);\n const p = entity.properties?.[pc];\n return p ? (loc(p.name) || pc) : c;\n }\n const f = entity.fields[c];\n return f ? fieldDisplayName(f, c, schema?.entities) : c;\n }}\n />\n\n {canViewDeleted && (\n <Button\n variant={includeDeleted ? \"secondary\" : \"outline\"}\n size=\"sm\"\n onClick={toggleIncludeDeleted}\n className=\"ml-auto\"\n >\n {includeDeleted ? <EyeOff className=\"w-4 h-4 mr-1.5\" /> : <Eye className=\"w-4 h-4 mr-1.5\" />}\n {includeDeleted ? \"Hide deleted\" : \"Show deleted\"}\n </Button>\n )}\n </div>\n\n {/* Filter chips (collapsed filter summary) */}\n <FilterChips\n filters={jsonFilters}\n onRemove={(field) => setJsonFilters(removeFilter(jsonFilters, field))}\n onClearAll={clearFilters}\n onChipClick={() => setFilterDrawerOpen(true)}\n fieldLabel={(f) => {\n if (f.startsWith(\"$status.\")) {\n const groupCode = f.slice(8);\n const group = entity.status_groups?.[groupCode];\n return group ? (loc(group.name) || groupCode) : f;\n }\n if (f.startsWith(\"$property.\")) {\n const propCode = f.slice(10);\n const prop = entity.properties?.[propCode];\n return prop ? (loc(prop.name) || propCode) : f;\n }\n const field = entity.fields[f];\n return field ? fieldDisplayName(field, f, schema?.entities) : f;\n }}\n />\n </div>\n\n {/* Table */}\n {isLoading ? (\n <TableSkeleton cols={screen.columns?.length ?? 4} />\n ) : isError ? (\n <div className=\"px-6\">\n <EmptyState\n icon=\"alert-circle\"\n title=\"Failed to load data\"\n description=\"Something went wrong. Please try again.\"\n />\n </div>\n ) : data.length === 0 ? (\n <div className=\"px-6\">\n <EmptyState\n icon={screenIcon}\n title={debouncedSearch || filterCount > 0 ? \"No results found\" : `No ${screenName.toLowerCase()} yet`}\n description={\n debouncedSearch || filterCount > 0\n ? \"Try adjusting your search or filters\"\n : `Create your first ${loc(entityDisplay.name).toLowerCase()} to get started`\n }\n action={\n !debouncedSearch && filterCount === 0 && !entity?.readonly ? (\n <Button onClick={() => tabNavigate(`${screen.route}/new`, { title: `New ${loc(entityDisplay.name)}`, icon: screenIcon })}>\n <Plus className=\"w-4 h-4\" />\n New {loc(entityDisplay.name)}\n </Button>\n ) : undefined\n }\n />\n </div>\n ) : (\n <div ref={parentRef} className=\"flex-1 overflow-auto px-6\">\n <table className=\"w-full text-sm\">\n <thead className=\"sticky top-0 bg-[var(--background)] z-10\">\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id} className=\"border-b\">\n {headerGroup.headers.map((header) => {\n const canSort = header.id !== \"_actions\";\n const sorted = header.column.getIsSorted();\n\n return (\n <th\n key={header.id}\n className=\"h-10 px-3 text-left align-middle font-medium text-[var(--muted-foreground)]\"\n style={{ width: header.getSize() }}\n >\n {header.isPlaceholder ? null : canSort ? (\n <button\n className=\"inline-flex items-center gap-1 hover:text-[var(--foreground)] transition-colors\"\n onClick={header.column.getToggleSortingHandler()}\n >\n {flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n {sorted === \"asc\" ? (\n <ArrowUp className=\"w-3 h-3\" />\n ) : sorted === \"desc\" ? (\n <ArrowDown className=\"w-3 h-3\" />\n ) : (\n <ArrowUpDown className=\"w-3 h-3 opacity-40\" />\n )}\n </button>\n ) : (\n flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )\n )}\n </th>\n );\n })}\n </tr>\n ))}\n </thead>\n <tbody>\n {rowVirtualizer.getVirtualItems().length > 0 && (\n <tr>\n <td\n style={{ height: rowVirtualizer.getVirtualItems()[0]?.start ?? 0 }}\n colSpan={columns.length}\n />\n </tr>\n )}\n {rowVirtualizer.getVirtualItems().map((virtualRow) => {\n const row = rows[virtualRow.index];\n const isDeleted = hasSoftDelete && row.original[entity!.soft_delete!] != null;\n return (\n <tr\n key={row.id}\n data-index={virtualRow.index}\n ref={(node) => rowVirtualizer.measureElement(node)}\n className={cn(\n \"border-b transition-colors\",\n hasRowDetailTarget && \"hover:bg-[var(--muted)]/50 cursor-pointer\",\n isDeleted && \"opacity-50 italic\",\n )}\n onClick={hasRowDetailTarget ? () => handleRowClick(row.original) : undefined}\n >\n {row.getVisibleCells().map((cell) => (\n <td\n key={cell.id}\n className=\"px-3 py-2.5 align-middle\"\n style={{ width: cell.column.getSize() }}\n onClick={\n cell.column.id === \"_actions\" || cell.column.id === \"_select\"\n ? (e) => e.stopPropagation()\n : undefined\n }\n >\n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n )}\n </td>\n ))}\n </tr>\n );\n })}\n {rowVirtualizer.getVirtualItems().length > 0 && (\n <tr>\n <td\n style={{\n height:\n rowVirtualizer.getTotalSize() -\n (rowVirtualizer.getVirtualItems().at(-1)?.end ?? 0),\n }}\n colSpan={columns.length}\n />\n </tr>\n )}\n </tbody>\n </table>\n </div>\n )}\n\n {/* Pagination */}\n {meta && meta.total_pages > 1 && (\n <div className=\"flex items-center justify-between px-6 py-3 border-t border-[var(--border)]\">\n <span className=\"text-sm text-[var(--muted-foreground)]\">\n {meta.total} {meta.total === 1 ? \"record\" : \"records\"}\n </span>\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => goToPage(page - 1)}\n disabled={page <= 1}\n >\n <ChevronLeft className=\"w-4 h-4\" />\n Prev\n </Button>\n <span className=\"text-sm text-[var(--muted-foreground)]\">\n Page {meta.page} of {meta.total_pages}\n </span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => goToPage(page + 1)}\n disabled={page >= meta.total_pages}\n >\n Next\n <ChevronRight className=\"w-4 h-4\" />\n </Button>\n </div>\n </div>\n )}\n\n {/* Filter drawer */}\n <FilterDrawer\n open={filterDrawerOpen}\n onClose={() => setFilterDrawerOpen(false)}\n filters={jsonFilters}\n onApply={setJsonFilters}\n availableFields={buildFilterFieldMeta(screen, entity, schema?.entities)}\n />\n\n {/* Delete confirmation */}\n <ConfirmDialog\n open={deleteState !== null}\n onOpenChange={(open) => !open && setDeleteState(null)}\n title={`Delete ${loc(entityDisplay.name)}`}\n description={\n deleteState?.confirmation\n ? deleteState.confirmation\n : hasSoftDelete\n ? `Are you sure you want to delete this ${loc(entityDisplay.name).toLowerCase()}? It can be restored later by an admin.`\n : `Are you sure you want to delete this ${loc(entityDisplay.name).toLowerCase()}? This action cannot be undone.`\n }\n confirmLabel=\"Delete\"\n onConfirm={handleDelete}\n destructive\n />\n </div>\n );\n}\n\n/** Build FilterFieldMeta array from screen + entity for the FilterDrawer. */\nfunction buildFilterFieldMeta(\n screen: { filters?: string[] } | undefined,\n entity: { fields: Record<string, EntityField>; status_groups?: Record<string, { name?: Record<string, string>; statuses: { code: string; name?: Record<string, string>; color?: string }[] }>; properties?: Record<string, { name?: Record<string, string>; type?: string }> } | undefined,\n entities?: Record<string, any>,\n): FilterFieldMeta[] {\n if (!screen || !entity) return [];\n const filterFields = screen.filters ?? Object.keys(entity.fields);\n const meta: FilterFieldMeta[] = [];\n\n for (const f of filterFields) {\n if (f.startsWith(\"$status.\")) {\n const groupCode = f.slice(8);\n const group = entity.status_groups?.[groupCode];\n if (!group) continue;\n meta.push({\n code: f,\n label: loc(group.name) || groupCode,\n type: \"status\",\n operators: [\"eq\", \"not_eq\", \"in\", \"not_in\"],\n options: group.statuses.map((s) => ({\n value: s.code,\n label: loc(s.name) || s.code,\n color: s.color,\n })),\n });\n continue;\n }\n if (f.startsWith(\"$property.\")) {\n const propCode = f.slice(10);\n const prop = entity.properties?.[propCode];\n if (!prop) continue;\n meta.push({\n code: f,\n label: loc(prop.name) || propCode,\n type: \"property\",\n operators: [\"eq\", \"not_eq\", \"contains\", \"is_empty\", \"is_not_empty\"],\n });\n continue;\n }\n const field = entity.fields[f];\n if (!field) continue;\n const label = fieldDisplayName(field, f, entities);\n const ops = fieldTypeToOperators(field.type);\n const options = field.values?.map((v) => ({\n value: v.code,\n label: loc(v.name) || v.code,\n color: v.color,\n }));\n meta.push({ code: f, label, type: field.type, operators: ops, options });\n }\n\n return meta;\n}\n\n/** Map field type to available filter operators. */\nfunction fieldTypeToOperators(type: string): import(\"@/lib/filters\").FilterOp[] {\n switch (type) {\n case \"string\": case \"text\": case \"email\": case \"url\": case \"phone\":\n return [\"eq\", \"not_eq\", \"contains\", \"starts_with\", \"is_empty\", \"is_not_empty\"];\n case \"enum\":\n return [\"eq\", \"not_eq\", \"in\", \"not_in\", \"is_empty\", \"is_not_empty\"];\n case \"int\": case \"float\": case \"decimal\":\n return [\"eq\", \"not_eq\", \"gt\", \"gte\", \"lt\", \"lte\", \"between\", \"is_empty\", \"is_not_empty\"];\n case \"date\":\n return [\"eq\", \"not_eq\", \"gt\", \"gte\", \"lt\", \"lte\", \"between\", \"today\", \"this_week\", \"this_month\", \"last_7_days\", \"last_30_days\", \"is_empty\", \"is_not_empty\"];\n case \"timestamp\":\n return [\"eq\", \"not_eq\", \"gt\", \"gte\", \"lt\", \"lte\", \"between\", \"today\", \"this_week\", \"this_month\", \"last_7_days\", \"last_30_days\", \"last_hour\", \"last_24_hours\", \"is_empty\", \"is_not_empty\"];\n case \"bool\":\n return [\"eq\", \"is_empty\"];\n case \"ref\": case \"uuid\":\n return [\"eq\", \"not_eq\", \"is_empty\", \"is_not_empty\"];\n default:\n return [\"eq\", \"not_eq\", \"is_empty\", \"is_not_empty\"];\n }\n}\n\n","/**\n * Format an offset-aware timestamp string (e.g. \"2026-03-27T14:30:00+03:00\")\n * for display WITHOUT browser-local timezone conversion. The server returns\n * timestamps already converted to the target timezone - we display as-is.\n *\n * Falls back to browser-local formatting for bare datetime strings.\n */\nexport function formatOffsetTimestamp(raw: string): string {\n const offsetMatch = raw.match(/([+-]\\d{2}:\\d{2})$/);\n const isUTC = raw.endsWith(\"Z\");\n\n if (offsetMatch || isUTC) {\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n\n let tz: string | undefined;\n if (isUTC) {\n tz = \"UTC\";\n } else if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0);\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n if (minutes === 0) {\n tz = hours === 0 ? \"UTC\" : `Etc/GMT${sign === \"+\" ? \"-\" : \"+\"}${hours}`;\n }\n }\n\n if (tz) {\n try {\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: tz,\n }).format(date);\n } catch {\n // Fall through.\n }\n }\n\n // Non-standard offset (e.g. +05:30): compute local time manually.\n if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0) === \"+\" ? 1 : -1;\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n const offsetMs = sign * (hours * 60 + minutes) * 60 * 1000;\n const localMs = date.getTime() + offsetMs;\n const localDate = new Date(localMs);\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\",\n }).format(localDate);\n }\n }\n\n // Bare datetime or unparseable: fall back to browser-local.\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n }).format(date);\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { getEntity } from \"@/api/data\";\nimport type { PkValues } from \"@/types/schema\";\n\n// useEntityItem fetches a single record by primary key.\n// pkValues can be:\n// - a string (single PK, backward compat)\n// - a PkValues object (composite PK)\n// - undefined (disabled)\nexport function useEntityItem(entity: string | undefined, pkValues: PkValues | string | undefined) {\n // Stable cache key: for string IDs use them directly; for PkValues sort keys\n // so that { a: \"1\", b: \"2\" } and { b: \"2\", a: \"1\" } hit the same cache entry.\n const cacheKey = pkValues === undefined || pkValues === \"new\"\n ? undefined\n : typeof pkValues === \"string\"\n ? pkValues\n : Object.keys(pkValues).sort().map((k) => `${k}=${pkValues[k]}`).join(\"&\");\n\n return useQuery({\n queryKey: [\"entity-item\", entity, cacheKey],\n queryFn: () => getEntity(entity!, pkValues!),\n enabled: !!entity && !!pkValues && pkValues !== \"new\" && cacheKey !== undefined,\n });\n}\n","import { useState, useMemo } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { ExternalLink } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardHeader, CardContent } from \"@/components/ui/card\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\nimport { renderField } from \"@/components/fields\";\nimport { resolveAssociation } from \"@/api/data\";\nimport { listEntities } from \"@/api/data\";\nimport { findListScreenForEntity } from \"@/lib/actions\";\nimport { useTabNavigate } from \"@/hooks/useTabNavigate\";\nimport { cn } from \"@/lib/utils\";\nimport { loc, fieldDisplayName } from \"@/types/schema\";\nimport type { AssociationDef, Schema } from \"@/types/schema\";\n\ninterface AssociationTabsProps {\n entityCode: string;\n recordId: string;\n associations: Record<string, AssociationDef>;\n schema: Schema;\n}\n\nexport function AssociationTabs({\n entityCode,\n recordId,\n associations,\n schema,\n}: AssociationTabsProps) {\n const assocEntries = useMemo(\n () => Object.entries(associations),\n [associations],\n );\n const [activeTab, setActiveTab] = useState(0);\n\n if (assocEntries.length === 0) return null;\n\n const [activeKey, activeAssoc] = assocEntries[activeTab];\n\n return (\n <Card>\n <CardHeader className=\"py-3\">\n <div className=\"flex items-center gap-1 border-b border-[var(--border)]\">\n {assocEntries.map(([key, assoc], idx) => (\n <button\n key={key}\n className={cn(\n \"flex items-center gap-1.5 px-3 py-2 text-sm transition-colors border-b-2 -mb-px\",\n idx === activeTab\n ? \"border-[var(--foreground)] text-[var(--foreground)]\"\n : \"border-transparent text-[var(--muted-foreground)] hover:text-[var(--foreground)]\",\n )}\n onClick={() => setActiveTab(idx)}\n >\n {assoc.display?.icon && (\n <DynamicIcon name={assoc.display.icon} className=\"w-4 h-4\" />\n )}\n {loc(assoc.display?.name) || key}\n </button>\n ))}\n </div>\n </CardHeader>\n <CardContent className=\"pt-0\">\n <AssociationContent\n entityCode={entityCode}\n recordId={recordId}\n assocKey={activeKey}\n association={activeAssoc}\n schema={schema}\n />\n </CardContent>\n </Card>\n );\n}\n\nfunction AssociationContent({\n entityCode,\n recordId,\n assocKey,\n association,\n schema,\n}: {\n entityCode: string;\n recordId: string;\n assocKey: string;\n association: AssociationDef;\n schema: Schema;\n}) {\n const tabNavigate = useTabNavigate();\n const assocCode = `${entityCode}.${assocKey}`;\n\n // Resolve association to get target IDs.\n const { data: assocResult, isLoading: resolving } = useQuery({\n queryKey: [\"association\", assocCode, recordId],\n queryFn: () => resolveAssociation(assocCode, [recordId]),\n });\n\n const targetEntityCode = assocResult?.target_entity ?? association.target;\n const targetEntity = schema.entities[targetEntityCode];\n const targetIds = assocResult?.ids ?? [];\n\n // Fetch target records by IDs.\n const pk = useMemo(\n () => targetEntity?.field_order?.find((f) => targetEntity.fields[f]?.primary) ?? \"id\",\n [targetEntity],\n );\n\n // Limit IDs sent as filter to avoid exceeding URL length limits.\n // The tab only shows 50 rows; \"View all\" links to the full list.\n const filterIds = useMemo(() => targetIds.slice(0, 50), [targetIds]);\n\n const { data: listResponse, isLoading: loadingRecords } = useQuery({\n queryKey: [\"association-records\", targetEntityCode, filterIds],\n queryFn: () =>\n listEntities(targetEntityCode, {\n per_page: 50,\n filters: [{ field: pk, op: \"in\", value: filterIds }],\n }),\n enabled: filterIds.length > 0 && !!targetEntity,\n });\n\n const rows = listResponse?.data ?? [];\n const refs = listResponse?.$refs;\n\n // Determine columns to display - same logic as ChildrenTable.\n const columns = useMemo(() => {\n if (!targetEntity) return [];\n return targetEntity.field_order\n .filter((name) => {\n const f = targetEntity.fields[name];\n return f && !f.primary && !f.auto && f.display?.is_listable !== false;\n })\n .slice(0, 6);\n }, [targetEntity]);\n\n const handleViewAll = () => {\n const targetScreen = findListScreenForEntity(schema, targetEntityCode);\n if (!targetScreen) return;\n const displayName = loc(association.display?.name) || assocKey;\n const search = new URLSearchParams();\n search.set(\"filters\", JSON.stringify([{ field: pk, op: \"in\", value: targetIds }]));\n tabNavigate(targetScreen.route, {\n title: displayName,\n icon: association.display?.icon || targetScreen.icon,\n search: search.toString(),\n });\n };\n\n if (resolving || loadingRecords) {\n return (\n <div className=\"text-sm text-[var(--muted-foreground)] py-4\">\n Loading...\n </div>\n );\n }\n\n if (!targetEntity) {\n return (\n <div className=\"text-sm text-[var(--muted-foreground)] py-4\">\n Entity not found.\n </div>\n );\n }\n\n if (targetIds.length === 0) {\n return (\n <div className=\"text-sm text-[var(--muted-foreground)] py-4\">\n No related records.\n </div>\n );\n }\n\n const targetScreen = findListScreenForEntity(schema, targetEntityCode);\n\n return (\n <div>\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b\">\n {columns.map((col) => (\n <th\n key={col}\n className=\"h-8 px-3 text-left align-middle font-medium text-[var(--muted-foreground)]\"\n >\n {fieldDisplayName(targetEntity.fields[col], col, schema.entities)}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map((row, i) => (\n <tr key={i} className=\"border-b last:border-0\">\n {columns.map((col) => {\n const field = targetEntity.fields[col];\n if (!field) return <td key={col} />;\n return (\n <td key={col} className=\"px-3 py-2 align-middle\">\n {renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"display\",\n record: row,\n refs,\n })}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n {targetScreen && assocResult && assocResult.count > rows.length && (\n <div className=\"pt-3 text-center\">\n <Button variant=\"outline\" size=\"sm\" onClick={handleViewAll}>\n <ExternalLink className=\"w-3 h-3 mr-1.5\" />\n View all {assocResult.count} records\n </Button>\n </div>\n )}\n {targetScreen && rows.length > 0 && assocResult && assocResult.count <= rows.length && (\n <div className=\"pt-3 text-center\">\n <Button variant=\"ghost\" size=\"sm\" onClick={handleViewAll}>\n <ExternalLink className=\"w-3 h-3 mr-1.5\" />\n Open in list view\n </Button>\n </div>\n )}\n </div>\n );\n}\n","import type { SizeValue } from \"@/types/schema\";\n\n// ParsedSizeValue represents a parsed and normalized SizeValue.\nexport type ParsedSizeValue =\n | { kind: \"weight\"; value: number }\n | { kind: \"px\"; value: number }\n | { kind: \"auto\" }\n | { kind: \"fill\" };\n\nconst PX_PATTERN = /^(\\d+)px$/;\n\n// parseSizeValue parses a SizeValue string into a structured representation.\n// Returns null if the value is invalid.\nexport function parseSizeValue(raw: SizeValue | undefined): ParsedSizeValue | null {\n if (raw == null || raw === \"\") return null;\n\n if (raw === \"auto\") return { kind: \"auto\" };\n if (raw === \"fill\") return { kind: \"fill\" };\n\n // Check for \"<n>px\" format.\n const pxMatch = PX_PATTERN.exec(raw);\n if (pxMatch) {\n const n = parseInt(pxMatch[1], 10);\n if (n > 0) return { kind: \"px\", value: n };\n return null; // 0px or negative is invalid\n }\n\n // Check for integer weight (plain number string or actual number coerced to string).\n const intVal = parseInt(raw, 10);\n if (!isNaN(intVal) && String(intVal) === raw && intVal > 0) {\n return { kind: \"weight\", value: intVal };\n }\n\n return null; // unknown token\n}\n\n// isValidSizeValue returns true if the value can be parsed as a valid SizeValue.\nexport function isValidSizeValue(raw: SizeValue | undefined): boolean {\n if (raw == null || raw === \"\") return true; // omitted is valid\n return parseSizeValue(raw) !== null;\n}\n\n// sizeValueToCSS converts a parsed SizeValue into a CSS value string suitable\n// for flex or grid sizing.\n// weight -> flex: <n> (caller should apply to flex container)\n// px -> \"<n>px\"\n// auto -> \"auto\"\n// fill -> \"1fr\" (for grid) or \"flex: 1\" (for flex)\nexport function sizeValueToCSS(parsed: ParsedSizeValue): string {\n switch (parsed.kind) {\n case \"weight\":\n return String(parsed.value);\n case \"px\":\n return parsed.value + \"px\";\n case \"auto\":\n return \"auto\";\n case \"fill\":\n return \"1fr\";\n }\n}\n\n// normalizeSizeValue parses and returns a CSS-ready string, or the default\n// if the input is empty/undefined.\nexport function normalizeSizeValue(\n raw: SizeValue | undefined,\n defaultValue: ParsedSizeValue,\n): ParsedSizeValue {\n if (raw == null || raw === \"\") return defaultValue;\n return parseSizeValue(raw) ?? defaultValue;\n}\n","import { useState, useCallback, useRef, useEffect } from \"react\";\nimport type { RowConfig, SizeValue } from \"@/types/schema\";\nimport { cn } from \"@/lib/utils\";\nimport { parseSizeValue } from \"@/lib/size-value\";\nimport { LayoutNodeRenderer, type LayoutContext } from \"./LayoutRenderer\";\n\ninterface LayoutRowProps {\n config: RowConfig;\n ctx: LayoutContext;\n}\n\n// LayoutRow renders children horizontally with flex layout. Supports:\n// - gap between items\n// - resizable drag handles between items\n// - responsive stacking below a breakpoint\nexport function LayoutRow({ config, ctx }: LayoutRowProps) {\n const { items, gap = 0, resizable = false, stack_below } = config;\n const stackPx = stack_below === \"never\" ? 0 : (stack_below ?? 768);\n const [stacked, setStacked] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Track container width for responsive stacking.\n useEffect(() => {\n if (stackPx === 0) return;\n const el = containerRef.current;\n if (!el) return;\n\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n setStacked(entry.contentRect.width < stackPx);\n }\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, [stackPx]);\n\n // Track flex sizes when resizable.\n const [flexSizes, setFlexSizes] = useState<number[] | null>(null);\n const dragging = useRef<{ index: number; startX: number; startSizes: number[] } | null>(null);\n\n const getInitialSizes = useCallback((): number[] => {\n return items.map((item) => {\n // Width can live at the LayoutNode level OR inside the container config\n // (e.g. `column: { width: 3 }` vs `width: 3` beside `column:`). Check all.\n const w = item.width ?? item.column?.width ?? item.row?.width ?? config.width;\n const parsed = parseSizeValue(w);\n if (parsed && parsed.kind === \"weight\") return parsed.value;\n return 1;\n });\n }, [items, config.width]);\n\n const onDragStart = useCallback(\n (index: number, e: React.MouseEvent) => {\n e.preventDefault();\n const sizes = flexSizes ?? getInitialSizes();\n dragging.current = { index, startX: e.clientX, startSizes: [...sizes] };\n\n const onMove = (ev: MouseEvent) => {\n const d = dragging.current;\n if (!d || !containerRef.current) return;\n const totalWidth = containerRef.current.getBoundingClientRect().width;\n const delta = ev.clientX - d.startX;\n const totalFlex = d.startSizes.reduce((a, b) => a + b, 0);\n const flexDelta = (delta / totalWidth) * totalFlex;\n const newSizes = [...d.startSizes];\n newSizes[d.index] = Math.max(0.1, d.startSizes[d.index] + flexDelta);\n newSizes[d.index + 1] = Math.max(0.1, d.startSizes[d.index + 1] - flexDelta);\n setFlexSizes(newSizes);\n };\n\n const onUp = () => {\n dragging.current = null;\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n };\n\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n },\n [flexSizes, getInitialSizes],\n );\n\n const sizes = flexSizes ?? getInitialSizes();\n\n // Parse height for the row container (enables scrollable children).\n const heightStyle = config.height ? parseHeight(config.height) : undefined;\n\n return (\n <div\n ref={containerRef}\n className={cn(\"flex\", stacked && \"flex-col\")}\n style={{ gap: gap ? `${gap}px` : undefined, ...heightStyle }}\n >\n {items.map((item, i) => (\n <div\n key={i}\n className={cn(\"min-w-0 flex items-stretch\", stacked && \"w-full\")}\n style={stacked ? undefined : itemStyle(item.width ?? item.column?.width ?? item.row?.width ?? config.width, sizes[i], item.min_width, item.max_width)}\n >\n <div className={cn(\"flex-1 min-w-0 flex flex-col\", heightStyle && \"overflow-y-auto overflow-x-hidden\")}>\n <LayoutNodeRenderer node={item} ctx={ctx} />\n </div>\n {resizable && !stacked && i < items.length - 1 && (\n <div\n className=\"w-1 cursor-col-resize hover:bg-[var(--border)] transition-colors shrink-0\"\n onMouseDown={(e) => onDragStart(i, e)}\n />\n )}\n </div>\n ))}\n </div>\n );\n}\n\nfunction itemStyle(\n width: SizeValue | undefined,\n flexValue: number,\n minWidth?: string,\n maxWidth?: string,\n): React.CSSProperties {\n const parsed = parseSizeValue(width);\n let flex: string;\n if (!parsed || parsed.kind === \"weight\") {\n flex = `${flexValue} 1 0%`;\n } else if (parsed.kind === \"px\") {\n flex = `0 0 ${parsed.value}px`;\n } else if (parsed.kind === \"fill\") {\n flex = \"1 1 0%\";\n } else {\n flex = \"0 0 auto\";\n }\n return { flex, minWidth, maxWidth };\n}\n\nfunction parseHeight(height: SizeValue): React.CSSProperties | undefined {\n if (!height) return undefined;\n const parsed = parseSizeValue(height);\n if (parsed?.kind === \"px\") return { height: `${parsed.value}px`, overflow: \"hidden\" };\n // Support raw CSS values like \"calc(100vh - 200px)\" or \"80vh\" passed as strings.\n // parseSizeValue returns null for these, so we handle them directly.\n if (typeof height === \"string\" && (height.includes(\"vh\") || height.includes(\"calc\") || height.includes(\"%\"))) {\n return { height, overflow: \"hidden\" };\n }\n return undefined;\n}\n","import type { ColumnConfig, LayoutNode } from \"@/types/schema\";\nimport { LayoutNodeRenderer, type LayoutContext } from \"./LayoutRenderer\";\n\ninterface LayoutColumnProps {\n config: ColumnConfig;\n node: LayoutNode;\n ctx: LayoutContext;\n}\n\n// LayoutColumn renders children vertically with flex layout and optional gap.\nexport function LayoutColumn({ config, ctx }: LayoutColumnProps) {\n const { items, gap = 12 } = config;\n\n return (\n <div\n className=\"flex flex-col h-full\"\n style={{ gap: gap ? `${gap}px` : undefined }}\n >\n {items.map((item, i) => (\n <LayoutNodeRenderer key={i} node={item} ctx={ctx} />\n ))}\n </div>\n );\n}\n","import { useState } from \"react\";\nimport type { LayoutNode, TabsConfig } from \"@/types/schema\";\nimport { loc } from \"@/types/schema\";\nimport { cn } from \"@/lib/utils\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\nimport { Card, CardHeader, CardContent } from \"@/components/ui/card\";\nimport { LayoutNodeRenderer, type LayoutContext } from \"./LayoutRenderer\";\n\ninterface LayoutTabsProps {\n config: TabsConfig;\n ctx: LayoutContext;\n}\n\n// getTabLabel derives a user-visible label for a tab from its layout node.\nfunction getTabLabel(node: LayoutNode, ctx: LayoutContext): string {\n // Children nodes have a label or derive from the child entity name.\n if (node.children) {\n if (node.label) return loc(node.label);\n const childRelation = ctx.entity.children?.find((c) => c.entity === node.children);\n if (childRelation?.display?.name) return loc(childRelation.display.name);\n const childEntity = ctx.schema.entities[node.children];\n if (childEntity) return loc(childEntity.display.name_plural) || node.children;\n return node.children;\n }\n // Section nodes use the section name.\n if (node.section) {\n return loc(node.section.name);\n }\n return \"Tab\";\n}\n\n// getTabIcon derives an icon name for a tab.\nfunction getTabIcon(node: LayoutNode, ctx: LayoutContext): string | undefined {\n if (node.icon) return node.icon;\n if (node.children) {\n const childRelation = ctx.entity.children?.find((c) => c.entity === node.children);\n if (childRelation?.display?.icon) return childRelation.display.icon;\n const childEntity = ctx.schema.entities[node.children];\n if (childEntity) return childEntity.display.icon;\n }\n return undefined;\n}\n\n// LayoutTabs renders child nodes as switchable tabs, following the existing\n// tab styling pattern from SmartDetailPage.\nexport function LayoutTabs({ config, ctx }: LayoutTabsProps) {\n const { items } = config;\n const [activeTab, setActiveTab] = useState(0);\n\n if (items.length === 0) return null;\n\n return (\n <Card>\n <CardHeader className=\"py-3\">\n <div className=\"flex items-center gap-1 border-b border-[var(--border)]\">\n {items.map((item, idx) => {\n const label = getTabLabel(item, ctx);\n const icon = getTabIcon(item, ctx);\n return (\n <button\n key={idx}\n className={cn(\n \"flex items-center gap-1.5 px-3 py-2 text-sm transition-colors border-b-2 -mb-px\",\n idx === activeTab\n ? \"border-[var(--foreground)] text-[var(--foreground)]\"\n : \"border-transparent text-[var(--muted-foreground)] hover:text-[var(--foreground)]\",\n )}\n onClick={() => setActiveTab(idx)}\n >\n {icon && <DynamicIcon name={icon} className=\"w-4 h-4\" />}\n {label}\n </button>\n );\n })}\n </div>\n </CardHeader>\n <CardContent className=\"pt-0\">\n <LayoutNodeRenderer\n key={activeTab}\n node={items[activeTab]}\n ctx={ctx}\n />\n </CardContent>\n </Card>\n );\n}\n","import { useState } from \"react\";\nimport type { SectionNode } from \"@/types/schema\";\nimport { loc } from \"@/types/schema\";\nimport { cn } from \"@/lib/utils\";\nimport { Card, CardHeader, CardTitle, CardContent } from \"@/components/ui/card\";\nimport { ChevronDown } from \"lucide-react\";\nimport type { LayoutContext } from \"./LayoutRenderer\";\nimport { LayoutRenderer } from \"./LayoutRenderer\";\n\ninterface SectionBlockProps {\n config: SectionNode;\n ctx: LayoutContext;\n}\n\n// SectionBlock renders a collapsible card that wraps nested layout nodes.\nexport function SectionBlock({ config, ctx }: SectionBlockProps) {\n const { name, items, collapsed: defaultCollapsed = false, columns } = config;\n const [collapsed, setCollapsed] = useState(defaultCollapsed);\n const childCtx = columns ? { ...ctx, columns } : ctx;\n\n return (\n <Card>\n <CardHeader\n className=\"cursor-pointer py-4\"\n onClick={() => setCollapsed((c) => !c)}\n >\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">{loc(name)}</CardTitle>\n <ChevronDown\n className={cn(\n \"w-4 h-4 text-[var(--muted-foreground)] transition-transform\",\n collapsed && \"-rotate-90\",\n )}\n />\n </div>\n </CardHeader>\n {!collapsed && (\n <CardContent>\n <LayoutRenderer nodes={items} ctx={childCtx} />\n </CardContent>\n )}\n </Card>\n );\n}\n","import type {\n ChildDisplayMode,\n ChildQuickAdd,\n ChildRelation,\n CardsConfig,\n Entity,\n LayoutNode,\n LocalizedString,\n TimelineConfig,\n} from \"@/types/schema\";\nimport { getPrimaryKeyFields } from \"@/types/schema\";\n\n// ResolvedChildConfig is the fully-resolved rendering configuration for a\n// child entity on a detail screen. All optional fields are filled by the\n// three-layer precedence algorithm or auto-derivation.\nexport interface ResolvedChildConfig {\n entity: string;\n foreign_key: string | string[];\n name: LocalizedString;\n icon: string;\n mode: ChildDisplayMode;\n columns: string[];\n sort: string;\n limit: number;\n timeline?: TimelineConfig;\n cards?: CardsConfig;\n quick_add?: ChildQuickAdd;\n editable: boolean;\n position_field?: string;\n}\n\n// resolveChildConfig applies the three-layer precedence algorithm:\n// 1. Screen node override (highest priority)\n// 2. Entity-level child defaults\n// 3. Auto-derived defaults (lowest priority)\n//\n// Structural fields (entity, foreign_key) come from the relation and are\n// never overridable from screen layout.\nexport function resolveChildConfig(\n relation: ChildRelation,\n childEntity: Entity,\n screenNode?: LayoutNode,\n): ResolvedChildConfig {\n const display = relation.display;\n\n // Start with structural fields from the relation.\n const result: ResolvedChildConfig = {\n entity: relation.entity,\n foreign_key: relation.foreign_key,\n name: resolveField(screenNode?.label, display?.name, inferName(childEntity)),\n icon: resolveField(screenNode?.icon, display?.icon, childEntity.display.icon) ?? \"\",\n mode: resolveField(screenNode?.mode, display?.mode, \"table\") as ChildDisplayMode,\n columns: resolveField(screenNode?.columns, display?.columns, inferColumns(childEntity, relation.foreign_key)),\n sort: resolveField(screenNode?.sort, display?.sort, inferSort(childEntity)),\n limit: resolveField(screenNode?.limit, display?.limit, 20),\n editable: resolveField(screenNode?.editable, display?.editable, true),\n };\n\n // Resolve position_field: screen override > entity-level > undefined.\n const posField = resolveField(screenNode?.position_field, display?.position_field, undefined as string | undefined);\n if (posField) {\n result.position_field = posField;\n // When position_field is active, sort is always position_field:asc.\n result.sort = posField + \":asc\";\n }\n\n // Resolve timeline config.\n const timelineSource = screenNode?.timeline ?? display?.timeline;\n if (result.mode === \"timeline\") {\n result.timeline = inferTimelineFields(timelineSource ?? {}, childEntity);\n } else if (timelineSource) {\n result.timeline = timelineSource;\n }\n\n // Resolve cards config.\n const cardsSource = screenNode?.cards ?? display?.cards;\n if (cardsSource) {\n result.cards = cardsSource;\n }\n\n // Resolve quick_add.\n const quickAdd = screenNode?.quick_add ?? relation.quick_add;\n if (quickAdd) {\n result.quick_add = quickAdd;\n }\n\n return result;\n}\n\n// resolveField returns the first non-nullish value from the precedence chain.\nfunction resolveField<T>(screenOverride: T | undefined, entityDefault: T | undefined, autoDefault: T): T {\n if (screenOverride != null) return screenOverride;\n if (entityDefault != null) return entityDefault;\n return autoDefault;\n}\n\nfunction inferName(entity: Entity): LocalizedString {\n if (entity.display.name_plural && Object.keys(entity.display.name_plural).length > 0) {\n return entity.display.name_plural;\n }\n return entity.display.name;\n}\n\n// inferSort returns a default sort string using the fallback chain:\n// created_at:desc -> updated_at:desc -> first timestamp :desc ->\n// first date :desc -> primary_key:asc\nexport function inferSort(entity: Entity): string {\n if (entity.fields[\"created_at\"]?.type === \"timestamp\") {\n return \"created_at:desc\";\n }\n if (entity.fields[\"updated_at\"]?.type === \"timestamp\") {\n return \"updated_at:desc\";\n }\n for (const name of entity.field_order) {\n const f = entity.fields[name];\n if (f && f.type === \"timestamp\") {\n return name + \":desc\";\n }\n }\n for (const name of entity.field_order) {\n const f = entity.fields[name];\n if (f && f.type === \"date\") {\n return name + \":desc\";\n }\n }\n // Fall back to first primary key field.\n const pk = findPrimaryKey(entity);\n if (pk) return pk + \":asc\";\n return \"\";\n}\n\n// inferColumns returns up to 6 fields from field_order, excluding primary,\n// auto, is_listable, and the parent FK field(s).\nexport function inferColumns(entity: Entity, fk: string | string[]): string[] {\n const fkSet = new Set(Array.isArray(fk) ? fk : [fk]);\n const cols: string[] = [];\n for (const name of entity.field_order) {\n if (cols.length >= 6) break;\n const f = entity.fields[name];\n if (!f) continue;\n if (f.primary || f.auto) continue;\n if (f.display?.is_listable === false) continue;\n if (fkSet.has(name)) continue;\n cols.push(name);\n }\n return cols;\n}\n\n// inferTimelineFields fills missing timeline config fields from entity fields.\n// Missing optional fields are left empty (they are simply not rendered).\nexport function inferTimelineFields(tc: TimelineConfig, entity: Entity): TimelineConfig {\n const result: TimelineConfig = { ...tc };\n\n if (!result.time_field) {\n result.time_field = inferTimeField(entity);\n }\n if (!result.type_field) {\n result.type_field = inferFirstFieldOfType(entity, \"enum\");\n }\n if (!result.summary_field) {\n result.summary_field = inferFirstFieldOfTypes(entity, \"string\", \"text\");\n }\n if (!result.content_field) {\n result.content_field = inferFirstFieldOfType(entity, \"text\");\n }\n if (!result.author_field) {\n if (entity.fields[\"created_by\"]) {\n result.author_field = \"created_by\";\n }\n }\n if (!result.direction_field) {\n result.direction_field = inferDirectionField(entity);\n }\n if (!result.intent_field) {\n result.intent_field = inferIntentField(entity);\n }\n\n return result;\n}\n\nfunction inferDirectionField(entity: Entity): string | undefined {\n const direction = entity.fields[\"direction\"];\n if (direction && direction.type === \"enum\") return \"direction\";\n for (const name of [\"is_outbound\", \"outbound\", \"is_inbound\", \"inbound\"]) {\n const f = entity.fields[name];\n if (f && f.type === \"bool\") return name;\n }\n return undefined;\n}\n\nfunction inferIntentField(entity: Entity): string | undefined {\n const intent = entity.fields[\"intent\"];\n if (intent && intent.type === \"enum\") return \"intent\";\n return undefined;\n}\n\nfunction inferTimeField(entity: Entity): string | undefined {\n // Prefer explicit (non-auto) timestamps first.\n for (const name of entity.field_order) {\n const f = entity.fields[name];\n if (f && f.type === \"timestamp\" && !f.auto) {\n return name;\n }\n }\n // Fall back to auto timestamps: created_at/updated_at first, then any.\n if (entity.fields[\"created_at\"]?.type === \"timestamp\") return \"created_at\";\n if (entity.fields[\"updated_at\"]?.type === \"timestamp\") return \"updated_at\";\n for (const name of entity.field_order) {\n const f = entity.fields[name];\n if (f && f.type === \"timestamp\") return name;\n }\n return undefined;\n}\n\nfunction inferFirstFieldOfType(entity: Entity, type: string): string | undefined {\n for (const name of entity.field_order) {\n const f = entity.fields[name];\n if (f && f.type === type) {\n return name;\n }\n }\n return undefined;\n}\n\nfunction inferFirstFieldOfTypes(entity: Entity, ...types: string[]): string | undefined {\n for (const name of entity.field_order) {\n const f = entity.fields[name];\n if (!f) continue;\n for (const t of types) {\n if (f.type === t) return name;\n }\n }\n return undefined;\n}\n\n// findPrimaryKey returns the first primary key field name.\n// Supports composite PK via entity.primary_key (returns first element).\n// Used for backward-compat scenarios where a single field name is needed\n// (e.g. sort fallback). For full composite PK support, use getPrimaryKeyFields().\nexport function findPrimaryKey(entity: Entity): string | undefined {\n const pks = getPrimaryKeyFields(entity);\n return pks.length > 0 ? pks[0] : undefined;\n}\n\n// findPrimaryKeys returns all primary key field names as an array.\n// Delegates to getPrimaryKeyFields from schema types.\nexport function findPrimaryKeys(entity: Entity): string[] {\n return getPrimaryKeyFields(entity);\n}\n\n// findChildRelation looks up a child relation by entity code on the parent entity.\nexport function findChildRelation(parentEntity: Entity, childCode: string): ChildRelation | undefined {\n return parentEntity.children?.find((c) => c.entity === childCode);\n}\n","// buildQuickAddPayload builds the POST body for a quick-add submission.\n//\n// Precedence (highest first):\n// 1. FK auto-injection - always set, overwrites user input and defaults\n// 2. User field values - user input wins over defaults\n// 3. Configured defaults - from quick_add.defaults\n//\n// The FK is intentionally never shown as an input field and must always\n// reflect the current parent record's ID.\nexport function buildQuickAddPayload(\n fieldValues: Record<string, unknown>,\n defaults: Record<string, unknown> | undefined,\n foreignKey: string | string[],\n parentId: string | string[],\n): Record<string, unknown> {\n const result: Record<string, unknown> = {\n ...(defaults ?? {}),\n ...fieldValues,\n };\n if (Array.isArray(foreignKey)) {\n // For composite FK, parentId may be a pipe-joined string from the URL.\n const ids = Array.isArray(parentId) ? parentId : String(parentId).split(\"|\");\n for (let i = 0; i < foreignKey.length; i++) {\n result[foreignKey[i]] = ids[i];\n }\n } else {\n result[foreignKey] = Array.isArray(parentId) ? parentId[0] : parentId;\n }\n return result;\n}\n\n// isQuickAddReady returns true when all quick_add.fields with required entity\n// fields have non-empty values. Fields that are not marked required in the\n// entity definition are always considered satisfied.\nexport function isQuickAddReady(\n fieldValues: Record<string, unknown>,\n requiredFields: string[],\n): boolean {\n for (const name of requiredFields) {\n const val = fieldValues[name];\n if (val == null || val === \"\") return false;\n }\n return true;\n}\n","import { useState, type FormEvent } from \"react\";\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { createEntity } from \"@/api/data\";\nimport { buildQuickAddPayload, isQuickAddReady } from \"@/lib/quick-add\";\nimport { ENTITY_CHILDREN_KEY } from \"@/hooks/useChildrenData\";\nimport type { ResolvedChildConfig } from \"@/lib/child-config\";\nimport type { Schema } from \"@/types/schema\";\n\n/** Return current time as bare local datetime \"YYYY-MM-DDTHH:MM\" (no offset). */\nfunction toBareLocalNow(): string {\n const now = new Date();\n const y = now.getFullYear();\n const m = String(now.getMonth() + 1).padStart(2, \"0\");\n const d = String(now.getDate()).padStart(2, \"0\");\n const h = String(now.getHours()).padStart(2, \"0\");\n const min = String(now.getMinutes()).padStart(2, \"0\");\n return `${y}-${m}-${d}T${h}:${min}`;\n}\n\nexport interface UseQuickAddResult {\n values: Record<string, unknown>;\n quickAdd: ResolvedChildConfig[\"quick_add\"];\n childEntity: ReturnType<typeof getChildEntity>;\n isPending: boolean;\n error: Error | null;\n isReady: boolean;\n handleSubmit: (e: FormEvent) => void;\n handleFieldChange: (fieldName: string, val: unknown) => void;\n}\n\ntype ChildEntity = Schema[\"entities\"][string] | undefined;\n\nfunction getChildEntity(schema: Schema, entityCode: string): ChildEntity {\n return schema.entities[entityCode];\n}\n\n// useQuickAdd encapsulates all shared state and mutation logic for quick-add\n// forms. It is used by QuickAddForm (table/list/cards) and TimelineComposer\n// (timeline). All hooks are called unconditionally before any early returns\n// in the consuming component.\nexport function useQuickAdd(\n config: ResolvedChildConfig,\n parentEntity: string,\n parentId: string | string[],\n schema: Schema,\n): UseQuickAddResult {\n const [values, setValues] = useState<Record<string, unknown>>(() => {\n const qa0 = config.quick_add;\n const ce = schema.entities[config.entity];\n const initialValues: Record<string, unknown> = {};\n if (qa0?.fields) {\n for (const f of qa0.fields) {\n if (qa0.defaults?.[f] != null) {\n initialValues[f] = qa0.defaults[f];\n } else if (ce?.fields[f]?.type === \"timestamp\") {\n // Default timestamp fields to now as bare local datetime.\n // The server interprets this in the field's configured timezone.\n initialValues[f] = toBareLocalNow();\n }\n }\n }\n return initialValues;\n });\n const queryClient = useQueryClient();\n const { mutate, isPending, error, reset } = useMutation({\n mutationFn: (payload: Record<string, unknown>) => createEntity(config.entity, payload),\n onSuccess: () => {\n // Reset all visible fields to their defaults (or empty), clearing any\n // user-typed values for fields that have no configured default.\n const qa = config.quick_add;\n const ce = schema.entities[config.entity];\n const resetValues: Record<string, unknown> = {};\n if (qa?.fields) {\n for (const f of qa.fields) {\n if (qa?.defaults?.[f] != null) {\n resetValues[f] = qa.defaults[f];\n } else if (ce?.fields[f]?.type === \"timestamp\") {\n resetValues[f] = toBareLocalNow();\n } else {\n resetValues[f] = \"\";\n }\n }\n }\n setValues(resetValues);\n const normalizedParentId = Array.isArray(parentId) ? parentId.join(\"|\") : parentId;\n queryClient.invalidateQueries({\n queryKey: [ENTITY_CHILDREN_KEY, parentEntity, normalizedParentId, config.entity],\n });\n },\n });\n\n const quickAdd = config.quick_add;\n const childEntity = schema.entities[config.entity];\n\n // Derive required fields from the quick_add field list.\n // Only fields marked required on the entity definition are checked.\n const requiredFields = quickAdd?.fields.filter(\n (f) => childEntity?.fields[f]?.required,\n ) ?? [];\n const isReady = isQuickAddReady(values, requiredFields);\n\n function handleSubmit(e: FormEvent) {\n e.preventDefault();\n if (!quickAdd) return;\n const payload = buildQuickAddPayload(values, quickAdd.defaults, config.foreign_key, parentId);\n mutate(payload);\n }\n\n function handleFieldChange(fieldName: string, val: unknown) {\n if (error) reset();\n setValues((prev: Record<string, unknown>) => ({ ...prev, [fieldName]: val }));\n }\n\n return {\n values,\n quickAdd,\n childEntity,\n isPending,\n error,\n isReady,\n handleSubmit,\n handleFieldChange,\n };\n}\n","import { fieldDisplayName } from \"@/types/schema\";\nimport { renderField } from \"@/components/fields\";\nimport { Button } from \"@/components/ui/button\";\nimport { useQuickAdd } from \"./useQuickAdd\";\nimport type { ResolvedChildConfig } from \"@/lib/child-config\";\nimport type { Schema } from \"@/types/schema\";\n\ninterface QuickAddFormProps {\n config: ResolvedChildConfig;\n parentEntity: string;\n parentId: string | string[];\n schema: Schema;\n}\n\n// QuickAddForm renders an inline quick-add row above child content for\n// table, list, and cards display modes. On submit it POSTs to the child\n// entity endpoint, injects the FK, merges defaults, and invalidates the\n// child query so the list refreshes immediately.\nexport function QuickAddForm({ config, parentEntity, parentId, schema }: QuickAddFormProps) {\n // All hooks must be called unconditionally before any early returns.\n const { values, quickAdd, childEntity, isPending, error, isReady, handleSubmit, handleFieldChange } =\n useQuickAdd(config, parentEntity, parentId, schema);\n\n if (!quickAdd || quickAdd.fields.length === 0) return null;\n if (!childEntity) return null;\n\n return (\n <form\n onSubmit={handleSubmit}\n className=\"flex items-end gap-2 py-2 border-b border-[var(--border)]\"\n >\n {quickAdd.fields.map((fieldName) => {\n const field = childEntity.fields[fieldName];\n if (!field) return null;\n return (\n <div key={fieldName} className=\"flex-1 min-w-0\">\n <label className=\"text-xs text-[var(--muted-foreground)] mb-1 block\">\n {fieldDisplayName(field, fieldName, schema.entities)}\n </label>\n {renderField({\n field,\n fieldName,\n value: values[fieldName] ?? \"\",\n mode: \"edit\",\n onChange: (val) => handleFieldChange(fieldName, val),\n record: values,\n })}\n </div>\n );\n })}\n <Button type=\"submit\" size=\"sm\" disabled={isPending || !isReady} className=\"shrink-0 mb-0.5\">\n Add\n </Button>\n {error != null && (\n <span className=\"text-xs text-[var(--destructive)] self-end mb-1\">\n {error.message}\n </span>\n )}\n </form>\n );\n}\n","import { fieldDisplayName } from \"@/types/schema\";\nimport { renderField } from \"@/components/fields\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport { useChildrenData } from \"@/hooks/useChildrenData\";\nimport { QuickAddForm } from \"./QuickAddForm\";\nimport type { ChildDisplayProps } from \"./ChildrenBlock\";\n\n// ChildrenTable renders child records as a table with column headers.\n// Supports configurable columns, sort, and limit. Shows a quick-add form\n// above the table when quick_add is configured.\nexport function ChildrenTable({ config, parentEntity, parentId, schema }: ChildDisplayProps) {\n const childEntity = schema.entities[config.entity];\n const { data: response, isLoading, isError } = useChildrenData(parentEntity, parentId, config.entity, config.foreign_key, config.sort, config.limit);\n const rows = response?.data ?? [];\n const refs = response?.$refs;\n const columns = config.columns;\n\n if (!childEntity) {\n return <div className=\"text-sm text-[var(--muted-foreground)] py-2\">Entity not found.</div>;\n }\n\n const quickAddForm = (\n <QuickAddForm\n config={config}\n parentEntity={parentEntity}\n parentId={parentId}\n schema={schema}\n />\n );\n\n if (isError) {\n return (\n <div>\n {quickAddForm}\n <div className=\"text-sm text-[var(--destructive)] py-2\">Failed to load. Try again.</div>\n </div>\n );\n }\n\n\n if (isLoading) {\n return (\n <div>\n {quickAddForm}\n <div className=\"space-y-2 py-2\">\n <Skeleton className=\"h-8 w-full\" />\n <Skeleton className=\"h-8 w-full\" />\n <Skeleton className=\"h-8 w-full\" />\n </div>\n </div>\n );\n }\n\n if (rows.length === 0) {\n return (\n <div>\n {quickAddForm}\n <div className=\"text-sm text-[var(--muted-foreground)] py-4\">\n No records yet.\n </div>\n </div>\n );\n }\n\n return (\n <div>\n {quickAddForm}\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b\">\n {columns.map((col) => {\n const field = childEntity.fields[col];\n return (\n <th\n key={col}\n className=\"h-8 px-3 text-left align-middle font-medium text-[var(--muted-foreground)]\"\n >\n {field ? fieldDisplayName(field, col, schema.entities) : col}\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {rows.map((row, rowIdx) => (\n <tr key={String((row as Record<string, unknown>)[\"id\"] ?? rowIdx)} className=\"border-b last:border-0 hover:bg-[var(--muted)]/50\">\n {columns.map((col) => {\n const field = childEntity.fields[col];\n return (\n <td key={col} className=\"px-3 py-2 align-middle\">\n {field\n ? renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"display\",\n record: row,\n refs,\n })\n : String(row[col] ?? \"\")}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n","import { renderField } from \"@/components/fields\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport { useChildrenData } from \"@/hooks/useChildrenData\";\nimport { QuickAddForm } from \"./QuickAddForm\";\nimport type { ChildDisplayProps } from \"./ChildrenBlock\";\n\n// ChildrenList renders child records as compact rows without column headers.\n// Best for simple or narrow side panels. Shows a quick-add form above the\n// list when quick_add is configured.\nexport function ChildrenList({ config, parentEntity, parentId, schema }: ChildDisplayProps) {\n const childEntity = schema.entities[config.entity];\n const { data: response, isLoading, isError } = useChildrenData(parentEntity, parentId, config.entity, config.foreign_key, config.sort, config.limit);\n const rows = response?.data ?? [];\n const refs = response?.$refs;\n const columns = config.columns;\n\n if (!childEntity) {\n return <div className=\"text-sm text-[var(--muted-foreground)] py-2\">Entity not found.</div>;\n }\n\n const quickAddForm = (\n <QuickAddForm\n config={config}\n parentEntity={parentEntity}\n parentId={parentId}\n schema={schema}\n />\n );\n\n if (isError) {\n return (\n <div>\n {quickAddForm}\n <div className=\"text-sm text-[var(--destructive)] py-2\">Failed to load. Try again.</div>\n </div>\n );\n }\n\n\n if (isLoading) {\n return (\n <div>\n {quickAddForm}\n <div className=\"space-y-2 py-2\">\n <Skeleton className=\"h-6 w-full\" />\n <Skeleton className=\"h-6 w-full\" />\n <Skeleton className=\"h-6 w-3/4\" />\n </div>\n </div>\n );\n }\n\n if (rows.length === 0) {\n return (\n <div>\n {quickAddForm}\n <div className=\"text-sm text-[var(--muted-foreground)] py-4\">\n No records yet.\n </div>\n </div>\n );\n }\n\n // Use the display field if available, otherwise first column (may be\n // undefined if columns is empty, in which case rows render with no label).\n const displayField = columns.length > 0\n ? (childEntity.display.display_field ?? columns[0])\n : childEntity.display.display_field;\n\n return (\n <div>\n {quickAddForm}\n <div className=\"divide-y divide-[var(--border)]\">\n {rows.map((row, idx) => (\n <div key={String((row as Record<string, unknown>)[\"id\"] ?? idx)} className=\"flex items-center gap-3 py-2 px-1 hover:bg-[var(--muted)]/50\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm truncate\">\n {displayField && childEntity.fields[displayField]\n ? renderField({\n field: childEntity.fields[displayField],\n fieldName: displayField,\n value: row[displayField],\n mode: \"display\",\n record: row,\n refs,\n })\n : displayField && row[displayField] != null\n ? String(row[displayField])\n : null}\n </div>\n {columns.length > 1 && (() => {\n const subCols = columns.slice(1, 3).filter((col) => row[col] != null);\n if (subCols.length === 0) return null;\n return (\n <div className=\"text-xs text-[var(--muted-foreground)] truncate\">\n {subCols.map((col, i) => (\n <span key={col}>\n {i > 0 && \" - \"}\n {childEntity.fields[col]\n ? renderField({\n field: childEntity.fields[col],\n fieldName: col,\n value: row[col],\n mode: \"display\",\n record: row,\n refs,\n })\n : String(row[col])}\n </span>\n ))}\n </div>\n );\n })()}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import { renderField } from \"@/components/fields\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport { useChildrenData } from \"@/hooks/useChildrenData\";\nimport { QuickAddForm } from \"./QuickAddForm\";\nimport type { ChildDisplayProps } from \"./ChildrenBlock\";\n\n// ChildrenCards renders child records as a responsive card grid.\n// Supports configurable columns_count, header_field, and badge_field.\n// Shows a quick-add form above the grid when quick_add is configured.\nexport function ChildrenCards({ config, parentEntity, parentId, schema }: ChildDisplayProps) {\n const childEntity = schema.entities[config.entity];\n const { data: response, isLoading, isError } = useChildrenData(parentEntity, parentId, config.entity, config.foreign_key, config.sort, config.limit);\n const rows = response?.data ?? [];\n const refs = response?.$refs;\n const columns = config.columns;\n const cardsConfig = config.cards;\n const headerField = cardsConfig?.header_field ?? columns[0];\n const badgeField = cardsConfig?.badge_field;\n const colCount = cardsConfig?.columns_count;\n\n if (!childEntity) {\n return <div className=\"text-sm text-[var(--muted-foreground)] py-2\">Entity not found.</div>;\n }\n\n const quickAddForm = (\n <QuickAddForm\n config={config}\n parentEntity={parentEntity}\n parentId={parentId}\n schema={schema}\n />\n );\n\n if (isError) {\n return (\n <div>\n {quickAddForm}\n <div className=\"text-sm text-[var(--destructive)] py-2\">Failed to load. Try again.</div>\n </div>\n );\n }\n\n\n if (isLoading) {\n return (\n <div>\n {quickAddForm}\n <div className={gridClass(colCount)}>\n <Skeleton className=\"h-24 w-full rounded-xl\" />\n <Skeleton className=\"h-24 w-full rounded-xl\" />\n <Skeleton className=\"h-24 w-full rounded-xl\" />\n </div>\n </div>\n );\n }\n\n if (rows.length === 0) {\n return (\n <div>\n {quickAddForm}\n <div className=\"text-sm text-[var(--muted-foreground)] py-4\">\n No records yet.\n </div>\n </div>\n );\n }\n\n // Determine detail fields: columns minus header and badge.\n const detailFields = columns.filter((c) => c !== headerField && c !== badgeField);\n\n return (\n <div>\n {quickAddForm}\n <div className={gridClass(colCount)}>\n {rows.map((row, idx) => (\n <Card key={String((row as Record<string, unknown>)[\"id\"] ?? idx)} className=\"overflow-hidden\">\n <CardHeader className=\"py-3 px-4\">\n <div className=\"flex items-center justify-between gap-2\">\n <CardTitle className=\"text-sm truncate\">\n {headerField && childEntity.fields[headerField]\n ? renderField({\n field: childEntity.fields[headerField],\n fieldName: headerField,\n value: row[headerField],\n mode: \"display\",\n record: row,\n refs,\n })\n : `Record ${idx + 1}`}\n </CardTitle>\n {badgeField && row[badgeField] != null && (\n <Badge variant=\"secondary\" className=\"text-xs shrink-0\">\n {childEntity.fields[badgeField]\n ? renderField({\n field: childEntity.fields[badgeField],\n fieldName: badgeField,\n value: row[badgeField],\n mode: \"display\",\n record: row,\n refs,\n })\n : String(row[badgeField])}\n </Badge>\n )}\n </div>\n </CardHeader>\n {detailFields.length > 0 && (\n <CardContent className=\"px-4 pb-3 pt-0\">\n <div className=\"space-y-1\">\n {detailFields.slice(0, 4).map((col) => {\n const field = childEntity.fields[col];\n if (!field) return null;\n return (\n <div key={col} className=\"flex items-baseline gap-2 text-xs\">\n <span className=\"text-[var(--muted-foreground)] shrink-0\">\n {schema.entities[config.entity]?.fields[col]?.display?.name\n ? Object.values(schema.entities[config.entity].fields[col].display!.name)[0]\n : col}:\n </span>\n <span className=\"truncate\">\n {renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"display\",\n record: row,\n refs,\n })}\n </span>\n </div>\n );\n })}\n </div>\n </CardContent>\n )}\n </Card>\n ))}\n </div>\n </div>\n );\n}\n\nfunction gridClass(colCount: number | undefined): string {\n switch (colCount) {\n case 1: return \"grid grid-cols-1 gap-3\";\n case 2: return \"grid grid-cols-1 sm:grid-cols-2 gap-3\";\n case 3: return \"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3\";\n case 4: return \"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3\";\n default: return \"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3\"; // auto\n }\n}\n","import { useState, useCallback, useRef, useEffect, useMemo } from \"react\";\nimport { renderField } from \"@/components/fields\";\nimport { Button } from \"@/components/ui/button\";\nimport { useQuickAdd } from \"./useQuickAdd\";\nimport { registerFieldRegion } from \"@/lib/field-regions\";\nimport type { ResolvedChildConfig } from \"@/lib/child-config\";\nimport type { Schema } from \"@/types/schema\";\n\n// QUICK_ENTRY_REGION is the registered field-region name for the activity\n// composer. ui_steps reference it as \"quick_entry.FIELD\" (e.g. quick_entry.body).\nconst QUICK_ENTRY_REGION = \"quick_entry\";\n\ninterface TimelineComposerProps {\n config: ResolvedChildConfig;\n parentEntity: string;\n parentId: string | string[];\n schema: Schema;\n}\n\nconst MIN_HEIGHT = 100;\nconst DEFAULT_HEIGHT = 180;\n// Generous ceiling so users can compose long multi-paragraph messages\n// (LinkedIn main/bump messages are often 500-1500 chars) by dragging the\n// top handle up. Concrete pixel cap — not viewport-relative — so the\n// composer never covers more than the intended portion of the panel.\nconst MAX_HEIGHT = 800;\n\n// TimelineComposer renders a resizable bottom composer for timeline mode.\n// Sits at the bottom of the Activity panel. Drag the top edge to resize upward.\nexport function TimelineComposer({ config, parentEntity, parentId, schema }: TimelineComposerProps) {\n const { values, quickAdd, childEntity, isPending, error, isReady, handleSubmit, handleFieldChange } =\n useQuickAdd(config, parentEntity, parentId, schema);\n\n const [height, setHeight] = useState(DEFAULT_HEIGHT);\n const dragging = useRef<{ startY: number; startHeight: number } | null>(null);\n\n // Stable refs for the field region. React state closures would go stale\n // inside the region handle; refs always read the current value.\n const valuesRef = useRef(values);\n valuesRef.current = values;\n const handleFieldChangeRef = useRef(handleFieldChange);\n handleFieldChangeRef.current = handleFieldChange;\n const fieldNodesRef = useRef<Record<string, HTMLElement | null>>({});\n\n const region = useMemo(() => ({\n getField: (fieldName: string) => valuesRef.current[fieldName],\n setField: (fieldName: string, value: unknown) => {\n handleFieldChangeRef.current(fieldName, value);\n },\n focusField: (fieldName: string) => {\n const node = fieldNodesRef.current[fieldName];\n if (!node) return;\n const focusable = node.querySelector<HTMLElement>(\"textarea, input, select, [contenteditable]\");\n (focusable ?? node).focus();\n },\n }), []);\n\n useEffect(() => registerFieldRegion(QUICK_ENTRY_REGION, region), [region]);\n\n const onDragStart = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n dragging.current = { startY: e.clientY, startHeight: height };\n\n const onMove = (ev: MouseEvent) => {\n if (!dragging.current) return;\n const delta = dragging.current.startY - ev.clientY;\n const next = Math.min(MAX_HEIGHT, Math.max(MIN_HEIGHT, dragging.current.startHeight + delta));\n setHeight(next);\n };\n\n const onUp = () => {\n dragging.current = null;\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n };\n\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n },\n [height],\n );\n\n if (!quickAdd || quickAdd.fields.length === 0) return null;\n if (!childEntity) return null;\n\n // Partition the configured quick_add.fields into three zones so the\n // composer reads top-to-bottom as \"classify → write → timestamp+send\":\n // topFields — enum comboboxes (channel, intent, direction, …)\n // contentField — the one text/string field that gets the textarea\n // bottomFields — everything else (typically just the timestamp)\n const contentField = quickAdd.fields.find((f) => {\n const field = childEntity.fields[f];\n return field && (field.type === \"text\" || field.type === \"string\");\n });\n const topFields: string[] = [];\n const bottomFields: string[] = [];\n for (const f of quickAdd.fields) {\n if (f === contentField) continue;\n const field = childEntity.fields[f];\n if (!field) continue;\n if (field.type === \"enum\") {\n topFields.push(f);\n } else {\n bottomFields.push(f);\n }\n }\n\n const renderMetaField = (fieldName: string) => {\n const field = childEntity.fields[fieldName];\n if (!field) return null;\n return (\n <div key={fieldName} ref={(el) => { fieldNodesRef.current[fieldName] = el; }}>\n {renderField({\n field,\n fieldName,\n value: values[fieldName] ?? \"\",\n mode: \"edit\",\n onChange: (val) => handleFieldChange(fieldName, val),\n record: values,\n })}\n </div>\n );\n };\n\n return (\n <div\n className=\"shrink-0 border-t border-[var(--border)] bg-[var(--card)] flex flex-col\"\n style={{ height: `${height}px` }}\n >\n {/* Resize handle — drag up/down to make the composer taller or\n shorter. Wider hit area and a more prominent grip bar make it\n discoverable without cluttering the panel chrome. */}\n <div\n className=\"h-3 cursor-row-resize flex items-center justify-center shrink-0 hover:bg-[var(--muted)]/50 transition-colors group\"\n onMouseDown={onDragStart}\n title=\"Drag to resize\"\n >\n <div className=\"w-16 h-1 rounded-full bg-[var(--border)] group-hover:bg-[var(--muted-foreground)] transition-colors\" />\n </div>\n\n <form onSubmit={handleSubmit} className=\"flex-1 min-h-0 flex flex-col gap-1.5 px-3 pb-2\">\n {/* Top row: classifier enums (channel, intent, direction…).\n flex-wrap so narrow panels (sidebar mode, ~420px) don't cram\n controls into an unreadable strip. */}\n {topFields.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-2 shrink-0\">\n {topFields.map(renderMetaField)}\n </div>\n )}\n\n {/* Content textarea fills the remaining vertical space. */}\n {contentField && childEntity.fields[contentField] && (\n <div\n className=\"flex-1 min-h-0 [&_textarea]:!h-full [&_textarea]:!min-h-0 [&_textarea]:!resize-none\"\n ref={(el) => { fieldNodesRef.current[contentField] = el; }}\n >\n {renderField({\n field: childEntity.fields[contentField],\n fieldName: contentField,\n value: values[contentField] ?? \"\",\n mode: \"edit\",\n onChange: (val) => handleFieldChange(contentField, val),\n record: values,\n })}\n </div>\n )}\n\n {/* Bottom row: non-enum meta (typically the timestamp) + submit\n button. Submit stays right-aligned even when there are no\n bottom meta fields. */}\n <div className=\"flex flex-wrap items-center gap-2 shrink-0\">\n {bottomFields.map(renderMetaField)}\n <div className=\"ml-auto\">\n <Button type=\"submit\" size=\"sm\" disabled={isPending || !isReady}>\n Add Note\n </Button>\n </div>\n </div>\n\n {error != null && (\n <p className=\"text-xs text-[var(--destructive)] shrink-0\">{error.message}</p>\n )}\n </form>\n </div>\n );\n}\n","import { useState, useCallback, useRef, useEffect } from \"react\";\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { Pencil, Check, X, Trash2, ArrowDownLeft, ArrowUpRight } from \"lucide-react\";\nimport { renderField } from \"@/components/fields\";\nimport { Button } from \"@/components/ui/button\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport { useChildrenData, ENTITY_CHILDREN_KEY } from \"@/hooks/useChildrenData\";\nimport { updateEntity, deleteEntity } from \"@/api/data\";\nimport { toast } from \"sonner\";\nimport { loc, fieldDisplayName } from \"@/types/schema\";\nimport type { EntityField } from \"@/types/schema\";\nimport { TimelineComposer } from \"./TimelineComposer\";\nimport type { ChildDisplayProps } from \"./ChildrenBlock\";\n\ntype RowData = Record<string, unknown>;\n\nexport function ChildrenTimeline({ config, parentEntity, parentId, schema }: ChildDisplayProps) {\n const childEntity = schema.entities[config.entity];\n const { data: response, isLoading, isError } = useChildrenData(parentEntity, parentId, config.entity, config.foreign_key, config.sort, config.limit);\n const rows = response?.data ?? [];\n const refs = response?.$refs;\n const timeline = config.timeline;\n const scroll = timeline?.scroll ?? false;\n\n const autoScroll = timeline?.auto_scroll ?? \"none\";\n const scrollRef = useRef<HTMLDivElement>(null);\n const hasAutoScrolled = useRef(false);\n\n const prevRowCount = useRef(0);\n\n useEffect(() => {\n hasAutoScrolled.current = false;\n prevRowCount.current = 0;\n }, [parentId]);\n\n // Auto-scroll to bottom: on initial load (if configured) and whenever new rows appear.\n useEffect(() => {\n if (!scrollRef.current || rows.length === 0) return;\n const isInitialLoad = !hasAutoScrolled.current;\n const hasNewRows = rows.length > prevRowCount.current && prevRowCount.current > 0;\n prevRowCount.current = rows.length;\n\n if ((isInitialLoad && autoScroll === \"bottom\") || hasNewRows) {\n scrollRef.current.scrollTop = scrollRef.current.scrollHeight;\n hasAutoScrolled.current = true;\n }\n }, [rows, autoScroll]);\n\n const [editingId, setEditingId] = useState<string | null>(null);\n\n if (!childEntity) {\n return <div className=\"text-sm text-[var(--muted-foreground)] py-2\">Entity not found.</div>;\n }\n\n const editableFields = config.quick_add?.fields\n ?? [timeline?.content_field].filter(Boolean) as string[];\n\n const title = loc(childEntity.display?.name_plural) || loc(childEntity.display?.name) || config.entity;\n\n // Build entries\n let entries: React.ReactNode;\n if (isError) {\n entries = <div className=\"text-sm text-[var(--destructive)] p-3\">Failed to load.</div>;\n } else if (isLoading) {\n entries = (\n <div className=\"space-y-2 p-3\">\n <Skeleton className=\"h-16 w-full rounded-lg\" />\n <Skeleton className=\"h-16 w-full rounded-lg\" />\n </div>\n );\n } else if (rows.length === 0) {\n entries = <div className=\"text-sm text-[var(--muted-foreground)] p-3\">No activity yet.</div>;\n } else {\n entries = rows.map((row, idx) => {\n const rowId = String((row as RowData)[\"id\"] ?? idx);\n return (\n <TimelineEntry\n key={rowId}\n row={row}\n rowId={rowId}\n childEntity={childEntity}\n entityCode={config.entity}\n parentEntity={parentEntity}\n parentId={parentId}\n timeline={timeline}\n editableFields={editableFields}\n refs={refs}\n isEditing={editingId === rowId}\n onStartEdit={() => setEditingId(rowId)}\n onCancelEdit={() => setEditingId(null)}\n onSaved={() => setEditingId(null)}\n schema={schema}\n />\n );\n });\n }\n\n // Scroll mode: self-contained panel that fills its parent height.\n // Structure: header | scrollable entries | resizable composer\n if (scroll) {\n return (\n <div className=\"flex flex-col h-full border-l border-[var(--border)] bg-[var(--muted)]/50 text-[var(--card-foreground)]\">\n {/* Header */}\n <div className=\"px-4 py-3 border-b border-[var(--border)] bg-[var(--card)]\">\n <h3 className=\"text-sm font-semibold\">{title}</h3>\n </div>\n {/* Scrollable entries */}\n <div ref={scrollRef} className=\"flex-1 overflow-y-auto p-3 space-y-2\">\n {entries}\n </div>\n {/* Composer */}\n <TimelineComposer config={config} parentEntity={parentEntity} parentId={parentId} schema={schema} />\n </div>\n );\n }\n\n // Inline mode (no scroll): entries + composer, no card wrapper.\n return (\n <div>\n <div className=\"space-y-2\">{entries}</div>\n <TimelineComposer config={config} parentEntity={parentEntity} parentId={parentId} schema={schema} />\n </div>\n );\n}\n\n// --- TimelineEntry ---\n\ninterface TimelineEntryProps {\n row: RowData;\n rowId: string;\n childEntity: NonNullable<ChildDisplayProps[\"schema\"][\"entities\"][string]>;\n entityCode: string;\n parentEntity: string;\n parentId: string;\n timeline: ChildDisplayProps[\"config\"][\"timeline\"];\n editableFields: string[];\n refs?: Record<string, Record<string, Record<string, unknown>>>;\n isEditing: boolean;\n onStartEdit: () => void;\n onCancelEdit: () => void;\n onSaved: () => void;\n schema: ChildDisplayProps[\"schema\"];\n}\n\nfunction TimelineEntry({\n row, rowId, childEntity, entityCode, parentEntity, parentId,\n timeline, editableFields, refs, isEditing, onStartEdit, onCancelEdit, onSaved, schema,\n}: TimelineEntryProps) {\n const queryClient = useQueryClient();\n const [formData, setFormData] = useState<Record<string, unknown>>({});\n\n const invalidate = useCallback(() => {\n queryClient.invalidateQueries({ queryKey: [ENTITY_CHILDREN_KEY, parentEntity, parentId, entityCode] });\n }, [queryClient, parentEntity, parentId, entityCode]);\n\n const updateMut = useMutation({\n mutationFn: (data: Record<string, unknown>) => updateEntity(entityCode, rowId, data),\n onSuccess: () => { invalidate(); toast.success(\"Updated\"); onSaved(); },\n onError: (err: Error) => toast.error(err.message),\n });\n\n const deleteMut = useMutation({\n mutationFn: () => deleteEntity(entityCode, rowId),\n onSuccess: () => { invalidate(); toast.success(\"Deleted\"); },\n onError: (err: Error) => toast.error(err.message),\n });\n\n const startEdit = useCallback(() => {\n const data: Record<string, unknown> = {};\n for (const f of editableFields) data[f] = row[f] ?? \"\";\n setFormData(data);\n onStartEdit();\n }, [row, editableFields, onStartEdit]);\n\n const handleFieldChange = useCallback((fieldName: string, val: unknown) => {\n setFormData((prev) => ({ ...prev, [fieldName]: val }));\n }, []);\n\n const timeField = timeline?.time_field;\n const typeField = timeline?.type_field;\n const summaryField = timeline?.summary_field;\n const contentField = timeline?.content_field;\n const authorField = timeline?.author_field;\n const directionField = timeline?.direction_field;\n const intentField = timeline?.intent_field;\n\n // Edit mode\n if (isEditing) {\n return (\n <div className=\"rounded-lg border-2 border-[var(--primary)]/40 bg-[var(--card)] p-3 space-y-2\">\n {editableFields.map((fieldName) => {\n const field = childEntity.fields[fieldName];\n if (!field) return null;\n return (\n <div key={fieldName}>\n <label className=\"text-xs text-[var(--muted-foreground)] mb-1 block\">\n {fieldDisplayName(field, fieldName, schema.entities)}\n </label>\n {renderField({ field, fieldName, value: formData[fieldName] ?? \"\", mode: \"edit\", onChange: (val) => handleFieldChange(fieldName, val), record: formData })}\n </div>\n );\n })}\n <div className=\"flex items-center gap-1.5 pt-1\">\n <Button size=\"sm\" onClick={() => updateMut.mutate(formData)} disabled={updateMut.isPending} className=\"h-7 text-xs gap-1\">\n <Check className=\"h-3 w-3\" /> {updateMut.isPending ? \"Saving...\" : \"Save\"}\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={() => { setFormData({}); onCancelEdit(); }} disabled={updateMut.isPending} className=\"h-7 text-xs gap-1\">\n <X className=\"h-3 w-3\" /> Cancel\n </Button>\n </div>\n </div>\n );\n }\n\n // Display mode\n return (\n <div className=\"group rounded-lg border border-[var(--border)] bg-[var(--card)] p-3 hover:border-[var(--muted-foreground)]/30 transition-colors\">\n {/* Header row */}\n <div className=\"flex items-center gap-2 flex-wrap text-xs text-[var(--muted-foreground)]\">\n {timeField && row[timeField] != null && childEntity.fields[timeField] && (\n <span className=\"font-medium\">\n {renderField({ field: childEntity.fields[timeField], fieldName: timeField, value: row[timeField], mode: \"display\", record: row, refs })}\n </span>\n )}\n {typeField && row[typeField] != null && childEntity.fields[typeField] && (\n <span className=\"px-1.5 py-0.5 rounded bg-[var(--muted)] text-[10px] uppercase tracking-wide font-semibold\">\n {renderField({ field: childEntity.fields[typeField], fieldName: typeField, value: row[typeField], mode: \"display\", record: row, refs })}\n </span>\n )}\n {directionField && row[directionField] != null && childEntity.fields[directionField] && (\n <DirectionChip value={row[directionField]} field={childEntity.fields[directionField]} />\n )}\n {intentField && row[intentField] != null && childEntity.fields[intentField] && (\n <span className=\"px-1.5 py-0.5 rounded bg-[var(--muted)] text-[10px] uppercase tracking-wide font-medium\">\n {renderField({ field: childEntity.fields[intentField], fieldName: intentField, value: row[intentField], mode: \"display\", record: row, refs })}\n </span>\n )}\n {authorField && row[authorField] != null && childEntity.fields[authorField] && (\n <span>by {renderField({ field: childEntity.fields[authorField], fieldName: authorField, value: row[authorField], mode: \"display\", record: row, refs })}</span>\n )}\n <div className=\"ml-auto flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity\">\n <button onClick={startEdit} className=\"p-1 rounded hover:bg-[var(--muted)]\" title=\"Edit\"><Pencil className=\"h-3 w-3\" /></button>\n <button onClick={() => deleteMut.mutate()} disabled={deleteMut.isPending} className=\"p-1 rounded hover:bg-[var(--destructive)]/10 hover:text-[var(--destructive)]\" title=\"Delete\"><Trash2 className=\"h-3 w-3\" /></button>\n </div>\n </div>\n {/* Summary */}\n {summaryField && row[summaryField] != null && childEntity.fields[summaryField] && (\n <div className=\"text-sm font-medium mt-1.5\">\n {renderField({ field: childEntity.fields[summaryField], fieldName: summaryField, value: row[summaryField], mode: \"display\", record: row, refs })}\n </div>\n )}\n {/* Content — explicit font-normal (class + inline style) to override\n any inherited medium weight from host pages / reset chains that\n was reading as \"bold\" on multi-paragraph activity bodies. Inline\n style trumps CSS specificity without needing !important in the\n Tailwind class. */}\n {contentField && row[contentField] != null && contentField !== summaryField && childEntity.fields[contentField] && (\n <div className=\"text-sm font-normal mt-1.5\" style={{ fontWeight: 400 }}>\n {renderField({ field: childEntity.fields[contentField], fieldName: contentField, value: row[contentField], mode: \"display\", record: row, refs })}\n </div>\n )}\n </div>\n );\n}\n\n// DirectionChip shows an inbound/outbound indicator next to the activity type.\n// Supports enum \"direction\" (values inbound|outbound) or boolean flags\n// (is_outbound/outbound: true = outbound; is_inbound/inbound: true = inbound).\nfunction DirectionChip({ value, field }: { value: unknown; field: EntityField }) {\n const outbound = isOutbound(value, field);\n if (outbound === null) return null;\n const Icon = outbound ? ArrowUpRight : ArrowDownLeft;\n const label = outbound ? \"Out\" : \"In\";\n return (\n <span className=\"inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded bg-[var(--muted)] text-[10px] uppercase tracking-wide font-medium\">\n <Icon className=\"h-3 w-3\" />\n {label}\n </span>\n );\n}\n\nfunction isOutbound(value: unknown, field: EntityField): boolean | null {\n if (field.type === \"bool\") {\n // bool semantics depend on field name; pass field name via caller. Here we\n // assume truthy means the chip's polarity - caller chose the field name.\n // is_outbound=true -> outbound; is_inbound=true -> inbound.\n // Without the name we can't invert; ChildrenTimeline picks the field, so we\n // just read the value and assume \"true means outbound\" for the default\n // inferred cases (is_outbound/outbound). Inbound fields come through as\n // false-means-outbound via schema authoring.\n return value === true;\n }\n if (typeof value === \"string\") {\n const v = value.toLowerCase();\n if (v === \"outbound\" || v === \"out\") return true;\n if (v === \"inbound\" || v === \"in\") return false;\n }\n return null;\n}\n","import { useCallback, useRef } from \"react\";\nimport { Plus, Trash2, Undo2 } from \"lucide-react\";\nimport { fieldDisplayName } from \"@/types/schema\";\nimport type { Entity, Schema } from \"@/types/schema\";\nimport { renderField } from \"@/components/fields\";\nimport type { RefsMap } from \"@/components/fields\";\nimport { Button } from \"@/components/ui/button\";\nimport type { PendingChildRow } from \"./LayoutRenderer\";\nimport type { ResolvedChildConfig } from \"@/lib/child-config\";\n\ninterface EditableChildrenTableProps {\n config: ResolvedChildConfig;\n childEntity: Entity;\n schema: Schema;\n rows: PendingChildRow[];\n onChange: (rows: PendingChildRow[]) => void;\n validationErrors?: Record<string, string[]>; // rowKey -> fieldNames\n refs?: RefsMap;\n}\n\n// EditableChildrenTable renders child rows with all cells in edit mode.\n// Used for direct (aggregate) children when the parent detail page is in edit mode.\nexport function EditableChildrenTable({\n config,\n childEntity,\n schema,\n rows,\n onChange,\n validationErrors,\n refs,\n}: EditableChildrenTableProps) {\n const tableRef = useRef<HTMLTableElement>(null);\n const columns = config.columns;\n\n // Editable columns: exclude FK, auto, primary, and position_field.\n const fkSet = new Set(Array.isArray(config.foreign_key) ? config.foreign_key : [config.foreign_key]);\n const editableColumns = columns.filter((col) => {\n if (fkSet.has(col)) return false;\n if (config.position_field && col === config.position_field) return false;\n const field = childEntity.fields[col];\n if (!field) return false;\n if (field.auto || field.primary) return false;\n return true;\n });\n\n // Display-only columns (auto/primary but visible in column list, or position_field).\n const displayOnlyColumns = new Set(\n columns.filter((col) => {\n if (config.position_field && col === config.position_field) return true;\n const field = childEntity.fields[col];\n return field && (field.auto || field.primary);\n }),\n );\n\n const handleCellChange = useCallback(\n (rowKey: string, fieldName: string, value: unknown) => {\n const updated = rows.map((row) =>\n row._key === rowKey\n ? { ...row, [fieldName]: value, _dirty: true }\n : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleAddRow = useCallback(() => {\n const newRow: PendingChildRow = {\n _key: crypto.randomUUID(),\n _dirty: true,\n };\n // Pre-fill from quick_add.defaults first, then field-level defaults.\n const quickDefaults = config.quick_add?.defaults ?? {};\n for (const col of editableColumns) {\n const field = childEntity.fields[col];\n if (!field) continue;\n if (quickDefaults[col] !== undefined) {\n newRow[col] = quickDefaults[col];\n } else if (field.default !== undefined) {\n newRow[col] = field.default;\n } else if (field.type === \"bool\") {\n newRow[col] = false;\n }\n }\n onChange([...rows, newRow]);\n }, [rows, onChange, editableColumns, childEntity, config.quick_add?.defaults]);\n\n const handleDeleteRow = useCallback(\n (rowKey: string) => {\n const updated = rows.map((row) =>\n row._key === rowKey ? { ...row, _deleted: true } : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleUndoDelete = useCallback(\n (rowKey: string) => {\n const updated = rows.map((row) =>\n row._key === rowKey ? { ...row, _deleted: false } : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTableElement>) => {\n const target = e.target as HTMLElement;\n const cell = target.closest(\"td\");\n if (!cell) return;\n const row = cell.closest(\"tr\");\n if (!row) return;\n const tbody = row.closest(\"tbody\");\n if (!tbody) return;\n\n const cellIndex = Array.from(row.cells).indexOf(cell as HTMLTableCellElement);\n const rowIndex = Array.from(tbody.rows).indexOf(row as HTMLTableRowElement);\n\n if (e.key === \"Tab\") {\n // Tab/Shift+Tab navigate between editable cells.\n const direction = e.shiftKey ? -1 : 1;\n const allRows = Array.from(tbody.rows);\n let nextRow = rowIndex;\n let nextCell = cellIndex + direction;\n\n // Walk across rows to find next editable cell.\n while (nextRow >= 0 && nextRow < allRows.length) {\n if (nextCell >= 0 && nextCell < allRows[nextRow].cells.length) {\n const nextTd = allRows[nextRow].cells[nextCell];\n const input = nextTd.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (input) {\n e.preventDefault();\n input.focus();\n return;\n }\n nextCell += direction;\n } else {\n // Move to next/previous row.\n nextRow += direction;\n nextCell = direction > 0 ? 0 : (allRows[nextRow]?.cells.length ?? 1) - 1;\n }\n }\n // Let the browser handle focus leaving the table.\n } else if (e.key === \"Enter\") {\n // Enter: move to same column in next row, or add row if at last.\n e.preventDefault();\n const allRows = Array.from(tbody.rows);\n if (rowIndex < allRows.length - 1) {\n const nextTd = allRows[rowIndex + 1].cells[cellIndex];\n const input = nextTd?.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (input) input.focus();\n } else {\n // At last row: add a new row.\n handleAddRow();\n // Focus will happen on next render via autoFocus-like mechanism.\n requestAnimationFrame(() => {\n const newRows = tbody.querySelectorAll(\"tr\");\n const lastRow = newRows[newRows.length - 1];\n if (lastRow) {\n const firstInput = lastRow.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (firstInput) firstInput.focus();\n }\n });\n }\n } else if (e.key === \"Escape\") {\n // Escape: blur the current cell.\n (target as HTMLElement).blur?.();\n }\n },\n [handleAddRow],\n );\n\n return (\n <div>\n <div className=\"overflow-x-auto\">\n <table ref={tableRef} className=\"w-full text-sm\" onKeyDown={handleKeyDown}>\n <thead>\n <tr className=\"border-b\">\n {columns.map((col) => {\n const field = childEntity.fields[col];\n return (\n <th\n key={col}\n className=\"h-8 px-3 text-left align-middle font-medium text-[var(--muted-foreground)]\"\n >\n {field ? fieldDisplayName(field, col, schema.entities) : col}\n </th>\n );\n })}\n <th className=\"h-8 w-10 px-2\" />\n </tr>\n </thead>\n <tbody>\n {rows.map((row) => {\n const isDeleted = !!row._deleted;\n const rowErrors = validationErrors?.[row._key];\n return (\n <tr\n key={row._key}\n className={`border-b last:border-0 ${isDeleted ? \"opacity-50\" : \"\"}`}\n >\n {columns.map((col) => {\n const field = childEntity.fields[col];\n const hasError = rowErrors?.includes(col);\n const isDisplayOnly = displayOnlyColumns.has(col);\n\n if (isDeleted || isDisplayOnly) {\n return (\n <td\n key={col}\n className={`px-3 py-2 align-middle ${isDeleted ? \"line-through\" : \"\"}`}\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"display\",\n record: row as Record<string, unknown>,\n refs,\n })\n : String(row[col] ?? \"\")}\n </td>\n );\n }\n\n return (\n <td\n key={col}\n className={`px-1 py-1 align-middle ${hasError ? \"ring-1 ring-inset ring-[var(--destructive)] rounded\" : \"\"}`}\n title={hasError ? `${col} is required` : undefined}\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"edit\",\n onChange: (val) => handleCellChange(row._key, col, val),\n record: row as Record<string, unknown>,\n refs,\n })\n : String(row[col] ?? \"\")}\n </td>\n );\n })}\n <td className=\"px-2 py-1 align-middle\">\n {isDeleted ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7\"\n onClick={() => handleUndoDelete(row._key)}\n title=\"Undo delete\"\n >\n <Undo2 className=\"h-4 w-4\" />\n </Button>\n ) : (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 text-[var(--muted-foreground)] hover:text-[var(--destructive)]\"\n onClick={() => handleDeleteRow(row._key)}\n title=\"Delete row\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n )}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"mt-2 text-[var(--muted-foreground)]\"\n onClick={handleAddRow}\n >\n <Plus className=\"h-4 w-4 mr-1\" />\n Add row\n </Button>\n </div>\n );\n}\n","import { useCallback, useMemo, useRef } from \"react\";\nimport {\n DndContext,\n closestCenter,\n PointerSensor,\n useSensor,\n useSensors,\n type DragEndEvent,\n} from \"@dnd-kit/core\";\nimport {\n SortableContext,\n verticalListSortingStrategy,\n useSortable,\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { GripVertical, Plus, Trash2, Undo2 } from \"lucide-react\";\nimport { fieldDisplayName } from \"@/types/schema\";\nimport type { Entity, Schema } from \"@/types/schema\";\nimport { renderField } from \"@/components/fields\";\nimport type { RefsMap } from \"@/components/fields\";\nimport { Button } from \"@/components/ui/button\";\nimport type { PendingChildRow } from \"./LayoutRenderer\";\nimport type { ResolvedChildConfig } from \"@/lib/child-config\";\n\ninterface DraggableChildrenTableProps {\n config: ResolvedChildConfig;\n childEntity: Entity;\n schema: Schema;\n rows: PendingChildRow[];\n onChange: (rows: PendingChildRow[]) => void;\n validationErrors?: Record<string, string[]>;\n refs?: RefsMap;\n}\n\n// DraggableChildrenTable renders child rows with drag handles for reordering.\n// Used when position_field is configured on a child relation.\nexport function DraggableChildrenTable({\n config,\n childEntity,\n schema,\n rows,\n onChange,\n validationErrors,\n refs,\n}: DraggableChildrenTableProps) {\n const tableRef = useRef<HTMLTableElement>(null);\n const positionField = config.position_field!;\n const columns = config.columns;\n\n // distance: 5 separates click from drag.\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),\n );\n\n // Editable columns: exclude FK, auto, primary, and position_field.\n const fkSet = new Set(Array.isArray(config.foreign_key) ? config.foreign_key : [config.foreign_key]);\n const editableColumns = columns.filter((col) => {\n if (fkSet.has(col)) return false;\n if (col === positionField) return false;\n const field = childEntity.fields[col];\n if (!field) return false;\n if (field.auto || field.primary) return false;\n return true;\n });\n\n // Display-only columns (auto/primary but visible in column list, or position_field).\n const displayOnlyColumns = new Set(\n columns.filter((col) => {\n if (col === positionField) return true;\n const field = childEntity.fields[col];\n return field && (field.auto || field.primary);\n }),\n );\n\n // Visible columns: exclude position_field from display since it's managed by drag.\n const visibleColumns = columns.filter((col) => col !== positionField);\n\n // Row IDs for SortableContext - only non-deleted rows participate in drag.\n const rowIds = useMemo(\n () => rows.filter((r) => !r._deleted).map((r) => r._key),\n [rows],\n );\n\n const handleCellChange = useCallback(\n (rowKey: string, fieldName: string, value: unknown) => {\n const updated = rows.map((row) =>\n row._key === rowKey\n ? { ...row, [fieldName]: value, _dirty: true }\n : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleAddRow = useCallback(() => {\n const maxPosition = rows\n .filter((r) => !r._deleted)\n .reduce((max, r) => {\n const pos = typeof r[positionField] === \"number\" ? (r[positionField] as number) : -1;\n return Math.max(max, pos);\n }, -1);\n\n const newRow: PendingChildRow = {\n _key: crypto.randomUUID(),\n _dirty: true,\n [positionField]: maxPosition + 1,\n };\n // Pre-fill from quick_add.defaults first, then field-level defaults.\n const quickDefaults = config.quick_add?.defaults ?? {};\n for (const col of editableColumns) {\n const field = childEntity.fields[col];\n if (!field) continue;\n if (quickDefaults[col] !== undefined) {\n newRow[col] = quickDefaults[col];\n } else if (field.default !== undefined) {\n newRow[col] = field.default;\n } else if (field.type === \"bool\") {\n newRow[col] = false;\n }\n }\n onChange([...rows, newRow]);\n }, [rows, onChange, editableColumns, childEntity, config.quick_add?.defaults, positionField]);\n\n const handleDeleteRow = useCallback(\n (rowKey: string) => {\n const updated = rows.map((row) =>\n row._key === rowKey ? { ...row, _deleted: true } : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleUndoDelete = useCallback(\n (rowKey: string) => {\n const updated = rows.map((row) =>\n row._key === rowKey ? { ...row, _deleted: false } : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n const { active, over } = event;\n if (!over || active.id === over.id) return;\n\n // Reorder non-deleted rows.\n const nonDeleted = rows.filter((r) => !r._deleted);\n const deleted = rows.filter((r) => r._deleted);\n\n const oldIndex = nonDeleted.findIndex((r) => r._key === String(active.id));\n const newIndex = nonDeleted.findIndex((r) => r._key === String(over.id));\n if (oldIndex === -1 || newIndex === -1) return;\n\n // Move the row.\n const reordered = [...nonDeleted];\n const [moved] = reordered.splice(oldIndex, 1);\n reordered.splice(newIndex, 0, moved);\n\n // Re-assign sequential position values and mark dirty only if position changed.\n const withPositions = reordered.map((row, index) => ({\n ...row,\n [positionField]: index,\n _dirty: row[positionField] !== index ? true : row._dirty,\n }));\n\n // Append deleted rows at the end (they'll be excluded from payload).\n onChange([...withPositions, ...deleted]);\n },\n [rows, onChange, positionField],\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTableElement>) => {\n const target = e.target as HTMLElement;\n const cell = target.closest(\"td\");\n if (!cell) return;\n const row = cell.closest(\"tr\");\n if (!row) return;\n const tbody = row.closest(\"tbody\");\n if (!tbody) return;\n\n const cellIndex = Array.from(row.cells).indexOf(cell as HTMLTableCellElement);\n const rowIndex = Array.from(tbody.rows).indexOf(row as HTMLTableRowElement);\n\n if (e.key === \"Tab\") {\n const direction = e.shiftKey ? -1 : 1;\n const allRows = Array.from(tbody.rows);\n let nextRow = rowIndex;\n let nextCell = cellIndex + direction;\n\n while (nextRow >= 0 && nextRow < allRows.length) {\n if (nextCell >= 0 && nextCell < allRows[nextRow].cells.length) {\n const nextTd = allRows[nextRow].cells[nextCell];\n const input = nextTd.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (input) {\n e.preventDefault();\n input.focus();\n return;\n }\n nextCell += direction;\n } else {\n nextRow += direction;\n nextCell = direction > 0 ? 0 : (allRows[nextRow]?.cells.length ?? 1) - 1;\n }\n }\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n const allRows = Array.from(tbody.rows);\n if (rowIndex < allRows.length - 1) {\n const nextTd = allRows[rowIndex + 1].cells[cellIndex];\n const input = nextTd?.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (input) input.focus();\n } else {\n handleAddRow();\n requestAnimationFrame(() => {\n const newRows = tbody.querySelectorAll(\"tr\");\n const lastRow = newRows[newRows.length - 1];\n if (lastRow) {\n const firstInput = lastRow.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (firstInput) firstInput.focus();\n }\n });\n }\n } else if (e.key === \"Escape\") {\n (target as HTMLElement).blur?.();\n }\n },\n [handleAddRow],\n );\n\n return (\n <div>\n <div className=\"overflow-x-auto\">\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleDragEnd}\n >\n <table ref={tableRef} className=\"w-full text-sm\" onKeyDown={handleKeyDown}>\n <thead>\n <tr className=\"border-b\">\n <th className=\"h-8 w-8 px-1\" />\n {visibleColumns.map((col) => {\n const field = childEntity.fields[col];\n return (\n <th\n key={col}\n className=\"h-8 px-3 text-left align-middle font-medium text-[var(--muted-foreground)]\"\n >\n {field ? fieldDisplayName(field, col, schema.entities) : col}\n </th>\n );\n })}\n <th className=\"h-8 w-10 px-2\" />\n </tr>\n </thead>\n <SortableContext items={rowIds} strategy={verticalListSortingStrategy}>\n <tbody>\n {rows.map((row) => (\n <SortableRow\n key={row._key}\n row={row}\n columns={visibleColumns}\n editableColumns={editableColumns}\n displayOnlyColumns={displayOnlyColumns}\n childEntity={childEntity}\n validationErrors={validationErrors}\n refs={refs}\n onCellChange={handleCellChange}\n onDelete={handleDeleteRow}\n onUndoDelete={handleUndoDelete}\n />\n ))}\n </tbody>\n </SortableContext>\n </table>\n </DndContext>\n </div>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"mt-2 text-[var(--muted-foreground)]\"\n onClick={handleAddRow}\n >\n <Plus className=\"h-4 w-4 mr-1\" />\n Add row\n </Button>\n </div>\n );\n}\n\n// SortableRow wraps a table row with drag-and-drop support.\ninterface SortableRowProps {\n row: PendingChildRow;\n columns: string[];\n editableColumns: string[];\n displayOnlyColumns: Set<string>;\n childEntity: Entity;\n validationErrors?: Record<string, string[]>;\n refs?: RefsMap;\n onCellChange: (rowKey: string, fieldName: string, value: unknown) => void;\n onDelete: (rowKey: string) => void;\n onUndoDelete: (rowKey: string) => void;\n}\n\nfunction SortableRow({\n row,\n columns,\n editableColumns,\n displayOnlyColumns,\n childEntity,\n validationErrors,\n refs,\n onCellChange,\n onDelete,\n onUndoDelete,\n}: SortableRowProps) {\n const isDeleted = !!row._deleted;\n const rowErrors = validationErrors?.[row._key];\n\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: row._key, disabled: isDeleted });\n\n const style = {\n transform: CSS.Translate.toString(transform),\n transition,\n zIndex: isDragging ? 10 : undefined,\n opacity: isDragging ? 0.5 : undefined,\n };\n\n return (\n <tr\n ref={setNodeRef}\n style={style}\n className={`border-b last:border-0 ${isDeleted ? \"opacity-50\" : \"\"}`}\n >\n <td className=\"px-1 py-1 align-middle w-8\">\n {!isDeleted && (\n <button\n type=\"button\"\n className=\"cursor-grab active:cursor-grabbing p-1 text-[var(--muted-foreground)] hover:text-[var(--foreground)]\"\n {...attributes}\n {...listeners}\n >\n <GripVertical className=\"h-4 w-4\" />\n </button>\n )}\n </td>\n {columns.map((col) => {\n const field = childEntity.fields[col];\n const hasError = rowErrors?.includes(col);\n const isDisplayOnly = displayOnlyColumns.has(col);\n const isEditable = editableColumns.includes(col);\n\n if (isDeleted || isDisplayOnly || !isEditable) {\n return (\n <td\n key={col}\n className={`px-3 py-2 align-middle ${isDeleted ? \"line-through\" : \"\"}`}\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"display\",\n record: row as Record<string, unknown>,\n refs,\n })\n : String(row[col] ?? \"\")}\n </td>\n );\n }\n\n return (\n <td\n key={col}\n className={`px-1 py-1 align-middle ${hasError ? \"ring-1 ring-inset ring-[var(--destructive)] rounded\" : \"\"}`}\n title={hasError ? `${col} is required` : undefined}\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"edit\",\n onChange: (val) => onCellChange(row._key, col, val),\n record: row as Record<string, unknown>,\n refs,\n })\n : String(row[col] ?? \"\")}\n </td>\n );\n })}\n <td className=\"px-2 py-1 align-middle\">\n {isDeleted ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7\"\n onClick={() => onUndoDelete(row._key)}\n title=\"Undo delete\"\n >\n <Undo2 className=\"h-4 w-4\" />\n </Button>\n ) : (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 text-[var(--muted-foreground)] hover:text-[var(--destructive)]\"\n onClick={() => onDelete(row._key)}\n title=\"Delete row\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n )}\n </td>\n </tr>\n );\n}\n","import type { LayoutNode, Schema } from \"@/types/schema\";\nimport { resolveChildConfig, findChildRelation, type ResolvedChildConfig } from \"@/lib/child-config\";\nimport type { LayoutContext } from \"./LayoutRenderer\";\nimport { ChildrenTable } from \"./ChildrenTable\";\nimport { ChildrenList } from \"./ChildrenList\";\nimport { ChildrenCards } from \"./ChildrenCards\";\nimport { ChildrenTimeline } from \"./ChildrenTimeline\";\nimport { EditableChildrenTable } from \"./EditableChildrenTable\";\nimport { DraggableChildrenTable } from \"./DraggableChildrenTable\";\n\ninterface ChildrenBlockProps {\n node: LayoutNode;\n ctx: LayoutContext;\n}\n\nexport interface ChildDisplayProps {\n config: ResolvedChildConfig;\n parentEntity: string;\n parentId: string;\n schema: Schema;\n}\n\n// ChildrenBlock resolves the child config using the three-layer precedence\n// algorithm and dispatches to the appropriate display mode component.\n// In edit mode, dispatches to EditableChildrenTable for table-mode children\n// when editable is true and the child entity is not readonly.\nexport function ChildrenBlock({ node, ctx }: ChildrenBlockProps) {\n const childCode = node.children;\n if (!childCode) return null;\n\n // For non-new records, children cannot be loaded until the parent record exists.\n // For new records in edit mode, we show the editable table with pending data.\n if (ctx.isNew && ctx.mode !== \"edit\") return null;\n\n const relation = findChildRelation(ctx.entity, childCode);\n if (!relation) {\n return (\n <div className=\"text-sm text-[var(--muted-foreground)] py-2\">\n Unknown child relation: {childCode}\n </div>\n );\n }\n\n const childEntity = ctx.schema.entities[relation.entity];\n if (!childEntity) {\n return (\n <div className=\"text-sm text-[var(--muted-foreground)] py-2\">\n Entity not found: {relation.entity}\n </div>\n );\n }\n\n const config = resolveChildConfig(relation, childEntity, node);\n\n // In edit mode, dispatch to EditableChildrenTable for table-mode children\n // when editable is true and the child entity is not readonly.\n if (\n ctx.mode === \"edit\" &&\n config.editable &&\n !childEntity.readonly &&\n config.mode === \"table\" &&\n ctx.pendingChildren !== undefined &&\n ctx.onChildrenChange\n ) {\n const pendingRows = ctx.pendingChildren[childCode] ?? [];\n const validationErrors = ctx.childValidationErrors?.[childCode];\n const TableComponent = config.position_field\n ? DraggableChildrenTable\n : EditableChildrenTable;\n return (\n <TableComponent\n config={config}\n childEntity={childEntity}\n schema={ctx.schema}\n rows={pendingRows}\n onChange={(rows) => ctx.onChildrenChange!(childCode, rows)}\n validationErrors={validationErrors}\n refs={ctx.refs}\n />\n );\n }\n\n // For new records not in editable table mode, nothing to show.\n if (ctx.isNew) return null;\n\n const displayProps: ChildDisplayProps = {\n config,\n parentEntity: ctx.entityCode,\n parentId: ctx.recordId,\n schema: ctx.schema,\n };\n\n switch (config.mode) {\n case \"table\":\n return <ChildrenTable {...displayProps} />;\n case \"list\":\n return <ChildrenList {...displayProps} />;\n case \"cards\":\n return <ChildrenCards {...displayProps} />;\n case \"timeline\":\n return <ChildrenTimeline {...displayProps} />;\n default:\n return <ChildrenTable {...displayProps} />;\n }\n}\n","import { useInfiniteQuery } from \"@tanstack/react-query\";\nimport { apiFetch } from \"@/api/client\";\nimport type { V2ListResponse } from \"@/types/api\";\nimport { ENTITY_CHILDREN_KEY } from \"./useChildrenData\";\n\n/**\n * useAssociatedData fetches associated (non-aggregate) child entity records\n * with cursor-based pagination, search, and filter support.\n *\n * Uses useInfiniteQuery so that \"Load more\" accumulates pages rather than\n * replacing data. The query key is compatible with the SSE invalidation\n * predicate (index 0 = ENTITY_CHILDREN_KEY, index 3 = child entity code).\n */\nexport function useAssociatedData(\n parentEntity: string,\n parentId: string,\n entityCode: string,\n foreignKey: string,\n sort?: string,\n limit?: number,\n search?: string,\n filters?: Record<string, string>,\n) {\n // Stable serialization of filters for query key identity.\n const stableFilters = filters\n ? JSON.stringify(Object.entries(filters).sort())\n : undefined;\n\n return useInfiniteQuery({\n queryKey: [\n ENTITY_CHILDREN_KEY,\n parentEntity,\n parentId,\n entityCode,\n sort,\n limit,\n search,\n stableFilters,\n ],\n queryFn: ({ pageParam }) => {\n const params = new URLSearchParams();\n // Build JSON filter array: FK constraint + any additional filters.\n const filterNodes: Array<{ field: string; op: string; value: unknown }> = [\n { field: foreignKey, op: \"eq\", value: parentId },\n ];\n if (filters) {\n for (const [field, value] of Object.entries(filters)) {\n if (value && value !== \"__all__\") {\n filterNodes.push({ field, op: \"eq\", value });\n }\n }\n }\n params.set(\"filters\", JSON.stringify(filterNodes));\n if (sort) params.set(\"sort\", sort);\n if (limit) params.set(\"limit\", String(limit));\n if (search) params.set(\"search\", search);\n if (pageParam) params.set(\"after\", pageParam);\n return apiFetch<V2ListResponse>(\n `/api/data/${entityCode}?${params.toString()}`,\n );\n },\n getNextPageParam: (lastPage) =>\n lastPage.meta?.has_more ? lastPage.meta.cursor : undefined,\n initialPageParam: undefined as string | undefined,\n enabled:\n !!parentEntity && !!parentId && !!entityCode && !!foreignKey,\n });\n}\n","import { useMemo } from \"react\";\nimport { Search } from \"lucide-react\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { useEntity } from \"@/hooks/useEntity\";\nimport { useEntityData } from \"@/hooks/useEntityData\";\nimport { fieldDisplayName, loc } from \"@/types/schema\";\nimport type { Entity, EntityField } from \"@/types/schema\";\n\ninterface AssociatedToolbarProps {\n entity: Entity;\n searchable?: boolean;\n filterFields?: string[];\n searchValue: string;\n onSearchChange: (value: string) => void;\n filters: Record<string, string>;\n onFilterChange: (field: string, value: string) => void;\n allEntities?: Record<string, Entity>;\n}\n\nexport function AssociatedToolbar({\n entity,\n searchable,\n filterFields,\n searchValue,\n onSearchChange,\n filters,\n onFilterChange,\n allEntities,\n}: AssociatedToolbarProps) {\n const hasSearch = searchable === true;\n const hasFilters = filterFields && filterFields.length > 0;\n\n if (!hasSearch && !hasFilters) return null;\n\n return (\n <div className=\"flex items-center gap-2 mb-2\">\n {hasSearch && (\n <div className=\"relative flex-1 max-w-[200px]\">\n <Search className=\"absolute left-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-[var(--muted-foreground)]\" />\n <Input\n placeholder=\"Search...\"\n value={searchValue}\n onChange={(e) => onSearchChange(e.target.value)}\n className=\"pl-7 h-8 text-sm\"\n />\n </div>\n )}\n {hasFilters &&\n filterFields.map((filterField) => {\n const field = entity.fields[filterField];\n if (!field) return null;\n const currentVal = filters[filterField] ?? \"__all__\";\n const label = fieldDisplayName(field, filterField, allEntities);\n\n if (field.type === \"ref\" && field.ref?.entity) {\n return (\n <RefFilterDropdown\n key={filterField}\n field={field}\n label={label}\n value={currentVal}\n onChange={(v) => onFilterChange(filterField, v)}\n />\n );\n }\n\n if (!field.values) return null;\n return (\n <Select\n key={filterField}\n value={currentVal}\n onValueChange={(v) => onFilterChange(filterField, v)}\n >\n <SelectTrigger className=\"w-[140px] h-8 text-sm\">\n <SelectValue placeholder={label} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__all__\">All {label}</SelectItem>\n {field.values.map((v) => (\n <SelectItem key={v.code} value={v.code}>\n {loc(v.name)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n })}\n </div>\n );\n}\n\nfunction RefFilterDropdown({\n field,\n label,\n value,\n onChange,\n}: {\n field: EntityField;\n label: string;\n value: string;\n onChange: (value: string) => void;\n}) {\n const refEntity = useEntity(field.ref?.entity);\n const displayField =\n field.display?.ref_display_field ?? refEntity?.display?.display_field;\n const pk = useMemo(\n () =>\n refEntity\n ? Object.entries(refEntity.fields).find(([, f]) => f.primary)?.[0] ??\n \"id\"\n : \"id\",\n [refEntity],\n );\n\n const { data: response } = useEntityData(field.ref?.entity, {\n per_page: 200,\n sort: displayField ? `${displayField}:asc` : undefined,\n });\n const options = response?.data ?? [];\n\n const resolveDisplay = (val: unknown): string => {\n if (val == null) return \"-\";\n if (typeof val === \"object\" && !Array.isArray(val)) {\n const first = Object.values(val as Record<string, unknown>)[0];\n return first != null ? String(first) : \"-\";\n }\n return String(val);\n };\n\n return (\n <Select value={value} onValueChange={onChange}>\n <SelectTrigger className=\"w-[140px] h-8 text-sm\">\n <SelectValue placeholder={label} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__all__\">All {label}</SelectItem>\n {options.map((r) => {\n const id = String(r[pk]);\n const optLabel = displayField\n ? resolveDisplay(r[displayField] ?? id)\n : id;\n return (\n <SelectItem key={id} value={id}>\n {optLabel}\n </SelectItem>\n );\n })}\n </SelectContent>\n </Select>\n );\n}\n","import { useState, useCallback, useRef, useMemo, useEffect } from \"react\";\nimport { Plus, Trash2, Check, X, Loader2 } from \"lucide-react\";\nimport { fieldDisplayName, loc } from \"@/types/schema\";\nimport type { LayoutNode, Entity } from \"@/types/schema\";\nimport { renderField } from \"@/components/fields\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport { Button } from \"@/components/ui/button\";\nimport { useChildrenData } from \"@/hooks/useChildrenData\";\nimport { useAssociatedData } from \"@/hooks/useAssociatedData\";\nimport { updateEntity, createEntity, deleteEntity } from \"@/api/data\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { ENTITY_CHILDREN_KEY } from \"@/hooks/useChildrenData\";\nimport { ConfirmDialog } from \"@/components/shared/ConfirmDialog\";\nimport { AssociatedToolbar } from \"./AssociatedToolbar\";\nimport type { LayoutContext } from \"./LayoutRenderer\";\nimport type { Refs } from \"@/types/api\";\n\n// Per-row state for merge-debounce saving.\ninterface AssociatedRowState {\n buffer: Record<string, unknown>; // accumulated dirty fields\n ver: number; // monotonic counter, incremented on every cell change\n saving: boolean; // true while PATCH is in flight\n error?: string; // last save error (cleared on next successful save)\n}\n\ninterface AssociatedBlockProps {\n node: LayoutNode;\n ctx: LayoutContext;\n}\n\n// AssociatedBlock renders a filtered list of an associated entity (independent entity\n// with a FK ref field pointing back to the parent entity). Unlike ChildrenBlock,\n// associated entities are not aggregate children - they have independent lifecycles.\n// Supports inline editing: click-to-edit cells, add/delete rows with immediate saves.\n// When searchable or filters are configured, renders a toolbar and uses cursor-based pagination.\n// Server-side ordering only: set `sort:` on the layout node (e.g. `sort: created_at:desc`).\n// Manual drag-reorder via `position_field` is not supported on associated blocks - it is\n// semantically broken under pagination and prohibitively expensive under per-row save.\n// Use `children:` if you need manual ordering.\nexport function AssociatedBlock({ node, ctx }: AssociatedBlockProps) {\n const assocCode = node.associated;\n if (!assocCode) return null;\n if (ctx.isNew) return null;\n\n const assocEntity = ctx.schema.entities[assocCode];\n if (!assocEntity) {\n return (\n <div className=\"text-sm text-[var(--muted-foreground)] py-2\">\n Entity not found: {assocCode}\n </div>\n );\n }\n\n // Auto-discover FK: find the ref field on the associated entity that points to the parent entity.\n let fkField: string | null = null;\n for (const [fieldName, field] of Object.entries(assocEntity.fields)) {\n if (field.ref?.entity === ctx.entityCode) {\n fkField = fieldName;\n break;\n }\n }\n\n if (!fkField) {\n return (\n <div className=\"text-sm text-[var(--muted-foreground)] py-2\">\n No FK found for {assocCode} -&gt; {ctx.entityCode}\n </div>\n );\n }\n\n // Determine columns: use node.columns override or infer from field_order.\n const columns = node.columns && node.columns.length > 0\n ? node.columns.filter((col) => {\n if (col === fkField) return false;\n const field = assocEntity.fields[col];\n return !!field;\n })\n : (assocEntity.field_order ?? Object.keys(assocEntity.fields)).filter(\n (col) => {\n if (col === fkField) return false;\n const field = assocEntity.fields[col];\n if (!field) return false;\n if (field.primary) return false;\n if (field.display?.is_listable === false) return false;\n return true;\n },\n );\n\n // Resolve editable: node.editable overrides, default true.\n // Entity readonly forces read-only.\n const editable = assocEntity.readonly ? false : (node.editable !== false);\n\n const label = loc(assocEntity.display?.name_plural) || loc(assocEntity.display?.name) || assocCode;\n\n // Determine if toolbar features are enabled.\n const hasToolbar = node.searchable === true || (node.filters && node.filters.length > 0);\n\n return (\n <div>\n <h3 className=\"text-sm font-medium text-[var(--muted-foreground)] mb-2\">{label}</h3>\n {hasToolbar ? (\n <PaginatedAssociatedTable\n entityCode={assocCode}\n entity={assocEntity}\n parentEntity={ctx.entityCode}\n parentId={ctx.recordId}\n foreignKey={fkField}\n columns={columns}\n editable={editable}\n ctx={ctx}\n searchable={node.searchable}\n filterFields={node.filters}\n sort={node.sort}\n />\n ) : (\n <SimpleAssociatedTable\n entityCode={assocCode}\n entity={assocEntity}\n parentEntity={ctx.entityCode}\n parentId={ctx.recordId}\n foreignKey={fkField}\n columns={columns}\n editable={editable}\n ctx={ctx}\n sort={node.sort}\n />\n )}\n </div>\n );\n}\n\n// SimpleAssociatedTable uses the original useChildrenData hook (no search/filter/pagination).\ninterface SimpleTableProps {\n entityCode: string;\n entity: Entity;\n parentEntity: string;\n parentId: string;\n foreignKey: string;\n columns: string[];\n editable: boolean;\n ctx: LayoutContext;\n sort?: string;\n}\n\nfunction SimpleAssociatedTable({\n entityCode,\n entity,\n parentEntity,\n parentId,\n foreignKey,\n columns,\n editable,\n ctx,\n sort,\n}: SimpleTableProps) {\n const queryClient = useQueryClient();\n const { data: response, isLoading, isError } = useChildrenData(\n parentEntity,\n parentId,\n entityCode,\n foreignKey,\n sort,\n );\n const rows = response?.data ?? [];\n const refs = response?.$refs;\n\n const invalidateQuery = useCallback(() => {\n queryClient.invalidateQueries({\n queryKey: [ENTITY_CHILDREN_KEY, parentEntity, parentId, entityCode],\n });\n }, [queryClient, parentEntity, parentId, entityCode]);\n\n return (\n <AssociatedTableInner\n entityCode={entityCode}\n entity={entity}\n parentId={parentId}\n foreignKey={foreignKey}\n columns={columns}\n editable={editable}\n ctx={ctx}\n rows={rows}\n refs={refs}\n isLoading={isLoading}\n isError={isError}\n invalidateQuery={invalidateQuery}\n />\n );\n}\n\n// PaginatedAssociatedTable uses useAssociatedData with search/filter/pagination support.\ninterface PaginatedTableProps extends SimpleTableProps {\n searchable?: boolean;\n filterFields?: string[];\n}\n\nfunction PaginatedAssociatedTable({\n entityCode,\n entity,\n parentEntity,\n parentId,\n foreignKey,\n columns,\n editable,\n ctx,\n searchable,\n filterFields,\n sort,\n}: PaginatedTableProps) {\n const queryClient = useQueryClient();\n\n // Search and filter state.\n const [searchValue, setSearchValue] = useState(\"\");\n const [debouncedSearch, setDebouncedSearch] = useState(\"\");\n const [filters, setFilters] = useState<Record<string, string>>({});\n const searchTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n // Debounce search input.\n useEffect(() => {\n if (searchTimerRef.current) clearTimeout(searchTimerRef.current);\n searchTimerRef.current = setTimeout(() => {\n setDebouncedSearch(searchValue);\n }, 300);\n return () => {\n if (searchTimerRef.current) clearTimeout(searchTimerRef.current);\n };\n }, [searchValue]);\n\n const handleFilterChange = useCallback((field: string, value: string) => {\n setFilters((prev) => {\n if (value === \"__all__\") {\n const { [field]: _, ...rest } = prev;\n return rest;\n }\n return { ...prev, [field]: value };\n });\n }, []);\n\n // Active filters for the API call.\n const activeFilters = useMemo(() => {\n return Object.keys(filters).length > 0 ? filters : undefined;\n }, [filters]);\n\n const {\n data: infiniteData,\n isLoading,\n isError,\n hasNextPage,\n fetchNextPage,\n isFetchingNextPage,\n } = useAssociatedData(\n parentEntity,\n parentId,\n entityCode,\n foreignKey,\n sort,\n undefined, // limit\n debouncedSearch || undefined,\n activeFilters,\n );\n\n // Flatten pages into a single rows array and merge refs.\n const { rows, refs } = useMemo(() => {\n if (!infiniteData?.pages) return { rows: [] as Record<string, unknown>[], refs: undefined as Refs | undefined };\n const allRows: Record<string, unknown>[] = [];\n let mergedRefs: Refs | undefined;\n for (const page of infiniteData.pages) {\n allRows.push(...page.data);\n if (page.$refs) {\n if (!mergedRefs) {\n mergedRefs = { ...page.$refs };\n } else {\n for (const [entityKey, records] of Object.entries(page.$refs)) {\n mergedRefs[entityKey] = { ...mergedRefs[entityKey], ...records };\n }\n }\n }\n }\n return { rows: allRows, refs: mergedRefs };\n }, [infiniteData]);\n\n const invalidateQuery = useCallback(() => {\n queryClient.invalidateQueries({\n predicate: (query) => {\n const key = query.queryKey;\n return key[0] === ENTITY_CHILDREN_KEY && key[3] === entityCode;\n },\n });\n }, [queryClient, entityCode]);\n\n return (\n <div>\n <AssociatedToolbar\n entity={entity}\n searchable={searchable}\n filterFields={filterFields}\n searchValue={searchValue}\n onSearchChange={setSearchValue}\n filters={filters}\n onFilterChange={handleFilterChange}\n allEntities={ctx.schema.entities}\n />\n <AssociatedTableInner\n entityCode={entityCode}\n entity={entity}\n parentId={parentId}\n foreignKey={foreignKey}\n columns={columns}\n editable={editable}\n ctx={ctx}\n rows={rows}\n refs={refs}\n isLoading={isLoading}\n isError={isError}\n invalidateQuery={invalidateQuery}\n />\n {hasNextPage && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"mt-1 text-[var(--muted-foreground)]\"\n onClick={() => fetchNextPage()}\n disabled={isFetchingNextPage}\n >\n {isFetchingNextPage ? (\n <Loader2 className=\"h-4 w-4 mr-1 animate-spin\" />\n ) : null}\n Load more\n </Button>\n )}\n </div>\n );\n}\n\n// AssociatedTableInner is the shared table rendering logic used by both simple and paginated modes.\ninterface TableInnerProps {\n entityCode: string;\n entity: Entity;\n parentId: string;\n foreignKey: string;\n columns: string[];\n editable: boolean;\n ctx: LayoutContext;\n rows: Record<string, unknown>[];\n refs?: Refs;\n isLoading: boolean;\n isError: boolean;\n invalidateQuery: () => void;\n}\n\nfunction AssociatedTableInner({\n entityCode,\n entity,\n parentId,\n foreignKey,\n columns,\n editable,\n ctx,\n rows,\n refs,\n isLoading,\n isError,\n invalidateQuery,\n}: TableInnerProps) {\n // Editable columns: exclude FK, auto, primary.\n const editableColumns = useMemo(() => {\n if (!editable) return new Set<string>();\n return new Set(\n columns.filter((col) => {\n if (col === foreignKey) return false;\n const field = entity.fields[col];\n if (!field) return false;\n if (field.auto || field.primary) return false;\n return true;\n }),\n );\n }, [columns, foreignKey, entity.fields, editable]);\n\n // Per-row edit state: which cell is active (click-to-edit).\n const [activeCell, setActiveCell] = useState<{ rowId: string; col: string } | null>(null);\n // Per-row merge-debounce state.\n const [rowStates, setRowStates] = useState<Record<string, AssociatedRowState>>({});\n const rowStatesRef = useRef(rowStates);\n rowStatesRef.current = rowStates;\n const debounceTimers = useRef<Record<string, ReturnType<typeof setTimeout>>>({});\n\n // Clean up debounce timers on unmount.\n useEffect(() => {\n const timers = debounceTimers.current;\n return () => {\n for (const t of Object.values(timers)) clearTimeout(t);\n };\n }, []);\n\n // Draft row state for \"Add row\" flow.\n const [draftRow, setDraftRow] = useState<Record<string, unknown> | null>(null);\n const [draftErrors, setDraftErrors] = useState<string[]>([]);\n const [draftSaving, setDraftSaving] = useState(false);\n\n // Delete confirmation state.\n const [deleteConfirm, setDeleteConfirm] = useState<{ show: boolean; rowId: string; label: string } | null>(null);\n const [deletingIds, setDeletingIds] = useState<Set<string>>(new Set());\n\n // Flush a row's buffer as a single PATCH.\n const flushRow = useCallback(\n async (rowId: string, buffer: Record<string, unknown>, sentVer: number) => {\n setRowStates((prev) => ({\n ...prev,\n [rowId]: { ...prev[rowId], saving: true, error: undefined },\n }));\n try {\n await updateEntity(entityCode, rowId, buffer);\n setRowStates((prev) => {\n const current = prev[rowId];\n if (!current) return prev;\n // Drop stale response: if user made more edits, don't clear buffer.\n if (current.ver > sentVer) {\n return { ...prev, [rowId]: { ...current, saving: false } };\n }\n // Response is current: clear buffer.\n const { [rowId]: _, ...rest } = prev;\n return rest;\n });\n invalidateQuery();\n } catch (err) {\n const msg = err instanceof Error ? err.message : \"Save failed\";\n setRowStates((prev) => ({\n ...prev,\n [rowId]: { ...prev[rowId], saving: false, error: msg },\n }));\n }\n },\n [entityCode, invalidateQuery],\n );\n\n // Handle cell value change with merge-debounce.\n const handleCellChange = useCallback(\n (rowId: string, fieldName: string, value: unknown) => {\n setRowStates((prev) => {\n const current = prev[rowId] ?? { buffer: {}, ver: 0, saving: false };\n const nextVer = current.ver + 1;\n return {\n ...prev,\n [rowId]: {\n ...current,\n buffer: { ...current.buffer, [fieldName]: value },\n ver: nextVer,\n },\n };\n });\n // Reset debounce timer.\n if (debounceTimers.current[rowId]) {\n clearTimeout(debounceTimers.current[rowId]);\n }\n debounceTimers.current[rowId] = setTimeout(() => {\n const current = rowStatesRef.current[rowId];\n if (current && Object.keys(current.buffer).length > 0) {\n flushRow(rowId, { ...current.buffer }, current.ver);\n }\n }, 500);\n },\n [flushRow],\n );\n\n // Handle adding a new draft row.\n const handleStartDraft = useCallback(() => {\n const draft: Record<string, unknown> = {};\n // Pre-fill FK to parent.\n draft[foreignKey] = parentId;\n // Pre-fill field-level defaults, then bool fallback.\n for (const col of columns) {\n const field = entity.fields[col];\n if (!field) continue;\n if (field.default !== undefined) {\n draft[col] = field.default;\n } else if (field.type === \"bool\") {\n draft[col] = false;\n }\n }\n setDraftRow(draft);\n setDraftErrors([]);\n }, [foreignKey, parentId, columns, entity.fields]);\n\n // Validate and confirm the draft row.\n const handleConfirmDraft = useCallback(async () => {\n if (!draftRow) return;\n // Client-side required field validation.\n const errors: string[] = [];\n for (const col of columns) {\n const field = entity.fields[col];\n if (!field || !field.required) continue;\n if (field.auto || field.primary) continue;\n if (col === foreignKey) continue;\n const val = draftRow[col];\n if (val == null || val === \"\") {\n errors.push(col);\n }\n }\n if (errors.length > 0) {\n setDraftErrors(errors);\n return;\n }\n setDraftSaving(true);\n try {\n await createEntity(entityCode, draftRow);\n setDraftRow(null);\n setDraftErrors([]);\n invalidateQuery();\n } catch (err) {\n const msg = err instanceof Error ? err.message : \"Create failed\";\n setDraftErrors([`_error:${msg}`]);\n } finally {\n setDraftSaving(false);\n }\n }, [draftRow, columns, entity.fields, foreignKey, entityCode, invalidateQuery]);\n\n // Handle delete row with confirmation.\n const handleDeleteRow = useCallback(\n async (rowId: string) => {\n setDeleteConfirm(null);\n setDeletingIds((prev) => new Set(prev).add(rowId));\n try {\n await deleteEntity(entityCode, rowId);\n invalidateQuery();\n } catch {\n // On error, just remove from deleting set - row stays visible.\n } finally {\n setDeletingIds((prev) => {\n const next = new Set(prev);\n next.delete(rowId);\n return next;\n });\n }\n },\n [entityCode, invalidateQuery],\n );\n\n if (isError) {\n return <div className=\"text-sm text-[var(--destructive)] py-2\">Failed to load.</div>;\n }\n\n if (isLoading) {\n return (\n <div className=\"space-y-2 py-2\">\n <Skeleton className=\"h-8 w-full\" />\n <Skeleton className=\"h-8 w-full\" />\n </div>\n );\n }\n\n const showEmpty = rows.length === 0 && !draftRow;\n\n return (\n <div>\n {showEmpty && !editable && (\n <div className=\"text-sm text-[var(--muted-foreground)] py-4\">\n No records yet.\n </div>\n )}\n {(!showEmpty || editable) && (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b\">\n {columns.map((col) => {\n const field = entity.fields[col];\n return (\n <th\n key={col}\n className=\"h-8 px-3 text-left align-middle font-medium text-[var(--muted-foreground)]\"\n >\n {field ? fieldDisplayName(field, col, ctx.schema.entities) : col}\n </th>\n );\n })}\n {editable && <th className=\"h-8 w-10 px-2\" />}\n </tr>\n </thead>\n <tbody>\n {rows.map((row) => {\n const rowId = String((row as Record<string, unknown>)[\"id\"] ?? \"\");\n const isDeleting = deletingIds.has(rowId);\n const rowState = rowStates[rowId];\n return (\n <AssociatedRow\n key={rowId}\n rowId={rowId}\n row={row}\n entity={entity}\n columns={columns}\n editableColumns={editableColumns}\n editable={editable}\n isDeleting={isDeleting}\n activeCell={activeCell}\n setActiveCell={setActiveCell}\n rowState={rowState}\n onCellChange={handleCellChange}\n onDeleteClick={(id) => {\n const displayField = entity.display?.display_field;\n const label = displayField ? String(row[displayField] ?? \"\") : \"\";\n setDeleteConfirm({ show: true, rowId: id, label });\n }}\n refs={refs}\n />\n );\n })}\n {draftRow && (\n <DraftRow\n draftRow={draftRow}\n entity={entity}\n columns={columns}\n editableColumns={editableColumns}\n foreignKey={foreignKey}\n draftErrors={draftErrors}\n draftSaving={draftSaving}\n onChange={(field, value) =>\n setDraftRow((prev) => (prev ? { ...prev, [field]: value } : prev))\n }\n onConfirm={handleConfirmDraft}\n onCancel={() => {\n setDraftRow(null);\n setDraftErrors([]);\n }}\n refs={refs}\n />\n )}\n </tbody>\n </table>\n </div>\n )}\n {editable && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"mt-2 text-[var(--muted-foreground)]\"\n onClick={handleStartDraft}\n disabled={!!draftRow}\n >\n <Plus className=\"h-4 w-4 mr-1\" />\n Add row\n </Button>\n )}\n {deleteConfirm && (\n <ConfirmDialog\n open={deleteConfirm.show}\n onOpenChange={(open) => !open && setDeleteConfirm(null)}\n title=\"Delete record\"\n description={\n deleteConfirm.label\n ? `Are you sure you want to delete \"${deleteConfirm.label}\"?`\n : \"Are you sure you want to delete this record?\"\n }\n confirmLabel=\"Delete\"\n onConfirm={() => handleDeleteRow(deleteConfirm.rowId)}\n destructive\n />\n )}\n </div>\n );\n}\n\n// AssociatedRow renders a single data row with click-to-edit support.\ninterface AssociatedRowProps {\n rowId: string;\n row: Record<string, unknown>;\n entity: Entity;\n columns: string[];\n editableColumns: Set<string>;\n editable: boolean;\n isDeleting: boolean;\n activeCell: { rowId: string; col: string } | null;\n setActiveCell: (cell: { rowId: string; col: string } | null) => void;\n rowState?: AssociatedRowState;\n onCellChange: (rowId: string, fieldName: string, value: unknown) => void;\n onDeleteClick: (rowId: string) => void;\n refs?: Refs;\n}\n\nfunction AssociatedRow({\n rowId,\n row,\n entity,\n columns,\n editableColumns,\n editable,\n isDeleting,\n activeCell,\n setActiveCell,\n rowState,\n onCellChange,\n onDeleteClick,\n refs,\n}: AssociatedRowProps) {\n // Merge buffer values over server data for display while editing.\n const displayRow = useMemo(() => {\n if (!rowState || Object.keys(rowState.buffer).length === 0) return row;\n return { ...row, ...rowState.buffer };\n }, [row, rowState]);\n\n return (\n <tr\n className={`border-b last:border-0 hover:bg-[var(--muted)]/50 ${isDeleting ? \"opacity-50\" : \"\"}`}\n >\n {columns.map((col) => {\n const field = entity.fields[col];\n const isEditable = editableColumns.has(col);\n const isActive = activeCell?.rowId === rowId && activeCell?.col === col;\n\n if (isActive && isEditable) {\n return (\n <td\n key={col}\n className=\"px-1 py-1 align-middle\"\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: displayRow[col],\n mode: \"edit\",\n onChange: (val) => onCellChange(rowId, col, val),\n record: displayRow,\n refs,\n })\n : String(displayRow[col] ?? \"\")}\n </td>\n );\n }\n\n return (\n <td\n key={col}\n className={`px-3 py-2 align-middle ${isEditable ? \"cursor-pointer\" : \"\"}`}\n onClick={\n isEditable && !isDeleting\n ? () => setActiveCell({ rowId, col })\n : undefined\n }\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: displayRow[col],\n mode: \"display\",\n record: displayRow,\n refs,\n })\n : String(displayRow[col] ?? \"\")}\n </td>\n );\n })}\n {editable && (\n <td className=\"px-2 py-1 align-middle\">\n <div className=\"flex items-center gap-1\">\n {rowState?.saving && (\n <Loader2 className=\"h-3 w-3 animate-spin text-[var(--muted-foreground)]\" />\n )}\n {rowState?.error && (\n <span className=\"text-xs text-[var(--destructive)]\" title={rowState.error}>!</span>\n )}\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 text-[var(--muted-foreground)] hover:text-[var(--destructive)]\"\n onClick={() => onDeleteClick(rowId)}\n disabled={isDeleting}\n title=\"Delete row\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n </td>\n )}\n </tr>\n );\n}\n\n// DraftRow renders the inline draft for new row creation.\ninterface DraftRowProps {\n draftRow: Record<string, unknown>;\n entity: Entity;\n columns: string[];\n editableColumns: Set<string>;\n foreignKey: string;\n draftErrors: string[];\n draftSaving: boolean;\n onChange: (field: string, value: unknown) => void;\n onConfirm: () => void;\n onCancel: () => void;\n refs?: Refs;\n}\n\nfunction DraftRow({\n draftRow,\n entity,\n columns,\n editableColumns,\n foreignKey,\n draftErrors,\n draftSaving,\n onChange,\n onConfirm,\n onCancel,\n refs,\n}: DraftRowProps) {\n const apiError = draftErrors.find((e) => e.startsWith(\"_error:\"));\n const fieldErrors = new Set(draftErrors.filter((e) => !e.startsWith(\"_error:\")));\n\n return (\n <tr className=\"border-b last:border-0 border-dashed bg-[var(--muted)]/30\">\n {columns.map((col) => {\n const field = entity.fields[col];\n const isEditable = editableColumns.has(col) && col !== foreignKey;\n const hasError = fieldErrors.has(col);\n\n if (!isEditable) {\n return (\n <td key={col} className=\"px-3 py-2 align-middle text-[var(--muted-foreground)]\">\n {field?.auto ? \"-\" : String(draftRow[col] ?? \"\")}\n </td>\n );\n }\n\n return (\n <td\n key={col}\n className={`px-1 py-1 align-middle ${hasError ? \"ring-1 ring-inset ring-[var(--destructive)] rounded\" : \"\"}`}\n title={hasError ? `${col} is required` : undefined}\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: draftRow[col],\n mode: \"edit\",\n onChange: (val) => onChange(col, val),\n record: draftRow,\n refs,\n })\n : String(draftRow[col] ?? \"\")}\n </td>\n );\n })}\n <td className=\"px-2 py-1 align-middle\">\n <div className=\"flex items-center gap-1\">\n {apiError && (\n <span className=\"text-xs text-[var(--destructive)]\" title={apiError.slice(7)}>!</span>\n )}\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 text-[var(--primary)]\"\n onClick={onConfirm}\n disabled={draftSaving}\n title=\"Confirm\"\n >\n {draftSaving ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Check className=\"h-4 w-4\" />}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 text-[var(--muted-foreground)]\"\n onClick={onCancel}\n disabled={draftSaving}\n title=\"Cancel\"\n >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n </td>\n </tr>\n );\n}\n","import { fieldDisplayName } from \"@/types/schema\";\nimport type { LayoutField } from \"@/types/schema\";\nimport { renderField } from \"@/components/fields\";\nimport { ActionButton } from \"@/components/shared/ActionButton\";\nimport { cn } from \"@/lib/utils\";\nimport type { LayoutContext } from \"./LayoutRenderer\";\n\ninterface FieldsBlockProps {\n fields: LayoutField[];\n ctx: LayoutContext;\n}\n\n// FieldsBlock renders a list of fields without section chrome (no card, no\n// header). Useful for header-style field blocks or inline field groups.\n// When ctx.columns is 1, renders label above value (stacked, full width).\n// When ctx.columns is 2 (default), renders label beside value (side-by-side).\n// Per-field screen-scoped action buttons (LayoutField.actions) render as\n// icon-size buttons to the right of the field value, in display mode only.\nexport function FieldsBlock({ fields, ctx }: FieldsBlockProps) {\n const { entity, entityCode, record, mode, onFieldChange, schema } = ctx;\n const columns = ctx.columns ?? 2;\n // When columns=1 and there's only one field, the section header already\n // serves as label - skip the redundant field label.\n const hideLabels = columns === 1 && fields.length === 1;\n\n return (\n <div className={cn(\n \"grid gap-x-6 gap-y-3\",\n columns === 1 ? \"grid-cols-1\" : \"grid-cols-1 md:grid-cols-2\",\n )}>\n {fields.map((layoutField) => {\n const fieldName = layoutField.name;\n const field = entity.fields[fieldName];\n if (!field) return null;\n const value = record[fieldName];\n const hasActions = mode === \"display\" && layoutField.actions && layoutField.actions.length > 0;\n return (\n <div\n key={fieldName}\n className={columns === 1 ? \"flex flex-col gap-1\" : \"flex flex-col md:flex-row gap-1\"}\n >\n {!hideLabels && (\n <div className={cn(\n \"text-sm text-[var(--muted-foreground)]\",\n columns === 2 && \"md:w-40 md:pt-0.5\",\n )}>\n {fieldDisplayName(field, fieldName, schema.entities)}\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-start gap-1\">\n <div className=\"flex-1 min-w-0\">\n {renderField({\n field,\n fieldName,\n value,\n mode,\n onChange: onFieldChange\n ? (v: unknown) => onFieldChange(fieldName, v)\n : undefined,\n record,\n refs: ctx.refs,\n })}\n </div>\n {hasActions && (\n <div className=\"flex items-center gap-1 shrink-0\">\n {layoutField.actions!.map((action, i) => (\n <ActionButton\n key={i}\n actionCode={`${fieldName}.action[${i}]`}\n action={action}\n entityCode={entityCode}\n row={record}\n variant=\"ghost\"\n size=\"icon\"\n />\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n","import { useCallback, useEffect, useRef } from \"react\";\nimport { renderField } from \"@/components/fields\";\nimport { loc, propertyToField } from \"@/types/schema\";\nimport type { LayoutNode } from \"@/types/schema\";\nimport type { LayoutContext } from \"./LayoutRenderer\";\n\ninterface PropertiesBlockProps {\n node: LayoutNode;\n ctx: LayoutContext;\n}\n\n// Types where onChange fires on every keystroke and needs debouncing.\nconst DEBOUNCE_TYPES = new Set([\"string\", \"text\", \"int\", \"float\", \"decimal\", \"email\", \"url\"]);\nconst DEBOUNCE_MS = 500;\n\n// PropertiesBlock renders object properties using the same rich field renderers as entity fields.\nexport function PropertiesBlock({ node, ctx }: PropertiesBlockProps) {\n const { entity, objectProperties, onSetProperty, isNew, mode, refs } = ctx;\n const propertyDefs = entity.properties ?? {};\n\n // A brand-new record (pre-create) has no properties to render — the row\n // doesn't exist yet in the DB. In all other cases render the property\n // values; in display mode they're read-only, in edit mode they need\n // onSetProperty to propagate changes (gated per-property below).\n if (isNew) return null;\n\n // node.properties is true (all) or an array of property codes (subset).\n const filter: string[] | true = node.properties === true ? true : (node.properties as string[]);\n\n // When filter is an array, preserve its explicit order; otherwise sort alphabetically.\n const entries: [string, import(\"@/types/schema\").PropertyDef][] = filter === true\n ? Object.entries(propertyDefs).sort(([a], [b]) => a.localeCompare(b))\n : (filter as string[])\n .filter((code) => propertyDefs[code] != null)\n .map((code) => [code, propertyDefs[code]]);\n\n if (entries.length === 0) return null;\n\n return (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-3\">\n {entries.map(([propCode, prop]) => {\n const propVal = objectProperties?.find((p) => p.property_code === propCode);\n const field = propertyToField(prop);\n // Force display mode when the outer page has no write callback\n // (readonly entity, or view mode on a detail page) — even if the\n // property itself is writable.\n const effectiveMode = (prop.readonly || !onSetProperty) ? \"display\" : mode;\n\n return (\n <DebouncedProperty\n key={propCode}\n propCode={propCode}\n prop={prop}\n field={field}\n value={propVal?.value}\n mode={effectiveMode}\n onSetProperty={onSetProperty}\n refs={refs}\n />\n );\n })}\n </div>\n );\n}\n\n// DebouncedProperty wraps a single property field with optional debounce for text-like types.\n// onSetProperty is optional — omit it (display-mode / read-only containers) and the field\n// renders without an onChange handler.\nfunction DebouncedProperty({\n propCode,\n prop,\n field,\n value,\n mode,\n onSetProperty,\n refs,\n}: {\n propCode: string;\n prop: { name: import(\"@/types/schema\").LocalizedString; display?: { name: import(\"@/types/schema\").LocalizedString }; type: string };\n field: import(\"@/types/schema\").EntityField;\n value: unknown;\n mode: \"display\" | \"edit\";\n onSetProperty?: (code: string, value: unknown) => void;\n refs?: import(\"@/components/fields\").RefsMap;\n}) {\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (timerRef.current) clearTimeout(timerRef.current);\n };\n }, []);\n\n const onChange = useCallback(\n (v: unknown) => {\n if (!onSetProperty) return;\n if (DEBOUNCE_TYPES.has(prop.type)) {\n if (timerRef.current) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => onSetProperty(propCode, v), DEBOUNCE_MS);\n } else {\n onSetProperty(propCode, v);\n }\n },\n [propCode, prop.type, onSetProperty],\n );\n\n return (\n <div className=\"flex flex-col md:flex-row gap-1\">\n <div className=\"md:w-40 md:pt-0.5 text-sm text-[var(--muted-foreground)]\">\n {loc(prop.display?.name ?? prop.name)}\n </div>\n <div className=\"flex-1 min-w-0\">\n {renderField({\n field,\n fieldName: propCode,\n value,\n mode,\n onChange: mode === \"edit\" ? onChange : undefined,\n refs,\n })}\n </div>\n </div>\n );\n}\n","import { Badge } from \"@/components/ui/badge\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { loc } from \"@/types/schema\";\nimport type { StatusGroupDef } from \"@/types/schema\";\nimport type { StatusInfo } from \"@/types/api\";\n\ninterface StatusGroupsDisplayProps {\n statusGroups: Record<string, StatusGroupDef>;\n objectStatuses: StatusInfo[] | undefined;\n onSetStatus: (groupCode: string, statusCode: string) => void;\n isPending: boolean;\n mode?: \"display\" | \"edit\";\n}\n\n// StatusGroupsDisplay renders status group selectors with colored badges.\n// In display mode: read-only badges. In edit mode: interactive dropdowns.\nexport function StatusGroupsDisplay({\n statusGroups,\n objectStatuses,\n onSetStatus,\n isPending,\n mode = \"edit\",\n}: StatusGroupsDisplayProps) {\n return (\n <div className=\"flex flex-wrap items-center gap-4\">\n {Object.entries(statusGroups).map(([sgCode, sg]) => {\n const current = objectStatuses?.find((s) => s.group_code === sgCode);\n const currentCode = current?.status_code;\n const currentStatus = currentCode ? sg.statuses.find((s) => s.code === currentCode) : undefined;\n\n // Display mode: read-only badge\n if (mode === \"display\") {\n return (\n <div key={sgCode} className=\"flex items-center gap-2\">\n <span className=\"text-sm text-[var(--muted-foreground)]\">{loc(sg.name)}:</span>\n {currentStatus ? (\n <Badge\n className=\"text-xs\"\n style={{\n backgroundColor: currentStatus.color || undefined,\n color: currentStatus.color ? \"#fff\" : undefined,\n }}\n >\n {loc(currentStatus.name)}\n </Badge>\n ) : (\n <span className=\"text-sm text-[var(--muted-foreground)]\">-</span>\n )}\n </div>\n );\n }\n\n // Edit mode: interactive dropdown\n const available = sg.transitions && currentCode\n ? sg.statuses.filter(\n (s) =>\n s.code === currentCode ||\n (sg.transitions![currentCode]?.includes(s.code) ?? false),\n )\n : sg.statuses;\n\n return (\n <div key={sgCode} className=\"flex items-center gap-2\">\n <span className=\"text-sm text-[var(--muted-foreground)]\">{loc(sg.name)}:</span>\n <Select\n value={currentCode ?? \"\"}\n onValueChange={(statusCode) => onSetStatus(sgCode, statusCode)}\n disabled={isPending}\n >\n <SelectTrigger className=\"w-[180px]\">\n <SelectValue>\n {currentStatus ? (\n <Badge\n className=\"text-xs\"\n style={{\n backgroundColor: currentStatus.color || undefined,\n color: currentStatus.color ? \"#fff\" : undefined,\n }}\n >\n {loc(currentStatus.name)}\n </Badge>\n ) : (\n \"Select...\"\n )}\n </SelectValue>\n </SelectTrigger>\n <SelectContent>\n {available.map((s) => (\n <SelectItem key={s.code} value={s.code}>\n <div className=\"flex items-center gap-2\">\n {s.color && (\n <span\n className=\"w-2.5 h-2.5 rounded-full inline-block\"\n style={{ backgroundColor: s.color }}\n />\n )}\n {loc(s.name)}\n </div>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n );\n })}\n </div>\n );\n}\n","import { StatusGroupsDisplay } from \"@/components/shared/StatusGroupsDisplay\";\nimport type { LayoutNode } from \"@/types/schema\";\nimport type { LayoutContext } from \"./LayoutRenderer\";\n\nconst noop = () => {};\n\ninterface StatusesBlockProps {\n node: LayoutNode;\n ctx: LayoutContext;\n}\n\n// StatusesBlock renders status group selectors for a `statuses: true` layout node.\n// Filters to a subset of status groups if the node value is an array of group codes.\nexport function StatusesBlock({ node, ctx }: StatusesBlockProps) {\n const { entity, objectStatuses, onSetStatus, isStatusPending, isNew } = ctx;\n const statusGroups = entity.status_groups ?? {};\n\n if (isNew) return null;\n\n // node.statuses is true (all groups) or an array of group codes (subset).\n const filter: string[] | true = node.statuses === true ? true : (node.statuses as string[]);\n\n const filtered = Object.fromEntries(\n Object.entries(statusGroups).filter(\n ([code]) => filter === true || (filter as string[]).includes(code),\n ),\n );\n\n if (Object.keys(filtered).length === 0) return null;\n\n return (\n <StatusGroupsDisplay\n statusGroups={filtered}\n objectStatuses={objectStatuses}\n onSetStatus={onSetStatus ?? noop}\n isPending={isStatusPending ?? false}\n mode={ctx.mode}\n />\n );\n}\n","import type { Entity, LayoutNode, Schema } from \"@/types/schema\";\nimport type { StatusInfo, PropertyValue } from \"@/types/api\";\nimport { LayoutRow } from \"./LayoutRow\";\nimport { LayoutColumn } from \"./LayoutColumn\";\nimport { LayoutTabs } from \"./LayoutTabs\";\nimport { SectionBlock } from \"./SectionBlock\";\nimport { ChildrenBlock } from \"./ChildrenBlock\";\nimport { AssociatedBlock } from \"./AssociatedBlock\";\nimport { FieldsBlock } from \"./FieldsBlock\";\nimport { PropertiesBlock } from \"./PropertiesBlock\";\nimport { StatusesBlock } from \"./StatusesBlock\";\n\nimport type { RefsMap } from \"@/components/fields\";\n\n// PendingChildRow represents a single child row in the pending edit state.\n// Used for direct (aggregate) children during parent edit mode.\nexport interface PendingChildRow {\n _key: string; // stable React key (id for existing, nanoid() for new)\n _deleted?: boolean; // marked for deletion (shown with strikethrough, excluded from save)\n _dirty?: boolean; // has any field been modified since edit mode started\n [field: string]: unknown;\n}\n\n// LayoutContext carries the parent record context needed by all layout nodes.\nexport interface LayoutContext {\n schema: Schema;\n entity: Entity;\n entityCode: string;\n recordId: string;\n record: Record<string, unknown>;\n isNew: boolean;\n mode: \"display\" | \"edit\";\n onFieldChange?: (field: string, value: unknown) => void;\n // $refs from the detail response (entity -> id -> record).\n refs?: RefsMap;\n // Section-level column count override for FieldsBlock (1 = stacked, 2 = side-by-side).\n columns?: number;\n // Properties and statuses state - required for `properties` and `statuses` leaf nodes.\n objectProperties?: PropertyValue[];\n onSetProperty?: (propertyCode: string, value: unknown) => void;\n isPropertyPending?: boolean;\n objectStatuses?: StatusInfo[];\n onSetStatus?: (groupCode: string, statusCode: string) => void;\n isStatusPending?: boolean;\n // Children editing (direct/aggregate children only).\n // undefined = no edits to any children yet; skip $children in payload.\n pendingChildren?: Record<string, PendingChildRow[]>;\n onChildrenChange?: (childCode: string, rows: PendingChildRow[]) => void;\n // Validation errors keyed by childCode -> rowKey -> fieldNames with errors.\n childValidationErrors?: Record<string, Record<string, string[]>>;\n}\n\ninterface LayoutRendererProps {\n nodes: LayoutNode[];\n ctx: LayoutContext;\n}\n\n// LayoutRenderer renders an array of layout nodes, dispatching each to the\n// appropriate component based on which kind field is set.\nexport function LayoutRenderer({ nodes, ctx }: LayoutRendererProps) {\n return (\n <>\n {nodes.map((node, i) => (\n <LayoutNodeRenderer key={i} node={node} ctx={ctx} />\n ))}\n </>\n );\n}\n\ninterface LayoutNodeRendererProps {\n node: LayoutNode;\n ctx: LayoutContext;\n}\n\n// LayoutNodeRenderer dispatches a single node to the right component.\nexport function LayoutNodeRenderer({ node, ctx }: LayoutNodeRendererProps) {\n // Containers\n if (node.row) {\n return <LayoutRow config={node.row} ctx={ctx} />;\n }\n if (node.column) {\n return <LayoutColumn config={node.column} node={node} ctx={ctx} />;\n }\n if (node.tabs) {\n return <LayoutTabs config={node.tabs} ctx={ctx} />;\n }\n if (node.section) {\n return <SectionBlock config={node.section} ctx={ctx} />;\n }\n if (node.children) {\n return <ChildrenBlock node={node} ctx={ctx} />;\n }\n if (node.associated) {\n return <AssociatedBlock node={node} ctx={ctx} />;\n }\n if (node.fields) {\n return <FieldsBlock fields={node.fields} ctx={ctx} />;\n }\n if (node.properties != null) {\n return <PropertiesBlock node={node} ctx={ctx} />;\n }\n if (node.statuses != null) {\n return <StatusesBlock node={node} ctx={ctx} />;\n }\n\n return null;\n}\n\n// getNodeKind returns the kind string for a layout node, used for testing and debugging.\nexport function getNodeKind(node: LayoutNode): string | null {\n if (node.row) return \"row\";\n if (node.column) return \"column\";\n if (node.tabs) return \"tabs\";\n if (node.section) return \"section\";\n if (node.children) return \"children\";\n if (node.associated) return \"associated\";\n if (node.fields) return \"fields\";\n if (node.properties != null) return \"properties\";\n if (node.statuses != null) return \"statuses\";\n return null;\n}\n","import type { Schema } from \"@/types/schema\";\nimport type { PendingChildRow } from \"@/components/detail-layout/LayoutRenderer\";\n\n// collectFKFields returns the set of FK field names for a given child entity\n// by scanning all parent entities' children relations.\nfunction collectFKFields(childCode: string, schema: Schema): Set<string> {\n const fks = new Set<string>();\n for (const entity of Object.values(schema.entities)) {\n if (!entity.children) continue;\n for (const rel of entity.children) {\n if (rel.entity === childCode && rel.foreign_key) {\n const fkArr = Array.isArray(rel.foreign_key) ? rel.foreign_key : [rel.foreign_key];\n for (const fk of fkArr) {\n fks.add(fk);\n }\n }\n }\n }\n return fks;\n}\n\n// validatePendingChildren checks all non-deleted rows across all child codes\n// against their entity's required fields. Returns a map of validation errors:\n// { childCode: { rowKey: [fieldName, ...] } }\n// Empty object = no errors.\nexport function validatePendingChildren(\n pendingChildren: Record<string, PendingChildRow[]> | undefined,\n schema: Schema | undefined,\n): Record<string, Record<string, string[]>> {\n if (!pendingChildren || !schema) return {};\n\n const errors: Record<string, Record<string, string[]>> = {};\n\n for (const [childCode, rows] of Object.entries(pendingChildren)) {\n const childEntity = schema.entities[childCode];\n if (!childEntity) continue;\n\n // FK fields are auto-injected server-side, skip them.\n const fkFields = collectFKFields(childCode, schema);\n\n // Find required fields (non-auto, non-primary, non-FK).\n const requiredFields: string[] = [];\n for (const [fieldName, field] of Object.entries(childEntity.fields)) {\n if (field.required && !field.auto && !field.primary && !fkFields.has(fieldName)) {\n requiredFields.push(fieldName);\n }\n }\n if (requiredFields.length === 0) continue;\n\n for (const row of rows) {\n if (row._deleted) continue;\n\n const missingFields: string[] = [];\n for (const fieldName of requiredFields) {\n const val = row[fieldName];\n if (val == null || val === \"\") {\n missingFields.push(fieldName);\n }\n }\n if (missingFields.length > 0) {\n if (!errors[childCode]) errors[childCode] = {};\n errors[childCode][row._key] = missingFields;\n }\n }\n }\n\n return errors;\n}\n","import { useState, useMemo, useCallback, useEffect, useRef } from \"react\";\nimport { useParams, useNavigate, useLocation, useSearchParams } from \"react-router-dom\";\nimport { Save, X, Trash2, RotateCcw, AlertTriangle } from \"lucide-react\";\nimport { formatOffsetTimestamp } from \"@/lib/timestamp\";\nimport { Button } from \"@/components/ui/button\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport { useEntityItem } from \"@/hooks/useEntityItem\";\nimport { useCreateEntity, useUpdateEntity, useDeleteEntity, useRestoreEntity } from \"@/hooks/useMutations\";\nimport type { StatusInfo, PropertyValue } from \"@/types/api\";\nimport { PageHeader } from \"@/components/shared/PageHeader\";\nimport { DetailSkeleton } from \"@/components/shared/LoadingSkeleton\";\nimport { ConfirmDialog } from \"@/components/shared/ConfirmDialog\";\nimport { ActionButton } from \"@/components/shared/ActionButton\";\nimport { AssociationTabs } from \"@/components/shared/AssociationTabs\";\nimport { useTabStore } from \"@/stores/tabs\";\nimport { getScreenActions, getActionsByVisibility, evaluateConditions } from \"@/lib/actions\";\nimport { loc, getPrimaryKeyFields, extractPkValues, pkValuesToId } from \"@/types/schema\";\nimport type { LocalizedString, PkValues } from \"@/types/schema\";\nimport { LayoutRenderer, type LayoutContext, type PendingChildRow } from \"@/components/detail-layout\";\nimport { StatusGroupsDisplay } from \"@/components/shared/StatusGroupsDisplay\";\nimport { validatePendingChildren } from \"@/lib/children-validation\";\n\nconst noop = () => {};\n\n// Deep comparison of two arrays of plain objects for detecting children changes.\nfunction arraysEqual(a: Record<string, unknown>[], b: Record<string, unknown>[]): boolean {\n if (a.length !== b.length) return false;\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\ninterface SmartDetailPageProps {\n screenCode: string;\n}\n\nexport function SmartDetailPage({ screenCode }: SmartDetailPageProps) {\n const { id: urlId } = useParams<{ id: string }>();\n const navigate = useNavigate();\n const [searchParams, setSearchParams] = useSearchParams();\n const { data: schema } = useSchema();\n const selfUser = useAuthStore((s) => s.user);\n\n const screen = schema?.screens[screenCode];\n const entity = screen?.entity ? schema?.entities[screen.entity] : undefined;\n const entityCode = screen?.entity;\n\n // Self screens use the authenticated user's ID instead of URL param.\n const isSelf = screen?.self === true;\n const id = isSelf ? selfUser?.id : urlId;\n\n const isNew = !isSelf && id === \"new\";\n\n // Compute PK values for the API call.\n const pkValues: PkValues | string | undefined = useMemo(() => {\n if (!id || isNew) return undefined;\n if (!entity) return id;\n const pkFields = getPrimaryKeyFields(entity);\n if (pkFields.length === 1) {\n return { [pkFields[0]]: id };\n }\n // For composite PK, the URL id is pipe-separated: \"val1|val2\"\n const parts = id.split(\"|\");\n const values: PkValues = {};\n for (let i = 0; i < pkFields.length; i++) {\n values[pkFields[i]] = parts[i] ?? \"\";\n }\n return values;\n }, [id, isNew, entity]);\n\n const pkCacheKey = useMemo(() => {\n if (!pkValues) return undefined;\n if (typeof pkValues === \"string\") return pkValues;\n return pkValuesToId(pkValues);\n }, [pkValues]);\n\n const { data: itemResponse, isLoading } = useEntityItem(entityCode, pkValues);\n\n const createMutation = useCreateEntity(entityCode ?? \"\");\n const updateMutation = useUpdateEntity(entityCode ?? \"\");\n const deleteMutation = useDeleteEntity(entityCode ?? \"\");\n const restoreMutation = useRestoreEntity(entityCode ?? \"\");\n\n // $statuses and $properties are enriched inline on the record by\n // handlers/data.go:getByPKValues. Reading them directly from the\n // entity-item query result avoids a second round-trip AND an old bug\n // where the detail page fired GET /api/data/{entity}/{id} - a path\n // that does not exist and silently 404'd, leaving status/property\n // dropdowns blank even though the data was already in hand. See\n // TestGetByPKEnrichment for the backend contract.\n const hasStatusGroups = Object.keys(entity?.status_groups ?? {}).length > 0;\n const itemData = itemResponse?.data as Record<string, unknown> | undefined;\n const statuses = (itemData?.[\"$statuses\"] as StatusInfo[] | undefined);\n const objectProperties = (itemData?.[\"$properties\"] as PropertyValue[] | undefined);\n const openInEdit = searchParams.get(\"edit\") === \"true\";\n const [editing, setEditing] = useState(isNew || openInEdit);\n const [formData, setFormData] = useState<Record<string, unknown>>({});\n const [pendingStatuses, setPendingStatuses] = useState<Record<string, string>>({});\n const [pendingProperties, setPendingProperties] = useState<Record<string, unknown>>({});\n const [pendingChildren, setPendingChildren] = useState<Record<string, PendingChildRow[]> | undefined>(undefined);\n // Snapshot of $children at the time edit mode was entered, used to detect actual changes on save.\n const [childrenSnapshot, setChildrenSnapshot] = useState<Record<string, Record<string, unknown>[]> | undefined>(undefined);\n const [deleteConfirm, setDeleteConfirm] = useState<{ show: boolean; confirmation?: string }>({ show: false });\n\n // Sidebar resize: use a ref for live DOM updates during drag to avoid\n // re-rendering the entire component tree on every mousemove. Commit to\n // React state only on mouseup.\n const [sidebarW, setSidebarW] = useState(() => {\n const w = parseInt(screen?.sidebar_width || \"380\", 10);\n return isNaN(w) ? 380 : w;\n });\n const sidebarRef = useRef<HTMLDivElement>(null);\n const sidebarDrag = useRef<{ startX: number; startW: number } | null>(null);\n const onSidebarDragStart = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n const el = sidebarRef.current;\n if (!el) return;\n const startW = el.offsetWidth;\n sidebarDrag.current = { startX: e.clientX, startW };\n const onMove = (ev: MouseEvent) => {\n if (!sidebarDrag.current) return;\n const delta = sidebarDrag.current.startX - ev.clientX;\n const next = Math.max(280, Math.min(800, sidebarDrag.current.startW + delta));\n el.style.width = `${next}px`;\n };\n const onUp = () => {\n if (sidebarDrag.current && el) {\n setSidebarW(parseInt(el.style.width, 10) || sidebarDrag.current.startW);\n }\n sidebarDrag.current = null;\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n };\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n },\n [],\n );\n\n // Record data from API\n const record = itemResponse?.data as Record<string, unknown> | undefined;\n // Extract $refs from the record (detail responses embed refs inside the data object).\n const recordRefs = record?.[\"$refs\"] as Record<string, Record<string, Record<string, unknown>>> | undefined;\n\n // Soft-delete detection: if entity has soft_delete and the column is non-null, the record is deleted.\n const hasSoftDelete = !!entity?.soft_delete;\n const isRecordDeleted = hasSoftDelete && record != null && record[entity!.soft_delete!] != null;\n\n // Tab tracking: ensure this page has a tab and update title when record loads.\n const location = useLocation();\n const { openTab, updateTabTitle, findTabByPathname } = useTabStore();\n useEffect(() => {\n if (!entity || isSelf) return;\n const pathname = location.pathname;\n const tabName = loc(screen?.display?.name) || loc(entity.display.name);\n const tabIcon = screen?.display?.icon || entity.display.icon;\n const existing = findTabByPathname(pathname);\n if (!existing) {\n openTab({\n pathname,\n search: \"\",\n title: isNew ? `New ${tabName}` : tabName,\n icon: tabIcon,\n closable: true,\n });\n }\n }, [location.pathname, screen?.display?.name?.en, entity?.display.name?.en, screen?.display?.icon, entity?.display.icon, isNew, isSelf]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n if (!record || !entity || isSelf) return;\n const tab = findTabByPathname(location.pathname);\n if (tab) {\n const dfKey = entity.display?.display_field;\n const rawVal = dfKey ? record[dfKey] : undefined;\n const resolvedVal =\n rawVal && typeof rawVal === \"object\" && !Array.isArray(rawVal)\n ? loc(rawVal as LocalizedString)\n : rawVal;\n const displayTitle = resolvedVal\n ? String(resolvedVal)\n : (loc(screen?.display?.name) || loc(entity.display.name));\n updateTabTitle(tab.id, displayTitle);\n }\n }, [record, entity?.display.name?.en, entity?.display.display_field, location.pathname, isSelf]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Editable fields (non-auto, non-primary)\n const editableFields = useMemo(() => {\n if (!entity) return new Set<string>();\n const editable = new Set<string>();\n for (const [name, field] of Object.entries(entity.fields)) {\n if (!field.auto && !field.primary) {\n editable.add(name);\n }\n }\n return editable;\n }, [entity]);\n\n // Handle ?edit=true URL param: enter edit mode and populate form data.\n // Handles both initial mount and already-mounted tab receiving the param.\n useEffect(() => {\n if (!openInEdit || !record || editableFields.size === 0) return;\n // Enter edit mode if not already editing\n if (!editing) setEditing(true);\n // Populate form data if empty (avoid clobbering in-progress edits)\n if (Object.keys(formData).length === 0) {\n const data: Record<string, unknown> = {};\n editableFields.forEach((name) => {\n data[name] = record[name] ?? \"\";\n });\n setFormData(data);\n }\n // Always clean the param from URL\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.delete(\"edit\");\n return next;\n }, { replace: true });\n }, [openInEdit, record, editableFields]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Initialize pendingChildren for new records (isNew starts in edit mode).\n useEffect(() => {\n if (!isNew || !entity?.children || entity.children.length === 0) return;\n if (pendingChildren !== undefined) return; // already initialized\n setPendingChildren({});\n setChildrenSnapshot({});\n }, [isNew, entity?.children]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Initialize form data when entering edit mode or when record loads\n const startEditing = useCallback(() => {\n if (record) {\n const data: Record<string, unknown> = {};\n editableFields.forEach((name) => {\n data[name] = record[name] ?? \"\";\n });\n setFormData(data);\n }\n // Initialize pendingChildren from the detail response's $children.\n const serverChildren = record?.[\"$children\"] as Record<string, Record<string, unknown>[]> | undefined;\n if (serverChildren && Object.keys(serverChildren).length > 0) {\n const pending: Record<string, PendingChildRow[]> = {};\n for (const [childCode, rows] of Object.entries(serverChildren)) {\n pending[childCode] = rows.map((row) => ({\n ...row,\n _key: String(row.id ?? crypto.randomUUID()),\n }));\n }\n setPendingChildren(pending);\n setChildrenSnapshot(serverChildren);\n } else if (entity?.children && entity.children.length > 0) {\n // Entity has children but none exist yet - initialize empty so the UI can add rows.\n setPendingChildren({});\n setChildrenSnapshot({});\n }\n setEditing(true);\n }, [record, editableFields, entity?.children]);\n\n const cancelEditing = useCallback(() => {\n if (isNew) {\n const listRoute = screen?.route?.replace(\"/:id\", \"\") ?? \"/\";\n navigate(listRoute);\n } else {\n setEditing(false);\n setFormData({});\n setPendingStatuses({});\n setPendingProperties({});\n setPendingChildren(undefined);\n setChildrenSnapshot(undefined);\n }\n }, [isNew, screen, navigate]);\n\n const handleFieldChange = useCallback((fieldName: string, value: unknown) => {\n setFormData((prev) => ({ ...prev, [fieldName]: value }));\n }, []);\n\n // Find the list screen route for back navigation\n const listRoute = useMemo(() => {\n if (!screen?.route) return \"/\";\n // /leads/:id -> /leads\n const parts = screen.route.split(\"/\");\n parts.pop(); // Remove :id\n return parts.join(\"/\") || \"/\";\n }, [screen]);\n\n const listRouteExists = useMemo(() => {\n if (!schema?.screens || !listRoute || listRoute === \"/\") return false;\n return Object.values(schema.screens).some((s) => s.route === listRoute);\n }, [schema, listRoute]);\n\n const handleSave = useCallback(() => {\n if (!entityCode) return;\n\n // Build payload with only changed fields (lighter payloads, less churn).\n const payload: Record<string, unknown> = {};\n if (isNew) {\n // Only include non-empty fields to preserve schema defaults for unset fields.\n for (const [key, val] of Object.entries(formData)) {\n if (val !== \"\" && val !== null && val !== undefined) {\n payload[key] = val;\n }\n }\n } else {\n // Only send fields that actually changed.\n for (const [key, val] of Object.entries(formData)) {\n const original = record?.[key];\n // Treat null/undefined/empty-string as equivalent to avoid spurious writes.\n const normalizedVal = val === \"\" ? null : val;\n const normalizedOrig = original === \"\" || original === undefined ? null : original;\n if (normalizedVal !== normalizedOrig) {\n payload[key] = val;\n }\n }\n }\n // Include $statuses only if any status was changed.\n if (Object.keys(pendingStatuses).length > 0) {\n payload[\"$statuses\"] = Object.entries(pendingStatuses).map(\n ([groupCode, statusCode]) => ({ status_group_code: groupCode, status_code: statusCode }),\n );\n }\n // Include $properties only if any property was changed.\n if (Object.keys(pendingProperties).length > 0) {\n payload[\"$properties\"] = Object.entries(pendingProperties).map(\n ([propertyCode, value]) => ({ property_code: propertyCode, value }),\n );\n }\n // Include $children only for child codes with actual changes.\n if (pendingChildren) {\n const childrenPayload: Record<string, Record<string, unknown>[]> = {};\n for (const [childCode, rows] of Object.entries(pendingChildren)) {\n // Filter out deleted rows, strip meta fields.\n const cleaned = rows\n .filter((r) => !r._deleted)\n .map((r) => {\n const { _key, _deleted, _dirty, ...fields } = r;\n return fields;\n });\n // Compare against snapshot to detect actual changes.\n const original = childrenSnapshot?.[childCode] ?? [];\n if (isNew || !arraysEqual(cleaned, original)) {\n childrenPayload[childCode] = cleaned;\n }\n }\n if (Object.keys(childrenPayload).length > 0) {\n payload[\"$children\"] = childrenPayload;\n }\n }\n\n // Skip save if nothing changed.\n if (!isNew && Object.keys(payload).length === 0) {\n setEditing(false);\n setPendingStatuses({});\n setPendingProperties({});\n setPendingChildren(undefined);\n setChildrenSnapshot(undefined);\n return;\n }\n\n const clearPending = () => {\n setEditing(false);\n setPendingStatuses({});\n setPendingProperties({});\n setPendingChildren(undefined);\n setChildrenSnapshot(undefined);\n // No need to invalidate - useUpdateEntity.onSuccess uses the PATCH response\n // to update item, status, and property caches directly.\n };\n\n if (isNew) {\n createMutation.mutate(payload, {\n onSuccess: (response) => {\n const newRecord = response.data as Record<string, unknown>;\n const newPkValues = entity ? extractPkValues(entity, newRecord) : {};\n const newId = pkValuesToId(newPkValues);\n if (newId) {\n navigate(`${listRoute}/${encodeURIComponent(newId)}`, { replace: true });\n } else {\n navigate(listRoute, { replace: true });\n }\n clearPending();\n },\n });\n } else if (pkValues) {\n updateMutation.mutate(\n { pkValues, data: payload },\n { onSuccess: clearPending },\n );\n }\n }, [isNew, id, entityCode, formData, pendingStatuses, pendingProperties, pendingChildren, childrenSnapshot, createMutation, updateMutation, entity, navigate, listRoute, record]);\n\n const handleChildrenChange = useCallback((childCode: string, rows: PendingChildRow[]) => {\n setPendingChildren((prev) => ({ ...(prev ?? {}), [childCode]: rows }));\n }, []);\n\n const handleDelete = useCallback(() => {\n if (!pkValues || isNew) return;\n deleteMutation.mutate(pkValues, {\n onSuccess: () => navigate(listRoute, { replace: true }),\n });\n }, [pkValues, isNew, deleteMutation, navigate, listRoute]);\n\n const handleRestore = useCallback(() => {\n if (!pkValues || isNew) return;\n restoreMutation.mutate(pkValues);\n }, [pkValues, isNew, restoreMutation]);\n\n // Compute validation errors for direct children (required field checks).\n const childValidationErrors = useMemo(\n () => validatePendingChildren(pendingChildren, schema),\n [pendingChildren, schema],\n );\n const hasChildErrors = Object.keys(childValidationErrors).length > 0;\n\n if (!screen || !entity) return null;\n if (!isNew && isLoading) return <DetailSkeleton />;\n if (!isNew && !record) {\n return (\n <div className=\"p-6\">\n <PageHeader title=\"Not Found\" backTo={listRouteExists ? listRoute : undefined} />\n <p className=\"text-[var(--muted-foreground)]\">Record not found.</p>\n </div>\n );\n }\n\n const entityDisplay = entity.display;\n // Screen display name overrides entity name (e.g. custom detail screens).\n const detailName = loc(screen.display?.name) || loc(entityDisplay.name);\n const displayFieldKey = entity.display?.display_field;\n const rawDisplayValue = displayFieldKey ? record?.[displayFieldKey] : undefined;\n // Handle multilang fields (JSONB objects like {\"en\": \"...\", \"ru\": \"...\"}).\n const displayValue =\n rawDisplayValue && typeof rawDisplayValue === \"object\" && !Array.isArray(rawDisplayValue)\n ? loc(rawDisplayValue as LocalizedString)\n : rawDisplayValue;\n const title = isNew\n ? `New ${detailName}`\n : displayValue ? String(displayValue) : detailName;\n\n const isSaving = createMutation.isPending || updateMutation.isPending;\n\n // When screen.actions is defined, use only those; otherwise fall back to visibility.\n // Detail-page header actions = anything declaring visibility:[detail].\n // The platform loader assigns this canonical slot to scope:single and\n // scope:global actions automatically, so legacy schemas keep working.\n // (Previously a separate filter excluded scope:batch from detail; now the\n // visibility array is the single source of truth — if a schema author wants\n // a batch-capable action on the detail page too, they declare list_toolbar\n // AND detail in visibility.)\n const hasExplicitActions = screen.actions !== undefined;\n const headerActions = hasExplicitActions\n ? getScreenActions(entity.actions, screen.actions, \"detail\", schema?.actions)\n : getActionsByVisibility(entity.actions, \"detail\");\n\n const layoutCtx: LayoutContext = {\n schema: schema!,\n entity,\n entityCode: entityCode!,\n recordId: pkCacheKey ?? id ?? \"\",\n record: editing ? { ...(record ?? {}), ...formData } : (record ?? {}),\n isNew,\n mode: editing ? \"edit\" : \"display\",\n onFieldChange: editing ? handleFieldChange : undefined,\n refs: recordRefs,\n objectProperties: (() => {\n const base = objectProperties ?? [];\n if (!editing || Object.keys(pendingProperties).length === 0) return base.length > 0 ? base : undefined;\n const merged = base.map((p) =>\n pendingProperties[p.property_code] !== undefined\n ? { ...p, value: pendingProperties[p.property_code] }\n : p,\n );\n for (const [code, value] of Object.entries(pendingProperties)) {\n if (!base.some((p) => p.property_code === code)) {\n merged.push({ property_code: code, name: {}, type: \"string\", value });\n }\n }\n return merged;\n })(),\n onSetProperty: (isNew || entity?.readonly)\n ? undefined\n : editing\n ? (propertyCode, value) => setPendingProperties((prev) => ({ ...prev, [propertyCode]: value }))\n : undefined,\n isPropertyPending: false,\n // In edit mode, merge pending status changes into displayed statuses and\n // store changes locally (saved atomically on Save, discarded on Cancel).\n objectStatuses: (() => {\n const base = statuses ?? [];\n if (!editing || Object.keys(pendingStatuses).length === 0) return base.length > 0 ? base : undefined;\n // Merge: replace matching groups, keep others.\n const merged = base.map((s) =>\n pendingStatuses[s.group_code] !== undefined\n ? { ...s, status_code: pendingStatuses[s.group_code] }\n : s,\n );\n // Add groups that aren't in base yet (new status set for first time).\n for (const [gc, sc] of Object.entries(pendingStatuses)) {\n if (!base.some((s) => s.group_code === gc)) {\n merged.push({ group_code: gc, status_code: sc, status_name: {}, set_at: new Date().toISOString() });\n }\n }\n return merged;\n })(),\n onSetStatus: (isNew || entity?.readonly)\n ? undefined\n : editing\n ? (groupCode, statusCode) => setPendingStatuses((prev) => ({ ...prev, [groupCode]: statusCode }))\n : undefined,\n isStatusPending: false,\n // Children editing context for direct (aggregate) children.\n pendingChildren: editing ? pendingChildren : undefined,\n onChildrenChange: editing ? handleChildrenChange : undefined,\n childValidationErrors: editing ? childValidationErrors : undefined,\n };\n\n const hasSidebar = screen.sidebar && screen.sidebar.length > 0;\n\n const headerEl = (\n <PageHeader\n title={title}\n backTo={isSelf || !listRouteExists ? undefined : listRoute}\n actions={\n isRecordDeleted ? (\n <Button onClick={handleRestore} disabled={restoreMutation.isPending}>\n <RotateCcw className=\"w-4 h-4\" />\n {restoreMutation.isPending ? \"Restoring...\" : \"Restore\"}\n </Button>\n ) : editing ? (\n <>\n <Button variant=\"outline\" onClick={cancelEditing} disabled={isSaving}>\n <X className=\"w-4 h-4\" />\n Cancel\n </Button>\n <Button\n onClick={handleSave}\n disabled={isSaving || hasChildErrors}\n title={hasChildErrors ? \"Fix errors in child rows\" : undefined}\n >\n <Save className=\"w-4 h-4\" />\n {isSaving ? \"Saving...\" : \"Save\"}\n </Button>\n </>\n ) : (\n <>\n {!isNew && id && headerActions.map(({ code, action }) => {\n if (action.type === \"edit\") {\n const conditionsMet = record ? evaluateConditions(action.conditions, record) : true;\n return (\n <Button key={code} variant=\"outline\" onClick={startEditing} disabled={!conditionsMet}>\n {loc(action.display?.name) || \"Edit\"}\n </Button>\n );\n }\n if (action.type === \"delete\" && !isSelf) {\n const conditionsMet = record ? evaluateConditions(action.conditions, record) : true;\n return (\n <Button\n key={code}\n variant=\"outline\"\n onClick={() => setDeleteConfirm({ show: true, confirmation: loc(action.confirmation) || undefined })}\n disabled={!conditionsMet}\n className=\"text-[var(--destructive)] hover:text-[var(--destructive)]\"\n >\n <Trash2 className=\"w-4 h-4\" />\n {loc(action.display?.name) || \"Delete\"}\n </Button>\n );\n }\n return (\n <ActionButton\n key={code}\n actionCode={code}\n action={action}\n entityCode={entityCode}\n objectIds={[id]}\n row={record}\n variant=\"outline\"\n />\n );\n })}\n {!hasExplicitActions && !entity?.readonly && (\n <Button variant=\"outline\" onClick={startEditing}>\n Edit\n </Button>\n )}\n {!hasExplicitActions && !isNew && !isSelf && !entity?.readonly && (\n <Button\n variant=\"outline\"\n onClick={() => setDeleteConfirm({ show: true })}\n className=\"text-[var(--destructive)] hover:text-[var(--destructive)]\"\n >\n <Trash2 className=\"w-4 h-4\" />\n Delete\n </Button>\n )}\n </>\n )\n }\n />\n );\n\n const deletedBanner = isRecordDeleted && (\n <div className=\"flex items-center gap-2 px-4 py-3 mb-4 rounded-md border border-[var(--destructive)]/30 bg-[var(--destructive)]/10 text-sm text-[var(--destructive)]\">\n <AlertTriangle className=\"w-4 h-4 shrink-0\" />\n <span>\n This record was deleted on{\" \"}\n {formatOffsetTimestamp(String(record![entity.soft_delete!]))}\n </span>\n </div>\n );\n\n const statusesEl = hasStatusGroups && !isNew && !(screen.items && screen.items.length > 0) && (\n <div className=\"mb-4\">\n <StatusGroupsDisplay\n statusGroups={entity.status_groups ?? {}}\n objectStatuses={layoutCtx.objectStatuses}\n onSetStatus={entity?.readonly ? noop : editing\n ? (groupCode, statusCode) => setPendingStatuses((prev) => ({ ...prev, [groupCode]: statusCode }))\n : noop\n }\n isPending={false}\n mode={editing && !entity?.readonly ? \"edit\" : \"display\"}\n />\n </div>\n );\n\n const mainContent = (\n <>\n {screen.items && screen.items.length > 0 && (record || isNew) && schema && (\n <LayoutRenderer nodes={screen.items} ctx={layoutCtx} />\n )}\n {!isNew && id && entityCode && entity.associations && Object.keys(entity.associations).length > 0 && schema && (\n <AssociationTabs entityCode={entityCode} recordId={pkCacheKey ?? id ?? \"\"} associations={entity.associations} schema={schema} />\n )}\n {!isNew && record && (\n <div className=\"flex gap-6 px-1 py-2 text-xs text-[var(--muted-foreground)]\">\n {record.created_at != null && (\n <span>Created: {formatOffsetTimestamp(String(record.created_at))}</span>\n )}\n {record.updated_at != null && (\n <span>Updated: {formatOffsetTimestamp(String(record.updated_at))}</span>\n )}\n </div>\n )}\n </>\n );\n\n const deleteDialog = (\n <ConfirmDialog\n open={deleteConfirm.show}\n onOpenChange={(open) => !open && setDeleteConfirm({ show: false })}\n title={`Delete ${detailName}`}\n description={\n deleteConfirm.confirmation\n ? deleteConfirm.confirmation\n : hasSoftDelete\n ? `Are you sure you want to delete this ${detailName.toLowerCase()}? It can be restored later by an admin.`\n : `Are you sure you want to delete this ${detailName.toLowerCase()}? This action cannot be undone.`\n }\n confirmLabel=\"Delete\"\n onConfirm={handleDelete}\n destructive\n />\n );\n\n // Sidebar layout: two fully independent panes separated by resize handle.\n // Left pane: header + statuses + scrollable sections (entity details)\n // Right pane: sidebar content (e.g. activities) - completely separate, own header\n if (hasSidebar) {\n return (\n <div className=\"h-full flex overflow-hidden\">\n {/* Left pane - entity details */}\n <div className=\"flex-1 min-w-0 flex flex-col h-full\">\n {/* Sticky header (title + Edit/Delete) */}\n <div className=\"shrink-0 px-6 pt-6 pb-2\">\n {headerEl}\n {deletedBanner}\n {statusesEl}\n </div>\n {/* Scrollable content */}\n <div className=\"flex-1 min-h-0 overflow-y-auto px-6 pb-6 space-y-4\">\n {mainContent}\n </div>\n </div>\n {/* Resize handle - full height separator */}\n <div\n className=\"shrink-0 w-1 cursor-col-resize hover:bg-[var(--primary)]/20 active:bg-[var(--primary)]/30 transition-colors\"\n onMouseDown={onSidebarDragStart}\n />\n {/* Right pane - sidebar (activities etc.) */}\n <div ref={sidebarRef} className=\"shrink-0 h-full\" style={{ width: `${sidebarW}px` }}>\n {(record || isNew) && schema && (\n <LayoutRenderer nodes={screen.sidebar!} ctx={layoutCtx} />\n )}\n </div>\n {deleteDialog}\n </div>\n );\n }\n\n // Standard layout (no sidebar): sticky header + scrollable content\n return (\n <div className=\"h-full flex flex-col overflow-hidden\">\n <div className=\"shrink-0 px-6 pt-6 pb-2\">\n {headerEl}\n {deletedBanner}\n {statusesEl}\n </div>\n <div className=\"flex-1 min-h-0 overflow-y-auto px-6 pb-6 space-y-4\">\n {mainContent}\n </div>\n {deleteDialog}\n </div>\n );\n}\n\n","// NOTE: there is no separate \"get statuses\" API call. $statuses is enriched\n// inline on GET /api/data/{entity}?<pk>=<value> by handlers/data.go:getByPKValues.\n// Callers read record.$statuses directly from the useEntityItem query result.\n// See TestGetByPKEnrichment in the Go integration tests for the contract.\nimport { apiFetch } from \"./client\";\nimport type { StatusInfo } from \"@/types/api\";\n\nexport async function setObjectStatus(\n entity: string,\n id: string,\n groupCode: string,\n statusCode: string,\n note?: string,\n): Promise<StatusInfo> {\n const statusEntry: Record<string, unknown> = {\n status_group_code: groupCode,\n status_code: statusCode,\n };\n if (note != null) statusEntry.note = note;\n\n const results = await apiFetch<Record<string, unknown>[]>(\n `/api/data/${entity}`,\n {\n method: \"PATCH\",\n body: JSON.stringify([{ id, $statuses: [statusEntry] }]),\n },\n );\n const row = results[0];\n const statuses = (row?.[\"$statuses\"] ?? []) as StatusInfo[];\n return statuses.find((s) => s.group_code === groupCode) ?? statuses[0];\n}\n","// NOTE: there is no useObjectStatuses hook. $statuses is enriched inline\n// on the row returned by useEntityItem - read `record.$statuses` directly.\n// See api/status.ts and TestGetByPKEnrichment for the contract.\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { toast } from \"sonner\";\nimport * as statusApi from \"@/api/status\";\n\nexport function useSetStatus(entity: string | undefined, id: string | undefined) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({ groupCode, statusCode, note }: { groupCode: string; statusCode: string; note?: string }) =>\n statusApi.setObjectStatus(entity!, id!, groupCode, statusCode, note),\n onSuccess: () => {\n // $statuses rides the entity-item query response - invalidate it\n // (not a separate \"object-status\" cache key, which no longer exists).\n queryClient.invalidateQueries({\n queryKey: [\"entity-item\", entity],\n });\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n","// NOTE: there is no separate \"get properties\" API call. $properties is enriched\n// inline on GET /api/data/{entity}?<pk>=<value> by handlers/data.go:getByPKValues.\n// Callers read record.$properties directly from the useEntityItem query result.\n// See TestGetByPKEnrichment in the Go integration tests for the contract.\nimport { apiFetch } from \"./client\";\nimport type { PropertyValue } from \"@/types/api\";\n\nexport async function setObjectProperty(\n entity: string,\n id: string,\n propertyCode: string,\n value: unknown,\n): Promise<PropertyValue> {\n const results = await apiFetch<Record<string, unknown>[]>(\n `/api/data/${entity}`,\n {\n method: \"PATCH\",\n body: JSON.stringify([{ id, $properties: [{ property_code: propertyCode, value }] }]),\n },\n );\n const row = results[0];\n const props = (row?.[\"$properties\"] ?? []) as PropertyValue[];\n return props.find((p) => p.property_code === propertyCode) ?? props[0];\n}\n\nexport async function deleteObjectProperty(\n entity: string,\n id: string,\n propertyCode: string,\n): Promise<void> {\n await apiFetch(\n `/api/data/${entity}`,\n {\n method: \"PATCH\",\n body: JSON.stringify([{ id, $properties: [{ property_code: propertyCode, value: null }] }]),\n },\n );\n}\n","// NOTE: there is no useObjectProperties hook. $properties is enriched inline\n// on the row returned by useEntityItem - read `record.$properties` directly.\n// See api/properties.ts and TestGetByPKEnrichment for the contract.\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { toast } from \"sonner\";\nimport * as propsApi from \"@/api/properties\";\n\nexport function useSetProperty(entity: string | undefined, id: string | undefined) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({ propertyCode, value }: { propertyCode: string; value: unknown }) =>\n propsApi.setObjectProperty(entity!, id!, propertyCode, value),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: [\"entity-item\", entity],\n });\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n\nexport function useDeleteProperty(entity: string | undefined, id: string | undefined) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (propertyCode: string) =>\n propsApi.deleteObjectProperty(entity!, id!, propertyCode),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: [\"entity-item\", entity],\n });\n },\n onError: (err: Error) => {\n toast.error(err.message);\n },\n });\n}\n","import { useState, useMemo, useCallback, useEffect, useRef } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\nimport { Search, Pencil, Save, X } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { useEntityData } from \"@/hooks/useEntityData\";\nimport { useEntityItem } from \"@/hooks/useEntityItem\";\nimport { useUpdateEntity } from \"@/hooks/useMutations\";\nimport { useSetStatus } from \"@/hooks/useObjectStatus\";\nimport { useSetProperty } from \"@/hooks/useProperties\";\nimport type { StatusInfo, PropertyValue } from \"@/types/api\";\nimport { useDebounce } from \"@/hooks/useDebounce\";\nimport {\n type FilterNode,\n eqFilter,\n removeFilter,\n setFiltersInURL,\n parseFiltersFromURL,\n} from \"@/lib/filters\";\nimport { useTabStore } from \"@/stores/tabs\";\nimport { renderField } from \"@/components/fields\";\nimport { DetailSkeleton } from \"@/components/shared/LoadingSkeleton\";\nimport { LayoutRenderer, type LayoutContext } from \"@/components/detail-layout\";\nimport { cn } from \"@/lib/utils\";\nimport { toast } from \"sonner\";\nimport { loc, fieldDisplayName } from \"@/types/schema\";\nimport type { Entity, Schema, LayoutNode } from \"@/types/schema\";\n\ninterface SmartRecordListPageProps {\n screenCode: string;\n}\n\ntype RowData = Record<string, unknown>;\n\nexport function SmartRecordListPage({ screenCode }: SmartRecordListPageProps) {\n const [searchParams, setSearchParams] = useSearchParams();\n const { data: schema } = useSchema();\n\n const screen = schema?.screens[screenCode];\n const entity = screen?.entity ? schema?.entities[screen.entity] : undefined;\n const entityCode = screen?.entity;\n\n // Tab tracking\n const { openTab } = useTabStore();\n useEffect(() => {\n if (screen?.route && entity) {\n const tabName = loc(screen.display?.name) || loc(entity.display.name_plural);\n const tabIcon = screen.display?.icon || entity.display.icon;\n openTab({\n pathname: screen.route,\n search: searchParams.toString(),\n title: tabName,\n icon: tabIcon,\n closable: true,\n });\n }\n }, [screen?.route, screen?.display?.name?.en, entity?.display.name_plural?.en]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Selected record ID from URL\n const selectedId = searchParams.get(\"selected\") ?? null;\n\n // Search\n const searchValue = searchParams.get(\"search\") ?? \"\";\n const debouncedSearch = useDebounce(searchValue, 300);\n\n // Sort\n const sortParam = searchParams.get(\"sort\") ?? screen?.sort_default ?? \"\";\n\n // Parse JSON filters from URL.\n const filterNodes = useMemo(() => {\n const raw = searchParams.get(\"filters\");\n if (!raw) return undefined;\n try {\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed) && parsed.length > 0 ? parsed : undefined;\n } catch { return undefined; }\n }, [searchParams]);\n\n // Fetch list with higher per_page for panel-style browsing\n const { data: listResponse, isLoading: listLoading } = useEntityData(entityCode, {\n page: 1,\n per_page: 200,\n sort: sortParam || undefined,\n search: debouncedSearch || undefined,\n filters: filterNodes,\n });\n\n const records = listResponse?.data ?? [];\n const listRefs = listResponse?.$refs;\n\n const pkField = useMemo(\n () => entity?.field_order?.find((f) => entity.fields[f]?.primary) ?? \"id\",\n [entity],\n );\n\n const selectRecord = useCallback(\n (id: string | null) => {\n setSearchParams(\n (prev) => {\n const next = new URLSearchParams(prev);\n if (id) next.set(\"selected\", id);\n else next.delete(\"selected\");\n return next;\n },\n { replace: true },\n );\n },\n [setSearchParams],\n );\n\n const updateSearch = useCallback(\n (value: string) => {\n setSearchParams(\n (prev) => {\n const next = new URLSearchParams(prev);\n if (value) next.set(\"search\", value);\n else next.delete(\"search\");\n return next;\n },\n { replace: true },\n );\n },\n [setSearchParams],\n );\n\n const updateFilter = useCallback(\n (field: string, value: string) => {\n setSearchParams(\n (prev) => {\n const next = new URLSearchParams(prev);\n const current = parseFiltersFromURL(prev);\n let updated: FilterNode[];\n if (value && value !== \"__all__\") {\n updated = [...removeFilter(current, field), eqFilter(field, value)];\n } else {\n updated = removeFilter(current, field);\n }\n setFiltersInURL(updated, next);\n return next;\n },\n { replace: true },\n );\n },\n [setSearchParams],\n );\n\n // Resizable panel\n const listResizable = screen?.list_resizable ?? false;\n const containerRef = useRef<HTMLDivElement>(null);\n const [panelWidth, setPanelWidth] = useState<number | null>(null);\n const isDragging = useRef(false);\n\n // Resolve initial width once the container mounts.\n // The effect includes `entity` in deps so it re-fires after the early-return guard\n // passes and the container div actually mounts (making containerRef.current available).\n const listWidthRaw = screen?.list_width;\n useEffect(() => {\n if (!listResizable || panelWidth !== null) return;\n const container = containerRef.current;\n if (!container) return;\n if (listWidthRaw && listWidthRaw.endsWith(\"%\")) {\n const pct = parseFloat(listWidthRaw) / 100;\n setPanelWidth(Math.round(container.getBoundingClientRect().width * pct));\n } else if (listWidthRaw) {\n setPanelWidth(parseInt(listWidthRaw, 10) || 320);\n } else {\n setPanelWidth(320);\n }\n // entity is included to re-fire after the early return guard passes and the div mounts.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [listResizable, listWidthRaw, panelWidth, entity]);\n\n // Store cleanup fn so we can call it on unmount if drag is in-flight.\n const dragCleanup = useRef<(() => void) | null>(null);\n\n useEffect(() => {\n return () => { dragCleanup.current?.(); };\n }, []);\n\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n e.preventDefault();\n isDragging.current = true;\n const startX = e.clientX;\n const startWidth = panelWidth ?? 320;\n\n const onMouseMove = (ev: MouseEvent) => {\n if (!isDragging.current) return;\n const containerWidth = containerRef.current?.getBoundingClientRect().width ?? window.innerWidth;\n const minWidth = 200;\n const maxWidth = containerWidth - 300;\n const newWidth = Math.max(minWidth, Math.min(maxWidth, startWidth + ev.clientX - startX));\n setPanelWidth(newWidth);\n };\n\n const cleanup = () => {\n isDragging.current = false;\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", cleanup);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n dragCleanup.current = null;\n };\n\n document.body.style.cursor = \"col-resize\";\n document.body.style.userSelect = \"none\";\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", cleanup);\n dragCleanup.current = cleanup;\n }, [panelWidth]);\n\n if (!schema || !screen || !entity) return null;\n\n const listColumns =\n screen.columns ??\n entity.field_order\n .filter(\n (f) =>\n !entity.fields[f]?.primary &&\n !entity.fields[f]?.auto &&\n entity.fields[f]?.display?.is_listable !== false,\n )\n .slice(0, 4);\n\n const activeFilterCount = filterNodes?.length ?? 0;\n\n return (\n <div ref={containerRef} className=\"flex h-full overflow-hidden\">\n {/* Left panel - list */}\n <div\n className={cn(\"flex-none flex flex-col overflow-hidden\", !listResizable && \"border-r\")}\n style={{ width: listResizable && panelWidth !== null ? panelWidth : (screen.list_width ?? \"320px\") }}\n >\n {/* Toolbar */}\n <div className=\"p-3 space-y-2 border-b\">\n <div className=\"relative\">\n <Search className=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n className=\"pl-8 h-9 text-sm\"\n placeholder={`Search ${loc(entity.display.name_plural)}...`}\n value={searchValue}\n onChange={(e) => updateSearch(e.target.value)}\n />\n </div>\n {screen.filters && screen.filters.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5\">\n {screen.filters.map((filterField) => {\n const fieldDef = entity.fields[filterField];\n if (!fieldDef?.values) return null;\n const activeNode = filterNodes?.find(\n (n) => n.field === filterField && n.op === \"eq\",\n );\n const currentValue = (activeNode?.value as string) ?? \"__all__\";\n return (\n <Select\n key={filterField}\n value={currentValue}\n onValueChange={(v) => updateFilter(filterField, v)}\n >\n <SelectTrigger className=\"h-7 text-xs px-2 w-auto min-w-[90px]\">\n <SelectValue\n placeholder={fieldDisplayName(fieldDef, filterField, schema.entities)}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__all__\">\n All {fieldDisplayName(fieldDef, filterField, schema.entities)}\n </SelectItem>\n {fieldDef.values.map((v) => (\n <SelectItem key={v.code} value={v.code}>\n {loc(v.name)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n })}\n </div>\n )}\n <div className=\"flex items-center justify-between text-xs text-muted-foreground\">\n <span>\n {listLoading\n ? \"Loading...\"\n : `${records.length} ${loc(entity.display.name_plural)}`}\n </span>\n {activeFilterCount > 0 && (\n <button\n className=\"text-primary underline\"\n onClick={() =>\n setSearchParams(\n (prev) => {\n const next = new URLSearchParams(prev);\n next.delete(\"filters\");\n return next;\n },\n { replace: true },\n )\n }\n >\n Clear filters\n </button>\n )}\n </div>\n </div>\n\n {/* Records */}\n <div className=\"flex-1 overflow-y-auto\">\n {listLoading ? (\n <div className=\"p-3 space-y-2\">\n {Array.from({ length: 8 }).map((_, i) => (\n <div key={i} className=\"h-12 rounded bg-muted animate-pulse\" />\n ))}\n </div>\n ) : records.length === 0 ? (\n <div className=\"p-8 text-center text-sm text-muted-foreground\">No records found</div>\n ) : (\n records.map((record) => (\n <RecordListRow\n key={String(record[pkField] ?? \"\")}\n record={record}\n entity={entity}\n columns={listColumns}\n pkField={pkField}\n refs={listRefs}\n isSelected={record[pkField] === selectedId}\n onClick={() => selectRecord(String(record[pkField] ?? \"\"))}\n />\n ))\n )}\n </div>\n </div>\n\n {/* Resize handle */}\n {listResizable && (\n <div\n className=\"flex-none w-1 cursor-col-resize hover:bg-[var(--border)] active:bg-[var(--border)] transition-colors\"\n onMouseDown={handleMouseDown}\n />\n )}\n\n {/* Right panel - detail */}\n <div className=\"flex-1 min-w-0 overflow-hidden\">\n {selectedId ? (\n <RecordDetailPanel\n key={selectedId}\n entityCode={entityCode!}\n recordId={selectedId}\n items={screen.items}\n schema={schema}\n entity={entity}\n />\n ) : (\n <div className=\"flex items-center justify-center h-full text-muted-foreground\">\n <p className=\"text-sm\">Select a {loc(entity.display.name)} to view details</p>\n </div>\n )}\n </div>\n </div>\n );\n}\n\n// --- RecordListRow ---\n\ninterface RecordListRowProps {\n record: RowData;\n entity: Entity;\n columns: string[];\n pkField: string;\n refs?: Record<string, Record<string, Record<string, unknown>>>;\n isSelected: boolean;\n onClick: () => void;\n}\n\nfunction RecordListRow({\n record,\n entity,\n columns,\n pkField: _pkField,\n refs,\n isSelected,\n onClick,\n}: RecordListRowProps) {\n const primaryCol = columns[0];\n const secondaryCol = columns[1];\n const badgeCols = columns.slice(2, 4);\n\n return (\n <button\n className={cn(\n \"w-full text-left px-3 py-2.5 border-b hover:bg-accent/50 transition-colors\",\n isSelected && \"bg-accent border-l-2 border-l-primary\",\n )}\n onClick={onClick}\n >\n {primaryCol && (\n <div className=\"text-sm font-medium truncate\">\n {renderField({\n field: entity.fields[primaryCol],\n fieldName: primaryCol,\n value: record[primaryCol],\n mode: \"display\",\n record,\n refs,\n })}\n </div>\n )}\n <div className=\"flex items-center gap-1.5 mt-0.5\">\n {secondaryCol && (\n <div className=\"text-xs text-muted-foreground truncate flex-1\">\n {renderField({\n field: entity.fields[secondaryCol],\n fieldName: secondaryCol,\n value: record[secondaryCol],\n mode: \"display\",\n record,\n refs,\n })}\n </div>\n )}\n <div className=\"flex items-center gap-1 flex-shrink-0\">\n {badgeCols.map(\n (col) =>\n record[col] != null && (\n <div key={col} className=\"text-xs\">\n {renderField({\n field: entity.fields[col],\n fieldName: col,\n value: record[col],\n mode: \"display\",\n record,\n refs,\n })}\n </div>\n ),\n )}\n </div>\n </div>\n </button>\n );\n}\n\n// --- RecordDetailPanel ---\n\ninterface RecordDetailPanelProps {\n entityCode: string;\n recordId: string;\n items?: LayoutNode[];\n schema: Schema;\n entity: Entity;\n}\n\nfunction RecordDetailPanel({\n entityCode,\n recordId,\n items,\n schema,\n entity,\n}: RecordDetailPanelProps) {\n const { data: itemResponse, isLoading } = useEntityItem(entityCode, recordId);\n const updateMutation = useUpdateEntity(entityCode);\n\n const [editing, setEditing] = useState(false);\n const [formData, setFormData] = useState<Record<string, unknown>>({});\n\n const record = itemResponse?.data as Record<string, unknown> | undefined;\n\n // $statuses and $properties ride the entity-item query response -\n // handlers/data.go:getByPKValues enriches the row. See SmartDetailPage\n // for the same pattern and the TestGetByPKEnrichment contract test.\n const statuses = record?.[\"$statuses\"] as StatusInfo[] | undefined;\n const objectProperties = record?.[\"$properties\"] as PropertyValue[] | undefined;\n const setStatusMutation = useSetStatus(entityCode, recordId);\n const setPropertyMutation = useSetProperty(entityCode, recordId);\n\n const editableFields = useMemo(() => {\n const editable = new Set<string>();\n for (const [name, field] of Object.entries(entity.fields)) {\n if (!field.auto && !field.primary) editable.add(name);\n }\n return editable;\n }, [entity]);\n\n const startEditing = useCallback(() => {\n if (record) {\n const data: Record<string, unknown> = {};\n editableFields.forEach((name) => {\n data[name] = record[name] ?? \"\";\n });\n setFormData(data);\n }\n setEditing(true);\n }, [record, editableFields]);\n\n const cancelEditing = useCallback(() => {\n setEditing(false);\n setFormData({});\n }, []);\n\n const handleSave = useCallback(() => {\n updateMutation.mutate(\n { pkValues: recordId, data: formData },\n {\n onSuccess: () => {\n setEditing(false);\n setFormData({});\n toast.success(\"Saved\");\n },\n onError: () => toast.error(\"Failed to save\"),\n },\n );\n }, [updateMutation, recordId, formData]);\n\n const handleFieldChange = useCallback((field: string, value: unknown) => {\n setFormData((prev) => ({ ...prev, [field]: value }));\n }, []);\n\n if (isLoading) return <DetailSkeleton />;\n if (!record) return null;\n\n // Resolve display title from display_field or first non-system field\n const dfKey = entity.display?.display_field;\n const rawTitle = dfKey ? record[dfKey] : record[entity.field_order[0]];\n const displayTitle =\n rawTitle != null && typeof rawTitle !== \"object\" ? String(rawTitle) : loc(entity.display.name);\n\n const recordRefs = record?.[\"$refs\"] as Record<string, Record<string, Record<string, unknown>>> | undefined;\n\n const ctx: LayoutContext = {\n schema,\n entity,\n entityCode,\n recordId,\n record: editing ? { ...record, ...formData } : record,\n isNew: false,\n mode: editing ? \"edit\" : \"display\",\n onFieldChange: editing ? handleFieldChange : undefined,\n refs: recordRefs,\n objectProperties: objectProperties ?? undefined,\n onSetProperty: entity.readonly ? undefined : (code, val) => setPropertyMutation.mutate({ propertyCode: code, value: val }),\n isPropertyPending: setPropertyMutation.isPending,\n objectStatuses: statuses ?? undefined,\n onSetStatus: entity.readonly ? undefined : (groupCode, statusCode) => setStatusMutation.mutate({ groupCode, statusCode }),\n isStatusPending: setStatusMutation.isPending,\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b sticky top-0 bg-background z-10\">\n <h2 className=\"text-sm font-semibold truncate\">{displayTitle}</h2>\n <div className=\"flex items-center gap-1.5\">\n {!entity.readonly && (editing ? (\n <>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={cancelEditing}\n className=\"h-7 text-xs gap-1\"\n >\n <X className=\"h-3 w-3\" />\n Cancel\n </Button>\n <Button\n size=\"sm\"\n onClick={handleSave}\n disabled={updateMutation.isPending}\n className=\"h-7 text-xs gap-1\"\n >\n <Save className=\"h-3 w-3\" />\n {updateMutation.isPending ? \"Saving...\" : \"Save\"}\n </Button>\n </>\n ) : (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={startEditing}\n className=\"h-7 text-xs gap-1\"\n >\n <Pencil className=\"h-3 w-3\" />\n Edit\n </Button>\n ))}\n </div>\n </div>\n\n {/* Body */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\n {items && items.length > 0 ? (\n <LayoutRenderer nodes={items} ctx={ctx} />\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n No layout configured. Add <code>items:</code> to the screen definition.\n </p>\n )}\n </div>\n </div>\n );\n}\n","import { Component, type ErrorInfo, type ReactNode } from \"react\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface Props {\n children: ReactNode;\n /** Optional fallback UI. Defaults to a centered error card with retry button. */\n fallback?: ReactNode;\n}\n\ninterface State {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * Catches JavaScript errors in child components and renders a fallback UI\n * instead of crashing the entire app.\n */\nexport class ErrorBoundary extends Component<Props, State> {\n constructor(props: Props) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): State {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo) {\n console.error(\"[ErrorBoundary]\", error, info.componentStack);\n }\n\n handleRetry = () => {\n this.setState({ hasError: false, error: null });\n };\n\n render() {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n\n return (\n <div className=\"flex items-center justify-center min-h-[200px] p-8\">\n <div className=\"text-center space-y-4 max-w-md\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n Something went wrong\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {this.state.error?.message || \"An unexpected error occurred.\"}\n </p>\n <Button variant=\"outline\" onClick={this.handleRetry}>\n Try again\n </Button>\n </div>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n","import type { ThemeDef } from \"@/types/schema\";\n\n// Maps ThemeDef field names to CSS custom property names.\nconst TOKEN_MAP: Record<string, string> = {\n background: \"--background\",\n foreground: \"--foreground\",\n card: \"--card\",\n card_foreground: \"--card-foreground\",\n popover: \"--popover\",\n popover_foreground: \"--popover-foreground\",\n primary: \"--primary\",\n primary_foreground: \"--primary-foreground\",\n secondary: \"--secondary\",\n secondary_foreground: \"--secondary-foreground\",\n muted: \"--muted\",\n muted_foreground: \"--muted-foreground\",\n accent: \"--accent\",\n accent_foreground: \"--accent-foreground\",\n destructive: \"--destructive\",\n destructive_foreground: \"--destructive-foreground\",\n border: \"--border\",\n input: \"--input\",\n ring: \"--ring\",\n sidebar: \"--sidebar\",\n sidebar_foreground: \"--sidebar-foreground\",\n sidebar_border: \"--sidebar-border\",\n sidebar_accent: \"--sidebar-accent\",\n sidebar_muted: \"--sidebar-muted\",\n radius: \"--radius\",\n};\n\n// All CSS variable names managed by the theme system.\nexport const THEME_TOKENS = Object.values(TOKEN_MAP);\n\n// Converts a ThemeDef from the schema into a CSS variable map.\nexport function themeDefToTokens(def: ThemeDef): Record<string, string> {\n const tokens: Record<string, string> = {};\n for (const [field, cssVar] of Object.entries(TOKEN_MAP)) {\n const value = (def as Record<string, unknown>)[field];\n if (typeof value === \"string\" && value) {\n tokens[cssVar] = value;\n }\n }\n // Track the base theme for backward compat (.dark class).\n if (def.extends) {\n tokens[\"--_base\"] = def.extends;\n }\n return tokens;\n}\n","import { create } from \"zustand\";\nimport { THEME_TOKENS } from \"@/lib/theme-utils\";\n\ntype ThemeTokens = Record<string, string>;\n\ninterface ThemeState {\n // The user's selection: \"light\", \"dark\", \"system\", or a custom theme name.\n selectedTheme: string;\n // The resolved theme after system preference detection.\n effectiveTheme: string;\n // Custom themes from schema (name -> CSS variable map).\n availableThemes: Record<string, ThemeTokens>;\n setTheme: (name: string) => void;\n setAvailableThemes: (themes: Record<string, ThemeTokens>) => void;\n}\n\nconst STORAGE_KEY = \"declarion-theme\";\n\nfunction getSystemPreference(): \"light\" | \"dark\" {\n if (typeof window === \"undefined\") return \"dark\";\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\";\n}\n\nfunction resolveEffective(selected: string): string {\n if (selected === \"system\") return getSystemPreference();\n return selected;\n}\n\nfunction applyTheme(themeName: string, customThemes: Record<string, ThemeTokens>) {\n const html = document.documentElement;\n\n // Remove old .dark class.\n html.classList.remove(\"dark\");\n\n // Set data-theme attribute for CSS selectors.\n html.setAttribute(\"data-theme\", themeName);\n\n // Clear any previously applied custom CSS properties.\n clearCustomProperties(html);\n\n // Apply CSS variables for custom themes.\n const tokens = customThemes[themeName];\n if (tokens) {\n for (const [key, value] of Object.entries(tokens)) {\n if (key.startsWith(\"--_\")) continue; // skip internal metadata\n html.style.setProperty(key, value);\n }\n // Backward compat: add .dark class for dark-based themes (prose-invert etc.).\n const base = tokens[\"--_base\"];\n if (base === \"dark\" || themeName === \"dark\") {\n html.classList.add(\"dark\");\n }\n } else if (themeName === \"dark\") {\n // Built-in dark theme.\n html.classList.add(\"dark\");\n }\n}\n\nfunction clearCustomProperties(el: HTMLElement) {\n for (const name of THEME_TOKENS) {\n el.style.removeProperty(name);\n }\n}\n\nfunction getInitialTheme(): string {\n if (typeof window === \"undefined\") return \"light\";\n return localStorage.getItem(STORAGE_KEY) || \"light\";\n}\n\nconst initialSelected = getInitialTheme();\nconst initialEffective = resolveEffective(initialSelected);\n\n// Apply immediately on module load (prevents FOUC).\nif (typeof window !== \"undefined\") {\n applyTheme(initialEffective, {});\n}\n\nexport const useThemeStore = create<ThemeState>((set, get) => ({\n selectedTheme: initialSelected,\n effectiveTheme: initialEffective,\n availableThemes: {},\n setTheme: (name) => {\n const effective = resolveEffective(name);\n localStorage.setItem(STORAGE_KEY, name);\n applyTheme(effective, get().availableThemes);\n set({ selectedTheme: name, effectiveTheme: effective });\n },\n setAvailableThemes: (themes) => {\n set({ availableThemes: themes });\n // Re-apply current theme in case it's a custom one that just loaded.\n const { effectiveTheme } = get();\n applyTheme(effectiveTheme, themes);\n },\n}));\n\n// Listen for OS preference changes when \"system\" is selected.\nif (typeof window !== \"undefined\") {\n window.matchMedia(\"(prefers-color-scheme: dark)\").addEventListener(\"change\", () => {\n const state = useThemeStore.getState();\n if (state.selectedTheme === \"system\") {\n const effective = getSystemPreference();\n applyTheme(effective, state.availableThemes);\n useThemeStore.setState({ effectiveTheme: effective });\n }\n });\n}\n","import type { ComponentType } from \"react\";\n\nconst registry = new Map<string, ComponentType>();\n\nexport function registerScreen(code: string, component: ComponentType): void {\n registry.set(code, component);\n}\n\nexport function getRegisteredScreen(code: string): ComponentType | undefined {\n return registry.get(code);\n}\n","import { useEffect, useMemo, type ReactNode } from \"react\";\nimport { BrowserRouter, Routes, Route, Navigate } from \"react-router-dom\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { Toaster } from \"sonner\";\nimport { Layout } from \"@/components/layout/Layout\";\nimport { LoginPage } from \"@/components/pages/LoginPage\";\nimport { SignupPage } from \"@/components/pages/SignupPage\";\nimport { SSOCallbackPage } from \"@/components/pages/SSOCallbackPage\";\nimport { NotFoundPage } from \"@/components/pages/NotFoundPage\";\nimport { AdminCatalogPage } from \"@/components/pages/AdminCatalogPage\";\nimport { SmartListPage } from \"@/components/pages/SmartListPage\";\nimport { SmartDetailPage } from \"@/components/pages/SmartDetailPage\";\nimport { SmartRecordListPage } from \"@/components/pages/SmartRecordListPage\";\nimport { ErrorBoundary } from \"@/components/shared/ErrorBoundary\";\nimport { useAuthStore } from \"@/stores/auth\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { useThemeStore } from \"@/stores/theme\";\nimport { themeDefToTokens } from \"@/lib/theme-utils\";\nimport { getRegisteredScreen } from \"@/stores/screen-registry\";\n\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 5 * 60 * 1000,\n retry: 1,\n },\n },\n});\n\nfunction useDynamicRoutes(): { routes: ReactNode[]; defaultRoute: string | null } {\n const { data: schema } = useSchema();\n\n const routes = useMemo<ReactNode[]>(() => {\n if (!schema) return [];\n\n const out: ReactNode[] = [];\n for (const [code, screen] of Object.entries(schema.screens)) {\n if (screen.type === \"list\") {\n out.push(\n <Route\n key={code}\n path={screen.route}\n element={<ErrorBoundary><SmartListPage screenCode={code} /></ErrorBoundary>}\n />,\n );\n continue;\n }\n if (screen.type === \"detail\") {\n out.push(\n <Route\n key={code}\n path={screen.route}\n element={<ErrorBoundary><SmartDetailPage screenCode={code} /></ErrorBoundary>}\n />,\n );\n continue;\n }\n if (screen.type === \"record_list\") {\n out.push(\n <Route\n key={code}\n path={screen.route}\n element={<ErrorBoundary><SmartRecordListPage screenCode={code} /></ErrorBoundary>}\n />,\n );\n continue;\n }\n if (screen.type === \"custom\") {\n const CustomComponent = screen.component\n ? getRegisteredScreen(screen.component)\n : undefined;\n if (CustomComponent) {\n out.push(\n <Route\n key={code}\n path={screen.route}\n element={<ErrorBoundary><CustomComponent /></ErrorBoundary>}\n />,\n );\n }\n }\n }\n return out;\n }, [schema]);\n\n const defaultRoute = useMemo(() => {\n if (!schema?.navigation) return null;\n for (const node of schema.navigation) {\n if (node.screen) {\n const screen = schema.screens[node.screen];\n if (screen) return screen.route;\n }\n if (node.items) {\n for (const child of node.items) {\n if (child.screen) {\n const screen = schema.screens[child.screen];\n if (screen) return screen.route;\n }\n }\n }\n }\n return null;\n }, [schema]);\n\n return { routes, defaultRoute };\n}\n\nfunction AppRoutes() {\n const initialize = useAuthStore((s) => s.initialize);\n const { data: schema } = useSchema();\n const setAvailableThemes = useThemeStore((s) => s.setAvailableThemes);\n const { routes, defaultRoute } = useDynamicRoutes();\n\n useEffect(() => {\n initialize();\n }, [initialize]);\n\n // Wire YAML-defined themes to the theme store once schema loads.\n // Use JSON serialization as a stable dependency to avoid re-applying on every refetch.\n const themesJson = schema?.themes ? JSON.stringify(schema.themes) : null;\n useEffect(() => {\n if (!themesJson || !schema?.themes) return;\n const converted: Record<string, Record<string, string>> = {};\n for (const [name, def] of Object.entries(schema.themes)) {\n converted[name] = themeDefToTokens(def);\n }\n setAvailableThemes(converted);\n }, [themesJson, setAvailableThemes]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <Routes>\n <Route path=\"/login\" element={<LoginPage />} />\n <Route path=\"/login/sso-callback\" element={<SSOCallbackPage />} />\n <Route path=\"/signup\" element={<SignupPage />} />\n <Route element={<Layout />}>\n {defaultRoute && (\n <Route index element={<Navigate to={defaultRoute} replace />} />\n )}\n {routes}\n <Route path=\"/admin/catalog\" element={<AdminCatalogPage />} />\n <Route path=\"*\" element={<NotFoundPage />} />\n </Route>\n </Routes>\n );\n}\n\nexport function App() {\n return (\n <ErrorBoundary>\n <QueryClientProvider client={queryClient}>\n <BrowserRouter>\n <AppRoutes />\n <Toaster richColors position=\"top-right\" toastOptions={{ className: \"select-text\" }} />\n </BrowserRouter>\n </QueryClientProvider>\n </ErrorBoundary>\n );\n}\n","// TODO(T1): EntityClient is the v2 convenience layer built alongside the existing v1\n// hooks (useEntityData, useEntityItem, useMutations). The v1 hooks will be migrated to\n// use EntityClient internally over time. Until then, both layers coexist.\n//\n// TODO(T6): No tests exist for the v2 SDK yet. Unit tests are needed for EntityClient\n// methods, attachHelpers immutability, RefCache merge semantics, and URL building.\nimport { apiFetch } from \"./client\";\nimport type {\n Refs,\n V2ListParams,\n V2ListResponse,\n V2Meta,\n V2StatusInstance,\n V2PropertyInstance,\n EnrichedRow,\n} from \"@/types/api\";\n\n// ---------------------------------------------------------------------------\n// Helpers attached to returned rows\n// ---------------------------------------------------------------------------\n\n/** Find a status by group code on an enriched row. */\nfunction findStatus(\n row: EnrichedRow,\n groupCode: string,\n): V2StatusInstance | undefined {\n return row.$statuses?.find((s) => s.group_code === groupCode);\n}\n\n/** Find a property by code on an enriched row. */\nfunction findProperty(\n row: EnrichedRow,\n propertyCode: string,\n): V2PropertyInstance | undefined {\n return row.$properties?.find((p) => p.property_code === propertyCode);\n}\n\n/**\n * Attach $status() and $property() convenience helpers to a row.\n * Returns a shallow copy - never mutates the input (which may be a\n * TanStack Query cache entry where mutation breaks change detection).\n */\nfunction attachHelpers<T extends Record<string, unknown>>(\n row: T & EnrichedRow,\n): T & EnrichedRow & RowHelpers {\n const enriched = { ...row } as T & EnrichedRow & RowHelpers;\n enriched.$status = (groupCode: string) => findStatus(enriched, groupCode);\n enriched.$property = (propertyCode: string) => findProperty(enriched, propertyCode);\n return enriched;\n}\n\n/** Helper methods injected onto enriched rows. */\nexport interface RowHelpers {\n $status(groupCode: string): V2StatusInstance | undefined;\n $property(propertyCode: string): V2PropertyInstance | undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Ref cache - merges $refs across pages\n// ---------------------------------------------------------------------------\n\n/** Normalized ref cache that merges $refs across multiple responses. */\nexport class RefCache {\n private cache: Refs = {};\n\n /** Merge incoming refs into the cache. */\n merge(refs: Refs | undefined): void {\n if (!refs) return;\n for (const entityCode of Object.keys(refs)) {\n if (!this.cache[entityCode]) {\n this.cache[entityCode] = {};\n }\n const incoming = refs[entityCode];\n for (const id of Object.keys(incoming)) {\n // Newer data wins - shallow merge per ref object.\n this.cache[entityCode][id] = {\n ...this.cache[entityCode][id],\n ...incoming[id],\n };\n }\n }\n }\n\n /** Get a snapshot of all cached refs. */\n all(): Refs {\n return this.cache;\n }\n\n /** Look up a single ref by entity code and id. */\n get(entityCode: string, id: string): Record<string, unknown> | undefined {\n return this.cache[entityCode]?.[id];\n }\n\n /** Clear the cache. */\n clear(): void {\n this.cache = {};\n }\n}\n\n// ---------------------------------------------------------------------------\n// URL builder\n// ---------------------------------------------------------------------------\n\nfunction buildV2ListUrl(entity: string, params: V2ListParams): string {\n const url = new URL(`/api/data/${entity}`, window.location.origin);\n\n if (params.select && params.select.length > 0) {\n url.searchParams.set(\"select\", params.select.join(\",\"));\n }\n if (params.expand && params.expand.length > 0) {\n url.searchParams.set(\"expand\", params.expand.join(\",\"));\n }\n if (params.sort) url.searchParams.set(\"sort\", params.sort);\n if (params.search) url.searchParams.set(\"search\", params.search);\n if (params.limit) url.searchParams.set(\"limit\", String(params.limit));\n if (params.after) url.searchParams.set(\"after\", params.after);\n if (params.include_deleted) url.searchParams.set(\"include_deleted\", \"true\");\n\n if (params.filters && params.filters.length > 0) {\n url.searchParams.set(\"filters\", JSON.stringify(params.filters));\n }\n\n return url.pathname + url.search;\n}\n\n// ---------------------------------------------------------------------------\n// EntityClient<T>\n// ---------------------------------------------------------------------------\n\n/**\n * Generic, type-safe client for a single entity's v2 API.\n *\n * Single-item methods wrap arrays and unwrap the first result.\n * Bulk methods pass arrays through directly.\n *\n * All write responses return enriched rows with $refs, $statuses, etc.\n */\nexport class EntityClient<T extends Record<string, unknown> = Record<string, unknown>> {\n readonly entity: string;\n readonly refs: RefCache;\n\n constructor(entity: string, refCache?: RefCache) {\n this.entity = entity;\n this.refs = refCache ?? new RefCache();\n }\n\n // ---- Read ----------------------------------------------------------------\n\n /** Get a single record by ID. Returns the full object with all sub-resources. */\n async get(id: string): Promise<T & EnrichedRow & RowHelpers> {\n const res = await apiFetch<{ data: T & EnrichedRow }>(\n `/api/data/${this.entity}/${id}`,\n );\n return attachHelpers(res.data);\n }\n\n /** List records with cursor-based pagination, field selection, and expansion. */\n async list(\n params: V2ListParams = {},\n ): Promise<{ data: (T & RowHelpers)[]; meta: V2Meta; $refs: Refs }> {\n const res = await apiFetch<V2ListResponse<T & EnrichedRow>>(\n buildV2ListUrl(this.entity, params),\n );\n\n // Merge response-level $refs into the cache.\n this.refs.merge(res.$refs);\n\n const data = res.data.map((row) => attachHelpers(row));\n return { data, meta: res.meta, $refs: this.refs.all() };\n }\n\n // ---- Create --------------------------------------------------------------\n\n /** Create a single record. Wraps in array, returns unwrapped result. */\n async create(\n item: Partial<T> & Record<string, unknown>,\n ): Promise<T & EnrichedRow & RowHelpers> {\n const results = await this.createMany([item]);\n return results[0];\n }\n\n /** Create multiple records in one request. */\n async createMany(\n items: (Partial<T> & Record<string, unknown>)[],\n ): Promise<(T & EnrichedRow & RowHelpers)[]> {\n const res = await apiFetch<(T & EnrichedRow)[]>(\n `/api/data/${this.entity}`,\n { method: \"POST\", body: JSON.stringify(items) },\n );\n return res.map((row) => attachHelpers(row));\n }\n\n // ---- Update --------------------------------------------------------------\n\n /** Update a single record. Wraps in array, returns unwrapped result. */\n async update(\n id: string,\n data: Partial<T> & Record<string, unknown>,\n ): Promise<T & EnrichedRow & RowHelpers> {\n const results = await this.updateMany([{ id, ...data }]);\n return results[0];\n }\n\n /** Update multiple records in one request. Each item must include its id. */\n async updateMany(\n items: (Partial<T> & Record<string, unknown> & { id: string })[],\n ): Promise<(T & EnrichedRow & RowHelpers)[]> {\n const res = await apiFetch<(T & EnrichedRow)[]>(\n `/api/data/${this.entity}`,\n { method: \"PATCH\", body: JSON.stringify(items) },\n );\n return res.map((row) => attachHelpers(row));\n }\n\n // ---- Delete --------------------------------------------------------------\n\n /** Delete a single record by ID. */\n async delete(id: string): Promise<void> {\n await this.deleteMany([id]);\n }\n\n /** Delete multiple records in one request. Returns the count of deleted records. */\n async deleteMany(ids: string[]): Promise<{ count: number }> {\n return apiFetch<{ count: number }>(\n `/api/data/${this.entity}/delete`,\n { method: \"POST\", body: JSON.stringify(ids) },\n );\n }\n\n // ---- Restore -------------------------------------------------------------\n\n /** Restore a single soft-deleted record by ID. */\n async restore(id: string): Promise<void> {\n await this.restoreMany([id]);\n }\n\n /** Restore multiple soft-deleted records. Returns the count of restored records. */\n async restoreMany(ids: string[]): Promise<{ count: number }> {\n return apiFetch<{ count: number }>(\n `/api/data/${this.entity}/restore`,\n { method: \"POST\", body: JSON.stringify(ids) },\n );\n }\n\n // ---- Upsert --------------------------------------------------------------\n\n /** Upsert a single record. Wraps in array, returns unwrapped result. */\n async upsert(\n item: Partial<T> & Record<string, unknown>,\n uniqueFields: string[],\n ): Promise<T & EnrichedRow & RowHelpers> {\n const results = await this.upsertMany([item], uniqueFields);\n return results[0];\n }\n\n /** Upsert multiple records. Existing matches (by unique_fields) are updated. */\n async upsertMany(\n items: (Partial<T> & Record<string, unknown>)[],\n uniqueFields: string[],\n ): Promise<(T & EnrichedRow & RowHelpers)[]> {\n const uf = encodeURIComponent(uniqueFields.join(\",\"));\n const res = await apiFetch<(T & EnrichedRow)[]>(\n `/api/data/${this.entity}?unique_fields=${uf}`,\n { method: \"POST\", body: JSON.stringify(items) },\n );\n return res.map((row) => attachHelpers(row));\n }\n}\n\n/**\n * Create an EntityClient for the given entity code.\n * Optionally share a RefCache across multiple clients.\n *\n * NOTE(T5): Each call creates a new EntityClient (and a new RefCache if none is\n * provided). For cross-page ref accumulation, callers should create a persistent\n * RefCache instance and pass it to every entityClient() call, e.g. via React\n * context or a module-level singleton.\n */\nexport function entityClient<T extends Record<string, unknown> = Record<string, unknown>>(\n entity: string,\n refCache?: RefCache,\n): EntityClient<T> {\n return new EntityClient<T>(entity, refCache);\n}\n","import { apiFetch } from \"./client\";\nimport type {\n DataResponse,\n PublicParam,\n ResolvedParam,\n} from \"@/types/api\";\n\nexport async function fetchPublicParams(): Promise<PublicParam[]> {\n const res = await apiFetch<DataResponse<PublicParam[]>>(\"/api/params/public\");\n return res.data;\n}\n\nexport async function fetchParam(code: string): Promise<ResolvedParam> {\n const res = await apiFetch<DataResponse<ResolvedParam>>(\n `/api/params/${encodeURIComponent(code)}`,\n );\n return res.data;\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { fetchPublicParams, fetchParam } from \"@/api/params\";\n\nexport function usePublicParams() {\n return useQuery({\n queryKey: [\"params-public\"],\n queryFn: fetchPublicParams,\n staleTime: 5 * 60 * 1000,\n });\n}\n\nexport function useResolvedParam(code: string) {\n return useQuery({\n queryKey: [\"params\", code],\n queryFn: () => fetchParam(code),\n enabled: !!code,\n staleTime: 5 * 60 * 1000,\n });\n}\n","import { useMemo, useCallback } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\n\n/**\n * useColumns manages visible columns via URL `columns` param.\n * Falls back to screen defaults when no URL param is set.\n */\nexport function useColumns(\n availableColumns: string[],\n defaultColumns: string[],\n) {\n const [searchParams, setSearchParams] = useSearchParams();\n\n const visibleColumns = useMemo<string[]>(() => {\n const raw = searchParams.get(\"columns\");\n if (raw) {\n const fromURL = raw.split(\",\").filter(Boolean);\n // Intersect with available pool (drop stale column refs).\n return fromURL.filter((c) => availableColumns.includes(c));\n }\n return defaultColumns.length > 0 ? defaultColumns : availableColumns;\n }, [searchParams, availableColumns, defaultColumns]);\n\n const setColumns = useCallback(\n (cols: string[]) => {\n const next = new URLSearchParams(searchParams);\n if (cols.length === 0 || arraysEqual(cols, defaultColumns)) {\n next.delete(\"columns\"); // reset to defaults\n } else {\n next.set(\"columns\", cols.join(\",\"));\n }\n setSearchParams(next);\n },\n [searchParams, setSearchParams, defaultColumns],\n );\n\n const resetToDefaults = useCallback(() => {\n const next = new URLSearchParams(searchParams);\n next.delete(\"columns\");\n setSearchParams(next);\n }, [searchParams, setSearchParams]);\n\n const showAll = useCallback(() => {\n setColumns(availableColumns);\n }, [availableColumns, setColumns]);\n\n const isColumnVisible = useCallback(\n (col: string) => visibleColumns.includes(col),\n [visibleColumns],\n );\n\n const toggleColumn = useCallback(\n (col: string) => {\n if (visibleColumns.includes(col)) {\n // Don't allow hiding last column.\n if (visibleColumns.length <= 1) return;\n setColumns(visibleColumns.filter((c) => c !== col));\n } else {\n setColumns([...visibleColumns, col]);\n }\n },\n [visibleColumns, setColumns],\n );\n\n return {\n visibleColumns,\n availableColumns,\n setColumns,\n resetToDefaults,\n showAll,\n isColumnVisible,\n toggleColumn,\n };\n}\n\nfunction arraysEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n return a.every((v, i) => v === b[i]);\n}\n"],"names":["cn","inputs","twMerge","clsx","ApiError","status","message","code","index","__publicField","flatActionBody","args","refreshPromise","refreshAccessToken","init","res","retryAfter","r","ensureRefresh","defaultPersistentAuthFailureHandler","onPersistentAuthFailure","apiFetch","path","options","headers","body","retryHeaders","retryRes","retryBody","refreshErr","callHandler","fetchSchema","useSchema","useQuery","EXCLUDED_ROUTES","useTabStore","create","set","get","tab","existing","t","id","newTab","s","state","idx","remaining","nextActive","activeId","overId","oldIdx","newIdx","tabs","moved","pathname","title","search","useTabNavigate","navigate","useNavigate","openTab","switchTab","findTabByPathname","useCallback","opts","iconCache","loadIcon","name","cached","importFn","dynamicIconImports","LazyIcon","lazy","DynamicIcon","props","Icon","useMemo","jsx","Suspense","DETAIL_SCREEN_NONE","loc","ls","lang","fieldDisplayName","field","fieldName","entities","explicit","_a","_b","refEntity","entityName","_c","propertyToField","prop","baseName","display","getPrimaryKeyFields","entity","extractPkValues","record","fields","values","f","pkValuesToId","pkValues","vals","Sidebar","collapsed","setCollapsed","useState","collapsedSections","setCollapsedSections","location","useLocation","schema","tabNavigate","nodes","branding","appName","appInitial","accentColor","findFirstLeaf","items","node","found","toggleSection","prev","isActive","route","jsxs","first","screen","ChevronDown","item","active","ChevronRight","ChevronLeft","checkSetup","login","email","password","signup","displayName","getMe","listTenants","switchTenant","tenantId","logout","listSSOProviders","tenantCode","ssoAuthorizeUrl","slug","redirect","params","qs","useAuthStore","user","tenant","tenants","logoutApi","useAuth","isAuthenticated","isLoading","activeTenant","setUser","setTenants","storeLogout","queryClient","useQueryClient","loginMutation","useMutation","authApi.login","result","authApi.listTenants","err","toast","signupMutation","authApi.signup","switchTenantMutation","authApi.switchTenant","DropdownMenu","DropdownMenuPrimitive","DropdownMenuTrigger","DropdownMenuSubTrigger","React","className","inset","children","ref","DropdownMenuSubContent","DropdownMenuContent","sideOffset","DropdownMenuItem","DropdownMenuCheckboxItem","checked","Check","DropdownMenuRadioItem","Circle","DropdownMenuLabel","DropdownMenuSeparator","buttonVariants","cva","Button","variant","size","asChild","Slot","TopBar","isSwitchingTenant","initials","n","canSwitch","ChevronsUpDown","Fragment","LogOut","SortableTab","isOnly","onSwitch","onClose","attributes","listeners","setNodeRef","transform","transition","isDragging","useSortable","style","CSS","e","X","TabBar","activeTabId","closeTab","reorderTabs","sensors","useSensors","useSensor","PointerSensor","tabIds","handleSwitch","handleClose","_e","nextIdx","next","handleDragEnd","event","over","DndContext","closestCenter","SortableContext","horizontalListSortingStrategy","streamEvents","signal","reader","decoder","buffer","currentEvent","currentData","done","value","lines","line","parsed","ENTITY_CHILDREN_KEY","useChildrenData","parentEntity","parentId","childCode","foreignKey","sort","limit","fkArr","idArr","filters","fk","i","MAX_RECONNECT_DELAY","BASE_DELAY","COALESCE_WINDOW_MS","invalidateForEntityChanges","events","ev","mutated","query","key","useSSE","abortRef","useRef","useEffect","mounted","attempt","pending","flushTimer","flush","batch","scheduleFlush","connect","controller","delay","jitter","Layout","intended","redirectParam","Outlet","Input","type","labelVariants","Label","LabelPrimitive","Card","CardHeader","CardTitle","CardDescription","CardContent","CardFooter","LoginPage","searchParams","useSearchParams","isLoginPending","setEmail","setPassword","rawRedirect","redirectTo","ssoError","setupStatus","ssoProviders","handleSubmit","hasProviders","provider","Link","SignupPage","isSignupPending","setDisplayName","SSOCallbackPage","NotFoundPage","PageHeader","backTo","actions","handleBack","ArrowLeft","badgeVariants","Badge","color","colorStyle","AdminCatalogPage","activeTab","setActiveTab","HandlersTab","ActionsTab","allHandlers","h","entityCode","a","b","handler","HandlerCard","expanded","setExpanded","paramCode","param","ParamRow","allActions","action","grouped","groups","group","ActionCard","v","buildListUrl","url","listEntities","getEntity","createEntity","data","updateEntity","pkFields","deleteEntity","restoreEntity","buildActionBody","ids","executeAction","resolveAssociation","useEntityData","prevQuery","useCreateEntity","useUpdateEntity","_result","_variables","useDeleteEntity","_pkValues","useRestoreEntity","useExecuteAction","actionCode","useDebounce","debounced","setDebounced","timer","CopyButton","copied","setCopied","handleCopy","iconSize","Copy","StringField","mode","onChange","text","Textarea","remarkPlugins","remarkBreaks","TextField","widget","rendered","Markdown","rows","Select","SelectPrimitive","SelectValue","SelectTrigger","SelectScrollUpButton","ChevronUp","SelectScrollDownButton","SelectContent","position","SelectItem","SelectLabel","SelectSeparator","NULL_SENTINEL","EnumField","current","showClearOption","currentValue","EmailField","str","FAVICON_BASE","SAFE_PROTOCOLS","LONG_TLD","looksLikeTLD","label","looksLikeHostname","candidate","labels","normalizeUrl","raw","schemeMatch","scheme","afterColon","port","parseDomain","href","isValidUrl","UrlField","errorDomain","setErrorDomain","isLink","domain","showFavicon","linkText","ExternalLink","formatTimestamp","isDateOnly","d","offsetMatch","isUTC","date","tz","sign","hours","minutes","offsetMs","localMs","localDate","extractTzAbbrev","m","minPart","toInputValue","y","mo","mi","TimestampField","hasTz","formatted","tzAbbrev","inputValue","BoolField","formatDecimalString","trimmed","negative","abs","intPart","fracPart","formattedInt","numFormatter","NumberField","isMoney","isDecimal","units","unitSuffix","staticUnit","displayUnit","num","useEntity","resolveDisplay","val","RefField","refs","refEntityCode","displayField","_d","pk","response","optionsLoading","displayValue","strVal","entityRefs","refRecord","match","currentId","hasCurrentInOptions","JsonEditor","JsonEditorFallback","JsonField","parseLangMap","MultilangField","languages","langMap","displayVal","handleLangChange","updated","k","MultilangTextField","StructureField","structDef","StructureArrayRenderer","StructureObjectRenderer","obj","fieldOrder","fieldValue","renderField","handleFieldChange","handleItemChange","itemValue","handleAdd","handleRemove","_","Trash2","Plus","SECRET_SENTINEL","SecretField","showValue","setShowValue","setInputValue","isUpdate","hasExistingValue","handleChange","EyeOff","Eye","PasswordField","revealed","setRevealed","toStringArray","StringArrayField","draft","setDraft","addItem","removeItem","handleKeyDown","toIntArray","IntArrayField","fieldRenderers","Renderer","EmptyState","icon","description","Skeleton","TableSkeleton","cols","j","DetailSkeleton","AlertDialog","AlertDialogPrimitive","AlertDialogPortal","AlertDialogOverlay","AlertDialogContent","AlertDialogHeader","AlertDialogFooter","AlertDialogTitle","AlertDialogDescription","AlertDialogAction","AlertDialogCancel","ConfirmDialog","open","onOpenChange","confirmLabel","onConfirm","destructive","Dialog","DialogPrimitive","DialogPortal","DialogOverlay","DialogContent","DialogHeader","DialogFooter","DialogTitle","DialogDescription","regions","registerFieldRegion","region","getFieldRegion","interpolate","template","ctx","_match","resolvePath","parts","root","rest","acc","regionName","executeUISteps","steps","step","runStep","msg","target","splitPath","kind","dot","isUIAction","ROW_PREFILL_RE","resolveParamDefault","row","paramToEntityField","resolveFilterValue","formData","TEMPLATE_TOKEN_RE","referencesParam","paramName","StatusGroupPicker","statusGroups","entries","StatusPicker","statuses","groupKey","resolved","g","ActionDialog","actionName","onSubmit","isPending","hiddenDefaults","paramEntries","order","entityStatusGroups","buildInitialFormData","initial","setFormData","handleOpenChange","isOpen","filterBy","control","ActionConfirmDialog","ActionResultDialog","DisplayFieldRow","evaluateConditions","conditions","cond","rowStatus","evaluateFieldCondition","fieldVal","op","isTruthy","compareValues","fieldStr","condStr","getActionsByVisibility","visibility","getScreenActions","entityActions","screenActionCodes","fallbackVisibility","globalActions","actionHasParams","isAssociationAction","findListScreenForEntity","ActionButton","objectIds","onSuccess","onBatchStart","onBatchError","onBatchPartial","showDialog","setShowDialog","showConfirm","setShowConfirm","navigating","setNavigating","displayResult","setDisplayResult","executeMutation","isAssociation","hasParams","hasConfirmation","conditionsMet","isBatchEmpty","isSingleInvalid","handleAssociationNavigate","assocCode","targetScreen","targetEntity","qualifiedActionCode","actionIds","handleActionSuccess","closeDialog","handleClick","handleConfirm","handleDialogSubmit","RowActionItem","objectId","BatchActionProgress","count","isSuccess","isError","isPartial","Loader2","CheckCircle2","AlertTriangle","XCircle","NO_VALUE_OPS","OP_LABELS","parseFiltersFromURL","setFiltersInURL","hasOrGroups","flatFieldConditions","countActiveFilters","eqFilter","removeFilter","cleaned","useFilters","setSearchParams","activeCount","setFilters","newFilters","clearFilters","FilterChips","onRemove","onClearAll","onChipClick","fieldLabel","gi","formatValue","FilterChip","fieldNodes","onClick","FilterDrawer","onApply","availableFields","showFieldPicker","setShowFieldPicker","isOrMode","activeFields","addCondition","fieldCode","meta","defaultOp","updateCondition","updates","removeCondition","addOrGroup","currentConditions","otherNodes","handleApply","filteredOr","handleReset","Filter","FilterRow","OrGroupEditor","newGroups","newDraft","FieldPicker","onUpdate","isNoValue","opt","ni","firstAvailable","onSelect","onCancel","setSearch","filtered","ColumnPicker","availableColumns","visibleColumns","onToggle","onReset","onShowAll","columnLabel","c","setOpen","Columns3","col","isVisible","RotateCcw","ViewSwitcher","views","activeViewId","isDirty","onSave","onSaveAs","onSetDefault","activeView","systemViews","personalViews","sharedViews","ViewOption","Save","isDefault","isShared","_onSetDefault","Star","Globe","useScreen","screenCode","useViews","userId","dbResponse","isOwn","resolveDetailHref","list","allScreens","SmartListPage","deleteState","setDeleteState","rowSelection","setRowSelection","batchState","setBatchState","filterDrawerOpen","setFilterDrawerOpen","jsonFilters","filterCount","setJsonFilters","allViews","toolbarActions","rowActions","hasExplicitRowActions","hasBatchActions","hasSoftDelete","canViewDeleted","p","includeDeleted","updateTabSearch","tabName","tabIcon","page","searchValue","sortParam","debouncedSearch","visibleCols","expand","allCols","deleteMutation","sorting","dir","pkField","refsRef","columns","tbl","colKey","groupCode","statusMap","def","propCode","propDef","width","getValue","hasDefaultActions","editHref","MoreHorizontal","Pencil","table","useReactTable","getCoreRowModel","updater","selectedIds","tag","input","parentRef","rowVirtualizer","useVirtualizer","updateSearch","toggleIncludeDeleted","goToPage","hasRowDetailTarget","handleRowClick","firstCol","tabTitle","handleDelete","results","failed","succeededIds","entityDisplay","screenName","screenIcon","_f","rawIds","isDisabled","successIds","succeeded","view","Search","gc","pc","_g","headerGroup","header","canSort","sorted","flexRender","ArrowUp","ArrowDown","ArrowUpDown","_h","virtualRow","isDeleted","cell","_i","buildFilterFieldMeta","filterFields","ops","fieldTypeToOperators","formatOffsetTimestamp","useEntityItem","cacheKey","AssociationTabs","recordId","associations","assocEntries","activeKey","activeAssoc","assoc","AssociationContent","assocKey","association","assocResult","resolving","targetEntityCode","targetIds","filterIds","listResponse","loadingRecords","handleViewAll","PX_PATTERN","parseSizeValue","pxMatch","intVal","LayoutRow","config","gap","resizable","stack_below","stackPx","stacked","setStacked","containerRef","el","observer","entry","flexSizes","setFlexSizes","dragging","getInitialSizes","w","onDragStart","sizes","onMove","totalWidth","delta","totalFlex","flexDelta","newSizes","onUp","heightStyle","parseHeight","itemStyle","LayoutNodeRenderer","flexValue","minWidth","maxWidth","flex","height","LayoutColumn","getTabLabel","childRelation","childEntity","getTabIcon","LayoutTabs","SectionBlock","defaultCollapsed","childCtx","LayoutRenderer","resolveChildConfig","relation","screenNode","resolveField","inferName","inferColumns","inferSort","posField","timelineSource","inferTimelineFields","cardsSource","quickAdd","screenOverride","entityDefault","autoDefault","findPrimaryKey","fkSet","tc","inferTimeField","inferFirstFieldOfType","inferFirstFieldOfTypes","inferDirectionField","inferIntentField","direction","intent","types","pks","findChildRelation","buildQuickAddPayload","fieldValues","defaults","isQuickAddReady","requiredFields","toBareLocalNow","now","min","useQuickAdd","setValues","qa0","ce","initialValues","mutate","error","reset","payload","qa","resetValues","normalizedParentId","isReady","QuickAddForm","ChildrenTable","quickAddForm","rowIdx","ChildrenList","subCols","ChildrenCards","cardsConfig","headerField","badgeField","colCount","gridClass","detailFields","QUICK_ENTRY_REGION","MIN_HEIGHT","DEFAULT_HEIGHT","MAX_HEIGHT","TimelineComposer","setHeight","valuesRef","handleFieldChangeRef","fieldNodesRef","contentField","topFields","bottomFields","renderMetaField","ChildrenTimeline","timeline","scroll","autoScroll","scrollRef","hasAutoScrolled","prevRowCount","isInitialLoad","hasNewRows","editingId","setEditingId","editableFields","rowId","TimelineEntry","isEditing","onStartEdit","onCancelEdit","onSaved","invalidate","updateMut","deleteMut","startEdit","timeField","typeField","summaryField","authorField","directionField","intentField","DirectionChip","outbound","isOutbound","ArrowUpRight","ArrowDownLeft","EditableChildrenTable","validationErrors","tableRef","editableColumns","displayOnlyColumns","handleCellChange","rowKey","handleAddRow","newRow","quickDefaults","handleDeleteRow","handleUndoDelete","tbody","cellIndex","rowIndex","allRows","nextRow","nextCell","nextTd","newRows","lastRow","firstInput","rowErrors","hasError","isDisplayOnly","Undo2","DraggableChildrenTable","positionField","rowIds","maxPosition","max","pos","nonDeleted","deleted","oldIndex","newIndex","reordered","withPositions","verticalListSortingStrategy","SortableRow","onCellChange","onDelete","onUndoDelete","GripVertical","isEditable","ChildrenBlock","pendingRows","TableComponent","displayProps","useAssociatedData","stableFilters","useInfiniteQuery","pageParam","filterNodes","lastPage","AssociatedToolbar","searchable","onSearchChange","onFilterChange","allEntities","hasSearch","hasFilters","filterField","currentVal","RefFilterDropdown","optLabel","AssociatedBlock","assocEntity","fkField","editable","hasToolbar","PaginatedAssociatedTable","SimpleAssociatedTable","invalidateQuery","AssociatedTableInner","setSearchValue","setDebouncedSearch","searchTimerRef","handleFilterChange","activeFilters","infiniteData","hasNextPage","fetchNextPage","isFetchingNextPage","mergedRefs","entityKey","records","activeCell","setActiveCell","rowStates","setRowStates","rowStatesRef","debounceTimers","timers","draftRow","setDraftRow","draftErrors","setDraftErrors","draftSaving","setDraftSaving","deleteConfirm","setDeleteConfirm","deletingIds","setDeletingIds","flushRow","sentVer","nextVer","handleStartDraft","handleConfirmDraft","errors","showEmpty","isDeleting","rowState","AssociatedRow","DraftRow","onDeleteClick","displayRow","apiError","fieldErrors","FieldsBlock","onFieldChange","hideLabels","layoutField","hasActions","DEBOUNCE_TYPES","DEBOUNCE_MS","PropertiesBlock","objectProperties","onSetProperty","isNew","propertyDefs","filter","propVal","effectiveMode","DebouncedProperty","timerRef","StatusGroupsDisplay","objectStatuses","onSetStatus","sgCode","sg","currentCode","currentStatus","available","statusCode","noop","StatusesBlock","isStatusPending","collectFKFields","fks","rel","validatePendingChildren","pendingChildren","fkFields","missingFields","arraysEqual","SmartDetailPage","urlId","useParams","selfUser","isSelf","pkCacheKey","itemResponse","createMutation","updateMutation","restoreMutation","hasStatusGroups","itemData","openInEdit","editing","setEditing","pendingStatuses","setPendingStatuses","pendingProperties","setPendingProperties","setPendingChildren","childrenSnapshot","setChildrenSnapshot","sidebarW","setSidebarW","sidebarRef","sidebarDrag","onSidebarDragStart","startW","recordRefs","isRecordDeleted","updateTabTitle","dfKey","rawVal","resolvedVal","displayTitle","startEditing","serverChildren","cancelEditing","listRoute","listRouteExists","handleSave","original","propertyCode","childrenPayload","_key","_deleted","_dirty","clearPending","newRecord","newPkValues","newId","handleChildrenChange","handleRestore","childValidationErrors","hasChildErrors","detailName","displayFieldKey","rawDisplayValue","isSaving","hasExplicitActions","headerActions","layoutCtx","base","merged","sc","hasSidebar","headerEl","deletedBanner","statusesEl","mainContent","deleteDialog","setObjectStatus","note","statusEntry","useSetStatus","statusApi.setObjectStatus","setObjectProperty","deleteObjectProperty","useSetProperty","propsApi.setObjectProperty","useDeleteProperty","propsApi.deleteObjectProperty","SmartRecordListPage","selectedId","listLoading","listRefs","selectRecord","updateFilter","listResizable","panelWidth","setPanelWidth","listWidthRaw","container","pct","dragCleanup","handleMouseDown","startX","startWidth","onMouseMove","containerWidth","newWidth","cleanup","listColumns","activeFilterCount","fieldDef","activeNode","RecordListRow","RecordDetailPanel","_pkField","isSelected","primaryCol","secondaryCol","badgeCols","setStatusMutation","setPropertyMutation","rawTitle","ErrorBoundary","Component","info","TOKEN_MAP","THEME_TOKENS","themeDefToTokens","tokens","cssVar","STORAGE_KEY","getSystemPreference","resolveEffective","selected","applyTheme","themeName","customThemes","html","clearCustomProperties","getInitialTheme","initialSelected","initialEffective","useThemeStore","effective","themes","effectiveTheme","registry","registerScreen","component","getRegisteredScreen","QueryClient","useDynamicRoutes","routes","out","Route","CustomComponent","defaultRoute","child","AppRoutes","initialize","setAvailableThemes","themesJson","converted","Routes","Navigate","App","QueryClientProvider","BrowserRouter","Toaster","findStatus","findProperty","attachHelpers","enriched","RefCache","incoming","buildV2ListUrl","EntityClient","refCache","uniqueFields","uf","entityClient","fetchPublicParams","fetchParam","usePublicParams","useResolvedParam","useColumns","defaultColumns","setColumns","resetToDefaults","showAll","isColumnVisible","toggleColumn"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGO,SAASA,KAAMC,GAAsB;AAC1C,SAAOC,GAAQC,GAAKF,CAAM,CAAC;AAC7B;ACwBO,MAAMG,WAAiB,MAAM;AAAA,EAMlC,YAAYC,GAAgBC,GAAiBC,GAAcC,GAAgB;AACzE,UAAMF,CAAO;AANf,IAAAG,GAAA;AACA,IAAAA,GAAA;AAEA;AAAA,IAAAA,GAAA;AAIE,SAAK,OAAO,YACZ,KAAK,SAASJ,GACd,KAAK,OAAOE,GACZ,KAAK,QAAQC;AAAA,EACf;AACF;AC1BA,MAAME,KAAiB,CAACC,MACtB,KAAK,UAAUA,KAAQ,CAAA,CAAE;AAE3B,IAAIC,KAAuC;AAK3C,eAAeC,KAAoC;AACjD,QAAMC,IAAoB;AAAA,IACxB,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,SAAS,EAAE,gBAAgB,mBAAA;AAAA,IAC3B,MAAMJ,GAAe,CAAA,CAAE;AAAA,EAAA,GAEnBK,IAAM,MAAM,MAAM,6BAA6BD,CAAI;AAGzD,MAAIC,EAAI,WAAW,KAAK;AACtB,UAAMC,IAAa,SAASD,EAAI,QAAQ,IAAI,aAAa,KAAK,KAAK,EAAE;AAGrE,QAFA,MAAM,IAAI,QAAQ,CAACE,MAAM,WAAWA,GAAGD,IAAa,GAAI,CAAC,GAErD,EADa,MAAM,MAAM,6BAA6BF,CAAI,GAChD;AACZ,YAAM,IAAI,MAAM,4BAA4B;AAE9C;AAAA,EACF;AAEA,MAAI,CAACC,EAAI;AACP,UAAM,IAAI,MAAM,gBAAgB;AAEpC;AAEA,eAAsBG,KAA+B;AACnD,SAAIN,OACJA,KAAiBC,KAAqB,QAAQ,MAAM;AAClD,IAAAD,KAAiB;AAAA,EACnB,CAAC,GACMA;AACT;AASA,MAAMO,KAAoE,MAAM;AAC9E,EAAI,OAAO,SAAW,OAEpB,OAAO,SAAS,SAAS,WAAW,QAAQ,KAC5C,OAAO,SAAS,SAAS,WAAW,SAAS,MAI/C,OAAO,SAAS,OAAO;AACzB;AAEA,IAAIC,KACFD;AAaF,eAAsBE,GACpBC,GACAC,IAAuB,IACX;AACZ,QAAMC,IAAU,IAAI,QAAQD,EAAQ,OAAO;AAE3C,EAAI,CAACC,EAAQ,IAAI,cAAc,KAAKD,EAAQ,QAC1CC,EAAQ,IAAI,gBAAgB,kBAAkB;AAGhD,QAAMT,IAAM,MAAM,MAAMO,GAAM,EAAE,GAAGC,GAAS,SAAAC,GAAS,aAAa,WAAW;AAE7E,MAAIT,EAAI,WAAW,KAInB;AAAA,QAAI,CAACA,EAAI,IAAI;AACX,UAAIT,IAAU,kBACVC,IAAO,WACPC;AAEJ,UAAI;AACF,cAAMiB,IAAQ,MAAMV,EAAI,KAAA;AACxB,QAAAT,IAAUmB,EAAK,MAAM,SACrBlB,IAAOkB,EAAK,MAAM,MACdA,EAAK,SAAS,SAAMjB,IAAQiB,EAAK;AAAA,MACvC,QAAQ;AAAA,MAER;AAGA,UAAIV,EAAI,WAAW,QAAQR,MAAS,0BAA0BA,MAAS;AACrE,YAAI;AACF,gBAAMW,GAAA;AACN,gBAAMQ,IAAe,IAAI,QAAQH,EAAQ,OAAO;AAChD,UAAI,CAACG,EAAa,IAAI,cAAc,KAAKH,EAAQ,QAC/CG,EAAa,IAAI,gBAAgB,kBAAkB;AAErD,gBAAMC,IAAW,MAAM,MAAML,GAAM;AAAA,YACjC,GAAGC;AAAA,YACH,SAASG;AAAA,YACT,aAAa;AAAA,UAAA,CACd;AACD,cAAIC,EAAS,WAAW;AACtB;AAEF,cAAI,CAACA,EAAS,IAAI;AAChB,YAAAP,GAAA;AACA,kBAAMQ,IAAa,MAAMD,EACtB,KAAA,EACA,MAAM,OAAO,EAAE,OAAO,EAAE,SAAS,kBAAkB,MAAM,UAAA,IAAc;AAC1E,kBAAM,IAAIvB,GAASuB,EAAS,QAAQC,EAAU,MAAM,SAASA,EAAU,MAAM,MAAMA,EAAU,KAAK;AAAA,UACpG;AACA,iBAAOD,EAAS,KAAA;AAAA,QAClB,SAASE,GAAY;AACnB,gBAAIA,aAAsBzB,KAClByB,KAERT,GAAA,GACM,IAAIhB,GAAS,KAAKE,GAASC,GAAMC,CAAK;AAAA,QAC9C;AAIF,YAAIO,EAAI,WAAW,OACjBK,GAAA,GAGF,QAAQ,MAAM,QAAQL,EAAI,MAAM,KAAKR,CAAI,KAAKD,CAAO,EAAE,GACjD,IAAIF,GAASW,EAAI,QAAQT,GAASC,GAAMC,CAAK;AAAA,IACrD;AAEA,WAAOO,EAAI,KAAA;AAAA;AACb;AAoBA,eAAsBe,GACpBvB,GACAI,IAAgB,IACJ;AAQZ,UAPY,MAAMU;AAAA,IAChB,gBAAgB,mBAAmBd,CAAI,CAAC;AAAA,IACxC;AAAA,MACE,QAAQ;AAAA,MACR,MAAMG,GAAeC,CAAI;AAAA,IAAA;AAAA,EAC3B,GAES;AACb;AC/LA,eAAsBoB,KAA+B;AACnD,SAAOV,GAAiB,aAAa;AACvC;ACFO,SAASW,KAAY;AAC1B,SAAOC,GAAS;AAAA,IACd,UAAU,CAAC,QAAQ;AAAA,IACnB,SAASF;AAAA,IACT,WAAW;AAAA,EAAA,CACZ;AACH;ACgBA,MAAMG,KAAkB,CAAC,UAAU,SAAS,GAE/BC,KAAcC,GAAiB,CAACC,GAAKC,OAAS;AAAA,EACzD,MAAM,CAAA;AAAA,EACN,aAAa;AAAA,EAEb,SAAS,CAACC,MAAQ;AAChB,QAAIL,GAAgB,SAASK,EAAI,QAAQ;AACvC,aAAO;AAKT,UAAMC,IAFQF,EAAA,EAES,KAAK,KAAK,CAACG,MAAMA,EAAE,aAAaF,EAAI,QAAQ;AACnE,QAAIC;AACF,aAAAH,EAAI,EAAE,aAAaG,EAAS,GAAA,CAAI,GACzBA,EAAS;AAGlB,UAAME,IAAK,OAAO,WAAA,GACZC,IAAkB,EAAE,GAAGJ,GAAK,IAAAG,EAAA;AAClC,WAAAL,EAAI,CAACO,OAAO;AAAA,MACV,MAAM,CAAC,GAAGA,EAAE,MAAMD,CAAM;AAAA,MACxB,aAAaD;AAAA,IAAA,EACb,GACKA;AAAA,EACT;AAAA,EAEA,UAAU,CAACA,MAAO;AAChB,UAAMG,IAAQP,EAAA,GACRQ,IAAMD,EAAM,KAAK,UAAU,CAACJ,MAAMA,EAAE,OAAOC,CAAE;AAOnD,QANII,MAAQ,MAGR,CADQD,EAAM,KAAKC,CAAG,EACjB,YAGLD,EAAM,KAAK,WAAW,EAAG;AAE7B,UAAME,IAAYF,EAAM,KAAK,OAAO,CAACJ,MAAMA,EAAE,OAAOC,CAAE;AACtD,QAAIM,IAAaH,EAAM;AAEvB,IAAIA,EAAM,gBAAgBH,MACpBK,EAAU,WAAW,IACvBC,IAAa,OACJF,IAAMC,EAAU,SAEzBC,IAAaD,EAAUD,CAAG,EAAE,KAG5BE,IAAaD,EAAUA,EAAU,SAAS,CAAC,EAAE,KAIjDV,EAAI,EAAE,MAAMU,GAAW,aAAaC,GAAY;AAAA,EAClD;AAAA,EAEA,WAAW,CAACN,MAAO;AACjB,IAAAL,EAAI,EAAE,aAAaK,GAAI;AAAA,EACzB;AAAA,EAEA,aAAa,CAACO,GAAUC,MAAW;AACjC,IAAAb,EAAI,CAACO,MAAM;AACT,YAAMO,IAASP,EAAE,KAAK,UAAU,CAACH,MAAMA,EAAE,OAAOQ,CAAQ,GAClDG,IAASR,EAAE,KAAK,UAAU,CAACH,MAAMA,EAAE,OAAOS,CAAM;AACtD,UAAIC,MAAW,MAAMC,MAAW,MAAMD,MAAWC,EAAQ,QAAOR;AAChE,YAAMS,IAAO,CAAC,GAAGT,EAAE,IAAI,GACjB,CAACU,CAAK,IAAID,EAAK,OAAOF,GAAQ,CAAC;AACrC,aAAAE,EAAK,OAAOD,GAAQ,GAAGE,CAAK,GACrB,EAAE,MAAAD,EAAA;AAAA,IACX,CAAC;AAAA,EACH;AAAA,EAEA,mBAAmB,CAACE,MACXjB,EAAA,EAAM,KAAK,KAAK,CAACG,MAAMA,EAAE,aAAac,CAAQ;AAAA,EAGvD,gBAAgB,CAACb,GAAIc,MAAU;AAC7B,IAAAnB,EAAI,CAACO,OAAO;AAAA,MACV,MAAMA,EAAE,KAAK,IAAI,CAACH,MAAOA,EAAE,OAAOC,IAAK,EAAE,GAAGD,GAAG,OAAAe,EAAA,IAAUf,CAAE;AAAA,IAAA,EAC3D;AAAA,EACJ;AAAA,EAEA,iBAAiB,CAACC,GAAIe,MAAW;AAC/B,IAAApB,EAAI,CAACO,OAAO;AAAA,MACV,MAAMA,EAAE,KAAK,IAAI,CAACH,MAAOA,EAAE,OAAOC,IAAK,EAAE,GAAGD,GAAG,QAAAgB,EAAA,IAAWhB,CAAE;AAAA,IAAA,EAC5D;AAAA,EACJ;AACF,EAAE;ACtGK,SAASiB,KAAiB;AAC/B,QAAMC,IAAWC,GAAA,GACX,EAAE,SAAAC,GAAS,WAAAC,GAAW,mBAAAC,EAAA,IAAsB5B,GAAA;AA+BlD,SA7BoB6B;AAAA,IAClB,CAACT,GAAkBU,MAA8B;AAE/C,YAAMzB,IAAWuB,EAAkBR,CAAQ;AAC3C,UAAIf,GAAU;AACZ,QAAAsB,EAAUtB,EAAS,EAAE,GACrBmB;AAAA,UACE,EAAE,UAAAJ,GAAU,QAAQU,KAAA,gBAAAA,EAAM,OAAA;AAAA,UAC1B,EAAE,SAASA,KAAA,gBAAAA,EAAM,QAAA;AAAA,QAAQ;AAE3B;AAAA,MACF;AAGA,MAAAJ,EAAQ;AAAA,QACN,UAAAN;AAAA,QACA,SAAQU,KAAA,gBAAAA,EAAM,WAAU;AAAA,QACxB,QAAOA,KAAA,gBAAAA,EAAM,UAASV;AAAA,QACtB,MAAMU,KAAA,gBAAAA,EAAM;AAAA,QACZ,UAAU;AAAA,MAAA,CACX,GACDN;AAAA,QACE,EAAE,UAAAJ,GAAU,QAAQU,KAAA,gBAAAA,EAAM,OAAA;AAAA,QAC1B,EAAE,SAASA,KAAA,gBAAAA,EAAM,QAAA;AAAA,MAAQ;AAAA,IAE7B;AAAA,IACA,CAACN,GAAUE,GAASC,GAAWC,CAAiB;AAAA,EAAA;AAIpD;ACvCA,MAAMG,yBAAgB,IAAA;AAKtB,SAASC,GAASC,GAAc;AAC9B,QAAMC,IAASH,GAAU,IAAIE,CAAI;AACjC,MAAIC,EAAQ,QAAOA;AAEnB,QAAMC,IAAWC,GAAmBH,CAAgB;AACpD,MAAI,CAACE,EAAU,QAAO;AAEtB,QAAME,IAAWC,GAAKH,CAAQ;AAG9B,SAAAJ,GAAU,IAAIE,GAAMI,CAAQ,GACrBA;AACT;AAMO,SAASE,GAAY,EAAE,MAAAN,GAAM,GAAGO,KAA2B;AAChE,QAAMC,IAAOC,EAAQ,MAAMV,GAASC,CAAI,GAAG,CAACA,CAAI,CAAC;AAEjD,SAAKQ,IAGH,gBAAAE,EAACC,IAAA,EAAS,UAAU,gBAAAD,EAAC,OAAA,EAAI,WAAU,UAAA,CAAU,GAC3C,UAAA,gBAAAA,EAACF,GAAA,EAAM,GAAGD,EAAA,CAAO,GACnB,IALgB;AAOpB;AChCO,MAAMK,KAAqB;AAE3B,SAASC,EAAIC,GAAiCC,IAAO,MAAc;AACxE,SAAKD,IACEA,EAAGC,CAAI,KAAK,OAAO,OAAOD,CAAE,EAAE,CAAC,KAAK,KAD3B;AAElB;AAKO,SAASE,GACdC,GACAC,GACAC,GACQ;;AACR,QAAMC,IAAWP,GAAIQ,IAAAJ,EAAM,YAAN,gBAAAI,EAAe,IAAI;AACxC,MAAID,EAAU,QAAOA;AACrB,MAAIH,EAAM,SAAS,WAASK,IAAAL,EAAM,QAAN,QAAAK,EAAW,WAAUH,GAAU;AACzD,UAAMI,IAAYJ,EAASF,EAAM,IAAI,MAAM;AAC3C,QAAIM,GAAW;AACb,YAAMC,IAAaX,GAAIY,IAAAF,EAAU,YAAV,gBAAAE,EAAmB,IAAI;AAC9C,UAAID,EAAY,QAAOA;AAAA,IACzB;AAAA,EACF;AACA,SAAON;AACT;AAqIO,SAASQ,GAAgBC,GAAgC;AAC9D,QAAMC,IAAWD,EAAK,MAChBE,IAAUF,EAAK,UACjB,EAAE,GAAGA,EAAK,SAAS,MAAMA,EAAK,QAAQ,QAAQC,EAAA,IAC9C,EAAE,MAAMA,EAAA;AACZ,SAAO;AAAA,IACL,MAAMD,EAAK;AAAA,IACX,SAAAE;AAAA,IACA,QAAQF,EAAK;AAAA,IACb,KAAKA,EAAK;AAAA,IACV,WAAWA,EAAK;AAAA,EAAA;AAEpB;AA2DO,SAASG,GAAoBC,GAA0B;;AAC5D,MAAIA,EAAO,eAAeA,EAAO,YAAY,SAAS;AACpD,WAAOA,EAAO;AAEhB,aAAW/B,KAAQ+B,EAAO;AACxB,SAAIV,IAAAU,EAAO,OAAO/B,CAAI,MAAlB,QAAAqB,EAAqB,QAAS,QAAO,CAACrB,CAAI;AAEhD,SAAO,CAAC,IAAI;AACd;AAMO,SAASgC,GAAgBD,GAAgBE,GAA2C;AACzF,QAAMC,IAASJ,GAAoBC,CAAM,GACnCI,IAAmB,CAAA;AACzB,aAAWC,KAAKF;AACd,IAAAC,EAAOC,CAAC,IAAI,OAAOH,EAAOG,CAAC,KAAK,EAAE;AAEpC,SAAOD;AACT;AAKO,SAASE,GAAaC,GAA4B;AACvD,QAAMC,IAAO,OAAO,OAAOD,CAAQ;AACnC,SAAIC,EAAK,WAAW,IAAUA,EAAK,CAAC,IAC7BA,EAAK,KAAK,GAAG;AACtB;ACjQO,SAASC,KAAU;AACxB,QAAM,CAACC,GAAWC,CAAY,IAAIC,EAAS,EAAK,GAC1C,CAACC,GAAmBC,CAAoB,IAAIF,EAAkC,CAAA,CAAE,GAChFG,IAAWC,GAAA,GACX,EAAE,MAAMC,EAAA,IAAWpF,GAAA,GACnBqF,IAAc3D,GAAA,GAEd4D,KAAQF,KAAA,gBAAAA,EAAQ,eAAc,CAAA,GAC9BG,IAAWH,KAAA,gBAAAA,EAAQ,UACnBI,KAAUD,KAAA,gBAAAA,EAAU,aAAY,aAChCE,KAAaF,KAAA,gBAAAA,EAAU,gBAAeC,EAAQ,OAAO,CAAC,GACtDE,KAAcH,KAAA,gBAAAA,EAAU,iBAAgB;AAE9C,WAASI,EAAcC,GAAuC;AAC5D,eAAWC,KAAQD,GAAO;AACxB,UAAIC,EAAK,OAAQ,QAAOA;AACxB,UAAIA,EAAK,OAAO;AACd,cAAMC,IAAQH,EAAcE,EAAK,KAAK;AACtC,YAAIC,EAAO,QAAOA;AAAA,MACpB;AAAA,IACF;AAAA,EAEF;AAEA,WAASC,EAAcjF,GAAa;AAClC,IAAAmE,EAAqB,CAACe,OAAU,EAAE,GAAGA,GAAM,CAAClF,CAAG,GAAG,CAACkF,EAAKlF,CAAG,EAAA,EAAI;AAAA,EACjE;AAEA,WAASmF,EAASC,GAAe;AAC/B,WAAOhB,EAAS,aAAagB,KAAShB,EAAS,SAAS,WAAWgB,IAAQ,GAAG;AAAA,EAChF;AAEA,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWnI;AAAA,QACT;AAAA,QACA6G,IAAY,SAAS;AAAA,MAAA;AAAA,MAIvB,UAAA;AAAA,QAAA,gBAAA/B,EAAC,OAAA,EAAI,WAAU,uEACb,UAAA,gBAAAqD;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAM;AACb,oBAAMC,IAAQT,EAAcL,CAAK,GAC3Be,IAASD,KAAA,QAAAA,EAAO,SAAShB,KAAA,gBAAAA,EAAQ,QAAQgB,EAAM,UAAU;AAC/D,cAAIC,KAAUD,KACZf,EAAYgB,EAAO,OAAO;AAAA,gBACxB,OAAOpD,EAAImD,EAAM,IAAI;AAAA,gBACrB,MAAMA,EAAM;AAAA,cAAA,CACb;AAAA,YAEL;AAAA,YACA,WAAU;AAAA,YAET,UAAA;AAAA,cAAAb,KAAA,QAAAA,EAAU,WACT,gBAAAzC,EAAC,OAAA,EAAI,KAAKyC,EAAS,UAAU,KAAKC,GAAS,WAAU,8BAAA,CAA8B,IAEnF,gBAAA1C,EAAC,SAAI,WAAU,gEAA+D,OAAO,EAAE,iBAAiB4C,EAAA,GACtG,UAAA,gBAAA5C,EAAC,QAAA,EAAK,WAAU,gCAAgC,UAAA2C,EAAA,CAAW,EAAA,CAC7D;AAAA,cAED,CAACZ,KACA,gBAAA/B,EAAC,QAAA,EAAK,WAAU,2CACb,UAAA0C,EAAA,CACH;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA,GAGN;AAAA,QAGA,gBAAA1C,EAAC,OAAA,EAAI,WAAU,8CACZ,UAAAwC,EAAM;AAAA,UAAI,CAACO,GAAM/E,MAChB+E,EAAK;AAAA;AAAA,8BAEF,OAAA,EACE,UAAA;AAAA,cAAA,CAAChB,KACA,gBAAAsB;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,SAAS,MAAMJ,EAAcjF,CAAG;AAAA,kBAChC,WAAU;AAAA,kBAEV,UAAA;AAAA,oBAAA,gBAAAgC,EAAC,QAAA,EAAM,UAAAG,EAAI4C,EAAK,IAAI,GAAE;AAAA,oBACtB,gBAAA/C;AAAA,sBAACwD;AAAA,sBAAA;AAAA,wBACC,WAAWtI;AAAA,0BACT;AAAA,0BACAgH,EAAkBlE,CAAG,KAAK;AAAA,wBAAA;AAAA,sBAC5B;AAAA,oBAAA;AAAA,kBACF;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGH,CAACkE,EAAkBlE,CAAG,KACrB,gBAAAgC,EAAC,OAAA,EAAI,WAAU,eACZ,UAAA+C,EAAK,MAAM,IAAI,CAACU,MAAS;AACxB,oBAAI,CAACA,EAAK,OAAQ,QAAO;AACzB,sBAAMF,IAASjB,KAAA,gBAAAA,EAAQ,QAAQmB,EAAK;AACpC,oBAAI,CAACF,EAAQ,QAAO;AACpB,sBAAMH,IAAQG,EAAO,OACfG,IAASP,EAASC,CAAK;AAE7B,uBACE,gBAAAC;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBAEC,SAAS,MACPd,EAAYa,GAAO;AAAA,sBACjB,OAAOjD,EAAIsD,EAAK,IAAI;AAAA,sBACpB,MAAMA,EAAK;AAAA,oBAAA,CACZ;AAAA,oBAEH,WAAWvI;AAAA,sBACT;AAAA,sBACAwI,IACI,gEACA;AAAA,oBAAA;AAAA,oBAEN,OAAO3B,IAAY5B,EAAIsD,EAAK,IAAI,IAAI;AAAA,oBAEnC,UAAA;AAAA,sBAAAA,EAAK,QAAQ,gBAAAzD,EAACJ,IAAA,EAAY,MAAM6D,EAAK,MAAM,WAAU,oBAAmB;AAAA,sBACxE,CAAC1B,KAAa,gBAAA/B,EAAC,UAAM,UAAAG,EAAIsD,EAAK,IAAI,EAAA,CAAE;AAAA,oBAAA;AAAA,kBAAA;AAAA,kBAhBhCA,EAAK;AAAA,gBAAA;AAAA,cAmBhB,CAAC,EAAA,CACH;AAAA,YAAA,EAAA,GA9CMzF,CAgDV;AAAA,cACE+E,EAAK;AAAA;AAAA,aAEN,MAAM;AACL,oBAAMQ,IAASjB,KAAA,gBAAAA,EAAQ,QAAQS,EAAK;AACpC,kBAAI,CAACQ,EAAQ,QAAO;AACpB,oBAAMH,IAAQG,EAAO,OACfG,IAASP,EAASC,CAAK;AAC7B,qBACE,gBAAAC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,SAAS,MACPd,EAAYa,GAAO;AAAA,oBACjB,OAAOjD,EAAI4C,EAAK,IAAI;AAAA,oBACpB,MAAMA,EAAK;AAAA,kBAAA,CACZ;AAAA,kBAEH,WAAW7H;AAAA,oBACT;AAAA,oBACAwI,IACI,gEACA;AAAA,kBAAA;AAAA,kBAEN,OAAO3B,IAAY5B,EAAI4C,EAAK,IAAI,IAAI;AAAA,kBAEnC,UAAA;AAAA,oBAAAA,EAAK,QAAQ,gBAAA/C,EAACJ,IAAA,EAAY,MAAMmD,EAAK,MAAM,WAAU,oBAAmB;AAAA,oBACxE,CAAChB,KAAa,gBAAA/B,EAAC,UAAM,UAAAG,EAAI4C,EAAK,IAAI,EAAA,CAAE;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAhBhCA,EAAK;AAAA,cAAA;AAAA,YAmBhB,GAAA;AAAA,cACE;AAAA,QAAA,GAER;AAAA,QAGA,gBAAA/C;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAMgC,EAAa,CAACD,CAAS;AAAA,YACtC,WAAU;AAAA,YAET,UAAAA,sBACE4B,IAAA,EAAa,WAAU,WAAU,IAElC,gBAAA3D,EAAC4D,IAAA,EAAY,WAAU,UAAA,CAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MAErC;AAAA,IAAA;AAAA,EAAA;AAGN;ACnKA,eAAsBC,KAA0C;AAC9D,SAAO7G,GAAgC,kBAAkB;AAC3D;AAEA,eAAsB8G,GACpBC,GACAC,GACwB;AACxB,SAAOhH,GAA2B,cAAc,EAAE,OAAA+G,GAAO,UAAAC,GAAU;AACrE;AAEA,eAAsBC,GACpBF,GACAC,GACAE,GACwB;AACxB,SAAOlH,GAA2B,eAAe;AAAA,IAC/C,OAAA+G;AAAA,IACA,UAAAC;AAAA,IACA,cAAcE;AAAA,EAAA,CACf;AACH;AAIA,eAAsBC,KAA2B;AAC/C,SAAOnH,GAAsB,SAAS;AACxC;AAGA,eAAsBoH,KAAiC;AAErD,UADe,MAAMpH,GAAmC,mBAAmB,GAC7D;AAChB;AAEA,eAAsBqH,GAAaC,GAA0C;AAC3E,SAAOtH,GAA2B,sBAAsB;AAAA,IACtD,WAAWsH;AAAA,EAAA,CACZ;AACH;AAMA,eAAsBC,KAAwB;AAC5C,QAAMvH,GAAY,aAAa;AACjC;AAIA,eAAsBwH,GAAiBC,GAA6C;AAKlF,UAJe,MAAMzH;AAAA,IACnB;AAAA,IAC2C,CAAA;AAAA,EAAC,GAEhC;AAChB;AAEO,SAAS0H,GACdC,GACAF,GACAG,GACQ;AACR,QAAMC,IAAS,IAAI,gBAAA;AAEL,EAAAA,EAAO,IAAI,YAAYD,CAAQ;AAC7C,QAAME,IAAKD,EAAO,SAAA;AAClB,SAAO,2BAA2B,mBAAmBF,CAAI,CAAC,GAAGG,IAAK,IAAIA,CAAE,KAAK,EAAE;AACjF;ACnEO,MAAMC,KAAezH,GAAkB,CAACC,OAAS;AAAA,EACtD,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,cAAc;AAAA,EACd,SAAS,CAAA;AAAA,EAET,YAAY,YAAY;AAItB,QAAI;AACF,YAAMyH,IAAO,MAAMb,GAAA,GACbc,IAASD,EAAK,UAAU;AAE9B,UAAIE,IAAoB,CAAA;AACxB,UAAI;AACF,QAAAA,IAAU,MAAMd,GAAA;AAAA,MAClB,QAAQ;AAAA,MAER;AAEA,MAAA7G,EAAI;AAAA,QACF,MAAAyH;AAAA,QACA,iBAAiB;AAAA,QACjB,WAAW;AAAA,QACX,cAAcC;AAAA,QACd,SAAAC;AAAA,MAAA,CACD;AAAA,IACH,QAAQ;AACN,MAAA3H,EAAI,EAAE,MAAM,MAAM,iBAAiB,IAAO,WAAW,IAAO;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,SAAS,CAACyH,GAAgBC,MAAoB;AAC5C,IAAA1H,EAAI;AAAA,MACF,MAAAyH;AAAA,MACA,iBAAiB;AAAA,MACjB,WAAW;AAAA,MACX,cAAcC,KAAU;AAAA,IAAA,CACzB;AAAA,EACH;AAAA,EAEA,YAAY,CAACC,MAAsB;AACjC,IAAA3H,EAAI,EAAE,SAAA2H,GAAS;AAAA,EACjB;AAAA,EAEA,iBAAiB,CAACD,MAAmB;AACnC,IAAA1H,EAAI,EAAE,cAAc0H,GAAQ;AAAA,EAC9B;AAAA,EAEA,QAAQ,YAAY;AAClB,QAAI;AACF,YAAME,GAAA;AAAA,IACR,QAAQ;AAAA,IAER;AACA,IAAA5H,EAAI;AAAA,MACF,MAAM;AAAA,MACN,iBAAiB;AAAA,MACjB,cAAc;AAAA,MACd,SAAS,CAAA;AAAA,IAAC,CACX;AAAA,EACH;AACF,EAAE;AC3EK,SAAS6H,KAAU;AACxB,QAAM;AAAA,IACJ,MAAAJ;AAAA,IACA,iBAAAK;AAAA,IACA,WAAAC;AAAA,IACA,cAAAC;AAAA,IACA,SAAAL;AAAA,IACA,SAAAM;AAAA,IACA,YAAAC;AAAA,IACA,QAAQC;AAAA,EAAA,IACNX,GAAA,GACElG,IAAWC,GAAA,GACX6G,IAAcC,GAAA,GAEdC,IAAgBC,GAAY;AAAA,IAChC,YAAY,CAAC,EAAE,OAAA/B,GAAO,UAAAC,QACpB+B,GAAchC,GAAOC,CAAQ;AAAA,IAC/B,WAAW,CAACgC,MAAW;AACrB,MAAAR,EAAQQ,EAAO,MAAMA,EAAO,MAAM,GAElCC,KAAsB,KAAKR,CAAU,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC,GACrD5G,EAAS,GAAG;AAAA,IACd;AAAA,IACA,SAAS,CAACqH,MAAe;AACvB,MAAAC,GAAM,MAAMD,EAAI,OAAO;AAAA,IACzB;AAAA,EAAA,CACD,GAEKE,IAAiBN,GAAY;AAAA,IACjC,YAAY,CAAC;AAAA,MACX,OAAA/B;AAAA,MACA,UAAAC;AAAA,MACA,aAAAE;AAAA,IAAA,MAKImC,GAAetC,GAAOC,GAAUE,CAAW;AAAA,IACjD,WAAW,CAAC8B,MAAW;AACrB,MAAAR,EAAQQ,EAAO,MAAMA,EAAO,MAAM,GAClCC,KAAsB,KAAKR,CAAU,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC,GACrD5G,EAAS,GAAG;AAAA,IACd;AAAA,IACA,SAAS,CAACqH,MAAe;AACvB,MAAAC,GAAM,MAAMD,EAAI,OAAO;AAAA,IACzB;AAAA,EAAA,CACD,GAEKI,IAAuBR,GAAY;AAAA,IACvC,YAAY,CAACxB,MAAqBiC,GAAqBjC,CAAQ;AAAA,IAC/D,WAAW,CAAC0B,MAAW;AAGrB,MAAAR,EAAQQ,EAAO,MAAMA,EAAO,MAAM,GAElCL,EAAY,kBAAA;AAAA,IACd;AAAA,IACA,SAAS,CAACO,MAAe;AACvB,MAAAC,GAAM,MAAMD,EAAI,OAAO;AAAA,IACzB;AAAA,EAAA,CACD,GAEK3B,IAAS,YAAY;AACzB,UAAMmB,EAAA,GACNC,EAAY,MAAA,GACZ9G,EAAS,QAAQ;AAAA,EACnB;AAEA,SAAO;AAAA,IACL,MAAAmG;AAAA,IACA,iBAAAK;AAAA,IACA,WAAAC;AAAA,IACA,cAAAC;AAAA,IACA,SAAAL;AAAA,IACA,OAAOW,EAAc;AAAA,IACrB,QAAQO,EAAe;AAAA,IACvB,cAAcE,EAAqB;AAAA,IACnC,QAAA/B;AAAA,IACA,gBAAgBsB,EAAc;AAAA,IAC9B,iBAAiBO,EAAe;AAAA,IAChC,mBAAmBE,EAAqB;AAAA,EAAA;AAE5C;ACnFA,MAAME,KAAeC,GAAsB,MACrCC,KAAsBD,GAAsB,SAM5CE,KAAyBC,GAAM,WAKnC,CAAC,EAAE,WAAAC,GAAW,OAAAC,GAAO,UAAAC,GAAU,GAAGlH,KAASmH,MAC3C,gBAAA3D;AAAA,EAACoD,GAAsB;AAAA,EAAtB;AAAA,IACC,KAAAO;AAAA,IACA,WAAW9L;AAAA,MACT;AAAA,MACA4L,KAAS;AAAA,MACTD;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,IAEH,UAAA;AAAA,MAAAkH;AAAA,MACD,gBAAA/G,EAAC2D,IAAA,EAAa,WAAU,UAAA,CAAU;AAAA,IAAA;AAAA,EAAA;AACpC,CACD;AACDgD,GAAuB,cACrBF,GAAsB,WAAW;AAEnC,MAAMQ,KAAyBL,GAAM,WAGnC,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACyG,GAAsB;AAAA,EAAtB;AAAA,IACC,KAAAO;AAAA,IACA,WAAW9L;AAAA,MACT;AAAA,MACA2L;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,EAAA;AACN,CACD;AACDoH,GAAuB,cACrBR,GAAsB,WAAW;AAEnC,MAAMS,KAAsBN,GAAM,WAGhC,CAAC,EAAE,WAAAC,GAAW,YAAAM,IAAa,GAAG,GAAGtH,KAASmH,MAC1C,gBAAAhH,EAACyG,GAAsB,QAAtB,EACC,UAAA,gBAAAzG;AAAA,EAACyG,GAAsB;AAAA,EAAtB;AAAA,IACC,KAAAO;AAAA,IACA,YAAAG;AAAA,IACA,WAAWjM;AAAA,MACT;AAAA,MACA2L;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,EAAA;AACN,EAAA,CACF,CACD;AACDqH,GAAoB,cAAcT,GAAsB,QAAQ;AAEhE,MAAMW,KAAmBR,GAAM,WAK7B,CAAC,EAAE,WAAAC,GAAW,OAAAC,GAAO,GAAGjH,KAASmH,MACjC,gBAAAhH;AAAA,EAACyG,GAAsB;AAAA,EAAtB;AAAA,IACC,KAAAO;AAAA,IACA,WAAW9L;AAAA,MACT;AAAA,MACA4L,KAAS;AAAA,MACTD;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,EAAA;AACN,CACD;AACDuH,GAAiB,cAAcX,GAAsB,KAAK;AAE1D,MAAMY,KAA2BT,GAAM,WAGrC,CAAC,EAAE,WAAAC,GAAW,UAAAE,GAAU,SAAAO,GAAS,GAAGzH,KAASmH,MAC7C,gBAAA3D;AAAA,EAACoD,GAAsB;AAAA,EAAtB;AAAA,IACC,KAAAO;AAAA,IACA,WAAW9L;AAAA,MACT;AAAA,MACA2L;AAAA,IAAA;AAAA,IAEF,SAAAS;AAAA,IACC,GAAGzH;AAAA,IAEJ,UAAA;AAAA,MAAA,gBAAAG,EAAC,QAAA,EAAK,WAAU,gEACd,UAAA,gBAAAA,EAACyG,GAAsB,eAAtB,EACC,UAAA,gBAAAzG,EAACuH,IAAA,EAAM,WAAU,UAAA,CAAU,EAAA,CAC7B,GACF;AAAA,MACCR;AAAA,IAAA;AAAA,EAAA;AACH,CACD;AACDM,GAAyB,cACvBZ,GAAsB,aAAa;AAErC,MAAMe,KAAwBZ,GAAM,WAGlC,CAAC,EAAE,WAAAC,GAAW,UAAAE,GAAU,GAAGlH,KAASmH,MACpC,gBAAA3D;AAAA,EAACoD,GAAsB;AAAA,EAAtB;AAAA,IACC,KAAAO;AAAA,IACA,WAAW9L;AAAA,MACT;AAAA,MACA2L;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,IAEJ,UAAA;AAAA,MAAA,gBAAAG,EAAC,QAAA,EAAK,WAAU,gEACd,UAAA,gBAAAA,EAACyG,GAAsB,eAAtB,EACC,UAAA,gBAAAzG,EAACyH,IAAA,EAAO,WAAU,uBAAA,CAAuB,EAAA,CAC3C,GACF;AAAA,MACCV;AAAA,IAAA;AAAA,EAAA;AACH,CACD;AACDS,GAAsB,cACpBf,GAAsB,UAAU;AAElC,MAAMiB,KAAoBd,GAAM,WAK9B,CAAC,EAAE,WAAAC,GAAW,OAAAC,GAAO,GAAGjH,KAASmH,MACjC,gBAAAhH;AAAA,EAACyG,GAAsB;AAAA,EAAtB;AAAA,IACC,KAAAO;AAAA,IACA,WAAW9L;AAAA,MACT;AAAA,MACA4L,KAAS;AAAA,MACTD;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,EAAA;AACN,CACD;AACD6H,GAAkB,cAAcjB,GAAsB,MAAM;AAE5D,MAAMkB,KAAwBf,GAAM,WAGlC,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACyG,GAAsB;AAAA,EAAtB;AAAA,IACC,KAAAO;AAAA,IACA,WAAW9L,EAAG,qCAAqC2L,CAAS;AAAA,IAC3D,GAAGhH;AAAA,EAAA;AACN,CACD;AACD8H,GAAsB,cACpBlB,GAAsB,UAAU;AC7JlC,MAAMmB,KAAiBC;AAAA,EACrB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SACE;AAAA,QACF,aACE;AAAA,QACF,SACE;AAAA,QACF,WACE;AAAA,QACF,OACE;AAAA,QACF,MAAM;AAAA,MAAA;AAAA,MAER,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IAAA;AAAA,EACR;AAEJ,GAQMC,IAASlB,GAAM;AAAA,EACnB,CAAC,EAAE,WAAAC,GAAW,SAAAkB,GAAS,MAAAC,GAAM,SAAAC,IAAU,IAAO,GAAGpI,EAAA,GAASmH,MAGtD,gBAAAhH;AAAA,IAFWiI,IAAUC,KAAO;AAAA,IAE3B;AAAA,MACC,WAAWhN,EAAG0M,GAAe,EAAE,SAAAG,GAAS,MAAAC,GAAM,WAAAnB,EAAA,CAAW,CAAC;AAAA,MAC1D,KAAAG;AAAA,MACC,GAAGnH;AAAA,IAAA;AAAA,EAAA;AAIZ;AACAiI,EAAO,cAAc;AC3Cd,SAASK,KAAS;;AACvB,QAAMnD,IAAOD,GAAa,CAACjH,MAAMA,EAAE,IAAI,GACjC,EAAE,QAAAyG,GAAQ,cAAAgB,GAAc,SAAAL,GAAS,cAAAb,GAAc,mBAAA+D,EAAA,IACnDhD,GAAA,GAEIiD,IAAWrD,KAAA,QAAAA,EAAM,eACnBA,EAAK,aACF,MAAM,GAAG,EACT,IAAI,CAACsD,MAAMA,EAAE,CAAC,CAAC,EACf,KAAK,EAAE,EACP,cACA,MAAM,GAAG,CAAC,MACb1H,KAAAD,IAAAqE,KAAA,gBAAAA,EAAM,UAAN,gBAAArE,EAAc,OAAd,gBAAAC,EAAkB,kBAAiB,KAEjC2H,IAAYrD,EAAQ,SAAS;AAEnC,SACE,gBAAA7B,EAAC,UAAA,EAAO,WAAU,sGAChB,UAAA;AAAA,IAAA,gBAAArD,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAAuF,uBACEiB,IAAA,EACC,UAAA;AAAA,MAAA,gBAAAxG,EAAC0G,IAAA,EAAoB,SAAO,IAC1B,UAAA,gBAAArD;AAAA,QAACyE;AAAA,QAAA;AAAA,UACC,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU,CAACS,KAAaH;AAAA,UAEvB,UAAA;AAAA,YAAA7C,EAAa;AAAA,YACbgD,KACC,gBAAAvI,EAACwI,IAAA,EAAe,WAAU,yBAAA,CAAyB;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA,GAGzD;AAAA,MACCD,uBACErB,IAAA,EAAoB,OAAM,SACxB,UAAAhC,EAAQ,IAAI,CAACvH,MACZ,gBAAAqC;AAAA,QAACoH;AAAA,QAAA;AAAA,UAEC,SAAS,MAAM/C,EAAa1G,EAAE,EAAE;AAAA,UAChC,WACEA,EAAE,QAAO4H,KAAA,gBAAAA,EAAc,MAAK,gBAAgB;AAAA,UAG7C,UAAA5H,EAAE;AAAA,QAAA;AAAA,QANEA,EAAE;AAAA,MAAA,CAQV,EAAA,CACH;AAAA,IAAA,EAAA,CAEJ,EAAA,CAEJ;AAAA,IACA,gBAAAqC,EAAC,OAAA,EAAI,WAAU,2BACZ,eACC,gBAAAqD,EAAAoF,IAAA,EACE,UAAA;AAAA,MAAA,gBAAAzI,EAAC,QAAA,EAAK,WAAU,2DACb,UAAAgF,EAAK,OACR;AAAA,MACA,gBAAAhF,EAAC,SAAI,WAAU,2EACb,4BAAC,QAAA,EAAK,WAAU,sDACb,UAAAqI,EAAA,CACH,EAAA,CACF;AAAA,MACA,gBAAArI;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAASuE;AAAA,UACT,WAAU;AAAA,UACV,OAAM;AAAA,UAEN,UAAA,gBAAAvE,EAAC0I,IAAA,EAAO,WAAU,UAAA,CAAU;AAAA,QAAA;AAAA,MAAA;AAAA,IAC9B,EAAA,CACF,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ;ACjEA,SAASC,GAAY;AAAA,EACnB,KAAAlL;AAAA,EACA,UAAA0F;AAAA,EACA,QAAAyF;AAAA,EACA,UAAAC;AAAA,EACA,SAAAC;AACF,GAMG;AACD,QAAM;AAAA,IACJ,YAAAC;AAAA,IACA,WAAAC;AAAA,IACA,YAAAC;AAAA,IACA,WAAAC;AAAA,IACA,YAAAC;AAAA,IACA,YAAAC;AAAA,EAAA,IACEC,GAAY,EAAE,IAAI5L,EAAI,IAAI,GAExB6L,IAAQ;AAAA,IACZ,WAAWC,GAAI,UAAU,SAASL,CAAS;AAAA,IAC3C,YAAAC;AAAA,IACA,QAAQC,IAAa,KAAK;AAAA,IAC1B,SAASA,IAAa,MAAM;AAAA,EAAA;AAG9B,SACE,gBAAA/F;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK4F;AAAA,MACL,OAAAK;AAAA,MACC,GAAGP;AAAA,MACH,GAAGC;AAAA,MACJ,SAAS,MAAMH,EAASpL,EAAI,IAAIA,EAAI,UAAUA,EAAI,MAAM;AAAA,MACxD,WAAWvC;AAAA,QACT;AAAA,QACAiI,IACI,+CACA;AAAA,MAAA;AAAA,MAGL,UAAA;AAAA,QAAA1F,EAAI,QACH,gBAAAuC,EAACJ,IAAA,EAAY,MAAMnC,EAAI,MAAM,WAAU,oBAAmB;AAAA,QAE5D,gBAAAuC,EAAC,QAAA,EAAK,WAAU,YAAY,YAAI,OAAM;AAAA,QACrCvC,EAAI,YAAY,CAACmL,KAChB,gBAAA5I;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,eAAe,CAACwJ,MAAMA,EAAE,gBAAA;AAAA,YACxB,SAAS,CAACA,MAAM;AACd,cAAAA,EAAE,gBAAA,GACFV,EAAQU,GAAG/L,EAAI,EAAE;AAAA,YACnB;AAAA,YACA,WAAU;AAAA,YAEV,UAAA,gBAAAuC,EAACyJ,IAAA,EAAE,WAAU,UAAA,CAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACzB;AAAA,IAAA;AAAA,EAAA;AAIR;AAEO,SAASC,KAAS;AACvB,QAAM7K,IAAWC,GAAA,GACX,EAAE,MAAAP,GAAM,aAAAoL,GAAa,WAAA3K,GAAW,UAAA4K,GAAU,aAAAC,EAAA,IAC9CxM,GAAA,GAGIyM,IAAUC;AAAA,IACdC,GAAUC,IAAe,EAAE,sBAAsB,EAAE,UAAU,EAAA,GAAK;AAAA,EAAA,GAG9DC,IAASnK,EAAQ,MAAMxB,EAAK,IAAI,CAACZ,MAAMA,EAAE,EAAE,GAAG,CAACY,CAAI,CAAC,GAEpD4L,IAAejL;AAAA,IACnB,CAACtB,GAAYa,GAAkBE,MAAmB;AAChD,MAAAK,EAAUpB,CAAE,GACZiB,EAAS,EAAE,UAAAJ,GAAU,QAAQE,KAAU,QAAW;AAAA,IACpD;AAAA,IACA,CAACK,GAAWH,CAAQ;AAAA,EAAA,GAGhBuL,IAAclL;AAAA,IAClB,CAACmL,GAAsBzM,MAAe;AACpC,YAAMG,IAAQV,GAAY,SAAA,GACpBW,IAAMD,EAAM,KAAK,UAAU,CAACJ,MAAMA,EAAE,OAAOC,CAAE,GAC7CuF,IAAWpF,EAAM,gBAAgBH;AAIvC,UAFAgM,EAAShM,CAAE,GAEPuF,GAAU;AACZ,cAAMlF,IAAYF,EAAM,KAAK,OAAO,CAACJ,MAAMA,EAAE,OAAOC,CAAE;AACtD,YAAIK,EAAU,SAAS,GAAG;AACxB,gBAAMqM,IAAUtM,IAAMC,EAAU,SAASD,IAAMC,EAAU,SAAS,GAC5DsM,IAAOtM,EAAUqM,CAAO;AAC9B,UAAAzL,EAAS;AAAA,YACP,UAAU0L,EAAK;AAAA,YACf,QAAQA,EAAK,UAAU;AAAA,UAAA,CACxB;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAACX,GAAU/K,CAAQ;AAAA,EAAA,GAGf2L,IAAgBtL;AAAA,IACpB,CAACuL,MAAwB;AACvB,YAAM,EAAE,QAAA/G,GAAQ,MAAAgH,EAAA,IAASD;AACzB,MAAIC,KAAQhH,EAAO,OAAOgH,EAAK,MAC7Bb,EAAY,OAAOnG,EAAO,EAAE,GAAG,OAAOgH,EAAK,EAAE,CAAC;AAAA,IAElD;AAAA,IACA,CAACb,CAAW;AAAA,EAAA;AAGd,MAAItL,EAAK,WAAW,EAAG,QAAO;AAE9B,QAAMqK,IAASrK,EAAK,WAAW;AAE/B,SACE,gBAAAyB,EAAC,OAAA,EAAI,WAAU,sHACb,UAAA,gBAAAA;AAAA,IAAC2K;AAAA,IAAA;AAAA,MACC,SAAAb;AAAA,MACA,oBAAoBc;AAAA,MACpB,WAAWJ;AAAA,MAEX,UAAA,gBAAAxK;AAAA,QAAC6K;AAAA,QAAA;AAAA,UACC,OAAOX;AAAA,UACP,UAAUY;AAAA,UAET,UAAAvM,EAAK,IAAI,CAACd,MACT,gBAAAuC;AAAA,YAAC2I;AAAA,YAAA;AAAA,cAEC,KAAAlL;AAAA,cACA,UAAUA,EAAI,OAAOkM;AAAA,cACrB,QAAAf;AAAA,cACA,UAAUuB;AAAA,cACV,SAASC;AAAA,YAAA;AAAA,YALJ3M,EAAI;AAAA,UAAA,CAOZ;AAAA,QAAA;AAAA,MAAA;AAAA,IACH;AAAA,EAAA,GAEJ;AAEJ;AC9JA,gBAAuBsN,GACrBC,GAC0B;AAC1B,QAAM/O,IAAM,MAAM,MAAM,eAAe,EAAE,aAAa,WAAW,QAAA+O,GAAQ;AAEzE,MAAI,CAAC/O,EAAI,MAAM,CAACA,EAAI;AAClB,UAAM,IAAI,MAAM,0BAA0BA,EAAI,MAAM,EAAE;AAGxD,QAAMgP,IAAShP,EAAI,KAAK,UAAA,GAClBiP,IAAU,IAAI,YAAA;AACpB,MAAIC,IAAS,IACTC,IAAe,IACfC,IAAc;AAElB,MAAI;AACF,eAAa;AACX,YAAM,EAAE,MAAAC,GAAM,OAAAC,EAAA,IAAU,MAAMN,EAAO,KAAA;AACrC,UAAIK,EAAM;AAEV,MAAAH,KAAUD,EAAQ,OAAOK,GAAO,EAAE,QAAQ,IAAM;AAChD,YAAMC,IAAQL,EAAO,MAAM;AAAA,CAAI;AAC/B,MAAAA,IAASK,EAAM,SAAS;AAExB,iBAAWC,KAAQD;AACjB,YAAIC,EAAK,WAAW,SAAS;AAC3B,UAAAL,IAAeK,EAAK,MAAM,CAAC;AAAA,iBAClBA,EAAK,WAAW,QAAQ;AACjC,UAAAJ,IAAcI,EAAK,MAAM,CAAC;AAAA,iBACjBA,MAAS,MAAML,GAAc;AACtC,cAAI;AACF,gBAAIA,MAAiB;AACnB,oBAAM,EAAE,MAAM,kBAAA;AAAA,qBACLA,MAAiB,oBAAoBC,GAAa;AAC3D,oBAAMK,IAAS,KAAK,MAAML,CAAW;AAKrC,oBAAM;AAAA,gBACJ,MAAM;AAAA,gBACN,QAAQK,EAAO;AAAA,gBACf,KAAKA,EAAO;AAAA,gBACZ,QAAQA,EAAO;AAAA,cAAA;AAAA,YAEnB;AAAA,UACF,QAAQ;AAAA,UAER;AACA,UAAAN,IAAe,IACfC,IAAc;AAAA,QAChB;AAAA,IAEJ;AAAA,EACF,UAAA;AACE,IAAAJ,EAAO,YAAA;AAAA,EACT;AACF;AC3DO,MAAMU,KAAsB;AAK5B,SAASC,GACdC,GACAC,GACAC,GACAC,GACAC,GACAC,GACA;AACA,SAAO/O,GAAS;AAAA,IACd,UAAU,CAACwO,IAAqBE,GAAcC,GAAUC,GAAWE,GAAMC,CAAK;AAAA,IAC9E,SAAS,MAAM;AACb,YAAMrH,IAAS,IAAI,gBAAA,GAEbsH,IAAQ,MAAM,QAAQH,CAAU,IAAIA,IAAa,CAACA,CAAU,GAC5DI,IAAQD,EAAM,SAAS,IAAIL,EAAS,MAAM,GAAG,IAAI,CAACA,CAAQ,GAC1DO,IAAUF,EAAM,IAAI,CAACG,GAAIC,OAAO,EAAE,OAAOD,GAAI,IAAI,MAAM,OAAOF,EAAMG,CAAC,IAAI;AAC/E,aAAA1H,EAAO,IAAI,WAAW,KAAK,UAAUwH,CAAO,CAAC,GACzCJ,KAAMpH,EAAO,IAAI,QAAQoH,CAAI,GAC7BC,KAAOrH,EAAO,IAAI,SAAS,OAAOqH,CAAK,CAAC,GACrC3P;AAAA,QACL,aAAawP,CAAS,IAAIlH,EAAO,UAAU;AAAA,MAAA;AAAA,IAE/C;AAAA,IACA,SAAS,CAAC,CAACgH,KAAgB,CAAC,CAACC,KAAY,CAAC,CAACC,KAAa,CAAC,CAACC;AAAA,EAAA,CAC3D;AACH;AC9BA,MAAMQ,KAAsB,KACtBC,KAAa,KAQbC,KAAqB;AAgBpB,SAASC,GACdhH,GACAiH,GACM;AACN,MAAIA,EAAO,WAAW,EAAG;AAEzB,QAAMnM,wBAAe,IAAA;AACrB,aAAWoM,KAAMD,GAAQ;AACvB,UAAM1J,IAAOzC,EAAS,IAAIoM,EAAG,MAAM,GAC7BC,IACJD,EAAG,WAAW,aACdA,EAAG,WAAW,aACdA,EAAG,WAAW;AAChB,IAAApM,EAAS,IAAIoM,EAAG,QAAQ,EAAE,WAAU3J,KAAA,gBAAAA,EAAM,YAAW,OAAU4J,GAAS;AAAA,EAC1E;AAEA,aAAW,CAACzL,GAAQtD,CAAK,KAAK0C;AAC5B,IAAAkF,EAAY,kBAAkB,EAAE,UAAU,CAAC,eAAetE,CAAM,GAAG,GAEnEsE,EAAY,kBAAkB;AAAA,MAC5B,WAAW,CAACoH,MAAU;AACpB,cAAMC,IAAMD,EAAM;AAClB,eAAOC,EAAI,CAAC,MAAMrB,MAAuBqB,EAAI,CAAC,MAAM3L;AAAA,MACtD;AAAA,IAAA,CACD,GAEGtD,EAAM,WACR4H,EAAY,kBAAkB,EAAE,UAAU,CAAC,eAAetE,CAAM,GAAG;AAGzE;AAEO,SAAS4L,KAAS;AACvB,QAAM5H,IAAkBN,GAAa,CAAC,MAAM,EAAE,eAAe,GACvDY,IAAcC,GAAA,GACdsH,IAAWC,GAA+B,IAAI;AAEpD,EAAAC,GAAU,MAAM;AACd,QAAI,CAAC/H,EAAiB;AAEtB,QAAIgI,IAAU,IACVC,IAAU;AAEd,UAAMC,IAAgC,CAAA;AACtC,QAAIC,IAAmD;AAEvD,UAAMC,IAAQ,MAAM;AAElB,UADAD,IAAa,MACTD,EAAQ,WAAW,EAAG;AAC1B,YAAMG,IAAQH,EAAQ,OAAO,GAAGA,EAAQ,MAAM;AAC9C,MAAAZ,GAA2BhH,GAAa+H,CAAK;AAAA,IAC/C,GAEMC,IAAgB,MAAM;AAC1B,MAAIH,MAAe,SACnBA,IAAa,WAAWC,GAAOf,EAAkB;AAAA,IACnD;AAEA,mBAAekB,IAAU;AACvB,aAAOP,KAAS;AACd,cAAMQ,IAAa,IAAI,gBAAA;AACvB,QAAAX,EAAS,UAAUW;AAEnB,YAAI;AACF,2BAAiBpD,KAASM,GAAa8C,EAAW,MAAM,GAAG;AACzD,gBAAI,CAACR,EAAS;AAKd,gBAFAC,IAAU,GAEN7C,EAAM,SAAS,mBAAmB;AAEpC,kBAAI;AACF,sBAAMrO,GAAA;AAAA,cACR,QAAQ;AAAA,cAER;AACA;AAAA,YACF;AAEA,YAAIqO,EAAM,SAAS,qBACjB8C,EAAQ,KAAK,EAAE,QAAQ9C,EAAM,QAAQ,QAAQA,EAAM,QAAQ,GAC3DkD,EAAA;AAAA,UAEJ;AAAA,QACF,SAASzH,GAAK;AAEZ,cADI,CAACmH,KACDnH,aAAe,gBAAgBA,EAAI,SAAS,aAAc;AAAA,QAChE;AAGA,YAAImH,GAAS;AACX,gBAAMS,IAAQ,KAAK,IAAIrB,KAAa,KAAK,IAAI,GAAGa,CAAO,GAAGd,EAAmB,GACvEuB,IAASD,IAAQ,MAAM,KAAK,OAAA;AAClC,gBAAM,IAAI,QAAQ,CAAC3R,MAAM,WAAWA,GAAG2R,IAAQC,CAAM,CAAC,GACtDT;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAAM,EAAA,GAEO,MAAM;;AACX,MAAAP,IAAU,KACV1M,IAAAuM,EAAS,YAAT,QAAAvM,EAAkB,SACd6M,MAAe,SACjB,aAAaA,CAAU,GACvBA,IAAa,OAEXD,EAAQ,SAAS,KACnBZ,GAA2BhH,GAAa4H,EAAQ,OAAO,GAAGA,EAAQ,MAAM,CAAC;AAAA,IAE7E;AAAA,EACF,GAAG,CAAClI,GAAiBM,CAAW,CAAC;AACnC;AC1IO,SAASqI,KAAS;AACvB,QAAM,EAAE,iBAAA3I,GAAiB,WAAAC,EAAA,IAAcP,GAAA,GACjClG,IAAWC,GAAA,GACXsD,IAAWC,GAAA;AAcjB,SAXA4K,GAAA,GAEAG,GAAU,MAAM;AACd,QAAI,CAAC9H,KAAa,CAACD,GAAiB;AAElC,YAAM4I,IAAW7L,EAAS,WAAWA,EAAS,QACxC8L,IAAgBD,KAAYA,MAAa,MAAM,aAAa,mBAAmBA,CAAQ,CAAC,KAAK;AACnG,MAAApP,EAAS,SAASqP,CAAa,IAAI,EAAE,SAAS,IAAM;AAAA,IACtD;AAAA,EACF,GAAG,CAAC5I,GAAWD,GAAiBxG,GAAUuD,EAAS,UAAUA,EAAS,MAAM,CAAC,GAEzEkD,IAEA,gBAAAtF,EAAC,SAAI,WAAU,oEACb,4BAAC,OAAA,EAAI,WAAU,kCAAiC,UAAA,aAAA,CAAU,EAAA,CAC5D,IAICqF,IAKH,gBAAAhC,EAAC,OAAA,EAAI,WAAU,wDACb,UAAA;AAAA,IAAA,gBAAArD,EAAC8B,IAAA,EAAQ;AAAA,IACT,gBAAAuB,EAAC,OAAA,EAAI,WAAU,wCACb,UAAA;AAAA,MAAA,gBAAArD,EAACmI,IAAA,EAAO;AAAA,wBACP,QAAA,EAAK,WAAU,wBACd,UAAA,gBAAAnI,EAACmO,MAAO,GACV;AAAA,wBACCzE,IAAA,CAAA,CAAO;AAAA,IAAA,EAAA,CACV;AAAA,EAAA,GACF,IAbO;AAeX;AC9CA,MAAM0E,KAAQxH,GAAM,WAGlB,CAAC,EAAE,WAAAC,GAAW,MAAAwH,GAAM,GAAGxO,EAAA,GAASmH,MAE9B,gBAAAhH;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,MAAAqO;AAAA,IACA,WAAWnT;AAAA,MACT;AAAA,MACA2L;AAAA,IAAA;AAAA,IAEF,KAAAG;AAAA,IACC,GAAGnH;AAAA,EAAA;AAAA,CAGT;AACDuO,GAAM,cAAc;ACdpB,MAAME,KAAgBzG;AAAA,EACpB;AACF,GAEM0G,KAAQ3H,GAAM,WAIlB,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACwO,GAAe;AAAA,EAAf;AAAA,IACC,KAAAxH;AAAA,IACA,WAAW9L,EAAGoT,GAAA,GAAiBzH,CAAS;AAAA,IACvC,GAAGhH;AAAA,EAAA;AACN,CACD;AACD0O,GAAM,cAAcC,GAAe,KAAK;ACjBxC,MAAMC,KAAO7H,GAAM,WAGjB,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAgH;AAAA,IACA,WAAW9L;AAAA,MACT;AAAA,MACA2L;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,EAAA;AACN,CACD;AACD4O,GAAK,cAAc;AAEnB,MAAMC,KAAa9H,GAAM,WAGvB,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAgH;AAAA,IACA,WAAW9L,EAAG,iCAAiC2L,CAAS;AAAA,IACvD,GAAGhH;AAAA,EAAA;AACN,CACD;AACD6O,GAAW,cAAc;AAEzB,MAAMC,KAAY/H,GAAM,WAGtB,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAgH;AAAA,IACA,WAAW9L,EAAG,6CAA6C2L,CAAS;AAAA,IACnE,GAAGhH;AAAA,EAAA;AACN,CACD;AACD8O,GAAU,cAAc;AAExB,MAAMC,KAAkBhI,GAAM,WAG5B,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAgH;AAAA,IACA,WAAW9L,EAAG,0CAA0C2L,CAAS;AAAA,IAChE,GAAGhH;AAAA,EAAA;AACN,CACD;AACD+O,GAAgB,cAAc;AAE9B,MAAMC,KAAcjI,GAAM,WAGxB,CAAC,EAAE,WAAAC,GAAW,GAAGhH,KAASmH,wBACzB,OAAA,EAAI,KAAAA,GAAU,WAAW9L,EAAG,YAAY2L,CAAS,GAAI,GAAGhH,GAAO,CACjE;AACDgP,GAAY,cAAc;AAE1B,MAAMC,KAAalI,GAAM,WAGvB,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAgH;AAAA,IACA,WAAW9L,EAAG,8BAA8B2L,CAAS;AAAA,IACpD,GAAGhH;AAAA,EAAA;AACN,CACD;AACDiP,GAAW,cAAc;AC5DlB,SAASC,KAAY;AAC1B,QAAMlQ,IAAWC,GAAA,GACX,CAACkQ,CAAY,IAAIC,GAAA,GACjB,EAAE,OAAAnL,GAAO,gBAAAoL,GAAgB,iBAAA7J,EAAA,IAAoBD,GAAA,GAC7C,CAACrB,GAAOoL,CAAQ,IAAIlN,EAAS,EAAE,GAC/B,CAAC+B,GAAUoL,CAAW,IAAInN,EAAS,EAAE,GACrCoN,IAAcL,EAAa,IAAI,UAAU,KAAK,KAC9CM,IAAaD,EAAY,WAAW,GAAG,KAAK,CAACA,EAAY,WAAW,IAAI,IAAIA,IAAc,KAC1FE,IAAWP,EAAa,IAAI,WAAW,GAEvC,EAAE,MAAMQ,EAAA,IAAgBrS,GAAS;AAAA,IACrC,UAAU,CAAC,aAAa;AAAA,IACxB,SAAS0G;AAAA,EAAA,CACV,GAEK,EAAE,MAAM4L,EAAA,IAAiBtS,GAAwB;AAAA,IACrD,UAAU,CAAC,eAAe;AAAA,IAC1B,SAAS,MAAMqH,GAAA;AAAA,IACf,WAAW;AAAA,EAAA,CACZ;AAED,EAAA4I,GAAU,MAAM;AACd,IAAIoC,KAAA,QAAAA,EAAa,eACf3Q,EAAS,WAAW,EAAE,SAAS,GAAA,CAAM;AAAA,EAEzC,GAAG,CAAC2Q,GAAa3Q,CAAQ,CAAC,GAE1BuO,GAAU,MAAM;AACd,IAAI/H,KACFxG,EAASyQ,GAAY,EAAE,SAAS,GAAA,CAAM;AAAA,EAE1C,GAAG,CAACjK,GAAiBxG,GAAUyQ,CAAU,CAAC,GAE1ClC,GAAU,MAAM;AACd,IAAImC,KACFpJ,GAAM,MAAMoJ,CAAQ;AAAA,EAExB,GAAG,CAACA,CAAQ,CAAC;AAEb,WAASG,EAAalG,GAAc;AAClC,IAAAA,EAAE,eAAA,GACF1F,EAAM,EAAE,OAAAC,GAAO,UAAAC,GAAU;AAAA,EAC3B;AAEA,QAAM2L,IAAeF,KAAgBA,EAAa,SAAS;AAE3D,2BACG,OAAA,EAAI,WAAU,6EACb,UAAA,gBAAApM,EAACoL,IAAA,EAAK,WAAU,mBACd,UAAA;AAAA,IAAA,gBAAApL,EAACqL,IAAA,EAAW,WAAU,eACpB,UAAA;AAAA,MAAA,gBAAA1O,EAAC,OAAA,EAAI,WAAU,0FACb,UAAA,gBAAAA,EAAC,UAAK,WAAU,sDAAqD,eAAC,EAAA,CACxE;AAAA,MACA,gBAAAA,EAAC2O,IAAA,EAAU,WAAU,YAAW,UAAA,WAAO;AAAA,MACvC,gBAAA3O,EAAC4O,MAAgB,UAAA,qCAAA,CAAkC;AAAA,IAAA,GACrD;AAAA,sBACCC,IAAA,EACE,UAAA;AAAA,MAAAc,KACC,gBAAAtM,EAAC,OAAA,EAAI,WAAU,kBACZ,UAAA;AAAA,QAAAoM,EAAa,IAAI,CAACG,MACjB,gBAAA5P;AAAA,UAAC8H;AAAA,UAAA;AAAA,YAEC,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAO;AAAA,YAEP,UAAA,gBAAAzE,EAAC,OAAE,MAAMqB,GAAgBkL,EAAS,MAAM,QAAWN,CAAU,GAAG,UAAA;AAAA,cAAA;AAAA,cAChDM,EAAS;AAAA,YAAA,EAAA,CACzB;AAAA,UAAA;AAAA,UAPKA,EAAS;AAAA,QAAA,CASjB;AAAA,QACD,gBAAAvM,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,UAAA,gBAAArD,EAAC,SAAI,WAAU,sCACb,4BAAC,QAAA,EAAK,WAAU,mBAAkB,EAAA,CACpC;AAAA,UACA,gBAAAA,EAAC,SAAI,WAAU,kDACb,4BAAC,QAAA,EAAK,WAAU,wDAAuD,UAAA,yBAAA,CAEvE,EAAA,CACF;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,GACF;AAAA,MAEF,gBAAAqD,EAAC,QAAA,EAAK,UAAUqM,GAAc,WAAU,aACtC,UAAA;AAAA,QAAA,gBAAArM,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,UAAA,gBAAArD,EAACuO,IAAA,EAAM,SAAQ,SAAQ,UAAA,SAAK;AAAA,UAC5B,gBAAAvO;AAAA,YAACoO;AAAA,YAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,aAAY;AAAA,cACZ,OAAOrK;AAAA,cACP,UAAU,CAACyF,MAAM2F,EAAS3F,EAAE,OAAO,KAAK;AAAA,cACxC,UAAQ;AAAA,cACR,WAAS;AAAA,YAAA;AAAA,UAAA;AAAA,QACX,GACF;AAAA,QACA,gBAAAnG,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,UAAA,gBAAArD,EAACuO,IAAA,EAAM,SAAQ,YAAW,UAAA,YAAQ;AAAA,UAClC,gBAAAvO;AAAA,YAACoO;AAAA,YAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,aAAY;AAAA,cACZ,OAAOpK;AAAA,cACP,UAAU,CAACwF,MAAM4F,EAAY5F,EAAE,OAAO,KAAK;AAAA,cAC3C,UAAQ;AAAA,YAAA;AAAA,UAAA;AAAA,QACV,GACF;AAAA,QACA,gBAAAxJ,EAAC8H,GAAA,EAAO,MAAK,UAAS,WAAU,UAAS,UAAUoH,GAChD,UAAAA,IAAiB,kBAAkB,UAAA,CACtC;AAAA,MAAA,GACF;AAAA,MACA,gBAAA7L,EAAC,KAAA,EAAE,WAAU,2DAA0D,UAAA;AAAA,QAAA;AAAA,QACzD;AAAA,0BACXwM,IAAA,EAAK,IAAG,WAAU,WAAU,yCAAwC,UAAA,iBAAA,CAErE;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;AC3HO,SAASC,KAAa;AAC3B,QAAMjR,IAAWC,GAAA,GACX,EAAE,QAAAmF,GAAQ,iBAAA8L,GAAiB,iBAAA1K,EAAA,IAAoBD,GAAA,GAC/C,CAACrB,GAAOoL,CAAQ,IAAIlN,EAAS,EAAE,GAC/B,CAAC+B,GAAUoL,CAAW,IAAInN,EAAS,EAAE,GACrC,CAACiC,GAAa8L,CAAc,IAAI/N,EAAS,EAAE,GAE3C,EAAE,MAAMuN,EAAA,IAAgBrS,GAAS;AAAA,IACrC,UAAU,CAAC,aAAa;AAAA,IACxB,SAAS0G;AAAA,EAAA,CACV;AAED,EAAAuJ,GAAU,MAAM;AACd,IAAIoC,KAAe,CAACA,EAAY,eAC9B3Q,EAAS,UAAU,EAAE,SAAS,GAAA,CAAM;AAAA,EAExC,GAAG,CAAC2Q,GAAa3Q,CAAQ,CAAC,GAE1BuO,GAAU,MAAM;AACd,IAAI/H,KACFxG,EAAS,KAAK,EAAE,SAAS,GAAA,CAAM;AAAA,EAEnC,GAAG,CAACwG,GAAiBxG,CAAQ,CAAC;AAE9B,WAAS6Q,EAAalG,GAAc;AAClC,IAAAA,EAAE,eAAA,GACFvF,EAAO,EAAE,OAAAF,GAAO,UAAAC,GAAU,aAAAE,EAAA,CAAa;AAAA,EACzC;AAEA,2BACG,OAAA,EAAI,WAAU,6EACb,UAAA,gBAAAb,EAACoL,IAAA,EAAK,WAAU,mBACd,UAAA;AAAA,IAAA,gBAAApL,EAACqL,IAAA,EAAW,WAAU,eACpB,UAAA;AAAA,MAAA,gBAAA1O,EAAC,OAAA,EAAI,WAAU,0FACb,UAAA,gBAAAA,EAAC,UAAK,WAAU,sDAAqD,eAAC,EAAA,CACxE;AAAA,MACA,gBAAAA,EAAC2O,IAAA,EAAU,WAAU,YAAW,UAAA,kBAAc;AAAA,MAC9C,gBAAA3O,EAAC4O,MAAgB,UAAA,iCAAA,CAA8B;AAAA,IAAA,GACjD;AAAA,sBACCC,IAAA,EACC,UAAA,gBAAAxL,EAAC,UAAK,UAAUqM,GAAc,WAAU,aACtC,UAAA;AAAA,MAAA,gBAAArM,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,QAAA,gBAAArD,EAACuO,IAAA,EAAM,SAAQ,eAAc,UAAA,QAAI;AAAA,QACjC,gBAAAvO;AAAA,UAACoO;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,aAAY;AAAA,YACZ,OAAOlK;AAAA,YACP,UAAU,CAACsF,MAAMwG,EAAexG,EAAE,OAAO,KAAK;AAAA,YAC9C,UAAQ;AAAA,YACR,WAAS;AAAA,UAAA;AAAA,QAAA;AAAA,MACX,GACF;AAAA,MACA,gBAAAnG,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,QAAA,gBAAArD,EAACuO,IAAA,EAAM,SAAQ,SAAQ,UAAA,SAAK;AAAA,QAC5B,gBAAAvO;AAAA,UAACoO;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,aAAY;AAAA,YACZ,OAAOrK;AAAA,YACP,UAAU,CAACyF,MAAM2F,EAAS3F,EAAE,OAAO,KAAK;AAAA,YACxC,UAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,MACV,GACF;AAAA,MACA,gBAAAnG,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,QAAA,gBAAArD,EAACuO,IAAA,EAAM,SAAQ,YAAW,UAAA,YAAQ;AAAA,QAClC,gBAAAvO;AAAA,UAACoO;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,aAAY;AAAA,YACZ,OAAOpK;AAAA,YACP,UAAU,CAACwF,MAAM4F,EAAY5F,EAAE,OAAO,KAAK;AAAA,YAC3C,UAAQ;AAAA,YACR,WAAW;AAAA,UAAA;AAAA,QAAA;AAAA,MACb,GACF;AAAA,MACA,gBAAAxJ,EAAC8H,GAAA,EAAO,MAAK,UAAS,WAAU,UAAS,UAAUiI,GAChD,UAAAA,IAAkB,gBAAgB,iBAAA,CACrC;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;ACzFO,SAASE,KAAkB;AAChC,QAAMpR,IAAWC,GAAA,GACX,CAACkQ,CAAY,IAAIC,GAAA,GACjB,EAAE,SAAAzJ,GAAS,YAAAC,EAAA,IAAeV,GAAA;AAEhC,SAAAqI,GAAU,MAAM;AAId,UAAMiC,IAAcL,EAAa,IAAI,UAAU,KAAK,KAC9CpK,IACJyK,EAAY,WAAW,GAAG,KAAK,CAACA,EAAY,WAAW,IAAI,IAAIA,IAAc;AAE/E,IAAAlL,GAAA,EACG,KAAK,CAACa,MAAS;AACd,MAAAQ,EAAQR,GAAMA,EAAK,MAAM,GACzBZ,GAAA,EAAc,KAAKqB,CAAU,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC,GAC7C5G,EAAS+F,GAAU,EAAE,SAAS,GAAA,CAAM;AAAA,IACtC,CAAC,EACA,MAAM,MAAM;AACX,MAAA/F,EAAS,0CAA0C,EAAE,SAAS,GAAA,CAAM;AAAA,IACtE,CAAC;AAAA,EACL,GAAG,CAACA,GAAUmQ,GAAcxJ,GAASC,CAAU,CAAC,GAG9C,gBAAAzF,EAAC,SAAI,WAAU,iDACb,4BAAC,KAAA,EAAE,WAAU,kCAAiC,UAAA,wBAAA,CAAqB,EAAA,CACrE;AAEJ;AC/BO,SAASkQ,KAAe;AAC7B,2BACG,OAAA,EAAI,WAAU,2CACb,UAAA,gBAAA7M,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,IAAA,gBAAArD,EAAC,MAAA,EAAG,WAAU,qDAAoD,UAAA,OAAG;AAAA,IACrE,gBAAAA,EAAC,KAAA,EAAE,WAAU,+CAA8C,UAAA,kBAAc;AAAA,IACzE,gBAAAA,EAAC8H,GAAA,EAAO,SAAO,IAAC,SAAQ,WAAU,WAAU,QAC1C,UAAA,gBAAA9H,EAAC6P,IAAA,EAAK,IAAG,KAAI,qBAAO,EAAA,CACtB;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;ACHO,SAASM,GAAW,EAAE,OAAAzR,GAAO,QAAA0R,GAAQ,SAAAC,KAA4B;AACtE,QAAMxR,IAAWC,GAAA,GACX,EAAE,WAAAE,GAAW,mBAAAC,EAAA,IAAsB5B,GAAA;AAEzC,WAASiT,IAAa;AACpB,QAAI,CAACF,EAAQ;AACb,UAAM3S,IAAMwB,EAAkBmR,CAAM;AACpC,IAAI3S,KACFuB,EAAUvB,EAAI,EAAE,GAElBoB,EAASuR,CAAM;AAAA,EACjB;AAEA,SACE,gBAAA/M,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,MAAA+M,KACC,gBAAApQ;AAAA,QAAC8H;AAAA,QAAA;AAAA,UACC,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,SAASwI;AAAA,UAET,UAAA,gBAAAtQ,EAACuQ,IAAA,EAAU,WAAU,UAAA,CAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAGnC,gBAAAvQ,EAAC,MAAA,EAAG,WAAU,0BAA0B,UAAAtB,EAAA,CAAM;AAAA,IAAA,GAChD;AAAA,IACC2R,KAAW,gBAAArQ,EAAC,OAAA,EAAI,WAAU,2BAA2B,UAAAqQ,EAAA,CAAQ;AAAA,EAAA,GAChE;AAEJ;ACvCA,MAAMG,KAAgB3I;AAAA,EACpB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SACE;AAAA,QACF,WACE;AAAA,QACF,aACE;AAAA,QACF,SAAS;AAAA,MAAA;AAAA,IACX;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ;AAQA,SAAS4I,GAAM,EAAE,WAAA5J,GAAW,SAAAkB,GAAS,OAAA2I,GAAO,OAAApH,GAAO,GAAGzJ,KAAqB;AACzE,QAAM8Q,IAAaD,IACf;AAAA,IACE,iBAAiBA,IAAQ;AAAA,IACzB,OAAAA;AAAA,IACA,aAAaA,IAAQ;AAAA,IACrB,GAAGpH;AAAA,EAAA,IAELA;AAEJ,SACE,gBAAAtJ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW9E,EAAGsV,GAAc,EAAE,SAASE,IAAQ,SAAY3I,GAAS,GAAGlB,CAAS;AAAA,MAChF,OAAO8J;AAAA,MACN,GAAG9Q;AAAA,IAAA;AAAA,EAAA;AAGV;ACnCO,SAAS+Q,KAAmB;AACjC,QAAM,EAAE,MAAMtO,EAAA,IAAWpF,GAAA,GACnB,CAAC2T,GAAWC,CAAY,IAAI7O,EAAc,UAAU;AAE1D,SAAKK,IAGH,gBAAAe,EAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,gBAAArD,EAACmQ,IAAA,EAAW,OAAM,2BAAA,CAA2B;AAAA,MAC7C,gBAAA9M,EAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,QAAA,gBAAArD;AAAA,UAAC8H;AAAA,UAAA;AAAA,YACC,SAAS+I,MAAc,aAAa,YAAY;AAAA,YAChD,MAAK;AAAA,YACL,SAAS,MAAMC,EAAa,UAAU;AAAA,YACvC,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGD,gBAAA9Q;AAAA,UAAC8H;AAAA,UAAA;AAAA,YACC,SAAS+I,MAAc,YAAY,YAAY;AAAA,YAC/C,MAAK;AAAA,YACL,SAAS,MAAMC,EAAa,SAAS;AAAA,YACtC,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IACA,gBAAAzN,EAAC,OAAA,EAAI,WAAU,kCACZ,UAAA;AAAA,MAAAwN,MAAc,cAAc,gBAAA7Q,EAAC+Q,IAAA,EAAY,QAAAzO,EAAA,CAAgB;AAAA,MACzDuO,MAAc,aAAa,gBAAA7Q,EAACgR,IAAA,EAAW,QAAA1O,EAAA,CAAgB;AAAA,IAAA,EAAA,CAC1D;AAAA,EAAA,GACF,IA3BkB;AA6BtB;AAEA,SAASyO,GAAY,EAAE,QAAAzO,KAAyE;AAC9F,QAAM2O,IAAclR,EAAQ,MAAM;AAChC,UAAMiG,IAAwE,CAAA;AAG9E,QAAI1D,EAAO;AACT,iBAAW,CAAC7G,GAAMyV,CAAC,KAAK,OAAO,QAAQ5O,EAAO,QAAQ;AACpD,QAAA0D,EAAO,KAAK,EAAE,MAAAvK,GAAM,SAASyV,GAAG;AAKpC,eAAW,CAACC,GAAY9P,CAAM,KAAK,OAAO,QAAQiB,EAAO,QAAQ;AAC/D,UAAIjB,EAAO;AACT,mBAAW,CAAC5F,GAAMyV,CAAC,KAAK,OAAO,QAAQ7P,EAAO,QAAsC;AAClF,UAAA2E,EAAO,KAAK,EAAE,MAAM,GAAGmL,CAAU,IAAI1V,CAAI,IAAI,SAASyV,GAAG,QAAQC,EAAA,CAAY;AAKnF,WAAOnL,EAAO,KAAK,CAACoL,GAAGC,MAAMD,EAAE,KAAK,cAAcC,EAAE,IAAI,CAAC;AAAA,EAC3D,GAAG,CAAC/O,CAAM,CAAC;AAEX,SACE,gBAAAe,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,KAAA,EAAE,WAAU,0CACV,UAAA;AAAA,MAAA4N,EAAY;AAAA,MAAO;AAAA,IAAA,GACtB;AAAA,sBACC,OAAA,EAAI,WAAU,cACZ,UAAAA,EAAY,IAAI,CAAC,EAAE,MAAAxV,GAAM,SAAA6V,GAAS,QAAAjQ,EAAA,wBAChCkQ,IAAA,EAAuB,MAAA9V,GAAY,SAAA6V,GAAkB,QAAAjQ,EAAA,GAApC5F,CAAoD,CACvE,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;AAEA,SAAS8V,GAAY,EAAE,MAAA9V,GAAM,SAAA6V,GAAS,QAAAjQ,KAAkE;;AACtG,QAAM,CAACmQ,GAAUC,CAAW,IAAIxP,EAAS,EAAK,GACxCiC,KAAcvD,IAAA2Q,EAAQ,YAAR,QAAA3Q,EAAiB,OAAOR,EAAImR,EAAQ,QAAQ,IAAI,IAAI7V;AAExE,SACE,gBAAA4H,EAAC,OAAA,EAAI,WAAU,gDACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,oDAAmD,SAAS,MAAMoO,EAAY,CAACD,CAAQ,GACpG,UAAA;AAAA,MAAA,gBAAAnO,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,UAAAzC,IAAA0Q,EAAQ,YAAR,gBAAA1Q,EAAiB,SAAQ,gBAAAZ,EAACJ,IAAA,EAAY,MAAM0R,EAAQ,QAAQ,MAAM,WAAU,yCAAA,CAAyC;AAAA,0BACrH,OAAA,EACC,UAAA;AAAA,UAAA,gBAAAtR,EAAC,QAAA,EAAK,WAAU,iCAAiC,UAAAvE,GAAK;AAAA,UACrDyI,MAAgBzI,KACf,gBAAAuE,EAAC,QAAA,EAAK,WAAU,+CAA+C,UAAAkE,EAAA,CAAY;AAAA,QAAA,EAAA,CAE/E;AAAA,MAAA,GACF;AAAA,MACA,gBAAAb,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,QAAA,gBAAArD,EAACyQ,IAAA,EAAM,SAAQ,WAAW,UAAAa,EAAQ,MAAK;AAAA,QACtCjQ,KAAU,gBAAArB,EAACyQ,IAAA,EAAM,SAAQ,aAAa,UAAApP,GAAO;AAAA,QAC7CiQ,EAAQ,iBAAiB,gBAAAjO,EAACoN,IAAA,EAAM,SAAQ,aAAY,UAAA;AAAA,UAAA;AAAA,UAAQa,EAAQ;AAAA,QAAA,EAAA,CAAc;AAAA,MAAA,EAAA,CACrF;AAAA,IAAA,GACF;AAAA,IACCE,KAAYF,EAAQ,UAAU,OAAO,KAAKA,EAAQ,MAAM,EAAE,SAAS,KAClE,gBAAAjO,EAAC,OAAA,EAAI,WAAU,6CACb,UAAA;AAAA,MAAA,gBAAArD,EAAC,KAAA,EAAE,WAAU,2DAA0D,UAAA,cAAU;AAAA,MACjF,gBAAAA,EAAC,OAAA,EAAI,WAAU,aACX,WAAAsR,EAAQ,eAAe,OAAO,KAAKA,EAAQ,MAAM,GAAG,IAAI,CAACI,MAAc;AACvE,cAAMC,IAAQL,EAAQ,OAAQI,CAAS;AACvC,eAAKC,IACE,gBAAA3R,EAAC4R,IAAA,EAAyB,MAAMF,GAAW,OAAAC,KAA5BD,CAA0C,IAD7C;AAAA,MAErB,CAAC,EAAA,CACH;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;AAEA,SAASE,GAAS,EAAE,MAAAnW,GAAM,OAAAkW,KAAgD;;AACxE,QAAMzN,KAAcvD,IAAAgR,EAAM,YAAN,QAAAhR,EAAe,OAAOR,EAAIwR,EAAM,QAAQ,IAAI,IAAI;AACpE,SACE,gBAAAtO,EAAC,OAAA,EAAI,WAAU,wCACb,UAAA;AAAA,IAAA,gBAAArD,EAAC,QAAA,EAAK,WAAU,mCAAmC,UAAAvE,GAAK;AAAA,IACxD,gBAAAuE,EAACyQ,MAAM,SAAQ,WAAU,WAAU,WAAW,UAAAkB,EAAM,QAAQ,SAAA,CAAS;AAAA,IACpEA,EAAM,YAAY,gBAAA3R,EAACyQ,IAAA,EAAM,SAAQ,eAAc,WAAU,WAAU,UAAA,WAAA,CAAQ;AAAA,IAC3EkB,EAAM,UAAU,gBAAA3R,EAACyQ,IAAA,EAAM,SAAQ,aAAY,WAAU,WAAU,UAAA,SAAA,CAAM;AAAA,IACrEkB,EAAM,WAAW,QAChB,gBAAAtO,EAAC,QAAA,EAAK,WAAU,0CAAyC,UAAA;AAAA,MAAA;AAAA,MAAU,OAAOsO,EAAM,OAAO;AAAA,IAAA,GAAE;AAAA,IAE1FzN,KACC,gBAAAlE,EAAC,QAAA,EAAK,WAAU,0CAA0C,UAAAkE,EAAA,CAAY;AAAA,EAAA,GAE1E;AAEJ;AAEA,SAAS8M,GAAW,EAAE,QAAA1O,KAAyE;AAC7F,QAAMuP,IAAa9R,EAAQ,MAAM;AAC/B,UAAMiG,IAAmE,CAAA;AAGzE,QAAI1D,EAAO;AACT,iBAAW,CAAC7G,GAAMqW,CAAM,KAAK,OAAO,QAAQxP,EAAO,OAAO;AACxD,QAAA0D,EAAO,KAAK,EAAE,MAAAvK,GAAM,QAAAqW,EAAA,CAAQ;AAKhC,eAAW,CAACX,GAAY9P,CAAM,KAAK,OAAO,QAAQiB,EAAO,QAAQ;AAC/D,UAAIjB,EAAO;AACT,mBAAW,CAAC5F,GAAMqW,CAAM,KAAK,OAAO,QAAQzQ,EAAO,OAAO;AACxD,UAAA2E,EAAO,KAAK,EAAE,MAAM,GAAGmL,CAAU,IAAI1V,CAAI,IAAI,QAAAqW,GAAQ,QAAQX,EAAA,CAAY;AAK/E,WAAOnL,EAAO,KAAK,CAACoL,GAAGC,MAAMD,EAAE,KAAK,cAAcC,EAAE,IAAI,CAAC;AAAA,EAC3D,GAAG,CAAC/O,CAAM,CAAC,GAGLyP,IAAUhS,EAAQ,MAAM;AAC5B,UAAMiS,IAA4C,CAAA;AAClD,eAAWvO,KAAQoO,GAAY;AAC7B,YAAM7E,IAAMvJ,EAAK,UAAU;AAC3B,MAAKuO,EAAOhF,CAAG,MAAGgF,EAAOhF,CAAG,IAAI,CAAA,IAChCgF,EAAOhF,CAAG,EAAE,KAAKvJ,CAAI;AAAA,IACvB;AACA,WAAO,OAAO,QAAQuO,CAAM,EAAE,KAAK,CAAC,CAACZ,CAAC,GAAG,CAACC,CAAC,MAAMD,EAAE,cAAcC,CAAC,CAAC;AAAA,EACrE,GAAG,CAACQ,CAAU,CAAC;AAEf,SACE,gBAAAxO,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,KAAA,EAAE,WAAU,0CACV,UAAA;AAAA,MAAAwO,EAAW;AAAA,MAAO;AAAA,IAAA,GACrB;AAAA,IACCE,EAAQ,IAAI,CAAC,CAACE,GAAO5B,CAAO,wBAC1B,OAAA,EACC,UAAA;AAAA,MAAA,gBAAArQ,EAAC,MAAA,EAAG,WAAU,qDAAqD,UAAAiS,GAAM;AAAA,wBACxE,OAAA,EAAI,WAAU,cACZ,UAAA5B,EAAQ,IAAI,CAAC,EAAE,MAAA5U,GAAM,QAAAqW,EAAA,MACpB,gBAAA9R,EAACkS,IAAA,EAAsB,MAAAzW,GAAY,QAAAqW,EAAA,GAAlBrW,CAAkC,CACpD,EAAA,CACH;AAAA,IAAA,EAAA,GANQwW,CAOV,CACD;AAAA,EAAA,GACH;AAEJ;AAEA,SAASC,GAAW,EAAE,MAAAzW,GAAM,QAAAqW,KAA4C;;AACtE,QAAM5N,IAAc/D,GAAIQ,IAAAmR,EAAO,YAAP,gBAAAnR,EAAgB,IAAI;AAC5C,SACE,gBAAA0C,EAAC,OAAA,EAAI,WAAU,kFACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,QAAAzC,IAAAkR,EAAO,YAAP,gBAAAlR,EAAgB,SAAQ,gBAAAZ,EAACJ,IAAA,EAAY,MAAMkS,EAAO,QAAQ,MAAM,WAAU,yCAAA,CAAyC;AAAA,wBACnH,OAAA,EACC,UAAA;AAAA,QAAA,gBAAA9R,EAAC,QAAA,EAAK,WAAU,qBAAqB,UAAAvE,GAAK;AAAA,QACzCyI,KAAeA,MAAgBzI,uBAC7B,QAAA,EAAK,WAAU,+CAA+C,UAAAyI,EAAA,CAAY;AAAA,MAAA,EAAA,CAE/E;AAAA,IAAA,GACF;AAAA,IACA,gBAAAb,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,MAAAyO,EAAO,QAAQ,gBAAA9R,EAACyQ,IAAA,EAAM,SAAQ,WAAW,YAAO,MAAK;AAAA,MACrDqB,EAAO,WACN,gBAAAzO,EAAC,QAAA,EAAK,WAAU,oDAAmD,UAAA;AAAA,QAAA;AAAA,QAAUyO,EAAO;AAAA,MAAA,GAAQ;AAAA,MAE7FA,EAAO,cAAcA,EAAO,WAAW,SAAS,KAC/C,gBAAA9R,EAAC,OAAA,EAAI,WAAU,cACZ,UAAA8R,EAAO,WAAW,IAAI,CAACK,MACtB,gBAAAnS,EAACyQ,IAAA,EAAc,SAAQ,WAAU,WAAU,WAAW,UAAA0B,EAAA,GAA1CA,CAA4C,CACzD,EAAA,CACH;AAAA,IAAA,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ;ACxNA,SAASC,GAAa/Q,GAAgBwD,GAA4B;AAChE,QAAMwN,IAAM,IAAI,IAAI,aAAahR,CAAM,IAAI,OAAO,SAAS,MAAM;AAejE,MAbIwD,EAAO,QAAMwN,EAAI,aAAa,IAAI,QAAQ,OAAOxN,EAAO,IAAI,CAAC,GAC7DA,EAAO,YAAUwN,EAAI,aAAa,IAAI,YAAY,OAAOxN,EAAO,QAAQ,CAAC,GACzEA,EAAO,QAAMwN,EAAI,aAAa,IAAI,QAAQxN,EAAO,IAAI,GACrDA,EAAO,UAAQwN,EAAI,aAAa,IAAI,UAAUxN,EAAO,MAAM,GAE3DA,EAAO,WAAWA,EAAO,QAAQ,SAAS,KAC5CwN,EAAI,aAAa,IAAI,WAAW,KAAK,UAAUxN,EAAO,OAAO,CAAC,GAG5DA,EAAO,mBACTwN,EAAI,aAAa,IAAI,mBAAmB,MAAM,GAG5CxN,EAAO;AACT,eAAW2E,KAAK3E,EAAO;AACrB,MAAAwN,EAAI,aAAa,OAAO,UAAU7I,CAAC;AAIvC,SAAI3E,EAAO,UAAQwN,EAAI,aAAa,IAAI,UAAUxN,EAAO,MAAM,GAExDwN,EAAI,WAAWA,EAAI;AAC5B;AAEA,eAAsBC,GACpBjR,GACAwD,IAAqB,IACE;AACvB,SAAOtI,GAAuB6V,GAAa/Q,GAAQwD,CAAM,CAAC;AAC5D;AAKA,eAAsB0N,GACpBlR,GACAO,GACuB;AACvB,QAAMiD,IAAS,IAAI,gBAAA;AACnB,MAAI,OAAOjD,KAAa;AACtB,IAAAiD,EAAO,IAAI,MAAMjD,CAAQ;AAAA;AAEzB,eAAW,CAACoL,GAAKzB,CAAK,KAAK,OAAO,QAAQ3J,CAAQ;AAChD,MAAAiD,EAAO,IAAImI,GAAKzB,CAAK;AAGzB,SAAOhP,GAAuB,aAAa8E,CAAM,IAAIwD,EAAO,SAAA,CAAU,EAAE;AAC1E;AAEA,eAAsB2N,GACpBnR,GACAoR,GACuB;AAKvB,SAAO,EAAE,OAJO,MAAMlW,GAAoC,aAAa8E,CAAM,IAAI;AAAA,IAC/E,QAAQ;AAAA,IACR,MAAM,KAAK,UAAU,CAACoR,CAAI,CAAC;AAAA,EAAA,CAC5B,GACsB,CAAC,EAAA;AAC1B;AAKA,eAAsBC,GACpBrR,GACAO,GACA6Q,GACuB;AACvB,QAAME,IAAW,OAAO/Q,KAAa,WAAW,EAAE,IAAIA,MAAaA;AAKnE,SAAO,EAAE,OAJO,MAAMrF,GAAoC,aAAa8E,CAAM,IAAI;AAAA,IAC/E,QAAQ;AAAA,IACR,MAAM,KAAK,UAAU,CAAC,EAAE,GAAGsR,GAAU,GAAGF,GAAM,CAAC;AAAA,EAAA,CAChD,GACsB,CAAC,EAAA;AAC1B;AAIA,eAAsBG,GACpBvR,GACAO,GACe;AACf,QAAM6B,IAAO,OAAO7B,KAAa,WAAW,EAAE,IAAIA,MAAaA;AAC/D,QAAMrF,GAAS,aAAa8E,CAAM,WAAW;AAAA,IAC3C,QAAQ;AAAA,IACR,MAAM,KAAK,UAAU,CAACoC,CAAI,CAAC;AAAA,EAAA,CAC5B;AACH;AAIA,eAAsBoP,GACpBxR,GACAO,GACe;AACf,QAAM6B,IAAO,OAAO7B,KAAa,WAAW,EAAE,IAAIA,MAAaA;AAC/D,QAAMrF,GAAS,aAAa8E,CAAM,YAAY;AAAA,IAC5C,QAAQ;AAAA,IACR,MAAM,KAAK,UAAU,CAACoC,CAAI,CAAC;AAAA,EAAA,CAC5B;AACH;AAyBO,SAASqP,GACdjO,GACAkO,GACsB;AACtB,QAAMpW,IAAgC,EAAE,GAAIkI,KAAU,GAAC;AACvD,MAAI,UAAUlI;AACZ,UAAM,IAAI,MAAM,iDAAiD;AAEnE,SAAIoW,MAAQ,WACVpW,EAAK,OAAOoW,IAEPpW;AACT;AAOA,eAAsBqW,GACpBvX,GACAkB,GACgC;AAChC,SAAOJ,GAAgC,gBAAgBd,CAAI,IAAI;AAAA,IAC7D,QAAQ;AAAA,IACR,MAAM,KAAK,UAAUkB,CAAI;AAAA,EAAA,CAC1B;AACH;AAQA,eAAsBsW,GACpBxX,GACAsX,GAC8B;AAC9B,QAAMlO,IAAS,IAAI,gBAAA;AACnB,SAAAA,EAAO,IAAI,OAAOkO,EAAI,KAAK,GAAG,CAAC,GACxBxW,GAA8B,qBAAqBd,CAAI,IAAIoJ,EAAO,SAAA,CAAU,EAAE;AACvF;AC1KO,SAASqO,GAAc7R,GAA4BwD,GAAoB;AAC5E,SAAO1H,GAAS;AAAA,IACd,UAAU,CAAC,eAAekE,GAAQwD,CAAM;AAAA,IACxC,SAAS,MAAMyN,GAAajR,GAASwD,CAAM;AAAA,IAC3C,SAAS,CAAC,CAACxD;AAAA,IACX,iBAAiB,CAAC6B,GAAMiQ,MAAc;;AAIpC,eADoBxS,IAAAwS,KAAA,gBAAAA,EAAW,aAAX,gBAAAxS,EAAoC,QAClCU,IAAS6B,IAAO;AAAA,IACxC;AAAA,EAAA,CACD;AACH;ACRO,SAASkQ,GAAgBjC,GAAoB;AAClD,QAAMxL,IAAcC,GAAA;AAEpB,SAAOE,GAAY;AAAA,IACjB,YAAY,CAAC2M,MACXD,GAAarB,GAAYsB,CAAI;AAAA,IAC/B,WAAW,MAAM;AACf,MAAA9M,EAAY,kBAAkB,EAAE,UAAU,CAAC,eAAewL,CAAU,GAAG,GACvEhL,GAAM,QAAQ,gBAAgB;AAAA,IAChC;AAAA,IACA,SAAS,CAACD,MAAe;AACvB,MAAAC,GAAM,MAAMD,EAAI,OAAO;AAAA,IACzB;AAAA,EAAA,CACD;AACH;AAEO,SAASmN,GAAgBlC,GAAoB;AAClD,QAAMxL,IAAcC,GAAA;AAEpB,SAAOE,GAAY;AAAA,IACjB,YAAY,CAAC,EAAE,UAAAlE,GAAU,MAAA6Q,QACvBC,GAAavB,GAAYvP,GAAU6Q,CAAI;AAAA,IACzC,WAAW,CAACa,GAASC,MAAe;AAKlC,MAAA5N,EAAY,kBAAkB,EAAE,UAAU,CAAC,eAAewL,CAAU,GAAG,GACvExL,EAAY,kBAAkB,EAAE,UAAU,CAAC,eAAewL,CAAU,GAAG,GACvExL,EAAY,kBAAkB,EAAE,UAAU,CAACgG,IAAqBwF,CAAU,GAAG,GAC7ExL,EAAY,kBAAkB,EAAE,UAAU,CAAC,iBAAiBwL,CAAU,GAAG,GACzExL,EAAY,kBAAkB,EAAE,UAAU,CAAC,qBAAqBwL,CAAU,GAAG,GAC7EhL,GAAM,QAAQ,gBAAgB;AAAA,IAChC;AAAA,IACA,SAAS,CAACD,MAAe;AACvB,MAAAC,GAAM,MAAMD,EAAI,OAAO;AAAA,IACzB;AAAA,EAAA,CACD;AACH;AAEO,SAASsN,GAAgBrC,GAAoB;AAClD,QAAMxL,IAAcC,GAAA;AAEpB,SAAOE,GAAY;AAAA,IACjB,YAAY,CAAClE,MAAgCgR,GAAazB,GAAYvP,CAAQ;AAAA,IAC9E,WAAW,CAAC0R,GAASG,MAAc;AACjC,MAAA9N,EAAY,kBAAkB,EAAE,UAAU,CAAC,eAAewL,CAAU,GAAG,GACvExL,EAAY,kBAAkB,EAAE,UAAU,CAAC,eAAewL,CAAU,GAAG,GACvEhL,GAAM,QAAQ,gBAAgB;AAAA,IAChC;AAAA,IACA,SAAS,CAACD,MAAe;AACvB,MAAAC,GAAM,MAAMD,EAAI,OAAO;AAAA,IACzB;AAAA,EAAA,CACD;AACH;AAEO,SAASwN,GAAiBvC,GAAoB;AACnD,QAAMxL,IAAcC,GAAA;AAEpB,SAAOE,GAAY;AAAA,IACjB,YAAY,CAAClE,MAAgCiR,GAAc1B,GAAYvP,CAAQ;AAAA,IAC/E,WAAW,MAAM;AACf,MAAA+D,EAAY,kBAAkB,EAAE,UAAU,CAAC,eAAewL,CAAU,GAAG,GACvExL,EAAY,kBAAkB,EAAE,UAAU,CAAC,eAAewL,CAAU,GAAG,GACvExL,EAAY,kBAAkB,EAAE,UAAU,CAAC,iBAAiBwL,CAAU,GAAG,GACzExL,EAAY,kBAAkB,EAAE,UAAU,CAAC,qBAAqBwL,CAAU,GAAG,GAC7EhL,GAAM,QAAQ,iBAAiB;AAAA,IACjC;AAAA,IACA,SAAS,CAACD,MAAe;AACvB,MAAAC,GAAM,MAAMD,EAAI,OAAO;AAAA,IACzB;AAAA,EAAA,CACD;AACH;AAEO,SAASyN,GAAiBxC,GAAqB;AACpD,QAAMxL,IAAcC,GAAA;AAEpB,SAAOE,GAAY;AAAA,IACjB,YAAY,OAAO,EAAE,YAAA8N,GAAY,MAAAjX,QAA+D;AAC9F,YAAMqJ,IAAS,MAAMgN,GAAcY,GAAYjX,CAAI;AACnD,UAAIqJ,EAAO,WAAW;AACpB,cAAM,IAAI,MAAM,6BAA6B;AAE/C,aAAOA;AAAA,IACT;AAAA,IACA,WAAW,CAACA,MAAW;AACrB,MAAImL,MACFxL,EAAY,kBAAkB,EAAE,UAAU,CAAC,eAAewL,CAAU,GAAG,GACvExL,EAAY,kBAAkB,EAAE,UAAU,CAAC,eAAewL,CAAU,GAAG,GACvExL,EAAY,kBAAkB,EAAE,UAAU,CAACgG,IAAqBwF,CAAU,GAAG,GAC7ExL,EAAY,kBAAkB,EAAE,UAAU,CAAC,iBAAiBwL,CAAU,GAAG,GACzExL,EAAY,kBAAkB,EAAE,UAAU,CAAC,qBAAqBwL,CAAU,GAAG,IAE3EnL,EAAO,WAAW,aACpBG,GAAM,QAAQ,2CAA2C,IAChDH,EAAO,WAAW,YAC3BG,GAAM,QAAQ,gEAAgE,IAE9EA,GAAM,QAAQ,iBAAiB;AAAA,IAEnC;AAAA,IACA,SAAS,CAACD,MAAe;AACvB,MAAAC,GAAM,MAAMD,EAAI,OAAO;AAAA,IACzB;AAAA,EAAA,CACD;AACH;AC/GO,SAAS2N,GAAetI,GAAUuC,GAAkB;AACzD,QAAM,CAACgG,GAAWC,CAAY,IAAI9R,EAASsJ,CAAK;AAEhD,SAAA6B,GAAU,MAAM;AACd,UAAM4G,IAAQ,WAAW,MAAMD,EAAaxI,CAAK,GAAGuC,CAAK;AACzD,WAAO,MAAM,aAAakG,CAAK;AAAA,EACjC,GAAG,CAACzI,GAAOuC,CAAK,CAAC,GAEVgG;AACT;ACIO,SAASG,GAAW,EAAE,OAAA1I,GAAO,OAAA7M,GAAO,WAAAmI,GAAW,MAAAmB,IAAO,UAA2B;AACtF,QAAM,CAACkM,GAAQC,CAAS,IAAIlS,EAAS,EAAK,GAEpCmS,IAAalV,EAAY,OAAOsK,MAAwB;AAC5D,IAAAA,EAAE,gBAAA,GACFA,EAAE,eAAA;AACF,QAAI;AACF,YAAM,UAAU,UAAU,UAAU+B,CAAK,GACzC4I,EAAU,EAAI,GACd,WAAW,MAAMA,EAAU,EAAK,GAAG,GAAI;AAAA,IACzC,QAAQ;AAAA,IAGR;AAAA,EACF,GAAG,CAAC5I,CAAK,CAAC,GAEJ8I,IAAWrM,MAAS,OAAO,YAAY;AAG7C,SACE,gBAAAhI;AAAA,IAAC8H;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,WAAW,GAPKE,MAAS,OAAO,YAAY,SAOnB,aAAanB,KAAa,EAAE;AAAA,MACrD,SAASuN;AAAA,MACT,OAAO1V,KAAS;AAAA,MAEf,UAAAwV,IACC,gBAAAlU,EAACuH,IAAA,EAAM,WAAW,GAAG8M,CAAQ,kBAAA,CAAmB,IAEhD,gBAAArU,EAACsU,IAAA,EAAK,WAAW,GAAGD,CAAQ,kCAAA,CAAmC;AAAA,IAAA;AAAA,EAAA;AAIvE;AC9CO,SAASE,GAAY,EAAE,OAAAhU,GAAO,OAAAgL,GAAO,MAAAiJ,GAAM,UAAAC,KAAgC;AAChF,MAAID,MAAS,WAAW;AACtB,UAAME,IAAO,OAAOnJ,KAAS,EAAE;AAC/B,WAAIhL,EAAM,YAAYmU,IAElB,gBAAArR,EAAC,QAAA,EAAK,WAAU,kCACd,UAAA;AAAA,MAAA,gBAAArD,EAAC,QAAA,EAAK,WAAU,WAAW,UAAA0U,GAAK;AAAA,MAChC,gBAAA1U,EAACiU,IAAA,EAAW,OAAOS,GAAM,MAAK,KAAA,CAAK;AAAA,IAAA,GACrC,IAGG,gBAAA1U,EAAC,QAAA,EAAK,WAAU,WAAW,UAAA0U,GAAK;AAAA,EACzC;AAEA,SACE,gBAAA1U;AAAA,IAACoO;AAAA,IAAA;AAAA,MACC,OAAO,OAAO7C,KAAS,EAAE;AAAA,MACzB,UAAU,CAAC/B,MAAMiL,KAAA,gBAAAA,EAAWjL,EAAE,OAAO;AAAA,IAAK;AAAA,EAAA;AAGhD;ACrBA,MAAMmL,KAAW/N,GAAM,WAGrB,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAExB,gBAAAhH;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAW9E;AAAA,MACT;AAAA,MACA2L;AAAA,IAAA;AAAA,IAEF,KAAAG;AAAA,IACC,GAAGnH;AAAA,EAAA;AAAA,CAGT;AACD8U,GAAS,cAAc;ACZvB,MAAMC,KAAgB,CAACC,EAAY;AAE5B,SAASC,GAAU,EAAE,OAAAvU,GAAO,OAAAgL,GAAO,MAAAiJ,GAAM,UAAAC,KAAgC;;AAC9E,QAAMM,KAASpU,IAAAJ,EAAM,YAAN,gBAAAI,EAAe;AAE9B,MAAI6T,MAAS,WAAW;AACtB,UAAME,IAAO,OAAOnJ,KAAS,EAAE;AAC/B,QAAI,CAACmJ,EAAM,0BAAQ,QAAA,EAAK,WAAU,0CAAyC,UAAA,KAAC;AAE5E,UAAMM,IAAWD,MAAW,aAC1B,gBAAA/U,EAAC,OAAA,EAAI,WAAU,2EAIb,UAAA,gBAAAA,EAACiV,IAAA,EAAS,UAAQ,IAAC,eAAAL,IAA+B,UAAAF,EAAA,CAAK,EAAA,CACzD,IACEK,MAAW,SACb,gBAAA/U,EAAC,OAAA,EAAI,WAAU,0KACZ,UAAA0U,EAAA,CACH,IAEA,gBAAA1U,EAAC,KAAA,EAAE,WAAU,2CAA2C,UAAA0U,GAAK;AAG/D,WAAInU,EAAM,WAEN,gBAAA8C,EAAC,OAAA,EAAI,WAAU,kBACZ,UAAA;AAAA,MAAA2R;AAAA,MACD,gBAAAhV,EAAC,OAAA,EAAI,WAAU,+EACb,UAAA,gBAAAA,EAACiU,MAAW,OAAOS,GAAM,MAAK,KAAA,CAAK,EAAA,CACrC;AAAA,IAAA,GACF,IAIGM;AAAA,EACT;AAEA,QAAME,IAAOH,MAAW,cAAcA,MAAW,SAAS,KAAK;AAC/D,SACE,gBAAA/U;AAAA,IAAC2U;AAAA,IAAA;AAAA,MACC,OAAO,OAAOpJ,KAAS,EAAE;AAAA,MACzB,UAAU,CAAC/B,MAAMiL,KAAA,gBAAAA,EAAWjL,EAAE,OAAO;AAAA,MACrC,MAAA0L;AAAA,MACA,WAAU;AAAA,IAAA;AAAA,EAAA;AAGhB;AChDA,MAAMC,KAASC,GAAgB,MAEzBC,KAAcD,GAAgB,OAE9BE,KAAgB1O,GAAM,WAG1B,CAAC,EAAE,WAAAC,GAAW,UAAAE,GAAU,GAAGlH,KAASmH,MACpC,gBAAA3D;AAAA,EAAC+R,GAAgB;AAAA,EAAhB;AAAA,IACC,KAAApO;AAAA,IACA,WAAW9L;AAAA,MACT;AAAA,MACA2L;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,IAEH,UAAA;AAAA,MAAAkH;AAAA,MACD,gBAAA/G,EAACoV,GAAgB,MAAhB,EAAqB,SAAO,IAC3B,UAAA,gBAAApV,EAACwD,IAAA,EAAY,WAAU,qBAAA,CAAqB,EAAA,CAC9C;AAAA,IAAA;AAAA,EAAA;AACF,CACD;AACD8R,GAAc,cAAcF,GAAgB,QAAQ;AAEpD,MAAMG,KAAuB3O,GAAM,WAGjC,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACoV,GAAgB;AAAA,EAAhB;AAAA,IACC,KAAApO;AAAA,IACA,WAAW9L;AAAA,MACT;AAAA,MACA2L;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,IAEJ,UAAA,gBAAAG,EAACwV,IAAA,EAAU,WAAU,UAAA,CAAU;AAAA,EAAA;AACjC,CACD;AACDD,GAAqB,cAAcH,GAAgB,eAAe;AAElE,MAAMK,KAAyB7O,GAAM,WAGnC,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACoV,GAAgB;AAAA,EAAhB;AAAA,IACC,KAAApO;AAAA,IACA,WAAW9L;AAAA,MACT;AAAA,MACA2L;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,IAEJ,UAAA,gBAAAG,EAACwD,IAAA,EAAY,WAAU,UAAA,CAAU;AAAA,EAAA;AACnC,CACD;AACDiS,GAAuB,cACrBL,GAAgB,iBAAiB;AAEnC,MAAMM,KAAgB9O,GAAM,WAG1B,CAAC,EAAE,WAAAC,GAAW,UAAAE,GAAU,UAAA4O,IAAW,UAAU,GAAG9V,KAASmH,MACzD,gBAAAhH,EAACoV,GAAgB,QAAhB,EACC,UAAA,gBAAA/R;AAAA,EAAC+R,GAAgB;AAAA,EAAhB;AAAA,IACC,KAAApO;AAAA,IACA,WAAW9L;AAAA,MACT;AAAA,MACAya,MAAa,YACX;AAAA,MACF9O;AAAA,IAAA;AAAA,IAEF,UAAA8O;AAAA,IACC,GAAG9V;AAAA,IAEJ,UAAA;AAAA,MAAA,gBAAAG,EAACuV,IAAA,EAAqB;AAAA,MACtB,gBAAAvV;AAAA,QAACoV,GAAgB;AAAA,QAAhB;AAAA,UACC,WAAWla;AAAA,YACT;AAAA,YACAya,MAAa,YACX;AAAA,UAAA;AAAA,UAGH,UAAA5O;AAAA,QAAA;AAAA,MAAA;AAAA,wBAEF0O,IAAA,CAAA,CAAuB;AAAA,IAAA;AAAA,EAAA;AAC1B,EAAA,CACF,CACD;AACDC,GAAc,cAAcN,GAAgB,QAAQ;AAEpD,MAAMQ,KAAahP,GAAM,WAGvB,CAAC,EAAE,WAAAC,GAAW,UAAAE,GAAU,GAAGlH,KAASmH,MACpC,gBAAA3D;AAAA,EAAC+R,GAAgB;AAAA,EAAhB;AAAA,IACC,KAAApO;AAAA,IACA,WAAW9L;AAAA,MACT;AAAA,MACA2L;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,IAEJ,UAAA;AAAA,MAAA,gBAAAG,EAAC,QAAA,EAAK,WAAU,iEACd,UAAA,gBAAAA,EAACoV,GAAgB,eAAhB,EACC,UAAA,gBAAApV,EAACuH,IAAA,EAAM,WAAU,UAAA,CAAU,EAAA,CAC7B,GACF;AAAA,MACA,gBAAAvH,EAACoV,GAAgB,UAAhB,EAA0B,UAAArO,EAAA,CAAS;AAAA,IAAA;AAAA,EAAA;AACtC,CACD;AACD6O,GAAW,cAAcR,GAAgB,KAAK;AAE9C,MAAMS,KAAcjP,GAAM,WAGxB,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACoV,GAAgB;AAAA,EAAhB;AAAA,IACC,KAAApO;AAAA,IACA,WAAW9L,EAAG,qCAAqC2L,CAAS;AAAA,IAC3D,GAAGhH;AAAA,EAAA;AACN,CACD;AACDgW,GAAY,cAAcT,GAAgB,MAAM;AAEhD,MAAMU,KAAkBlP,GAAM,WAG5B,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACoV,GAAgB;AAAA,EAAhB;AAAA,IACC,KAAApO;AAAA,IACA,WAAW9L,EAAG,qCAAqC2L,CAAS;AAAA,IAC3D,GAAGhH;AAAA,EAAA;AACN,CACD;AACDiW,GAAgB,cAAcV,GAAgB,UAAU;AC7HxD,MAAMW,KAAgB;AAEf,SAASC,GAAU,EAAE,OAAAzV,GAAO,OAAAgL,GAAO,MAAAiJ,GAAM,UAAAC,KAAgC;AAC9E,QAAMhT,IAASlB,EAAM,UAAU,CAAA,GACzB0V,IAAUxU,EAAO,KAAK,CAAC0Q,MAAMA,EAAE,SAAS5G,CAAK;AAEnD,MAAIiJ,MAAS;AACX,WAAKyB,IAGE,gBAAAjW,EAACyQ,MAAM,OAAOwF,EAAQ,OAAQ,UAAA9V,EAAI8V,EAAQ,IAAI,EAAA,CAAE,IAF9C,gBAAAjW,EAAC,QAAA,EAAK,WAAU,0CAAyC,UAAA,KAAC;AASrE,QAAMkW,IAAkB,CAAC3V,EAAM,UACzB4V,IAAe5K,KAAS,QAAQA,MAAU,KAAK,OAAOA,CAAK,IAAIwK;AAErE,SACE,gBAAA1S;AAAA,IAAC8R;AAAA,IAAA;AAAA,MACC,OAAOgB;AAAA,MACP,eAAe,CAAChE,MAAMsC,KAAA,gBAAAA,EAAWtC,MAAM4D,KAAgB,OAAO5D;AAAA,MAE9D,UAAA;AAAA,QAAA,gBAAAnS,EAACsV,IAAA,EACC,UAAA,gBAAAtV,EAACqV,IAAA,EAAY,aAAY,aAAY,GACvC;AAAA,0BACCK,IAAA,EACE,UAAA;AAAA,UAAAQ,KACC,gBAAAlW,EAAC4V,MAAW,OAAOG,IACjB,4BAAC,QAAA,EAAK,WAAU,kCAAiC,UAAA,WAAA,CAAQ,EAAA,CAC3D;AAAA,UAEDtU,EAAO,IAAI,CAAC0Q,wBACVyD,IAAA,EAAwB,OAAOzD,EAAE,MAC/B,YAAIA,EAAE,IAAI,EAAA,GADIA,EAAE,IAEnB,CACD;AAAA,QAAA,EAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;ACtDO,SAASiE,GAAW,EAAE,OAAA7K,GAAO,MAAAiJ,GAAM,UAAAC,KAAgC;AACxE,QAAM4B,IAAM,OAAO9K,KAAS,EAAE;AAE9B,SAAIiJ,MAAS,YACN6B,IAEH,gBAAArW;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAM,UAAUqW,CAAG;AAAA,MACnB,WAAU;AAAA,MAET,UAAAA;AAAA,IAAA;AAAA,EAAA,sBANa,QAAA,EAAK,WAAU,0CAAyC,UAAA,KAAC,IAY3E,gBAAArW;AAAA,IAACoO;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAOiI;AAAA,MACP,UAAU,CAAC7M,MAAMiL,KAAA,gBAAAA,EAAWjL,EAAE,OAAO;AAAA,IAAK;AAAA,EAAA;AAGhD;ACpBA,MAAM8M,KAAe,sCACfC,KAAiB,oCAEjBC,KAAW;AAKjB,SAASC,GAAaC,GAAwB;AAC5C,SAAO,gBAAgB,KAAKA,CAAK,KAAKF,GAAS,KAAKE,CAAK;AAC3D;AAEA,SAASC,GAAkBC,GAA4B;AACrD,MAAI,CAACA,EAAU,SAAS,GAAG,EAAG,QAAO;AACrC,QAAMC,IAASD,EAAU,MAAM,GAAG;AAClC,MAAIC,EAAO,SAAS,EAAG,QAAO;AAC9B,QAAMvT,IAAQuT,EAAO,CAAC,EAAE,YAAA;AAExB,SAAI,0BAA0B,KAAKvT,CAAK,IAAU,KAK9C,iBAAiB,KAAKA,CAAK,IACtBmT,GAAaI,EAAOA,EAAO,SAAS,CAAC,CAAC,IAExC;AACT;AAEA,SAASC,GAAaC,GAA4B;AAEhD,MAAIR,GAAe,KAAKQ,CAAG,EAAG,QAAOA;AAErC,QAAMC,IAAcD,EAAI,MAAM,wBAAwB;AACtD,MAAIC,GAAa;AACf,UAAMC,IAASD,EAAY,CAAC,GACtBE,IAAaH,EAAI,MAAMC,EAAY,CAAC,EAAE,MAAM;AASlD,QAAI,gBAAgB,KAAKE,CAAU,KAAKP,GAAkBM,CAAM,GAAG;AACjE,YAAME,IAAO,SAASD,GAAY,EAAE;AACpC,UAAIC,KAAQ,KAAKA,KAAQ;AACvB,eAAO,WAAWJ,CAAG;AAAA,IAEzB;AAEA,WAAIE,EAAO,YAAA,MAAkB,cACpB,WAAWF,CAAG,KAGhB;AAAA,EACT;AAEA,SAAO,WAAWA,CAAG;AACvB;AAEA,SAASK,GAAYC,GAA6B;AAChD,MAAI;AAEF,WADiB,IAAI,IAAIA,CAAI,EAAE,SAAS,QAAQ,WAAW,EAAE,KAC1C;AAAA,EACrB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,GAAWD,GAAuB;AACzC,MAAI;AACF,eAAI,IAAIA,CAAI,GACL;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAASE,GAAS,EAAE,OAAAhX,GAAO,OAAAgL,GAAO,MAAAiJ,GAAM,UAAAC,KAAgC;;AAC7E,QAAM4B,IAAM,OAAO9K,KAAS,EAAE,GACxB,CAACiM,GAAaC,CAAc,IAAIxV,EAAwB,IAAI;AAElE,MAAIuS,MAAS,WAAW;AACtB,QAAI,CAAC6B,EAAK,0BAAQ,QAAA,EAAK,WAAU,0CAAyC,UAAA,KAAC;AAG3E,UAAMqB,MADS/W,IAAAJ,EAAM,YAAN,gBAAAI,EAAe,YACJ,QACpB0W,IAAOP,GAAaT,CAAG;AAG7B,QAAIgB,KAAQ,QAAQ,CAACC,GAAWD,CAAI;AAClC,aAAO,gBAAArX,EAAC,QAAA,EAAK,WAAU,WAAW,UAAAqW,GAAI;AAGxC,UAAMsB,IAASP,GAAYC,CAAI,GAKzBO,IAAc,CAACF,KAAUC,KAAU,QAAQH,MAAgBG,GAC3DE,IAAWH,IAASrB,IAAOsB,KAAUtB;AAE3C,WACE,gBAAAhT;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAAgU;AAAA,QACA,QAAO;AAAA,QACP,KAAI;AAAA,QACJ,OAAOhB;AAAA,QACP,WAAU;AAAA,QAET,UAAA;AAAA,UAAAuB,KACC,gBAAA5X;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAK,GAAGsW,EAAY,WAAW,mBAAmBqB,CAAM,CAAC;AAAA,cACzD,KAAI;AAAA,cACJ,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,SAAQ;AAAA,cACR,WAAU;AAAA,cACV,SAAS,MAAMF,EAAeE,CAAM;AAAA,YAAA;AAAA,UAAA;AAAA,UAGvCE;AAAA,UACD,gBAAA7X,EAAC8X,IAAA,EAAa,WAAU,mBAAA,CAAmB;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGjD;AAEA,SACE,gBAAA9X;AAAA,IAACoO;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAOiI;AAAA,MACP,UAAU,CAAC7M,MAAMiL,KAAA,gBAAAA,EAAWjL,EAAE,OAAO;AAAA,MACrC,aAAY;AAAA,IAAA;AAAA,EAAA;AAGlB;ACjIA,SAASuO,GAAgBhB,GAAaiB,GAA6B;AACjE,MAAIA,GAAY;AAEd,UAAMC,IAAI,oBAAI,KAAKlB,IAAM,WAAW;AACpC,WAAI,MAAMkB,EAAE,QAAA,CAAS,IAAUlB,IACxB,IAAI,KAAK,eAAe,QAAW;AAAA,MACxC,MAAM;AAAA,MACN,OAAO;AAAA,MACP,KAAK;AAAA,IAAA,CACN,EAAE,OAAOkB,CAAC;AAAA,EACb;AAIA,QAAMC,IAAcnB,EAAI,MAAM,oBAAoB,GAC5CoB,IAAQpB,EAAI,SAAS,GAAG;AAE9B,MAAImB,KAAeC,GAAO;AACxB,UAAMC,IAAO,IAAI,KAAKrB,CAAG;AACzB,QAAI,MAAMqB,EAAK,QAAA,CAAS,EAAG,QAAOrB;AAMlC,QAAIsB;AACJ,QAAIF;AACF,MAAAE,IAAK;AAAA,aACIH,GAAa;AACtB,YAAMI,IAAOJ,EAAY,CAAC,EAAE,OAAO,CAAC,GAC9BK,IAAQ,SAASL,EAAY,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE;AAEzD,MADgB,SAASA,EAAY,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE,MAC3C,MAEdG,IAAKE,MAAU,IAAI,QAAQ,UAAUD,MAAS,MAAM,MAAM,GAAG,GAAGC,CAAK;AAAA,IAIzE;AAEA,QAAIF;AACF,UAAI;AACF,eAAO,IAAI,KAAK,eAAe,QAAW;AAAA,UACxC,MAAM;AAAA,UACN,OAAO;AAAA,UACP,KAAK;AAAA,UACL,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,UAAUA;AAAA,QAAA,CACX,EAAE,OAAOD,CAAI;AAAA,MAChB,QAAQ;AAAA,MAER;AAKF,QAAIF,GAAa;AACf,YAAMI,IAAOJ,EAAY,CAAC,EAAE,OAAO,CAAC,MAAM,MAAM,IAAI,IAC9CK,IAAQ,SAASL,EAAY,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE,GACnDM,IAAU,SAASN,EAAY,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE,GACrDO,IAAWH,KAAQC,IAAQ,KAAKC,KAAW,KAAK,KAChDE,IAAUN,EAAK,QAAA,IAAYK,GAC3BE,IAAY,IAAI,KAAKD,CAAO;AAElC,aAAO,IAAI,KAAK,eAAe,QAAW;AAAA,QACxC,MAAM;AAAA,QACN,OAAO;AAAA,QACP,KAAK;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,UAAU;AAAA,MAAA,CACX,EAAE,OAAOC,CAAS;AAAA,IACrB;AAAA,EACF;AAGA,QAAMP,IAAO,IAAI,KAAKrB,CAAG;AACzB,SAAI,MAAMqB,EAAK,QAAA,CAAS,IAAUrB,IAC3B,IAAI,KAAK,eAAe,QAAW;AAAA,IACxC,MAAM;AAAA,IACN,OAAO;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,EAAA,CACT,EAAE,OAAOqB,CAAI;AAChB;AAMA,SAASQ,GAAgB7B,GAA4B;AACnD,MAAIA,EAAI,SAAS,GAAG,EAAG,QAAO;AAC9B,QAAM8B,IAAI9B,EAAI,MAAM,oBAAoB;AACxC,MAAI,CAAC8B,EAAG,QAAO;AACf,QAAMP,IAAOO,EAAE,CAAC,EAAE,OAAO,CAAC,GACpBN,IAAQ,SAASM,EAAE,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE,GACzCL,IAAU,SAASK,EAAE,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE;AACjD,MAAIN,MAAU,KAAKC,MAAY,EAAG,QAAO;AACzC,QAAMM,IAAUN,IAAU,IAAI,IAAI,OAAOA,CAAO,EAAE,SAAS,GAAG,GAAG,CAAC,KAAK;AACvE,SAAO,MAAMF,CAAI,GAAGC,CAAK,GAAGO,CAAO;AACrC;AAOA,SAASC,GAAahC,GAAaiB,GAA6B;AAC9D,QAAME,IAAcnB,EAAI,MAAM,oBAAoB,GAC5CoB,IAAQpB,EAAI,SAAS,GAAG;AAE9B,MAAImB,KAAeC,GAAO;AACxB,UAAMC,IAAO,IAAI,KAAKrB,CAAG;AACzB,QAAI,MAAMqB,EAAK,QAAA,CAAS,EAAG,QAAO;AAElC,QAAID,GAAO;AAET,YAAMa,IAAIZ,EAAK,eAAA,GACTa,IAAK,OAAOb,EAAK,YAAA,IAAgB,CAAC,EAAE,SAAS,GAAG,GAAG,GACnDH,IAAI,OAAOG,EAAK,WAAA,CAAY,EAAE,SAAS,GAAG,GAAG;AACnD,UAAIJ,EAAY,QAAO,GAAGgB,CAAC,IAAIC,CAAE,IAAIhB,CAAC;AACtC,YAAM/G,IAAI,OAAOkH,EAAK,YAAA,CAAa,EAAE,SAAS,GAAG,GAAG,GAC9Cc,IAAK,OAAOd,EAAK,cAAA,CAAe,EAAE,SAAS,GAAG,GAAG;AACvD,aAAO,GAAGY,CAAC,IAAIC,CAAE,IAAIhB,CAAC,IAAI/G,CAAC,IAAIgI,CAAE;AAAA,IACnC;AAGA,UAAMZ,IAAOJ,EAAa,CAAC,EAAE,OAAO,CAAC,MAAM,MAAM,IAAI,IAC/CK,IAAQ,SAASL,EAAa,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE,GACpDM,IAAU,SAASN,EAAa,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE,GACtDO,IAAWH,KAAQC,IAAQ,KAAKC,KAAW,KAAK,KAChDE,IAAUN,EAAK,QAAA,IAAYK,GAC3BE,IAAY,IAAI,KAAKD,CAAO,GAC5BM,IAAIL,EAAU,eAAA,GACdM,IAAK,OAAON,EAAU,YAAA,IAAgB,CAAC,EAAE,SAAS,GAAG,GAAG,GACxDV,IAAI,OAAOU,EAAU,WAAA,CAAY,EAAE,SAAS,GAAG,GAAG;AACxD,QAAIX,EAAY,QAAO,GAAGgB,CAAC,IAAIC,CAAE,IAAIhB,CAAC;AACtC,UAAM/G,IAAI,OAAOyH,EAAU,YAAA,CAAa,EAAE,SAAS,GAAG,GAAG,GACnDO,IAAK,OAAOP,EAAU,cAAA,CAAe,EAAE,SAAS,GAAG,GAAG;AAC5D,WAAO,GAAGK,CAAC,IAAIC,CAAE,IAAIhB,CAAC,IAAI/G,CAAC,IAAIgI,CAAE;AAAA,EACnC;AAIA,SAAIlB,IAAmBjB,EAAI,MAAM,GAAG,EAAE,IAE/BA,EAAI,MAAM,GAAG,EAAE;AACxB;AAEO,SAASoC,GAAe,EAAE,OAAA5Y,GAAO,OAAAgL,GAAO,MAAAiJ,GAAM,UAAAC,KAAgC;AACnF,QAAMuD,IAAazX,EAAM,SAAS,QAC5B6Y,IAAQ,CAAC,CAAC7Y,EAAM;AAEtB,MAAIiU,MAAS,WAAW;AACtB,QAAI,CAACjJ,EAAO,0BAAQ,QAAA,EAAK,WAAU,0CAAyC,UAAA,KAAC;AAC7E,UAAMwL,IAAM,OAAOxL,CAAK,GAClB8N,IAAYtB,GAAgBhB,GAAKiB,CAAU,GAE3CsB,IAAWF,KAAS,CAACpB,IAAaY,GAAgB7B,CAAG,IAAI;AAC/D,WACE,gBAAA1T,EAAC,QAAA,EAAK,WAAU,WACb,UAAA;AAAA,MAAAgW;AAAA,MACAC,KAAY,gBAAAtZ,EAAC,QAAA,EAAK,WAAU,uCAAuC,UAAAsZ,EAAA,CAAS;AAAA,IAAA,GAC/E;AAAA,EAEJ;AAKA,MAAIC,IAAa;AACjB,SAAIhO,MACFgO,IAAaR,GAAa,OAAOxN,CAAK,GAAGyM,CAAU,IAInD,gBAAAhY;AAAA,IAACoO;AAAA,IAAA;AAAA,MACC,MAAM4J,IAAa,SAAS;AAAA,MAC5B,OAAOuB;AAAA,MACP,UAAU,CAAC/P,MAAM;AACf,YAAI,CAACA,EAAE,OAAO,OAAO;AACnB,UAAAiL,KAAA,QAAAA,EAAW;AACX;AAAA,QACF;AAGA,QAAAA,KAAA,QAAAA,EAAWjL,EAAE,OAAO;AAAA,MACtB;AAAA,IAAA;AAAA,EAAA;AAGN;AC3MO,SAASgQ,GAAU,EAAE,OAAAjO,GAAO,MAAAiJ,GAAM,UAAAC,KAAgC;AACvE,QAAMnN,IAAU,EAAQiE;AAExB,SAAIiJ,MAAS,YAET,gBAAAnR,EAAC,QAAA,EAAK,WAAU,4CACd,UAAA;AAAA,IAAA,gBAAArD;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW,qCACTsH,IAAU,wBAAwB,8BACpC;AAAA,MAAA;AAAA,IAAA;AAAA,IAEDA,IAAU,QAAQ;AAAA,EAAA,GACrB,IAKF,gBAAAjE,EAAC,SAAA,EAAM,WAAU,0CACf,UAAA;AAAA,IAAA,gBAAArD;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAAsH;AAAA,QACA,UAAU,CAACkC,MAAMiL,KAAA,gBAAAA,EAAWjL,EAAE,OAAO;AAAA,QACrC,WAAU;AAAA,MAAA;AAAA,IAAA;AAAA,sBAEX,QAAA,EAAK,WAAU,WAAW,UAAAlC,IAAU,QAAQ,KAAA,CAAK;AAAA,EAAA,GACpD;AAEJ;ACtBA,SAASmS,GAAoBlO,GAAuB;AAClD,QAAMmO,IAAUnO,EAAM,KAAA;AACtB,MAAImO,MAAY,MAAMA,MAAY,IAAK,QAAOA;AAE9C,QAAMC,IAAWD,EAAQ,WAAW,GAAG,GACjCE,IAAMD,IAAWD,EAAQ,MAAM,CAAC,IAAIA,GACpC,CAACG,GAASC,CAAQ,IAAIF,EAAI,MAAM,GAAG;AAEzC,MAAIG;AACJ,MAAI;AACF,IAAAA,IAAe,IAAI,KAAK,aAAA,EAAe,OAAO,OAAOF,KAAW,GAAG,CAAC;AAAA,EACtE,QAAQ;AACN,WAAOtO;AAAA,EACT;AAEA,MAAIvF,IAAS2T,IAAW,IAAII,CAAY,KAAKA;AAC7C,SAAID,MAAa,WACf9T,KAAU,IAAI8T,CAAQ,KAEjB9T;AACT;AAEA,MAAMgU,KAAe,IAAI,KAAK,aAAA;AAEvB,SAASC,GAAY,EAAE,OAAA1Z,GAAO,WAAAC,GAAW,OAAA+K,GAAO,MAAAiJ,GAAM,UAAAC,GAAU,QAAAlT,KAA8B;;AACnG,QAAM2Y,MAAUvZ,IAAAJ,EAAM,YAAN,gBAAAI,EAAe,YAAW,SACpCwZ,IAAY5Z,EAAM,SAAS,aAAa2Z,GAGxCE,IAAQ7Y,KAAA,gBAAAA,EAAS,QACjB8Y,IAAaD,KAAA,gBAAAA,EAAQ5Z,IAGrB8Z,IAAa,CAACD,KAAc9Z,EAAM,OACnCA,EAAM,KAAK,WAAWA,EAAM,KAAK,UAClC,QAEEga,IAAcF,MACdC,KAAc,CAACA,EAAW,WAAW,GAAG,IAAIA,IAAa;AAE/D,MAAI9F,MAAS,WAAW;AACtB,QAAIjJ,KAAS,KAAM,0BAAQ,QAAA,EAAK,WAAU,0CAAyC,UAAA,KAAC;AAEpF,QAAI8N;AACJ,QAAIc,KAAa,OAAO5O,KAAU;AAChC,MAAA8N,IAAYI,GAAoBlO,CAAK;AAAA,SAChC;AACL,YAAMiP,IAAM,OAAOjP,CAAK;AACxB,MAAA8N,IAAY,MAAMmB,CAAG,IAAI,OAAOR,GAAa,OAAOQ,CAAG;AAAA,IACzD;AAEA,WAAInB,KAAa,yBAAc,QAAA,EAAK,WAAU,WAAU,UAAA,KAAC,IAGvD,gBAAAhW,EAAC,QAAA,EAAK,WAAU,wBACb,UAAA;AAAA,MAAAgW;AAAA,MACAkB,KAAe,gBAAAva,EAAC,QAAA,EAAK,WAAU,uCAAuC,UAAAua,EAAA,CAAY;AAAA,IAAA,GACrF;AAAA,EAEJ;AAGA,SAAIJ,IAEA,gBAAAna;AAAA,IAACoO;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MACV,SAAQ;AAAA,MACR,OAAO7C,KAAS,OAAO,OAAOA,CAAK,IAAI;AAAA,MACvC,UAAU,CAAC/B,MAAM;AACf,cAAM2I,IAAI3I,EAAE,OAAO;AACnB,QAAI2I,MAAM,KACRsC,KAAA,QAAAA,EAAW,QAGXA,KAAA,QAAAA,EAAWtC;AAAA,MAEf;AAAA,IAAA;AAAA,EAAA,IAOJ,gBAAAnS;AAAA,IAACoO;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,MAAM7N,EAAM,SAAS,UAAU,SAAS;AAAA,MACxC,OAAOgL,KAAS,OAAO,OAAOA,CAAK,IAAI;AAAA,MACvC,UAAU,CAAC/B,MAAM;AACf,cAAM2I,IAAI3I,EAAE,OAAO;AACnB,QAAI2I,MAAM,KACRsC,KAAA,QAAAA,EAAW,QAEXA,KAAA,QAAAA,EAAWlU,EAAM,SAAS,QAAQ,SAAS4R,GAAG,EAAE,IAAI,WAAWA,CAAC;AAAA,MAEpE;AAAA,IAAA;AAAA,EAAA;AAGN;ACtGO,SAASsI,GAAUtJ,GAAoD;AAC5E,QAAM,EAAE,MAAM7O,EAAA,IAAWpF,GAAA;AACzB,MAAI,GAACoF,KAAU,CAAC6O;AAChB,WAAO7O,EAAO,SAAS6O,CAAU;AACnC;ACDA,SAASuJ,GAAeC,GAAsB;AAC5C,MAAIA,KAAO,KAAM,QAAO;AACxB,MAAI,OAAOA,KAAQ,YAAY,CAAC,MAAM,QAAQA,CAAG,GAAG;AAClD,UAAMrX,IAAQ,OAAO,OAAOqX,CAAG,EAAE,CAAC;AAClC,WAAOrX,KAAS,OAAO,OAAOA,CAAK,IAAI;AAAA,EACzC;AACA,SAAO,OAAOqX,CAAG;AACnB;AAEO,SAASC,GAAS;AAAA,EACvB,OAAAra;AAAA,EACA,OAAAgL;AAAA,EACA,MAAAiJ;AAAA,EACA,UAAAC;AAAA,EACA,MAAAoG;AACF,GAAuB;;AACrB,QAAMC,KAAgBna,IAAAJ,EAAM,QAAN,gBAAAI,EAAW,QAC3BU,IAASoZ,GAAUK,CAAa,GAGhCC,MAAena,IAAAL,EAAM,YAAN,gBAAAK,EAAe,wBAAqBoa,KAAAja,IAAAR,EAAM,QAAN,gBAAAQ,EAAW,YAAX,gBAAAia,EAAoB,YAAS3Q,IAAAhJ,KAAA,gBAAAA,EAAQ,YAAR,gBAAAgJ,EAAiB,gBACjG4Q,IAAKlb;AAAA,IACT,MAAA;;AACE,aAAAsB,MACIV,IAAA,OAAO,QAAQU,EAAO,MAAM,EAAE,KAAK,CAAC,CAAA,EAAGK,CAAC,MAAMA,EAAE,OAAO,MAAvD,gBAAAf,EAA2D,OAAM,OACjE;AAAA;AAAA,IACN,CAACU,CAAM;AAAA,EAAA,GAIH,EAAE,MAAM6Z,GAAU,WAAWC,EAAA,IAAmBjI,GAAcsB,MAAS,SAASsG,IAAgB,QAAW;AAAA,IAC/G,UAAU;AAAA,IACV,MAAMC,IAAe,GAAGA,CAAY,SAAS;AAAA,EAAA,CAC9C,GACKte,KAAUye,KAAA,gBAAAA,EAAU,SAAQ,CAAA,GAG5BE,IAAerb,EAAQ,MAAM;AACjC,QAAIwL,KAAS,KAAM,QAAO;AAC1B,UAAM8P,IAAS,OAAO9P,CAAK;AAG3B,QAAIsP,KAAQC,GAAe;AACzB,YAAMQ,IAAaT,EAAKC,CAAa;AACrC,UAAIQ,GAAY;AACd,cAAMC,IAAYD,EAAWD,CAAM;AACnC,YAAIE;AACF,iBAAIR,IAAqBL,GAAea,EAAUR,CAAY,CAAC,IACxDM;AAAA,MAEX;AAAA,IACF;AAGA,QAAIN,KAAgBte,EAAQ,SAAS,GAAG;AACtC,YAAM+e,IAAQ/e,EAAQ,KAAK,CAACN,MAAM,OAAOA,EAAE8e,CAAE,CAAC,MAAMI,CAAM;AAC1D,UAAIG,EAAO,QAAOd,GAAec,EAAMT,CAAY,KAAKxP,CAAK;AAAA,IAC/D;AAEA,WAAO8P;AAAA,EACT,GAAG,CAAC9P,GAAOsP,GAAMC,GAAeC,GAActe,GAASwe,CAAE,CAAC;AAE1D,MAAIzG,MAAS;AACX,WAAO,gBAAAxU,EAAC,QAAA,EAAK,WAAU,WAAW,UAAAob,GAAa;AAKjD,QAAMK,IAAY,OAAOlQ,KAAS,EAAE,GAC9BmQ,IAAsBjf,EAAQ,KAAK,CAACN,MAAM,OAAOA,EAAE8e,CAAE,CAAC,MAAMQ,CAAS;AAE3E,SACE,gBAAApY;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAOoY;AAAA,MACP,UAAU,CAACjS,MAAMiL,KAAA,gBAAAA,EAAWjL,EAAE,OAAO,SAAS;AAAA,MAC9C,UAAU2R;AAAA,MAEV,UAAA;AAAA,QAAA,gBAAAnb,EAAC,UAAA,EAAO,OAAM,IAAG,UAAA,aAAS;AAAA,QACzBmb,KAAkBM,KACjB,gBAAAzb,EAAC,UAAA,EAAO,OAAOyb,GAAY,UAAAL,GAAa;AAAA,QAEzC,CAACD,KAAkBM,KAAa,CAACC,KAChC,gBAAA1b,EAAC,UAAA,EAAO,OAAOyb,GAAY,UAAAL,EAAA,CAAa;AAAA,QAEzC3e,EAAQ,IAAI,CAACN,MAAM;AAClB,gBAAMyB,IAAK,OAAOzB,EAAE8e,CAAE,CAAC,GACjBvE,IAAQqE,IACVL,GAAeve,EAAE4e,CAAY,KAAKnd,CAAE,IACpCA;AACJ,iBACE,gBAAAoC,EAAC,UAAA,EAAgB,OAAOpC,GACrB,eADUA,CAEb;AAAA,QAEJ,CAAC;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;ACrGA,MAAM+d,KAAahc;AAAA,EAAK,MACtB,OAAO,0BAAc,EAAE,KAAK,CAACkZ,OAAO,EAAE,SAASA,EAAE,aAAa;AAChE;AAEA,SAAS+C,KAAqB;AAC5B,SACE,gBAAA5b,EAAC,OAAA,EAAI,WAAU,gFAAA,CAAgF;AAEnG;AAEO,SAAS6b,GAAU,EAAE,OAAAtQ,GAAO,MAAAiJ,GAAM,UAAAC,KAAgC;AACvE,SAAID,MAAS,YACPjJ,KAAS,QAAS,OAAOA,KAAU,YAAY,CAACA,IAC3C,gBAAAvL,EAAC,QAAA,EAAK,WAAU,0CAAyC,UAAA,KAAC,IAGjE,gBAAAA,EAACC,IAAA,EAAS,UAAU,gBAAAD,EAAC4b,IAAA,EAAmB,GACtC,UAAA,gBAAA5b,EAAC2b,IAAA,EAAW,OAAApQ,GAAc,UAAQ,GAAA,CAAC,GACrC,IAKF,gBAAAvL,EAACC,IAAA,EAAS,UAAU,gBAAAD,EAAC4b,IAAA,CAAA,CAAmB,GACtC,UAAA,gBAAA5b,EAAC2b,IAAA,EAAW,OAAApQ,GAAc,UAAAkJ,EAAA,CAAoB,EAAA,CAChD;AAEJ;ACvBA,SAASqH,GAAavQ,GAAyB;AAC7C,SAAIA,KAAS,OAAa,CAAA,IACtB,OAAOA,KAAU,YAAY,CAAC,MAAM,QAAQA,CAAK,IAC5CA,IAEL,OAAOA,KAAU,WACZ,EAAE,IAAIA,EAAA,IAER,CAAA;AACT;AAEO,SAASwQ,GAAe;AAAA,EAC7B,OAAAxQ;AAAA,EACA,MAAAiJ;AAAA,EACA,UAAAC;AACF,GAAuB;;AACrB,QAAM,EAAE,MAAMnS,EAAA,IAAWpF,GAAA,GACnB8e,KAAYrb,IAAA2B,KAAA,gBAAAA,EAAQ,cAAR,QAAA3B,EAAmB,SACjC2B,EAAO,YACP,CAAC,EAAE,MAAM,MAAM,MAAM,EAAE,IAAI,UAAA,GAAa,GACtC2Z,IAAUH,GAAavQ,CAAK;AAElC,MAAIiJ,MAAS,WAAW;AAEtB,UAAM0H,IACJ,OAAO,OAAOD,CAAO,EAAE,CAAC,KAAK;AAC/B,WAAO,gBAAAjc,EAAC,QAAA,EAAK,WAAU,WAAW,UAAAkc,GAAW;AAAA,EAC/C;AAEA,QAAMC,IAAmB,CAAC9b,GAAcqU,MAAiB;AACvD,UAAM0H,IAAU,EAAE,GAAGH,GAAS,CAAC5b,CAAI,GAAGqU,EAAA;AAEtC,eAAW2H,KAAK,OAAO,KAAKD,CAAO;AACjC,MAAKA,EAAQC,CAAC,KAAG,OAAOD,EAAQC,CAAC;AAEnC,IAAA5H,KAAA,QAAAA,EAAW,OAAO,KAAK2H,CAAO,EAAE,SAAS,IAAIA,IAAU;AAAA,EACzD;AAEA,SACE,gBAAApc,EAAC,OAAA,EAAI,WAAU,aACZ,UAAAgc,EAAU,IAAI,CAAC3b,MACd,gBAAAgD,EAAC,OAAA,EAAoB,WAAU,2BAC7B,UAAA;AAAA,IAAA,gBAAArD,EAACuO,IAAA,EAAM,WAAU,iEACd,UAAAlO,EAAK,MACR;AAAA,IACA,gBAAAL;AAAA,MAACoO;AAAA,MAAA;AAAA,QACC,OAAO6N,EAAQ5b,EAAK,IAAI,KAAK;AAAA,QAC7B,UAAU,CAACmJ,MAAM2S,EAAiB9b,EAAK,MAAMmJ,EAAE,OAAO,KAAK;AAAA,QAC3D,aAAa,UAAUnJ,EAAK,IAAI;AAAA,MAAA;AAAA,IAAA;AAAA,EAClC,EAAA,GARQA,EAAK,IASf,CACD,GACH;AAEJ;ACtDA,SAASyb,GAAavQ,GAAyB;AAC7C,SAAIA,KAAS,OAAa,CAAA,IACtB,OAAOA,KAAU,YAAY,CAAC,MAAM,QAAQA,CAAK,IAC5CA,IAEL,OAAOA,KAAU,WACZ,EAAE,IAAIA,EAAA,IAER,CAAA;AACT;AAEO,SAAS+Q,GAAmB;AAAA,EACjC,OAAA/Q;AAAA,EACA,MAAAiJ;AAAA,EACA,UAAAC;AACF,GAAuB;;AACrB,QAAM,EAAE,MAAMnS,EAAA,IAAWpF,GAAA,GACnB8e,KAAYrb,IAAA2B,KAAA,gBAAAA,EAAQ,cAAR,QAAA3B,EAAmB,SACjC2B,EAAO,YACP,CAAC,EAAE,MAAM,MAAM,MAAM,EAAE,IAAI,UAAA,GAAa,GACtC2Z,IAAUH,GAAavQ,CAAK;AAElC,MAAIiJ,MAAS,WAAW;AACtB,UAAM0H,IAAa,OAAO,OAAOD,CAAO,EAAE,CAAC,KAAK;AAChD,WAAO,gBAAAjc,EAAC,KAAA,EAAE,WAAU,+BAA+B,UAAAkc,GAAW;AAAA,EAChE;AAEA,QAAMC,IAAmB,CAAC9b,GAAcqU,MAAiB;AACvD,UAAM0H,IAAU,EAAE,GAAGH,GAAS,CAAC5b,CAAI,GAAGqU,EAAA;AACtC,eAAW2H,KAAK,OAAO,KAAKD,CAAO;AACjC,MAAKA,EAAQC,CAAC,KAAG,OAAOD,EAAQC,CAAC;AAEnC,IAAA5H,KAAA,QAAAA,EAAW,OAAO,KAAK2H,CAAO,EAAE,SAAS,IAAIA,IAAU;AAAA,EACzD;AAEA,SACE,gBAAApc,EAAC,OAAA,EAAI,WAAU,aACZ,UAAAgc,EAAU,IAAI,CAAC3b,MACd,gBAAAgD,EAAC,OAAA,EAAoB,WAAU,aAC7B,UAAA;AAAA,IAAA,gBAAArD,EAACuO,IAAA,EAAM,WAAU,oDACd,UAAAlO,EAAK,MACR;AAAA,IACA,gBAAAL;AAAA,MAAC2U;AAAA,MAAA;AAAA,QACC,OAAOsH,EAAQ5b,EAAK,IAAI,KAAK;AAAA,QAC7B,UAAU,CAACmJ,MAAM2S,EAAiB9b,EAAK,MAAMmJ,EAAE,OAAO,KAAK;AAAA,QAC3D,aAAa,UAAUnJ,EAAK,IAAI;AAAA,QAChC,MAAM;AAAA,QACN,WAAU;AAAA,MAAA;AAAA,IAAA;AAAA,EACZ,EAAA,GAVQA,EAAK,IAWf,CACD,GACH;AAEJ;AClDO,SAASkc,GAAe1c,GAA2B;;AACxD,QAAM,EAAE,OAAAU,GAAO,OAAAgL,GAAO,MAAAiJ,GAAM,UAAAC,MAAa5U,GACnC,EAAE,MAAMyC,EAAA,IAAWpF,GAAA,GAEnBsf,IAAYjc,EAAM,aACpBI,IAAA2B,KAAA,gBAAAA,EAAQ,eAAR,gBAAA3B,EAAqBJ,EAAM,aAC3B;AAGJ,SAAKic,IAIDjc,EAAM,QAEN,gBAAAP;AAAA,IAACyc;AAAA,IAAA;AAAA,MACC,WAAAD;AAAA,MACA,OAAAjR;AAAA,MACA,MAAAiJ;AAAA,MACA,UAAAC;AAAA,IAAA;AAAA,EAAA,IAMJ,gBAAAzU;AAAA,IAAC0c;AAAA,IAAA;AAAA,MACC,WAAAF;AAAA,MACA,OAAAjR;AAAA,MACA,MAAAiJ;AAAA,MACA,UAAAC;AAAA,IAAA;AAAA,EAAA,IAnBK,gBAAAzU,EAAC6b,IAAA,EAAW,GAAGhc,EAAA,CAAO;AAsBjC;AAEA,SAAS6c,GAAwB;AAAA,EAC/B,WAAAF;AAAA,EACA,OAAAjR;AAAA,EACA,MAAAiJ;AAAA,EACA,UAAAC;AACF,GAKG;;AACD,QAAMkI,IAAO,OAAOpR,KAAU,YAAYA,MAAU,QAAQ,CAAC,MAAM,QAAQA,CAAK,IAC5EA,IACA,CAAA,GAEEqR,KAAajc,IAAA6b,EAAU,gBAAV,QAAA7b,EAAuB,SACtC6b,EAAU,cACV,OAAO,KAAKA,EAAU,MAAM;AAEhC,MAAIhI,MAAS;AAEX,WADoBoI,EAAW,KAAK,CAAC5P,MAAQ2P,EAAI3P,CAAG,KAAK,QAAQ2P,EAAI3P,CAAG,MAAM,EAAE,sBAM7E,OAAA,EAAI,WAAU,0DACZ,UAAA4P,EAAW,IAAI,CAAC5P,MAAQ;AACvB,YAAMzM,IAAQic,EAAU,OAAOxP,CAAG;AAClC,UAAI,CAACzM,EAAO,QAAO;AACnB,YAAMsc,IAAaF,EAAI3P,CAAG;AAC1B,aAAI6P,KAAc,OAAa,OAG7B,gBAAAxZ,EAAC,OAAA,EAAc,WAAU,6BACvB,UAAA;AAAA,QAAA,gBAAArD,EAAC,QAAA,EAAK,WAAU,6EACb,UAAAO,EAAM,UAAUJ,EAAII,EAAM,QAAQ,IAAI,IAAIyM,EAAA,CAC7C;AAAA,QACA,gBAAAhN,EAAC,SAAI,WAAU,kBACZ,YAAM,SAAS,eAAeO,EAAM,YACnC,gBAAAP;AAAA,UAACuc;AAAA,UAAA;AAAA,YACC,OAAAhc;AAAA,YACA,WAAWyM;AAAA,YACX,OAAO6P;AAAA,YACP,MAAK;AAAA,UAAA;AAAA,QAAA,IAGPC,GAAY;AAAA,UACV,OAAAvc;AAAA,UACA,WAAWyM;AAAA,UACX,OAAO6P;AAAA,UACP,MAAM;AAAA,QAAA,CACP,EAAA,CAEL;AAAA,MAAA,EAAA,GApBQ7P,CAqBV;AAAA,IAEJ,CAAC,EAAA,CACH,IApCO,gBAAAhN,EAAC,QAAA,EAAK,WAAU,0CAAyC,UAAA,KAAC;AAyCrE,QAAM+c,IAAoB,CAAC/P,MAAgB,CAAC6P,MAAwB;AAClE,IAAApI,KAAA,QAAAA,EAAW,EAAE,GAAGkI,GAAK,CAAC3P,CAAG,GAAG6P;EAC9B;AAEA,2BACG,OAAA,EAAI,WAAU,0DACZ,UAAAD,EAAW,IAAI,CAAC5P,MAAQ;AACvB,UAAMzM,IAAQic,EAAU,OAAOxP,CAAG;AAClC,WAAKzM,IAGH,gBAAA8C,EAAC,OAAA,EAAc,WAAU,aACvB,UAAA;AAAA,MAAA,gBAAAA,EAACkL,IAAA,EAAM,WAAU,WACd,UAAA;AAAA,QAAAhO,EAAM,UAAUJ,EAAII,EAAM,QAAQ,IAAI,IAAIyM;AAAA,QAC1CzM,EAAM,YACL,gBAAAP,EAAC,QAAA,EAAK,WAAU,oCAAmC,UAAA,IAAA,CAAC;AAAA,MAAA,GAExD;AAAA,MACCO,EAAM,SAAS,eAAeA,EAAM,YACnC,gBAAAP;AAAA,QAACuc;AAAA,QAAA;AAAA,UACC,OAAAhc;AAAA,UACA,WAAWyM;AAAA,UACX,OAAO2P,EAAI3P,CAAG;AAAA,UACd,MAAK;AAAA,UACL,UAAU+P,EAAkB/P,CAAG;AAAA,QAAA;AAAA,MAAA,IAGjC8P,GAAY;AAAA,QACV,OAAAvc;AAAA,QACA,WAAWyM;AAAA,QACX,OAAO2P,EAAI3P,CAAG;AAAA,QACd,MAAM;AAAA,QACN,UAAU+P,EAAkB/P,CAAG;AAAA,MAAA,CAChC;AAAA,IAAA,EAAA,GAtBKA,CAwBV,IA3BiB;AAAA,EA6BrB,CAAC,EAAA,CACH;AAEJ;AAEA,SAASyP,GAAuB;AAAA,EAC9B,WAAAD;AAAA,EACA,OAAAjR;AAAA,EACA,MAAAiJ;AAAA,EACA,UAAAC;AACF,GAKG;AACD,QAAM3R,IAAQ,MAAM,QAAQyI,CAAK,IAAIA,IAAQ,CAAA;AAE7C,MAAIiJ,MAAS;AACX,WAAI1R,EAAM,WAAW,IACZ,gBAAA9C,EAAC,QAAA,EAAK,WAAU,0CAAyC,UAAA,KAAC,IAIjE,gBAAAA,EAAC,SAAI,WAAU,aACZ,YAAM,IAAI,CAACyD,GAAMzF,MAChB,gBAAAgC;AAAA,MAAC0c;AAAA,MAAA;AAAA,QAEC,WAAAF;AAAA,QACA,OAAO/Y;AAAA,QACP,MAAK;AAAA,MAAA;AAAA,MAHAzF;AAAA,IAAA,CAKR,GACH;AAKJ,QAAMgf,IAAmB,CAAChf,MAAgB,CAACif,MAAuB;AAChE,UAAM1S,IAAO,CAAC,GAAGzH,CAAK;AACtB,IAAAyH,EAAKvM,CAAG,IAAIif,GACZxI,KAAA,QAAAA,EAAWlK;AAAA,EACb,GAEM2S,IAAY,MAAM;AACtB,IAAAzI,KAAA,QAAAA,EAAW,CAAC,GAAG3R,GAAO,CAAA,CAAE;AAAA,EAC1B,GAEMqa,IAAe,CAACnf,MAAgB,MAAM;AAC1C,UAAMuM,IAAOzH,EAAM,OAAO,CAACsa,GAAG7Q,MAAMA,MAAMvO,CAAG;AAC7C,IAAAyW,KAAA,QAAAA,EAAWlK;AAAA,EACb;AAEA,SACE,gBAAAlH,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,IAAAP,EAAM,IAAI,CAACW,GAAMzF,MAChB,gBAAAqF,EAAC,OAAA,EAAc,WAAU,YACvB,UAAA;AAAA,MAAA,gBAAArD;AAAA,QAAC0c;AAAA,QAAA;AAAA,UACC,WAAAF;AAAA,UACA,OAAO/Y;AAAA,UACP,MAAK;AAAA,UACL,UAAUuZ,EAAiBhf,CAAG;AAAA,QAAA;AAAA,MAAA;AAAA,MAEhC,gBAAAgC;AAAA,QAAC8H;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAASqV,EAAanf,CAAG;AAAA,UAEzB,UAAA,gBAAAgC,EAACqd,IAAA,EAAO,WAAU,cAAA,CAAc;AAAA,QAAA;AAAA,MAAA;AAAA,IAClC,EAAA,GAfQrf,CAgBV,CACD;AAAA,IACD,gBAAAqF;AAAA,MAACyE;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAASoV;AAAA,QAET,UAAA;AAAA,UAAA,gBAAAld,EAACsd,IAAA,EAAK,WAAU,cAAA,CAAc;AAAA,UAAE;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAElC,GACF;AAEJ;AC9NA,MAAMC,KAAkB;AAEjB,SAASC,GAAY,EAAE,OAAAjS,GAAO,MAAAiJ,GAAM,UAAAC,GAAU,QAAAlT,KAA8B;AACjF,QAAM,CAACkc,GAAWC,CAAY,IAAIzb,EAAS,EAAK,GAE1C,CAACsX,GAAYoE,CAAa,IAAI1b,EAAS,EAAE,GAEzC2b,IAAWrc,MAAW,QACtBsc,IACJtS,MAAUgS,MAAoB,OAAOhS,KAAU,YAAYA,MAAU;AAEvE,MAAIiJ,MAAS;AACX,WAAIqJ,IAEA,gBAAA7d,EAAC,QAAA,EAAK,WAAU,oDACb,UAAAud,IACH,IAIF,gBAAAvd,EAAC,QAAA,EAAK,WAAU,iDAAgD,UAAA,WAAO;AAO3E,QAAM8d,IAAe,CAAC3L,MAAc;AAClC,IAAAwL,EAAcxL,CAAC,GACXyL,KAGEzL,MAAM,KACRsC,KAAA,QAAAA,EAAWoJ,IAAmBN,KAAkB,MAMlD9I,KAAA,QAAAA,EAAWtC;AAAA,EAEf;AAEA,SACE,gBAAA9O,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,IAAA,gBAAArD;AAAA,MAACoO;AAAA,MAAA;AAAA,QACC,MAAMqP,IAAY,SAAS;AAAA,QAC3B,OAAOlE;AAAA,QACP,aAAaqE,IAAW,uCAAuC;AAAA,QAC/D,UAAU,CAACpU,MAAMsU,EAAatU,EAAE,OAAO,KAAK;AAAA,QAC5C,WAAU;AAAA,QACV,cAAa;AAAA,MAAA;AAAA,IAAA;AAAA,IAEf,gBAAAxJ;AAAA,MAAC8H;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAM4V,EAAa,CAACvL,MAAM,CAACA,CAAC;AAAA,QACrC,OAAOsL,IAAY,eAAe;AAAA,QAEjC,UAAAA,sBACEM,IAAA,EAAO,WAAU,WAAU,IAE5B,gBAAA/d,EAACge,IAAA,EAAI,WAAU,UAAA,CAAU;AAAA,MAAA;AAAA,IAAA;AAAA,EAE7B,GACF;AAEJ;ACtEA,MAAMT,KAAkB;AAEjB,SAASU,GAAc,EAAE,OAAA1S,GAAO,MAAAiJ,GAAM,UAAAC,GAAU,QAAAlT,KAA8B;AAEnF,QAAM,CAACgY,GAAYoE,CAAa,IAAI1b,EAAS,EAAE,GAEzC,CAACic,GAAUC,CAAW,IAAIlc,EAAS,EAAK,GAExC2b,IAAWrc,MAAW,QACtBsc,IACJtS,MAAUgS,MAAoB,OAAOhS,KAAU,YAAYA,MAAU;AAEvE,MAAIiJ,MAAS;AACX,WAAIqJ,IAEA,gBAAA7d,EAAC,QAAA,EAAK,WAAU,oDACb,UAAAud,IACH,IAIF,gBAAAvd,EAAC,QAAA,EAAK,WAAU,iDAAgD,UAAA,WAAO;AAO3E,QAAM8d,IAAe,CAAC3L,MAAc;AAClC,IAAAwL,EAAcxL,CAAC,GACXyL,KACEzL,MAAM,KACRsC,KAAA,QAAAA,EAAWoJ,IAAmBN,KAAkB,MAKlD9I,KAAA,QAAAA,EAAWtC;AAAA,EAEf;AAIA,SACE,gBAAA9O,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,IAAA,gBAAArD;AAAA,MAACoO;AAAA,MAAA;AAAA,QACC,MAAM8P,IAAW,SAAS;AAAA,QAC1B,OAAO3E;AAAA,QACP,aAAaqE,IAAW,uCAAuC;AAAA,QAC/D,UAAU,CAACpU,MAAMsU,EAAatU,EAAE,OAAO,KAAK;AAAA,QAC5C,cAAa;AAAA,QACb,WAAU;AAAA,MAAA;AAAA,IAAA;AAAA,IAEZ,gBAAAxJ;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,MAAMme,EAAY,CAAChiB,MAAM,CAACA,CAAC;AAAA,QACpC,cAAY+hB,IAAW,kBAAkB;AAAA,QACzC,UAAU;AAAA,QACV,WAAU;AAAA,QAET,UAAAA,sBAAYH,IAAA,EAAO,WAAU,WAAU,IAAK,gBAAA/d,EAACge,IAAA,EAAI,WAAU,UAAA,CAAU;AAAA,MAAA;AAAA,IAAA;AAAA,EACxE,GACF;AAEJ;ACjEA,SAASI,GAAc7S,GAA0B;AAC/C,SAAI,MAAM,QAAQA,CAAK,IAAUA,EAAM,OAAO,CAAC4G,MAAMA,KAAK,IAAI,EAAE,IAAI,MAAM,IACnE,CAAA;AACT;AAEO,SAASkM,GAAiB,EAAE,OAAA9S,GAAO,MAAAiJ,GAAM,UAAAC,KAAgC;AAC9E,QAAM3R,IAAQsb,GAAc7S,CAAK,GAC3B,CAAC+S,GAAOC,CAAQ,IAAItc,EAAS,EAAE;AAErC,MAAIuS,MAAS;AACX,WAAI1R,EAAM,WAAW,sBAAW,QAAA,EAAK,WAAU,iCAAgC,UAAA,IAAA,CAAC,IAE9E,gBAAA9C,EAAC,SAAI,WAAU,wBACZ,YAAM,IAAI,CAACyD,GAAM8I,MAChB,gBAAAvM;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAU;AAAA,QAET,UAAAyD;AAAA,MAAA;AAAA,MAHI8I;AAAA,IAAA,CAKR,GACH;AAIJ,QAAMiS,IAAU,MAAM;AACpB,UAAM9E,IAAU4E,EAAM,KAAA;AACtB,IAAK5E,MACLjF,KAAA,QAAAA,EAAW,CAAC,GAAG3R,GAAO4W,CAAO,IAC7B6E,EAAS,EAAE;AAAA,EACb,GAEME,IAAa,CAAC/iB,MAAkB;AACpC,IAAA+Y,KAAA,QAAAA,EAAW3R,EAAM,OAAO,CAACsa,GAAG7Q,MAAMA,MAAM7Q,CAAK;AAAA,EAC/C,GAEMgjB,IAAgB,CAAClV,MAAuC;AAC5D,IAAIA,EAAE,QAAQ,YACZA,EAAE,eAAA,GACFgV,EAAA;AAAA,EAEJ;AAEA,SACE,gBAAAnb,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,IAAAP,EAAM,SAAS,KACd,gBAAA9C,EAAC,OAAA,EAAI,WAAU,wBACZ,UAAA8C,EAAM,IAAI,CAACW,GAAM8I,MAChB,gBAAAlJ;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAU;AAAA,QAET,UAAA;AAAA,UAAAI;AAAA,UACD,gBAAAzD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,MAAMye,EAAWlS,CAAC;AAAA,cAC3B,WAAU;AAAA,cAEV,UAAA,gBAAAvM,EAACyJ,IAAA,EAAE,WAAU,UAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACzB;AAAA,MAAA;AAAA,MAVK8C;AAAA,IAAA,CAYR,GACH;AAAA,IAEF,gBAAAlJ,EAAC,OAAA,EAAI,WAAU,cACb,UAAA;AAAA,MAAA,gBAAArD;AAAA,QAACoO;AAAA,QAAA;AAAA,UACC,OAAOkQ;AAAA,UACP,UAAU,CAAC9U,MAAM+U,EAAS/U,EAAE,OAAO,KAAK;AAAA,UACxC,WAAWkV;AAAA,UACX,aAAY;AAAA,UACZ,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAEZ,gBAAA1e,EAAC8H,GAAA,EAAO,MAAK,UAAS,SAAQ,WAAU,MAAK,MAAK,SAAS0W,GACzD,UAAA,gBAAAxe,EAACsd,IAAA,EAAK,WAAU,WAAU,EAAA,CAC5B;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AC9EA,SAASqB,GAAWpT,GAA0B;AAC5C,SAAI,MAAM,QAAQA,CAAK,IACdA,EAAM,OAAO,CAAC4G,MAAMA,KAAK,IAAI,EAAE,IAAI,MAAM,EAAE,OAAO,CAAC7J,MAAM,CAAC,MAAMA,CAAC,CAAC,IAEpE,CAAA;AACT;AAEO,SAASsW,GAAc,EAAE,OAAArT,GAAO,MAAAiJ,GAAM,UAAAC,KAAgC;AAC3E,QAAM3R,IAAQ6b,GAAWpT,CAAK,GACxB,CAAC+S,GAAOC,CAAQ,IAAItc,EAAS,EAAE;AAErC,MAAIuS,MAAS;AACX,WAAI1R,EAAM,WAAW,sBAAW,QAAA,EAAK,WAAU,iCAAgC,UAAA,IAAA,CAAC,IAE9E,gBAAA9C,EAAC,SAAI,WAAU,wBACZ,YAAM,IAAI,CAACyD,GAAM8I,MAChB,gBAAAvM;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAU;AAAA,QAET,UAAAyD;AAAA,MAAA;AAAA,MAHI8I;AAAA,IAAA,CAKR,GACH;AAIJ,QAAMiS,IAAU,MAAM;AACpB,UAAM9E,IAAU4E,EAAM,KAAA;AACtB,QAAI,CAAC5E,EAAS;AACd,UAAMc,IAAM,OAAOd,CAAO;AAC1B,IAAI,MAAMc,CAAG,KAAK,CAAC,OAAO,UAAUA,CAAG,MACvC/F,KAAA,QAAAA,EAAW,CAAC,GAAG3R,GAAO0X,CAAG,IACzB+D,EAAS,EAAE;AAAA,EACb,GAEME,IAAa,CAAC/iB,MAAkB;AACpC,IAAA+Y,KAAA,QAAAA,EAAW3R,EAAM,OAAO,CAACsa,GAAG7Q,MAAMA,MAAM7Q,CAAK;AAAA,EAC/C,GAEMgjB,IAAgB,CAAClV,MAAuC;AAC5D,IAAIA,EAAE,QAAQ,YACZA,EAAE,eAAA,GACFgV,EAAA;AAAA,EAEJ;AAEA,SACE,gBAAAnb,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,IAAAP,EAAM,SAAS,KACd,gBAAA9C,EAAC,OAAA,EAAI,WAAU,wBACZ,UAAA8C,EAAM,IAAI,CAACW,GAAM8I,MAChB,gBAAAlJ;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAU;AAAA,QAET,UAAA;AAAA,UAAAI;AAAA,UACD,gBAAAzD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,MAAMye,EAAWlS,CAAC;AAAA,cAC3B,WAAU;AAAA,cAEV,UAAA,gBAAAvM,EAACyJ,IAAA,EAAE,WAAU,UAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACzB;AAAA,MAAA;AAAA,MAVK8C;AAAA,IAAA,CAYR,GACH;AAAA,IAEF,gBAAAlJ,EAAC,OAAA,EAAI,WAAU,cACb,UAAA;AAAA,MAAA,gBAAArD;AAAA,QAACoO;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,OAAOkQ;AAAA,UACP,UAAU,CAAC9U,MAAM+U,EAAS/U,EAAE,OAAO,KAAK;AAAA,UACxC,WAAWkV;AAAA,UACX,aAAY;AAAA,UACZ,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAEZ,gBAAA1e,EAAC8H,GAAA,EAAO,MAAK,UAAS,SAAQ,WAAU,MAAK,MAAK,SAAS0W,GACzD,UAAA,gBAAAxe,EAACsd,IAAA,EAAK,WAAU,WAAU,EAAA,CAC5B;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;ACtDA,MAAMuB,KAAgD;AAAA,EACpD,QAAQtK;AAAA,EACR,MAAMO;AAAA,EACN,MAAMkB;AAAA,EACN,OAAOI;AAAA,EACP,KAAKmB;AAAA,EACL,OAAOhD;AAAA,EACP,WAAW4E;AAAA,EACX,MAAMA;AAAA,EACN,MAAMA;AAAA,EACN,MAAMK;AAAA,EACN,KAAKS;AAAA,EACL,OAAOA;AAAA,EACP,SAASA;AAAA,EACT,MAAM1F;AAAA,EACN,KAAKqG;AAAA,EACL,MAAMiB;AAAA,EACN,MAAMtH;AAAA,EACN,cAAc8J;AAAA,EACd,WAAWO;AAAA,EACX,WAAW7C;AAAA,EACX,gBAAgBO;AAAA,EAChB,WAAWC;AAAA,EACX,QAAQiB;AAAA,EACR,UAAUS;AACZ;AAEO,SAASnB,GAAYjd,GAA4C;;AAEtE,MAAIA,EAAM,MAAM,SAAS,UAAUA,EAAM,MAAM;AAC7C,WAAO,gBAAAG,EAACuc,IAAA,EAAgB,GAAG1c,EAAA,CAAO;AAMpC,QAAMkV,KAASpU,IAAAd,EAAM,MAAM,YAAZ,gBAAAc,EAAqB;AACpC,MAAIoU,KAAU8J,GAAe9J,CAAM,GAAG;AACpC,UAAM+J,IAAWD,GAAe9J,CAAM;AACtC,WAAO,gBAAA/U,EAAC8e,GAAA,EAAU,GAAGjf,EAAA,CAAO;AAAA,EAC9B;AACA,QAAMif,IAAWD,GAAehf,EAAM,MAAM,IAAI,KAAK0U;AACrD,SAAO,gBAAAvU,EAAC8e,GAAA,EAAU,GAAGjf,EAAA,CAAO;AAC9B;ACpEO,SAASkf,GAAW,EAAE,MAAAC,GAAM,OAAAtgB,GAAO,aAAAugB,GAAa,QAAAnN,KAA2B;AAChF,SACE,gBAAAzO,EAAC,OAAA,EAAI,WAAU,+DACZ,UAAA;AAAA,IAAA2b,KACC,gBAAAhf,EAAC,OAAA,EAAI,WAAU,2CACb,UAAA,gBAAAA,EAACJ,MAAY,MAAMof,GAAM,WAAU,yCAAA,CAAyC,EAAA,CAC9E;AAAA,IAEF,gBAAAhf,EAAC,MAAA,EAAG,WAAU,gDAAgD,UAAAtB,GAAM;AAAA,IACnEugB,KACC,gBAAAjf,EAAC,KAAA,EAAE,WAAU,wDACV,UAAAif,GACH;AAAA,IAEDnN,KAAU,gBAAA9R,EAAC,OAAA,EAAI,WAAU,QAAQ,UAAA8R,EAAA,CAAO;AAAA,EAAA,GAC3C;AAEJ;ACzBA,SAASoN,GAAS;AAAA,EAChB,WAAArY;AAAA,EACA,GAAGhH;AACL,GAAyC;AACvC,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW9E;AAAA,QACT;AAAA,QACA2L;AAAA,MAAA;AAAA,MAED,GAAGhH;AAAA,IAAA;AAAA,EAAA;AAGV;ACbO,SAASsf,GAAc,EAAE,MAAAjK,IAAO,GAAG,MAAAkK,IAAO,KAAuC;AACtF,SACE,gBAAA/b,EAAC,OAAA,EAAI,WAAU,iBAEb,UAAA;AAAA,IAAA,gBAAArD,EAAC,OAAA,EAAI,WAAU,cACZ,UAAA,MAAM,KAAK,EAAE,QAAQof,GAAM,EAAE,IAAI,CAAChC,GAAG7Q,MACpC,gBAAAvM,EAACkf,IAAA,EAAiB,WAAU,aAAA,GAAb3S,CAA0B,CAC1C,GACH;AAAA,IAEC,MAAM,KAAK,EAAE,QAAQ2I,GAAM,EAAE,IAAI,CAACkI,GAAG7Q,MACpC,gBAAAvM,EAAC,OAAA,EAAY,WAAU,cACpB,UAAA,MAAM,KAAK,EAAE,QAAQof,EAAA,CAAM,EAAE,IAAI,CAAChC,GAAGiC,MACpC,gBAAArf,EAACkf,IAAA,EAAiB,WAAU,aAAA,GAAbG,CAA0B,CAC1C,EAAA,GAHO9S,CAIV,CACD;AAAA,EAAA,GACH;AAEJ;AAEO,SAAS+S,KAAiB;AAC/B,SACE,gBAAAjc,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,IAAA,gBAAArD,EAACkf,IAAA,EAAS,WAAU,WAAA,CAAW;AAAA,sBAC9B,OAAA,EAAI,WAAU,aACZ,UAAA,MAAM,KAAK,EAAE,QAAQ,EAAA,CAAG,EAAE,IAAI,CAAC9B,GAAG7Q,MACjC,gBAAAlJ,EAAC,OAAA,EAAY,WAAU,aACrB,UAAA;AAAA,MAAA,gBAAArD,EAACkf,IAAA,EAAS,WAAU,WAAA,CAAW;AAAA,MAC/B,gBAAAlf,EAACkf,IAAA,EAAS,WAAU,sBAAA,CAAsB;AAAA,IAAA,EAAA,GAFlC3S,CAGV,CACD,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;AChCA,MAAMgT,KAAcC,GAAqB,MAEnCC,KAAoBD,GAAqB,QAEzCE,KAAqB9Y,GAAM,WAG/B,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACwf,GAAqB;AAAA,EAArB;AAAA,IACC,WAAWtkB;AAAA,MACT;AAAA,MACA2L;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,IACJ,KAAAmH;AAAA,EAAA;AACF,CACD;AACD0Y,GAAmB,cAAcF,GAAqB,QAAQ;AAE9D,MAAMG,KAAqB/Y,GAAM,WAG/B,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAA3D,EAACoc,IAAA,EACC,UAAA;AAAA,EAAA,gBAAAzf,EAAC0f,IAAA,EAAmB;AAAA,EACpB,gBAAA1f;AAAA,IAACwf,GAAqB;AAAA,IAArB;AAAA,MACC,KAAAxY;AAAA,MACA,WAAW9L;AAAA,QACT;AAAA,QACA2L;AAAA,MAAA;AAAA,MAED,GAAGhH;AAAA,IAAA;AAAA,EAAA;AACN,EAAA,CACF,CACD;AACD8f,GAAmB,cAAcH,GAAqB,QAAQ;AAE9D,SAASI,GAAkB;AAAA,EACzB,WAAA/Y;AAAA,EACA,GAAGhH;AACL,GAAyC;AACvC,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW9E;AAAA,QACT;AAAA,QACA2L;AAAA,MAAA;AAAA,MAED,GAAGhH;AAAA,IAAA;AAAA,EAAA;AAGV;AAEA,SAASggB,GAAkB;AAAA,EACzB,WAAAhZ;AAAA,EACA,GAAGhH;AACL,GAAyC;AACvC,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW9E;AAAA,QACT;AAAA,QACA2L;AAAA,MAAA;AAAA,MAED,GAAGhH;AAAA,IAAA;AAAA,EAAA;AAGV;AAEA,MAAMigB,KAAmBlZ,GAAM,WAG7B,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACwf,GAAqB;AAAA,EAArB;AAAA,IACC,KAAAxY;AAAA,IACA,WAAW9L,EAAG,yBAAyB2L,CAAS;AAAA,IAC/C,GAAGhH;AAAA,EAAA;AACN,CACD;AACDigB,GAAiB,cAAcN,GAAqB,MAAM;AAE1D,MAAMO,KAAyBnZ,GAAM,WAGnC,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACwf,GAAqB;AAAA,EAArB;AAAA,IACC,KAAAxY;AAAA,IACA,WAAW9L,EAAG,0CAA0C2L,CAAS;AAAA,IAChE,GAAGhH;AAAA,EAAA;AACN,CACD;AACDkgB,GAAuB,cACrBP,GAAqB,YAAY;AAEnC,MAAMQ,KAAoBpZ,GAAM,WAG9B,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACwf,GAAqB;AAAA,EAArB;AAAA,IACC,KAAAxY;AAAA,IACA,WAAW9L,EAAG0M,GAAA,GAAkBf,CAAS;AAAA,IACxC,GAAGhH;AAAA,EAAA;AACN,CACD;AACDmgB,GAAkB,cAAcR,GAAqB,OAAO;AAE5D,MAAMS,KAAoBrZ,GAAM,WAG9B,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACwf,GAAqB;AAAA,EAArB;AAAA,IACC,KAAAxY;AAAA,IACA,WAAW9L;AAAA,MACT0M,GAAe,EAAE,SAAS,WAAW;AAAA,MACrC;AAAA,MACAf;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,EAAA;AACN,CACD;AACDogB,GAAkB,cAAcT,GAAqB,OAAO;ACtGrD,SAASU,GAAc;AAAA,EAC5B,MAAAC;AAAA,EACA,cAAAC;AAAA,EACA,OAAA1hB;AAAA,EACA,aAAAugB;AAAA,EACA,cAAAoB,IAAe;AAAA,EACf,WAAAC;AAAA,EACA,aAAAC,IAAc;AAChB,GAAuB;AACrB,SACE,gBAAAvgB,EAACuf,IAAA,EAAY,MAAAY,GAAY,cAAAC,GACvB,4BAACT,IAAA,EACC,UAAA;AAAA,IAAA,gBAAAtc,EAACuc,IAAA,EACC,UAAA;AAAA,MAAA,gBAAA5f,EAAC8f,MAAkB,UAAAphB,EAAA,CAAM;AAAA,MACzB,gBAAAsB,EAAC+f,MAAwB,UAAAd,EAAA,CAAY;AAAA,IAAA,GACvC;AAAA,sBACCY,IAAA,EACC,UAAA;AAAA,MAAA,gBAAA7f,EAACigB,MAAkB,UAAA,SAAA,CAAM;AAAA,MACzB,gBAAAjgB;AAAA,QAACggB;AAAA,QAAA;AAAA,UACC,SAASM;AAAA,UACT,WAAWC,IAAc,kGAAkG;AAAA,UAE1H,UAAAF;AAAA,QAAA;AAAA,MAAA;AAAA,IACH,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;AC5CA,MAAMG,KAASC,GAAgB,MAEzBC,KAAeD,GAAgB,QAG/BE,KAAgB/Z,GAAM,WAG1B,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACygB,GAAgB;AAAA,EAAhB;AAAA,IACC,KAAAzZ;AAAA,IACA,WAAW9L;AAAA,MACT;AAAA,MACA2L;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,EAAA;AACN,CACD;AACD8gB,GAAc,cAAcF,GAAgB,QAAQ;AAEpD,MAAMG,KAAgBha,GAAM,WAG1B,CAAC,EAAE,WAAAC,GAAW,UAAAE,GAAU,GAAGlH,EAAA,GAASmH,MACpC,gBAAA3D,EAACqd,IAAA,EACC,UAAA;AAAA,EAAA,gBAAA1gB,EAAC2gB,IAAA,EAAc;AAAA,EACf,gBAAAtd;AAAA,IAACod,GAAgB;AAAA,IAAhB;AAAA,MACC,KAAAzZ;AAAA,MACA,WAAW9L;AAAA,QACT;AAAA,QACA2L;AAAA,MAAA;AAAA,MAED,GAAGhH;AAAA,MAEH,UAAA;AAAA,QAAAkH;AAAA,QACD,gBAAA1D,EAACod,GAAgB,OAAhB,EAAsB,WAAU,qTAC/B,UAAA;AAAA,UAAA,gBAAAzgB,EAACyJ,IAAA,EAAE,WAAU,UAAA,CAAU;AAAA,UACvB,gBAAAzJ,EAAC,QAAA,EAAK,WAAU,WAAU,UAAA,QAAA,CAAK;AAAA,QAAA,EAAA,CACjC;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AACF,EAAA,CACF,CACD;AACD4gB,GAAc,cAAcH,GAAgB,QAAQ;AAEpD,SAASI,GAAa;AAAA,EACpB,WAAAha;AAAA,EACA,GAAGhH;AACL,GAAyC;AACvC,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW9E;AAAA,QACT;AAAA,QACA2L;AAAA,MAAA;AAAA,MAED,GAAGhH;AAAA,IAAA;AAAA,EAAA;AAGV;AAEA,SAASihB,GAAa;AAAA,EACpB,WAAAja;AAAA,EACA,GAAGhH;AACL,GAAyC;AACvC,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW9E;AAAA,QACT;AAAA,QACA2L;AAAA,MAAA;AAAA,MAED,GAAGhH;AAAA,IAAA;AAAA,EAAA;AAGV;AAEA,MAAMkhB,KAAcna,GAAM,WAGxB,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACygB,GAAgB;AAAA,EAAhB;AAAA,IACC,KAAAzZ;AAAA,IACA,WAAW9L;AAAA,MACT;AAAA,MACA2L;AAAA,IAAA;AAAA,IAED,GAAGhH;AAAA,EAAA;AACN,CACD;AACDkhB,GAAY,cAAcN,GAAgB,MAAM;AAEhD,MAAMO,KAAoBpa,GAAM,WAG9B,CAAC,EAAE,WAAAC,GAAW,GAAGhH,EAAA,GAASmH,MAC1B,gBAAAhH;AAAA,EAACygB,GAAgB;AAAA,EAAhB;AAAA,IACC,KAAAzZ;AAAA,IACA,WAAW9L,EAAG,0CAA0C2L,CAAS;AAAA,IAChE,GAAGhH;AAAA,EAAA;AACN,CACD;AACDmhB,GAAkB,cAAcP,GAAgB,YAAY;AC1F5D,MAAMQ,yBAAc,IAAA;AAEb,SAASC,GAAoB5hB,GAAc6hB,GAAiC;AACjF,SAAAF,GAAQ,IAAI3hB,GAAM6hB,CAAM,GACjB,MAAM;AAEX,IAAIF,GAAQ,IAAI3hB,CAAI,MAAM6hB,KAAQF,GAAQ,OAAO3hB,CAAI;AAAA,EACvD;AACF;AAEO,SAAS8hB,GAAe9hB,GAAuC;AACpE,SAAO2hB,GAAQ,IAAI3hB,CAAI;AACzB;ACNO,SAAS+hB,GAAYC,GAAkBC,GAA8B;AAC1E,SAAOD,EAAS,QAAQ,2BAA2B,CAACE,GAAQhlB,MAAiB;AAC3E,UAAM+O,IAAQkW,GAAYjlB,GAAM+kB,CAAG;AACnC,WAAOhW,KAAS,OAAO,KAAK,OAAOA,CAAK;AAAA,EAC1C,CAAC;AACH;AAEA,SAASkW,GAAYjlB,GAAc+kB,GAA+B;AAChE,QAAMG,IAAQllB,EAAK,MAAM,GAAG;AAC5B,MAAIklB,EAAM,SAAS,EAAG;AACtB,QAAM,CAACC,GAAM,GAAGC,CAAI,IAAIF;AACxB,MAAIC,MAAS;AACX,WAAKJ,EAAI,MACFK,EAAK,OAAgB,CAACC,GAAK7U,MAAQ;AACxC,UAAI6U,KAAO,OAAOA,KAAQ,SAAU,QAAQA,EAAgC7U,CAAG;AAAA,IAEjF,GAAGuU,EAAI,GAAG,IAJI;AAMhB,MAAII,MAAS,WAAWC,EAAK,UAAU,GAAG;AACxC,UAAM,CAACE,GAAYthB,CAAS,IAAIohB,GAC1BT,IAASC,GAAeU,CAAU;AACxC,WAAOX,KAAA,gBAAAA,EAAQ,SAAS3gB;AAAA,EAC1B;AACA,MAAImhB,MAAS;AACX,WAAKJ,EAAI,SACFK,EAAK,OAAgB,CAACC,GAAK7U,MAAQ;AACxC,UAAI6U,KAAO,OAAOA,KAAQ,SAAU,QAAQA,EAAgC7U,CAAG;AAAA,IAEjF,GAAGuU,EAAI,MAAM,IAJI;AAOrB;AAKA,eAAsBQ,GAAeC,GAAiBT,GAAqC;AACzF,aAAWU,KAAQD;AACjB,QAAI;AACF,YAAME,GAAQD,GAAMV,CAAG;AAAA,IACzB,SAASrb,GAAK;AACZ,YAAMic,IAAMjc,aAAe,QAAQA,EAAI,UAAU,OAAOA,CAAG;AAC3D,MAAAC,GAAM,MAAM,mBAAmBgc,CAAG,EAAE;AACpC;AAAA,IACF;AAEJ;AAEA,eAAeD,GAAQD,GAAcV,GAAqC;AACxE,MAAIU,EAAK,qBAAqB,MAAM;AAClC,UAAM1W,IAAQ8V,GAAYY,EAAK,mBAAmBV,CAAG;AACrD,UAAM,UAAU,UAAU,UAAUhW,CAAK;AACzC;AAAA,EACF;AACA,MAAI0W,EAAK,WAAW;AAClB,UAAM,EAAE,QAAAG,GAAQ,OAAA7W,EAAA,IAAU0W,EAAK,WACzB,EAAE,QAAAd,GAAQ,OAAA5gB,MAAU8hB,GAAUD,CAAM,GACpCjmB,IAAIilB,GAAeD,CAAM;AAC/B,QAAI,CAAChlB,EAAG,OAAM,IAAI,MAAM,WAAWglB,CAAM,kBAAkB;AAC3D,IAAAhlB,EAAE,SAASoE,GAAO8gB,GAAY9V,GAAOgW,CAAG,CAAC;AACzC;AAAA,EACF;AACA,MAAIU,EAAK,aAAa;AACpB,UAAM,EAAE,QAAAd,GAAQ,OAAA5gB,EAAA,IAAU8hB,GAAUJ,EAAK,WAAW,GAC9C9lB,IAAIilB,GAAeD,CAAM;AAC/B,QAAI,CAAChlB,EAAG,OAAM,IAAI,MAAM,WAAWglB,CAAM,kBAAkB;AAC3D,IAAAhlB,EAAE,WAAWoE,CAAK;AAClB;AAAA,EACF;AACA,MAAI0hB,EAAK,YAAY;AACnB,UAAME,IAAMd,GAAYY,EAAK,WAAW,SAASV,CAAG,GAC9Ce,IAAOL,EAAK,WAAW,QAAQ;AACrC,IAAIK,MAAS,YAAWnc,GAAM,QAAQgc,CAAG,IAChCG,MAAS,UAASnc,GAAM,MAAMgc,CAAG,OAC/BA,CAAG;AACd;AAAA,EACF;AACF;AAEA,SAASE,GAAU7lB,GAAiD;AAClE,QAAM+lB,IAAM/lB,EAAK,QAAQ,GAAG;AAC5B,MAAI+lB,KAAO,EAAG,OAAM,IAAI,MAAM,iBAAiB/lB,CAAI,6BAA6B;AAChF,SAAO,EAAE,QAAQA,EAAK,MAAM,GAAG+lB,CAAG,GAAG,OAAO/lB,EAAK,MAAM+lB,IAAM,CAAC,EAAA;AAChE;AAGO,SAASC,GAAW1Q,GAA4D;AACrF,SAAO,CAACA,EAAO,WAAW,CAAC,CAACA,EAAO,YAAYA,EAAO,SAAS,SAAS;AAC1E;AC9DA,MAAM2Q,KAAiB;AAEvB,SAASC,GACP3L,GACA4L,GACS;AACT,MAAI,OAAO5L,KAAQ;AACjB,WAAOA,KAAO;AAEhB,QAAMyE,IAAQzE,EAAI,MAAM0L,EAAc;AACtC,MAAI,CAACjH;AACH,WAAOzE;AAET,QAAMxW,IAAQib,EAAM,CAAC;AACrB,SAAImH,KAAOpiB,KAASoiB,IACXA,EAAIpiB,CAAK,KAAK,MAKnB,OAAO,UAAY,OAAe,QAAQ,QAC5C,QAAQ;AAAA,IACN,kCAAkCwW,CAAG,wDAAwDxW,CAAK;AAAA,EAAA,GAG/F;AACT;AAKA,SAASqiB,GAAmBjR,GAAkC;AAC5D,SAAO;AAAA,IACL,MAAMA,EAAM,QAAQ;AAAA,IACpB,UAAUA,EAAM;AAAA,IAChB,SAASA,EAAM,UACX;AAAA,MACE,MAAMA,EAAM,QAAQ,QAAQ,CAAA;AAAA,MAC5B,QAAQA,EAAM,QAAQ;AAAA,IAAA,IAExB;AAAA,IACJ,MAAMA,EAAM;AAAA,IACZ,QAAQA,EAAM;AAAA,IACd,KAAKA,EAAM,MAAM,EAAE,QAAQA,EAAM,QAAQ;AAAA,EAAA;AAE7C;AAIA,SAASkR,GACP9L,GACA+L,GACQ;AACR,SAAK/L,EAAI,SAAS,IAAI,IACfsK,GAAYtK,GAAK,EAAE,QAAQ+L,GAAU,IADZ/L;AAElC;AAKA,MAAMgM,KAAoB;AAK1B,SAASC,GAAgB1B,GAAkB2B,GAA4B;AACrE,QAAMb,IAAS,UAAUa,CAAS;AAClC,aAAWzH,KAAS8F,EAAS,SAASyB,EAAiB;AACrD,QAAIvH,EAAM,CAAC,MAAM4G,EAAQ,QAAO;AAElC,SAAO;AACT;AAWA,SAASc,GAAkB;AAAA,EACzB,OAAAvR;AAAA,EACA,OAAApG;AAAA,EACA,UAAAkJ;AAAA,EACA,cAAA0O;AACF,GAAsB;AACpB,QAAMC,IAAUrjB;AAAA,IACd,MAAOojB,IAAe,OAAO,QAAQA,CAAY,IAAI,CAAA;AAAA,IACrD,CAACA,CAAY;AAAA,EAAA;AAEf,SACE,gBAAA9f;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,OAAOkI,KAAU,WAAWA,IAAQ;AAAA,MAC3C,UAAU,CAAC/B,MAAMiL,EAASjL,EAAE,OAAO,KAAK;AAAA,MACxC,UAAUmI,EAAM;AAAA,MAEhB,UAAA;AAAA,QAAA,gBAAA3R,EAAC,UAAA,EAAO,OAAM,IAAG,UAAQ,IACtB,UAAA2R,EAAM,WAAW,2BAA2B,IAAA,CAC/C;AAAA,QACCyR,EAAQ,IAAI,CAAC,CAAC3nB,GAAMwW,CAAK,MACxB,gBAAAjS,EAAC,UAAA,EAAkB,OAAOvE,GACvB,UAAA0E,EAAI8R,EAAM,IAAI,KAAKxW,EAAA,GADTA,CAEb,CACD;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;AAGA,SAAS4nB,GAAa;AAAA,EACpB,OAAA1R;AAAA,EACA,OAAApG;AAAA,EACA,UAAAkJ;AAAA,EACA,cAAA0O;AAAA,EACA,UAAAL;AACF,GAAsB;AACpB,QAAMQ,IAAwBvjB,EAAQ,MAAM;;AAC1C,QAAI,CAACojB,EAAc,QAAO,CAAA;AAC1B,UAAMI,KAAW5iB,IAAAgR,EAAM,WAAN,gBAAAhR,EAAe;AAChC,QAAI4iB,GAAU;AACZ,YAAMC,IAAWX,GAAmBU,GAAUT,CAAQ;AACtD,aAAIU,KAAYL,EAAaK,CAAQ,IAC5BL,EAAaK,CAAQ,EAAE,WAGzB,CAAA;AAAA,IACT;AAEA,WAAO,OAAO,OAAOL,CAAY,EAAE,QAAQ,CAACM,MAAMA,EAAE,QAAQ;AAAA,EAC9D,GAAG,CAACN,GAAcxR,EAAM,QAAQmR,CAAQ,CAAC;AAEzC,SACE,gBAAAzf;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,OAAOkI,KAAU,WAAWA,IAAQ;AAAA,MAC3C,UAAU,CAAC/B,MAAMiL,EAASjL,EAAE,OAAO,KAAK;AAAA,MACxC,UAAUmI,EAAM;AAAA,MAChB,UAAU2R,EAAS,WAAW;AAAA,MAE9B,UAAA;AAAA,QAAA,gBAAAtjB,EAAC,UAAA,EAAO,OAAM,IAAG,UAAQ,IACtB,UAAAsjB,EAAS,WAAW,IAAI,8BAA8B,mBAAA,CACzD;AAAA,QACCA,EAAS,IAAI,CAACxlB,MACb,gBAAAkC,EAAC,YAAoB,OAAOlC,EAAE,MAC3B,UAAAqC,EAAIrC,EAAE,IAAI,KAAKA,EAAE,KAAA,GADPA,EAAE,IAEf,CACD;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;AAEO,SAAS4lB,GAAa;AAAA,EAC3B,MAAAvD;AAAA,EACA,cAAAC;AAAA,EACA,QAAAtO;AAAA,EACA,YAAA6R;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,KAAAlB;AACF,GAAsB;AACpB,QAAM,EAAE,MAAMrgB,EAAA,IAAWpF,GAAA,GACnB2H,IAASiN,EAAO,mBAAmB,CAAA,GACnCgS,IAAiBhS,EAAO,4BAA4B,CAAA,GACpDiS,IAAehkB,EAAQ,MAAM;AACjC,UAAMikB,IAAQlS,EAAO;AACrB,WAAIkS,KAASA,EAAM,SAAS,IACnBA,EACJ,OAAO,CAAChX,MAAQA,KAAOnI,CAAM,EAC7B,IAAI,CAACmI,MAAQ,CAACA,GAAKnI,EAAOmI,CAAG,CAAC,CAAoC,IAEhE,OAAO,QAAQnI,CAAM;AAAA,EAC9B,GAAG,CAACA,GAAQiN,EAAO,oBAAoB,CAAC,GAElCmS,IAAqBlkB,EAAQ,MAAM;;AACvC,QAAI,GAAC+R,EAAO,UAAU,CAACxP;AACvB,cAAO3B,IAAA2B,EAAO,SAASwP,EAAO,MAAM,MAA7B,gBAAAnR,EAAgC;AAAA,EACzC,GAAG,CAACmR,EAAO,QAAQxP,CAAM,CAAC,GAEpB4hB,IAAuBhlB,EAAY,MAAM;AAC7C,UAAMilB,IAAmC,EAAE,GAAGL,EAAA;AAC9C,eAAW,CAAC9W,GAAK2E,CAAK,KAAKoS;AACzB,MAAAI,EAAQnX,CAAG,IAAI0V,GAAoB/Q,EAAM,SAASgR,CAAG;AAEvD,WAAOwB;AAAA,EAGT,GAAG,CAACJ,GAAcpB,CAAG,CAAC,GAEhB,CAACG,GAAUsB,CAAW,IAAIniB;AAAA,IAC9BiiB;AAAA,EAAA,GAIIG,IAAmBnlB;AAAA,IACvB,CAAColB,MAAoB;AACnB,MAAIA,KACFF,EAAYF,GAAsB,GAEpC9D,EAAakE,CAAM;AAAA,IACrB;AAAA,IACA,CAAClE,GAAc8D,CAAoB;AAAA,EAAA,GAG/BnH,IAAoB7d,EAAY,CAACsB,GAAmB+K,MAAmB;AAC3E,IAAA6Y,EAAY,CAAClhB,MAAS;;AACpB,YAAMqH,IAAO,EAAE,GAAGrH,GAAM,CAAC1C,CAAS,GAAG+K,EAAA;AAKrC,iBAAW,CAACyB,GAAK2E,CAAK,KAAK,OAAO,QAAQ9M,CAAM,GAAG;AACjD,YAAI8M,EAAM,SAAS,SAAU;AAC7B,cAAM4S,KAAW5jB,IAAAgR,EAAM,WAAN,gBAAAhR,EAAe;AAChC,QAAK4jB,KACDvB,GAAgBuB,GAAU/jB,CAAS,MACrC+J,EAAKyC,CAAG,IAAI;AAAA,MAEhB;AACA,aAAOzC;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC1F,CAAM,CAAC,GAEL6K,IAAexQ,EAAY,MAAM;AAErC,eAAW,CAAC8N,GAAK2E,CAAK,KAAKoS;AACzB,UAAIpS,EAAM,UAAU;AAClB,cAAMgJ,IAAMmI,EAAS9V,CAAG;AACxB,YAAI2N,KAAO,QAAQA,MAAQ;AACzB;AAAA,MAEJ;AAEF,IAAAiJ,EAASd,CAAQ;AAAA,EACnB,GAAG,CAACA,GAAUiB,GAAcH,CAAQ,CAAC;AAErC,SACE,gBAAA5jB,EAACwgB,MAAO,MAAAL,GAAY,cAAckE,GAChC,UAAA,gBAAAhhB,EAACud,IAAA,EAAc,WAAU,YACvB,UAAA;AAAA,IAAA,gBAAAvd,EAACwd,IAAA,EACC,UAAA;AAAA,MAAA,gBAAA7gB,EAAC+gB,MAAa,UAAA4C,EAAA,CAAW;AAAA,MACzB,gBAAA3jB,EAACghB,MAAkB,UAAA,uDAAA,CAAoD;AAAA,IAAA,GACzE;AAAA,IAEA,gBAAAhhB,EAAC,OAAA,EAAI,WAAU,kBACZ,UAAA+jB,EAAa,IAAI,CAAC,CAAC/W,GAAK2E,CAAK,MAAM;;AAClC,YAAMsR,IAAY9iB,GAAIQ,IAAAgR,EAAM,YAAN,gBAAAhR,EAAe,IAAI,KAAKqM,GACxC0J,sBACHnI,IAAA,EACE,UAAA;AAAA,QAAA0U;AAAA,QACAtR,EAAM,YACL,gBAAA3R,EAAC,QAAA,EAAK,WAAU,oCAAmC,UAAA,IAAA,CAAC;AAAA,MAAA,GAExD;AAGF,UAAIwkB;AACJ,UAAI7S,EAAM,SAAS;AACjB,QAAA6S,IACE,gBAAAxkB;AAAA,UAACkjB;AAAA,UAAA;AAAA,YACC,OAAAvR;AAAA,YACA,OAAOmR,EAAS9V,CAAG;AAAA,YACnB,UAAU,CAACmF,MAAM4K,EAAkB/P,GAAKmF,CAAC;AAAA,YACzC,cAAc8R;AAAA,YACd,UAAAnB;AAAA,UAAA;AAAA,QAAA;AAAA,eAGKnR,EAAM,SAAS;AACxB,QAAA6S,IACE,gBAAAxkB;AAAA,UAACqjB;AAAA,UAAA;AAAA,YACC,OAAA1R;AAAA,YACA,OAAOmR,EAAS9V,CAAG;AAAA,YACnB,UAAU,CAACmF,MAAM4K,EAAkB/P,GAAKmF,CAAC;AAAA,YACzC,cAAc8R;AAAA,YACd,UAAAnB;AAAA,UAAA;AAAA,QAAA;AAAA,WAGC;AACL,cAAMviB,IAAQqiB,GAAmBjR,CAAK;AACtC,QAAA6S,IAAU1H,GAAY;AAAA,UACpB,OAAAvc;AAAA,UACA,WAAWyM;AAAA,UACX,OAAO8V,EAAS9V,CAAG;AAAA,UACnB,MAAM;AAAA,UACN,UAAU,CAACmF,MAAM4K,EAAkB/P,GAAKmF,CAAC;AAAA,QAAA,CAC1C;AAAA,MACH;AAEA,aACE,gBAAA9O,EAAC,OAAA,EAAc,WAAU,eACtB,UAAA;AAAA,QAAAqT;AAAA,QACA8N;AAAA,UACA5jB,IAAA+Q,EAAM,YAAN,gBAAA/Q,EAAe,gBACd,gBAAAZ,EAAC,KAAA,EAAE,WAAU,0CACV,UAAAG,EAAIwR,EAAM,QAAQ,WAAW,EAAA,CAChC;AAAA,MAAA,EAAA,GANM3E,CAQV;AAAA,IAEJ,CAAC,EAAA,CACH;AAAA,sBAEC8T,IAAA,EACC,UAAA;AAAA,MAAA,gBAAA9gB,EAAC8H,GAAA,EAAO,SAAQ,WAAU,SAAS,MAAMsY,EAAa,EAAK,GAAG,UAAUyD,GAAW,UAAA,SAAA,CAEnF;AAAA,MACA,gBAAA7jB,EAAC8H,KAAO,SAAS4H,GAAc,UAAUmU,GACtC,UAAAA,IAAY,iBAAiB,UAAA,CAChC;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;ACrVO,SAASY,GAAoB;AAAA,EAClC,MAAAtE;AAAA,EACA,cAAAC;AAAA,EACA,YAAAuD;AAAA,EACA,SAAAnoB;AAAA,EACA,WAAA8kB;AAAA,EACA,WAAAuD;AACF,GAA6B;AAC3B,SACE,gBAAA7jB,EAACuf,IAAA,EAAY,MAAAY,GAAY,cAAAC,GACvB,4BAACT,IAAA,EACC,UAAA;AAAA,IAAA,gBAAAtc,EAACuc,IAAA,EACC,UAAA;AAAA,MAAA,gBAAA5f,EAAC8f,MAAkB,UAAA6D,EAAA,CAAW;AAAA,MAC9B,gBAAA3jB,EAAC+f,MAAwB,UAAAvkB,EAAA,CAAQ;AAAA,IAAA,GACnC;AAAA,sBACCqkB,IAAA,EACC,UAAA;AAAA,MAAA,gBAAA7f,EAACigB,IAAA,EAAkB,UAAU4D,GAAW,UAAA,UAAM;AAAA,MAC9C,gBAAA7jB,EAACggB,MAAkB,SAASM,GAAW,UAAUuD,GAC9C,UAAAA,IAAY,iBAAiB,UAAA,CAChC;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;ACZO,SAASa,GAAmB,EAAE,MAAAvE,GAAM,SAAArX,GAAS,SAAA3H,KAAoC;AACtF,SACE,gBAAAnB,EAACwgB,IAAA,EAAO,MAAAL,GAAY,cAAc,CAACmE,MAAW;AAAE,IAAKA,KAAQxb,EAAA;AAAA,EAAW,GACtE,UAAA,gBAAAzF,EAACud,IAAA,EAAc,WAAU,YAAW,mBAAmB,CAACpX,MAAMA,EAAE,eAAA,GAAkB,iBAAiB,CAACA,MAAMA,EAAE,kBAC1G,UAAA;AAAA,IAAA,gBAAAnG,EAACwd,IAAA,EACC,UAAA;AAAA,MAAA,gBAAA7gB,EAAC+gB,IAAA,EAAa,UAAA5f,EAAQ,SAAS,iBAAgB;AAAA,MAC9CA,EAAQ,WACP,gBAAAnB,EAACghB,IAAA,EAAmB,YAAQ,QAAA,CAAQ;AAAA,IAAA,GAExC;AAAA,IAEC7f,EAAQ,UAAUA,EAAQ,OAAO,SAAS,KACzC,gBAAAnB,EAAC,SAAI,WAAU,kBACZ,YAAQ,OAAO,IAAI,CAACO,GAAO,wBACzBokB,IAAA,EAAwB,OAAApkB,EAAA,GAAH,CAAiB,CACxC,EAAA,CACH;AAAA,sBAGDugB,IAAA,EACC,UAAA,gBAAA9gB,EAAC8H,KAAO,SAASgB,GAAS,mBAAK,EAAA,CACjC;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;AAEA,SAAS6b,GAAgB,EAAE,OAAApkB,KAAkC;AAC3D,SACE,gBAAA8C,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAArD,EAAC,OAAA,EAAI,WAAU,sDACZ,UAAAO,EAAM,OACT;AAAA,IACA,gBAAA8C,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,MAAA,gBAAArD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,0EACTO,EAAM,YAAY,cAAc,EAClC;AAAA,UAEC,UAAAA,EAAM;AAAA,QAAA;AAAA,MAAA;AAAA,MAERA,EAAM,YAAY,gBAAAP,EAACiU,IAAA,EAAW,OAAO1T,EAAM,MAAA,CAAO;AAAA,IAAA,EAAA,CACrD;AAAA,EAAA,GACF;AAEJ;ACtEO,SAASqkB,GACdC,GACAlC,GACS;AACT,MAAI,CAACkC,KAAcA,EAAW,WAAW,EAAG,QAAO;AAEnD,aAAWC,KAAQD,GAAY;AAE7B,QAAIC,EAAK,UAAUA,EAAK,OAAO,SAAS,GAAG;AACzC,YAAMC,IAAYpC,EAAI;AAEtB,UADI,OAAOoC,KAAc,YACrB,CAACD,EAAK,OAAO,SAASC,CAAS,EAAG,QAAO;AAAA,IAC/C;AAEA,QAAID,EAAK,SACH,CAACE,GAAuBF,GAAMnC,CAAG;AAAG,aAAO;AAAA,EAEnD;AACA,SAAO;AACT;AAOA,SAASqC,GACPF,GACAnC,GACS;AACT,QAAMsC,IAAWtC,EAAImC,EAAK,KAAM,GAC1BI,IAAKJ,EAAK,MAAM;AAGtB,MAAI,OAAOA,EAAK,SAAU,aAAaI,MAAO;AAC5C,WAAOC,GAASF,CAAQ,MAAMH,EAAK;AAIrC,MAAI,OAAOG,KAAa,YAAY,OAAOH,EAAK,SAAU;AACxD,WAAOM,GAAcH,GAAUH,EAAK,OAAOI,CAAE;AAI/C,QAAMG,IAAWJ,KAAY,OAAO,KAAK,OAAOA,CAAQ,GAClDK,IAAUR,EAAK,SAAS,OAAO,KAAK,OAAOA,EAAK,KAAK;AAC3D,SAAOM,GAAcC,GAAUC,GAASJ,CAAE;AAC5C;AAEA,SAASC,GAASxK,GAAuB;AACvC,SAAIA,KAAO,OAAa,KACpB,OAAOA,KAAQ,YAAkBA,IACjC,OAAOA,KAAQ,WAAiBA,MAAQ,KACxC,OAAOA,KAAQ,WAAiBA,MAAQ,IACrC;AACT;AAEA,SAASyK,GAAyChU,GAAMC,GAAM6T,GAAqB;AACjF,UAAQA,GAAA;AAAA,IACN,KAAK;AAAM,aAAO9T,MAAMC;AAAA,IACxB,KAAK;AAAM,aAAOD,MAAMC;AAAA,IACxB,KAAK;AAAM,aAAOD,IAAIC;AAAA,IACtB,KAAK;AAAO,aAAOD,KAAKC;AAAA,IACxB,KAAK;AAAM,aAAOD,IAAIC;AAAA,IACtB,KAAK;AAAO,aAAOD,KAAKC;AAAA,IACxB;AAAS,aAAO;AAAA,EAAA;AAEpB;AAQO,SAASkU,GACdlV,GACAmV,GACyC;AACzC,SAAKnV,IACE,OAAO,QAAQA,CAAO,EAC1B,OAAO,CAAC,GAAGyB,CAAM;;AAAM,YAAAnR,IAAAmR,EAAO,eAAP,gBAAAnR,EAAmB,SAAS6kB;AAAA,GAAW,EAC9D,IAAI,CAAC,CAAC/pB,GAAMqW,CAAM,OAAO,EAAE,MAAArW,GAAM,QAAAqW,EAAA,EAAS,IAHxB,CAAA;AAIvB;AAOO,SAAS2T,GACdC,GACAC,GACAC,GACAC,GACyC;AACzC,SAAI,CAACH,KAAiB,CAACG,IAAsB,CAAA,IACzCF,MAAsB,SACjBA,EACJ,IAAI,CAAClqB,MAAS;AACb,UAAMqW,KAAS4T,KAAA,gBAAAA,EAAgBjqB,QAASoqB,KAAA,gBAAAA,EAAgBpqB;AACxD,WAAOqW,IAAS,EAAE,MAAArW,GAAM,QAAAqW,EAAA,IAAW;AAAA,EACrC,CAAC,EACA,OAAO,CAACrO,MAAmDA,MAAS,IAAI,IAEtE8hB,GAAuBG,GAAeE,CAAkB;AACjE;AAKO,SAASE,GAAgBhU,GAAyB;AACvD,QAAMjN,IAASiN,EAAO;AACtB,SAAKjN,IACE,OAAO,KAAKA,CAAM,EAAE,SAAS,IADhB;AAEtB;AAaO,SAASkhB,GAAoBjU,GAAyB;AAC3D,SAAOA,EAAO,SAAS,iBAAiB,CAAC,CAACA,EAAO;AACnD;AAMO,SAASkU,GACd1jB,GACA6O,GAC6C;;AAC7C,MAAK7O;AACL,eAAWiB,KAAU,OAAO,OAAOjB,EAAO,OAAO;AAC/C,UAAIiB,EAAO,WAAW4N,KAAc5N,EAAO,SAAS,QAAQ;AAC1D,cAAMlC,IAASiB,EAAO,SAAS6O,CAAU;AACzC,eAAO;AAAA,UACL,OAAO5N,EAAO;AAAA,UACd,QAAM5C,IAAA4C,EAAO,YAAP,gBAAA5C,EAAgB,WAAQC,IAAAS,KAAA,gBAAAA,EAAQ,YAAR,gBAAAT,EAAiB,SAAQ;AAAA,QAAA;AAAA,MAE3D;AAAA;AAGJ;ACvHO,SAASqlB,GAAa;AAAA,EAC3B,YAAArS;AAAA,EACA,QAAA9B;AAAA,EACA,YAAAX;AAAA,EACA,WAAA+U,IAAY,CAAA;AAAA,EACZ,KAAAvD;AAAA,EACA,SAAA5a,IAAU;AAAA,EACV,MAAAC,IAAO;AAAA,EACP,WAAAme;AAAA,EACA,cAAAC;AAAA,EACA,cAAAC;AAAA,EACA,gBAAAC;AACF,GAAsB;;AACpB,QAAM,CAACC,GAAYC,CAAa,IAAIvkB,EAAS,EAAK,GAC5C,CAACwkB,GAAaC,CAAc,IAAIzkB,EAAS,EAAK,GAC9C,CAAC0kB,GAAYC,CAAa,IAAI3kB,EAAS,EAAK,GAC5C,CAAC4kB,GAAeC,CAAgB,IAAI7kB,EAAqC,IAAI,GAC7E8kB,IAAkBpT,GAAiBxC,CAAU,GAC7C,EAAE,MAAM7O,EAAA,IAAWpF,GAAA,GACnBqF,IAAc3D,GAAA,GAEdooB,IAAgBjB,GAAoBjU,CAAM,GAC1CmV,IAAYnB,GAAgBhU,CAAM,GAClCoV,IAAkB,CAAC,CAACpV,EAAO,gBAAgB,OAAO,KAAKA,EAAO,YAAY,EAAE,SAAS,GAGrFqV,IAAgBxE,IAAMiC,GAAmB9S,EAAO,YAAY6Q,CAAG,IAAI,IAGnEyE,IAAe,IACfC,IAAkB,IAElBC,IAA4BpoB,EAAY,YAAY;;AACxD,QAAI,GAAC4S,EAAO,eAAeoU,EAAU,WAAW,IAChD;AAAA,MAAAU,EAAc,EAAI;AAClB,UAAI;AACF,cAAMW,KAAYpW,IAAa,GAAGA,CAAU,IAAIW,EAAO,WAAW,KAAKA,EAAO,aACxE9L,KAAS,MAAMiN,GAAmBsU,IAAWrB,CAAS,GACtDsB,KAAexB,GAAwB1jB,GAAQ0D,GAAO,aAAa;AACzE,YAAI,CAACwhB,IAAc;AACjB,UAAArhB,GAAM,MAAM,4BAA4BH,GAAO,aAAa,EAAE;AAC9D;AAAA,QACF;AACA,cAAMyhB,IAAenlB,KAAA,gBAAAA,EAAQ,SAAS0D,GAAO,gBACvC9B,KAAc/D,GAAIQ,KAAAmR,EAAO,YAAP,gBAAAnR,GAAgB,IAAI,KAAKqF,GAAO;AACxD,YAAIA,GAAO,IAAI,WAAW,GAAG;AAC3B,UAAAG,GAAM,KAAK,cAAcjC,EAAW,QAAQ;AAC5C;AAAA,QACF;AAEA,cAAM+W,OAAKra,KAAA6mB,KAAA,gBAAAA,EAAc,gBAAd,gBAAA7mB,GAA2B,KAAK,CAACc;;AAAM,kBAAAf,KAAA8mB,EAAa,OAAO/lB,EAAC,MAArB,gBAAAf,GAAwB;AAAA,eAAY,MAChFhC,KAAS,IAAI,gBAAA;AACnB,QAAAA,GAAO,IAAI,UAAUsc,EAAE,IAAIjV,GAAO,IAAI,KAAK,GAAG,CAAC,GAC/CzD,EAAYilB,GAAa,OAAO;AAAA,UAC9B,OAAOtjB;AAAAA,UACP,QAAMnD,KAAA+Q,EAAO,YAAP,gBAAA/Q,GAAgB,SAAQymB,GAAa;AAAA,UAC3C,QAAQ7oB,GAAO,SAAA;AAAA,QAAS,CACzB,GACDwnB,KAAA,QAAAA;AAAA,MACF,SAASjgB,IAAK;AACZ,QAAAC,GAAM,MAAMD,cAAe,QAAQA,GAAI,UAAU,+BAA+B;AAAA,MAClF,UAAA;AACE,QAAA0gB,EAAc,EAAK;AAAA,MACrB;AAAA;AAAA,EACF,GAAG,CAAC9U,GAAQX,GAAY+U,GAAW5jB,GAAQC,GAAa4jB,CAAS,CAAC,GAK5DuB,IAAsB5V,EAAO,SAAS,GAAGA,EAAO,MAAM,IAAI8B,CAAU,KAAKA,GAEzE+T,IAAYzB,EAAU,SAAS,IAAIA,IAAY,QAI/C0B,IAAsB1oB;AAAA,IAC1B,CAAC8G,IAA+F6hB,OAA6B;;AAG3H,UAFAA,MAAA,QAAAA,MAEI7hB,GAAO,WAAW,YAAY;AAChC,QAAAmgB,KAAA,QAAAA;AACA;AAAA,MACF;AAEA,YAAMhlB,MAAWR,KAAAqF,GAAO,WAAP,gBAAArF,GAAuD;AACxE,UAAIQ,IAAS;AACX,QAAA2lB,EAAiB3lB,EAAO;AACxB;AAAA,MACF;AACA,MAAI6E,GAAO,WAAW,YACpBsgB,KAAA,QAAAA,EAAiBJ,EAAU,QAAQlgB,GAAO,WAE1CmgB,KAAA,QAAAA;AAAA,IAEJ;AAAA,IACA,CAACD,EAAU,QAAQC,GAAWG,CAAc;AAAA,EAAA,GAGxCwB,KAAc5oB,EAAY,MAAM;AACpC,QAAIsjB,GAAW1Q,CAAM,GAAG;AAEtB,MAAKiQ,GAAejQ,EAAO,UAAW,EAAE,KAAA6Q,EAAA,CAAK,EAAE,KAAK,MAAMwD,KAAA,gBAAAA,GAAa;AACvE;AAAA,IACF;AACA,QAAIa,GAAe;AACjB,MAAAM,EAAA;AACA;AAAA,IACF;AACA,IAAIL,IACFT,EAAc,EAAI,IACTU,IACTR,EAAe,EAAI,KAGnBN,KAAA,QAAAA,EAAeF,EAAU,SACzBa,EAAgB;AAAA,MACd,EAAE,YAAYW,GAAqB,MAAM5U,GAAgB,QAAW6U,CAAS,EAAA;AAAA,MAC7E;AAAA,QACE,WAAW,CAAC3hB,OAAW4hB,EAAoB5hB,EAAM;AAAA,QACjD,SAAS,MAAMqgB,KAAA,gBAAAA,EAAeH,EAAU;AAAA,MAAM;AAAA,IAChD;AAAA,EAGN,GAAG,CAACpU,GAAQ6Q,GAAKqE,GAAeC,GAAWC,GAAiBQ,GAAqBC,GAAWzB,GAAWa,GAAiBa,GAAqBN,GAA2BlB,GAAcC,GAAcF,CAAS,CAAC,GAExM4B,IAAgB7oB,EAAY,MAAM;AACtC,IAAAknB,KAAA,QAAAA,EAAeF,EAAU,SACzBa,EAAgB;AAAA,MACd,EAAE,YAAYW,GAAqB,MAAM5U,GAAgB,QAAW6U,CAAS,EAAA;AAAA,MAC7E;AAAA,QACE,WAAW,CAAC3hB,OAAW4hB,EAAoB5hB,IAAQ,MAAM0gB,EAAe,EAAK,CAAC;AAAA,QAC9E,SAAS,MAAML,KAAA,gBAAAA,EAAeH,EAAU;AAAA,MAAM;AAAA,IAChD;AAAA,EAEJ,GAAG,CAACwB,GAAqBC,GAAWzB,GAAWa,GAAiBa,GAAqBxB,GAAcC,CAAY,CAAC,GAE1G2B,IAAqB9oB;AAAA,IACzB,CAAC2F,OAAoC;AACnC,MAAAuhB,KAAA,QAAAA,EAAeF,EAAU,SACzBa,EAAgB;AAAA,QACd,EAAE,YAAYW,GAAqB,MAAM5U,GAAgBjO,IAAQ8iB,CAAS,EAAA;AAAA,QAC1E;AAAA,UACE,WAAW,CAAC3hB,OAAW4hB,EAAoB5hB,IAAQ,MAAMwgB,EAAc,EAAK,CAAC;AAAA,UAC7E,SAAS,MAAMH,KAAA,gBAAAA,EAAeH,EAAU;AAAA,QAAM;AAAA,MAChD;AAAA,IAEJ;AAAA,IACA,CAACwB,GAAqBC,GAAWzB,GAAWa,GAAiBa,GAAqBxB,GAAcC,CAAY;AAAA,EAAA,GAGxGniB,IAAc/D,GAAIQ,IAAAmR,EAAO,YAAP,gBAAAnR,EAAgB,IAAI,GACtCqe,KAAOpe,IAAAkR,EAAO,YAAP,gBAAAlR,EAAgB;AAE7B,SACE,gBAAAyC,EAAAoF,IAAA,EACE,UAAA;AAAA,IAAA,gBAAApF;AAAA,MAACyE;AAAA,MAAA;AAAA,QACC,SAAAC;AAAA,QACA,MAAAC;AAAA,QACA,SAAS8f;AAAA,QACT,UAAU,CAACX,KAAiBC,KAAgBC,KAAmBN,EAAgB,aAAaJ;AAAA,QAC5F,OAAOziB;AAAA,QACP,cAAYA;AAAA,QAEX,UAAA;AAAA,UAAA8a,KAAQ,gBAAAhf,EAACJ,IAAA,EAAY,MAAMof,GAAM,WAAU,WAAU;AAAA,UACrDhX,MAAS,UAAU9D;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGrB+iB,KACC,gBAAAjnB;AAAA,MAAC0jB;AAAA,MAAA;AAAA,QACC,MAAM6C;AAAA,QACN,cAAcC;AAAA,QACd,QAAA1U;AAAA,QACA,YAAY5N;AAAA,QACZ,UAAU8jB;AAAA,QACV,WAAWjB,EAAgB;AAAA,QAC3B,KAAApE;AAAA,MAAA;AAAA,IAAA;AAAA,IAIHuE,KACC,gBAAAlnB;AAAA,MAACykB;AAAA,MAAA;AAAA,QACC,MAAMgC;AAAA,QACN,cAAcC;AAAA,QACd,YAAYxiB;AAAA,QACZ,SAAS/D,EAAI2R,EAAO,YAAY;AAAA,QAChC,WAAWiW;AAAA,QACX,WAAWhB,EAAgB;AAAA,MAAA;AAAA,IAAA;AAAA,IAI9BF,KACC,gBAAA7mB;AAAA,MAAC0kB;AAAA,MAAA;AAAA,QACC,MAAM,CAAC,CAACmC;AAAA,QACR,SAAS,MAAM;AACb,UAAAC,EAAiB,IAAI,GACrBX,KAAA,QAAAA;AAAA,QACF;AAAA,QACA,SAASU;AAAA,MAAA;AAAA,IAAA;AAAA,EACX,GAEJ;AAEJ;AC1NO,SAASoB,GAAc;AAAA,EAC5B,YAAArU;AAAA,EACA,QAAA9B;AAAA,EACA,YAAAX;AAAA,EACA,UAAA+W;AAAA,EACA,KAAAvF;AAAA,EACA,WAAAwD;AACF,GAAuB;;AACrB,QAAM,CAACI,GAAYC,CAAa,IAAIvkB,EAAS,EAAK,GAC5C,CAACwkB,GAAaC,CAAc,IAAIzkB,EAAS,EAAK,GAC9C8kB,IAAkBpT,GAAiBxC,CAAU,GAC7C,EAAE,MAAM7O,EAAA,IAAWpF,GAAA,GACnBqF,IAAc3D,GAAA,GAEdooB,IAAgBjB,GAAoBjU,CAAM,GAC1CmV,IAAYnB,GAAgBhU,CAAM,GAClCoV,IAAkB,CAAC,CAACpV,EAAO,gBAAgB,OAAO,KAAKA,EAAO,YAAY,EAAE,SAAS,GACrFqV,IAAgBvC,GAAmB9S,EAAO,YAAY6Q,CAAG,GAEzDze,IAAc/D,GAAIQ,IAAAmR,EAAO,YAAP,gBAAAnR,EAAgB,IAAI,GACtCqe,KAAOpe,IAAAkR,EAAO,YAAP,gBAAAlR,EAAgB,MAEvB0mB,IAA4BpoB,EAAY,YAAY;;AACxD,QAAK4S,EAAO;AACZ,UAAI;AACF,cAAMyV,IAAYpW,IAAa,GAAGA,CAAU,IAAIW,EAAO,WAAW,KAAKA,EAAO,aACxE9L,IAAS,MAAMiN,GAAmBsU,GAAW,CAACW,CAAQ,CAAC,GACvDV,IAAexB,GAAwB1jB,GAAQ0D,EAAO,aAAa;AACzE,YAAI,CAACwhB,GAAc;AACjB,UAAArhB,GAAM,MAAM,4BAA4BH,EAAO,aAAa,EAAE;AAC9D;AAAA,QACF;AACA,cAAMyhB,KAAenlB,KAAA,gBAAAA,EAAQ,SAAS0D,EAAO,gBACvC1G,IAAOa,GAAIQ,IAAAmR,EAAO,YAAP,gBAAAnR,EAAgB,IAAI,KAAKqF,EAAO;AACjD,YAAIA,EAAO,IAAI,WAAW,GAAG;AAC3B,UAAAG,GAAM,KAAK,cAAc7G,CAAI,QAAQ;AACrC;AAAA,QACF;AACA,cAAM2b,MAAKra,IAAA6mB,MAAA,gBAAAA,GAAc,gBAAd,gBAAA7mB,EAA2B,KAAK,CAACc;;AAAM,kBAAAf,IAAA8mB,GAAa,OAAO/lB,CAAC,MAArB,gBAAAf,EAAwB;AAAA,eAAY,MAChFhC,IAAS,IAAI,gBAAA;AACnB,QAAAA,EAAO,IAAI,UAAUsc,CAAE,IAAIjV,EAAO,IAAI,KAAK,GAAG,CAAC,GAC/CzD,EAAYilB,EAAa,OAAO;AAAA,UAC9B,OAAOloB;AAAA,UACP,QAAMyB,IAAA+Q,EAAO,YAAP,gBAAA/Q,EAAgB,SAAQymB,EAAa;AAAA,UAC3C,QAAQ7oB,EAAO,SAAA;AAAA,QAAS,CACzB,GACDwnB,KAAA,QAAAA;AAAA,MACF,SAASjgB,GAAK;AACZ,QAAAC,GAAM,MAAMD,aAAe,QAAQA,EAAI,UAAU,+BAA+B;AAAA,MAClF;AAAA,EACF,GAAG,CAAC4L,GAAQX,GAAY+W,GAAU5lB,GAAQC,GAAa4jB,CAAS,CAAC,GAI3DuB,IAAsB5V,EAAO,SAAS,GAAGA,EAAO,MAAM,IAAI8B,CAAU,KAAKA,GAEzEkU,IAAc5oB,EAAY,MAAM;AACpC,QAAI8nB,GAAe;AACjB,MAAAM,EAAA;AACA;AAAA,IACF;AACA,IAAIL,IACFT,EAAc,EAAI,IACTU,IACTR,EAAe,EAAI,IAEnBK,EAAgB;AAAA,MACd,EAAE,YAAYW,GAAqB,MAAM5U,GAAgB,QAAW,CAACoV,CAAQ,CAAC,EAAA;AAAA,MAC9E,EAAE,WAAA/B,EAAA;AAAA,IAAU;AAAA,EAGlB,GAAG,CAACa,GAAeC,GAAWC,GAAiBQ,GAAqBQ,GAAUnB,GAAiBZ,GAAWmB,CAAyB,CAAC,GAE9HS,IAAgB7oB,EAAY,MAAM;AACtC,IAAA6nB,EAAgB;AAAA,MACd,EAAE,YAAYW,GAAqB,MAAM5U,GAAgB,QAAW,CAACoV,CAAQ,CAAC,EAAA;AAAA,MAC9E,EAAE,WAAW,MAAM;AAAE,QAAAxB,EAAe,EAAK,GAAGP,KAAA,QAAAA;AAAA,MAAe,EAAA;AAAA,IAAE;AAAA,EAEjE,GAAG,CAACuB,GAAqBQ,GAAUnB,GAAiBZ,CAAS,CAAC,GAExD6B,IAAqB9oB;AAAA,IACzB,CAAC2F,MAAoC;AACnC,MAAAkiB,EAAgB;AAAA,QACd,EAAE,YAAYW,GAAqB,MAAM5U,GAAgBjO,GAAQ,CAACqjB,CAAQ,CAAC,EAAA;AAAA,QAC3E,EAAE,WAAW,MAAM;AAAE,UAAA1B,EAAc,EAAK,GAAGL,KAAA,QAAAA;AAAA,QAAe,EAAA;AAAA,MAAE;AAAA,IAEhE;AAAA,IACA,CAACuB,GAAqBQ,GAAUnB,GAAiBZ,CAAS;AAAA,EAAA;AAG5D,SACE,gBAAA9iB,EAAAoF,IAAA,EACE,UAAA;AAAA,IAAA,gBAAApF;AAAA,MAAC+D;AAAA,MAAA;AAAA,QACC,SAAS0gB;AAAA,QACT,UAAU,CAACX;AAAA,QAEV,UAAA;AAAA,UAAAnI,KAAQ,gBAAAhf,EAACJ,IAAA,EAAY,MAAMof,GAAM,WAAU,gBAAe;AAAA,UAC1D9a;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGF+iB,KACC,gBAAAjnB;AAAA,MAAC0jB;AAAA,MAAA;AAAA,QACC,MAAM6C;AAAA,QACN,cAAcC;AAAA,QACd,QAAA1U;AAAA,QACA,YAAY5N;AAAA,QACZ,UAAU8jB;AAAA,QACV,WAAWjB,EAAgB;AAAA,MAAA;AAAA,IAAA;AAAA,IAI9BG,KACC,gBAAAlnB;AAAA,MAACykB;AAAA,MAAA;AAAA,QACC,MAAMgC;AAAA,QACN,cAAcC;AAAA,QACd,YAAYxiB;AAAA,QACZ,SAAS/D,EAAI2R,EAAO,YAAY;AAAA,QAChC,WAAWiW;AAAA,QACX,WAAWhB,EAAgB;AAAA,MAAA;AAAA,IAAA;AAAA,EAC7B,GAEJ;AAEJ;AC/HO,SAASoB,GAAoB;AAAA,EAClC,OAAAC;AAAA,EACA,WAAAvE;AAAA,EACA,WAAAwE;AAAA,EACA,SAAAC;AAAA,EACA,WAAAC;AACF,GAA6B;AAC3B,SAAIH,MAAU,KAAK,CAACvE,KAAa,CAACwE,KAAa,CAACC,KAAW,CAACC,IAAkB,OAG5E,gBAAAllB,EAAC,OAAA,EAAI,WAAU,kEACZ,UAAA;AAAA,IAAAwgB,KACC,gBAAAxgB,EAAAoF,IAAA,EACE,UAAA;AAAA,MAAA,gBAAAzI,EAACwoB,IAAA,EAAQ,WAAU,uBAAA,CAAuB;AAAA,wBACzC,QAAA,EAAK,UAAA;AAAA,QAAA;AAAA,QAAYJ;AAAA,QAAM;AAAA,QAAEA,MAAU,IAAI,SAAS;AAAA,QAAQ;AAAA,MAAA,EAAA,CAAG;AAAA,IAAA,GAC9D;AAAA,IAED,CAACvE,KAAawE,KACb,gBAAAhlB,EAAAoF,IAAA,EACE,UAAA;AAAA,MAAA,gBAAAzI,EAACyoB,IAAA,EAAa,WAAU,yBAAA,CAAyB;AAAA,wBAChD,QAAA,EAAM,UAAA;AAAA,QAAAL;AAAA,QAAM;AAAA,QAAEA,MAAU,IAAI,SAAS;AAAA,QAAQ;AAAA,MAAA,EAAA,CAAU;AAAA,IAAA,GAC1D;AAAA,IAED,CAACvE,KAAa0E,KACb,gBAAAllB,EAAAoF,IAAA,EACE,UAAA;AAAA,MAAA,gBAAAzI,EAAC0oB,IAAA,EAAc,WAAU,0BAAA,CAA0B;AAAA,MACnD,gBAAA1oB,EAAC,UAAK,UAAA,0DAAA,CAAuD;AAAA,IAAA,GAC/D;AAAA,IAED,CAAC6jB,KAAayE,KACb,gBAAAjlB,EAAAoF,IAAA,EACE,UAAA;AAAA,MAAA,gBAAAzI,EAAC2oB,IAAA,EAAQ,WAAU,oCAAA,CAAoC;AAAA,wBACtD,QAAA,EAAK,UAAA;AAAA,QAAA;AAAA,QAAmBP;AAAA,QAAM;AAAA,QAAEA,MAAU,IAAI,SAAS;AAAA,MAAA,EAAA,CAAQ;AAAA,IAAA,GAClE;AAAA,IAED,CAACvE,KAAa,CAACwE,KAAa,CAACC,KAAW,CAACC,KAAaH,IAAQ,KAC7D,gBAAA/kB,EAAC,QAAA,EAAM,UAAA;AAAA,MAAA+kB;AAAA,MAAM;AAAA,MAAEA,MAAU,IAAI,SAAS;AAAA,MAAQ;AAAA,IAAA,EAAA,CAAS;AAAA,EAAA,GAE3D;AAEJ;ACzBO,MAAMQ,yBAAmB,IAAc;AAAA,EAC5C;AAAA,EAAY;AAAA,EACZ;AAAA,EAAS;AAAA,EAAa;AAAA,EACtB;AAAA,EAAe;AAAA,EACf;AAAA,EAAa;AACf,CAAC,GAGYC,KAAsC;AAAA,EACjD,IAAI;AAAA,EACJ,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,UAAU;AAAA,EACV,aAAa;AAAA,EACb,UAAU;AAAA,EACV,cAAc;AAAA,EACd,OAAO;AAAA,EACP,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,cAAc;AAAA,EACd,WAAW;AAAA,EACX,eAAe;AACjB;AAOO,SAASC,GAAoB9Z,GAA6C;AAC/E,QAAM+H,IAAM/H,EAAa,IAAI,SAAS;AACtC,MAAI,CAAC+H,EAAK,QAAO,CAAA;AACjB,MAAI;AACF,UAAMrL,IAAS,KAAK,MAAMqL,CAAG;AAC7B,WAAO,MAAM,QAAQrL,CAAM,IAAIA,IAAS,CAAA;AAAA,EAC1C,QAAQ;AACN,WAAO,CAAA;AAAA,EACT;AACF;AAGO,SAASqd,GACd1c,GACA2C,GACM;AACN,EAAI3C,EAAQ,WAAW,IACrB2C,EAAa,OAAO,SAAS,IAE7BA,EAAa,IAAI,WAAW,KAAK,UAAU3C,CAAO,CAAC;AAEvD;AAuBO,SAAS2c,GAAYxmB,GAA8B;AACxD,SAAOA,EAAM,KAAK,CAAC8F,MAAMA,EAAE,MAAM,IAAI;AACvC;AAGO,SAAS2gB,GAAoBzmB,GAAmC;AACrE,QAAMwD,IAAuB,CAAA;AAC7B,aAAWsC,KAAK9F,GAAO;AAIrB,QAHI8F,EAAE,SAASA,EAAE,MACftC,EAAO,KAAKsC,CAAC,GAEXA,EAAE;AACJ,iBAAW2J,KAAS3J,EAAE;AACpB,QAAAtC,EAAO,KAAK,GAAGijB,GAAoBhX,CAAK,CAAC;AAG7C,IAAI3J,EAAE,OACJtC,EAAO,KAAK,GAAGijB,GAAoB3gB,EAAE,GAAG,CAAC;AAAA,EAE7C;AACA,SAAOtC;AACT;AAGO,SAASkjB,GAAmB1mB,GAA6B;AAC9D,SAAOymB,GAAoBzmB,CAAK,EAAE;AACpC;AAgBO,SAAS2mB,GAAS5oB,GAAegL,GAA2B;AACjE,SAAO,EAAE,OAAAhL,GAAO,IAAI,MAAM,OAAAgL,EAAA;AAC5B;AAGO,SAAS6d,GAAa5mB,GAAqBjC,GAA6B;AAC7E,QAAMyF,IAAuB,CAAA;AAC7B,aAAWsC,KAAK9F;AACd,QAAI8F,EAAE,UAAU/H,GAChB;AAAA,UAAI+H,EAAE,IAAI;AACR,cAAM+gB,IAAU/gB,EAAE,GACf,IAAI,CAAC2J,MAAUmX,GAAanX,GAAO1R,CAAK,CAAC,EACzC,OAAO,CAAC0R,MAAUA,EAAM,SAAS,CAAC;AACrC,QAAIoX,EAAQ,SAAS,KAAGrjB,EAAO,KAAK,EAAE,GAAGsC,GAAG,IAAI+gB,GAAS;AACzD;AAAA,MACF;AACA,UAAI/gB,EAAE,KAAK;AACT,cAAM+gB,IAAUD,GAAa9gB,EAAE,KAAK/H,CAAK;AACzC,QAAI8oB,EAAQ,SAAS,KAAGrjB,EAAO,KAAK,EAAE,GAAGsC,GAAG,KAAK+gB,GAAS;AAC1D;AAAA,MACF;AACA,MAAArjB,EAAO,KAAKsC,CAAC;AAAA;AAEf,SAAOtC;AACT;ACvKO,SAASsjB,KAAa;AAC3B,QAAM,CAACta,GAAcua,CAAe,IAAIta,GAAA,GAElC5C,IAAUtM;AAAA,IACd,MAAM+oB,GAAoB9Z,CAAY;AAAA,IACtC,CAACA,CAAY;AAAA,EAAA,GAGTwa,IAAczpB,EAAQ,MAAMmpB,GAAmB7c,CAAO,GAAG,CAACA,CAAO,CAAC,GAElEod,IAAavqB;AAAA,IACjB,CAACwqB,MAA6B;AAC5B,YAAMnf,IAAO,IAAI,gBAAgByE,CAAY;AAC7C,MAAA+Z,GAAgBW,GAAYnf,CAAI,GAChCA,EAAK,IAAI,QAAQ,GAAG,GACpBgf,EAAgBhf,CAAI;AAAA,IACtB;AAAA,IACA,CAACyE,GAAcua,CAAe;AAAA,EAAA,GAG1BI,IAAezqB,EAAY,MAAM;AACrC,UAAMqL,IAAO,IAAI,gBAAgByE,CAAY;AAC7C,IAAAzE,EAAK,OAAO,SAAS,GACrBA,EAAK,IAAI,QAAQ,GAAG,GACpBgf,EAAgBhf,CAAI;AAAA,EACtB,GAAG,CAACyE,GAAcua,CAAe,CAAC;AAElC,SAAO,EAAE,SAAAld,GAAS,aAAAmd,GAAa,YAAAC,GAAY,cAAAE,EAAA;AAC7C;AChBO,SAASC,GAAY;AAAA,EAC1B,SAAAvd;AAAA,EACA,UAAAwd;AAAA,EACA,YAAAC;AAAA,EACA,aAAAC;AAAA,EACA,YAAAC,IAAa,CAACtoB,MAAMA;AACtB,GAAqB;AACnB,MAAI2K,EAAQ,WAAW,EAAG,QAAO;AAIjC,MAFiB2c,GAAY3c,CAAO;AAGlC,WACE,gBAAAhJ,EAAC,OAAA,EAAI,WAAU,0CACZ,UAAA;AAAA,MAAAgJ,EAAQ,IAAI,CAACtJ,GAAMwJ,MACdxJ,EAAK,KAEL,gBAAA/C,EAAC,OAAA,EAAY,WAAU,2BACpB,UAAA+C,EAAK,GAAG,IAAI,CAACkP,GAAOgY,MACnB,gBAAA5mB,EAAC,QAAA,EAAc,WAAU,2BACtB,UAAA;AAAA,QAAA4mB,IAAK,KACJ,gBAAAjqB,EAAC,QAAA,EAAK,WAAU,2DAA0D,UAAA,MAE1E;AAAA,QAEF,gBAAAA;AAAA,UAACyQ;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAASsZ;AAAA,YAER,UAAA9X,EACE,OAAO,CAAC3J,MAAMA,EAAE,SAASA,EAAE,EAAE,EAC7B,IAAI,CAACA,MAAM,GAAG0hB,EAAW1hB,EAAE,KAAM,CAAC,IAAI4hB,GAAY5hB,CAAC,CAAC,EAAE,EACtD,KAAK,OAAO;AAAA,UAAA;AAAA,QAAA;AAAA,MACjB,EAAA,GAfS2hB,CAgBX,CACD,EAAA,GAnBO1d,CAoBV,IAGAxJ,EAAK,SAASA,EAAK,KAEnB,gBAAA/C;AAAA,QAACmqB;AAAA,QAAA;AAAA,UAEC,MAAApnB;AAAA,UACA,YAAAinB;AAAA,UACA,UAAU,MAAMH,EAAS9mB,EAAK,KAAM;AAAA,UACpC,SAASgnB;AAAA,QAAA;AAAA,QAJJ,GAAGhnB,EAAK,KAAK,IAAIwJ,CAAC;AAAA,MAAA,IAQtB,IACR;AAAA,MACD,gBAAAlJ;AAAA,QAACyE;AAAA,QAAA;AAAA,UACC,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,SAASgiB;AAAA,UACT,WAAU;AAAA,UAEV,UAAA;AAAA,YAAA,gBAAA9pB,EAACyJ,IAAA,EAAE,WAAU,eAAA,CAAe;AAAA,YAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAEhC,GACF;AAKJ,QAAM2gB,IAAanB,GAAoB5c,CAAO;AAC9C,SACE,gBAAAhJ,EAAC,OAAA,EAAI,WAAU,0CACZ,UAAA;AAAA,IAAA+mB,EAAW,IAAI,CAACrnB,GAAMwJ,MACrB,gBAAAvM;AAAA,MAACmqB;AAAA,MAAA;AAAA,QAEC,MAAApnB;AAAA,QACA,YAAAinB;AAAA,QACA,UAAU,MAAMH,EAAS9mB,EAAK,KAAM;AAAA,QACpC,SAASgnB;AAAA,MAAA;AAAA,MAJJ,GAAGhnB,EAAK,KAAK,IAAIwJ,CAAC;AAAA,IAAA,CAM1B;AAAA,IACD,gBAAAlJ;AAAA,MAACyE;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,SAASgiB;AAAA,QACT,WAAU;AAAA,QAEV,UAAA;AAAA,UAAA,gBAAA9pB,EAACyJ,IAAA,EAAE,WAAU,eAAA,CAAe;AAAA,UAAE;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAEhC,GACF;AAEJ;AAEA,SAAS0gB,GAAW;AAAA,EAClB,MAAApnB;AAAA,EACA,YAAAinB;AAAA,EACA,UAAAH;AAAA,EACA,SAAAQ;AACF,GAKG;AACD,SACE,gBAAAhnB;AAAA,IAACoN;AAAA,IAAA;AAAA,MACC,SAAQ;AAAA,MACR,WAAU;AAAA,MAEV,UAAA;AAAA,QAAA,gBAAApN,EAAC,UAAK,SAAAgnB,GACH,UAAA;AAAA,UAAAL,EAAWjnB,EAAK,KAAM;AAAA,UAAE;AAAA,UAAE;AAAA,4BAC1B,QAAA,EAAK,WAAU,eAAe,UAAAmnB,GAAYnnB,CAAI,EAAA,CAAE;AAAA,QAAA,GACnD;AAAA,QACA,gBAAA/C;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,CAACwJ,MAAM;AACd,cAAAA,EAAE,gBAAA,GACFqgB,EAAA;AAAA,YACF;AAAA,YACA,WAAU;AAAA,YAEV,UAAA,gBAAA7pB,EAACyJ,IAAA,EAAE,WAAU,UAAA,CAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACzB;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,SAASygB,GAAYnnB,GAA0B;AAC7C,MAAI,CAACA,EAAK,GAAI,QAAO;AACrB,QAAM2T,IAAQmS,GAAU9lB,EAAK,EAAE,KAAKA,EAAK;AACzC,MAAI6lB,GAAa,IAAI7lB,EAAK,EAAE,EAAG,QAAO2T;AACtC,QAAMiE,IAAM,MAAM,QAAQ5X,EAAK,KAAK,IAChCA,EAAK,MAAM,KAAK,IAAI,IACpB,OAAOA,EAAK,SAAS,EAAE;AAC3B,SAAO,GAAG2T,CAAK,IAAIiE,CAAG;AACxB;AC7GO,SAAS2P,GAAa;AAAA,EAC3B,MAAAnK;AAAA,EACA,SAAArX;AAAA,EACA,SAAAuD;AAAA,EACA,SAAAke;AAAA,EACA,iBAAAC;AACF,GAAsB;AAEpB,QAAM,CAAClM,GAAOC,CAAQ,IAAItc,EAAuBoK,CAAO,GAClD,CAACoe,GAAiBC,CAAkB,IAAIzoB,EAAS,EAAK;AAO5D,MAJAmL,GAAU,MAAM;AACd,IAAI+S,OAAe9T,CAAO;AAAA,EAC5B,GAAG,CAAC8T,GAAM9T,CAAO,CAAC,GAEd,CAAC8T,EAAM,QAAO;AAElB,QAAMwK,IAAW3B,GAAY1K,CAAK,GAG5BsM,IAAe,IAAI;AAAA,IACvBtM,EAAM,OAAO,CAAChW,MAAMA,EAAE,KAAK,EAAE,IAAI,CAACA,MAAMA,EAAE,KAAM;AAAA,EAAA,GAG5CuiB,IAAe,CAACC,MAAsB;AAC1C,UAAMC,IAAOP,EAAgB,KAAK,CAAC9oB,MAAMA,EAAE,SAASopB,CAAS;AAC7D,QAAI,CAACC,EAAM;AACX,UAAMC,IAAYD,EAAK,UAAU,CAAC,KAAK;AACvC,IAAAxM,EAAS,CAAC,GAAGD,GAAO,EAAE,OAAOwM,GAAW,IAAIE,EAAA,CAAW,CAAC,GACxDN,EAAmB,EAAK;AAAA,EAC1B,GAEMO,IAAkB,CAACvvB,GAAewvB,MAAiC;AACvE,IAAA3M,EAASD,EAAM,IAAI,CAAChW,GAAGiE,MAAOA,MAAM7Q,IAAQ,EAAE,GAAG4M,GAAG,GAAG4iB,EAAA,IAAY5iB,CAAE,CAAC;AAAA,EACxE,GAEM6iB,IAAkB,CAACzvB,MAAkB;AACzC,IAAA6iB,EAASD,EAAM,OAAO,CAAClB,GAAG7Q,MAAMA,MAAM7Q,CAAK,CAAC;AAAA,EAC9C,GAEM0vB,IAAa,MAAM;AAEvB,UAAMC,IAAoB/M,EAAM,OAAO,CAAChW,MAAMA,EAAE,SAASA,EAAE,EAAE,GACvDgjB,IAAahN,EAAM,OAAO,CAAChW,MAAM,CAACA,EAAE,SAAS,CAACA,EAAE,EAAE;AACxD,IAAAiW,EAAS;AAAA,MACP,GAAG+M;AAAA,MACH;AAAA,QACE,IAAI;AAAA,UACFD,EAAkB,SAAS,IAAIA,IAAoB,CAAA;AAAA,UACnD,CAAA;AAAA,QAAC;AAAA,MACH;AAAA,IACF,CACD;AAAA,EACH,GAEME,IAAc,MAAM;AAExB,UAAMlC,IAAU/K,EACb,IAAI,CAAChW,MAAM;AACV,UAAIA,EAAE,IAAI;AACR,cAAMkjB,IAAaljB,EAAE,GAAG,OAAO,CAACmb,MAAMA,EAAE,SAAS,CAAC;AAClD,eAAO+H,EAAW,SAAS,IAAI,EAAE,GAAGljB,GAAG,IAAIkjB,MAAe;AAAA,MAC5D;AACA,aAAOljB,EAAE,SAASA,EAAE,KAAKA,IAAI;AAAA,IAC/B,CAAC,EACA,OAAO,CAACA,MAAuBA,MAAM,IAAI;AAC5C,IAAAiiB,EAAQlB,CAAO,GACfvgB,EAAA;AAAA,EACF,GAEM2iB,IAAc,MAAM;AACxB,IAAAlN,EAAS,CAAA,CAAE;AAAA,EACb;AAEA,SACE,gBAAAlb,EAAC,OAAA,EAAI,WAAU,oIAEb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,+EACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,QAAA,gBAAArD,EAAC0rB,IAAA,EAAO,WAAU,UAAA,CAAU;AAAA,QAC5B,gBAAA1rB,EAAC,MAAA,EAAG,WAAU,yBAAwB,UAAA,UAAA,CAAO;AAAA,MAAA,GAC/C;AAAA,MACA,gBAAAA,EAAC8H,GAAA,EAAO,SAAQ,SAAQ,MAAK,QAAO,SAASgB,GAAS,WAAU,WAC9D,UAAA,gBAAA9I,EAACyJ,IAAA,EAAE,WAAU,WAAU,EAAA,CACzB;AAAA,IAAA,GACF;AAAA,IAGA,gBAAApG,EAAC,OAAA,EAAI,WAAU,sCACZ,UAAA;AAAA,MAACsnB;AAAA;AAAA,QAoBArM,EAAM,IAAI,CAACvb,GAAMwJ,MAAM;AACrB,cAAI,CAACxJ,EAAK,IAAI;AACZ,gBAAI,CAACA,EAAK,SAAS,CAACA,EAAK,GAAI,QAAO;AACpC,kBAAMgoB,IAAOP,EAAgB,KAAK,CAAC9oB,MAAMA,EAAE,SAASqB,EAAK,KAAK;AAC9D,mBAAKgoB,IAEH,gBAAA/qB;AAAA,cAAC2rB;AAAA,cAAA;AAAA,gBAEC,MAAA5oB;AAAA,gBACA,MAAAgoB;AAAA,gBACA,UAAU,CAACG,MAAYD,EAAgB1e,GAAG2e,CAAO;AAAA,gBACjD,UAAU,MAAMC,EAAgB5e,CAAC;AAAA,cAAA;AAAA,cAJ5B,GAAGxJ,EAAK,KAAK,IAAIwJ,CAAC;AAAA,YAAA,IAHT;AAAA,UAUpB;AACA,iBACE,gBAAAvM;AAAA,YAAC4rB;AAAA,YAAA;AAAA,cAEC,QAAQ7oB,EAAK;AAAA,cACb,iBAAAynB;AAAA,cACA,UAAU,CAACqB,MAAc;AACvB,sBAAMC,IAAW,CAAC,GAAGxN,CAAK;AAC1B,gBAAAwN,EAASvf,CAAC,IAAI,EAAE,IAAIsf,EAAA,GACpBtN,EAASuN,CAAQ;AAAA,cACnB;AAAA,YAAA;AAAA,YAPK,MAAMvf,CAAC;AAAA,UAAA;AAAA,QAUlB,CAAC;AAAA;AAAA;AAAA,QA7CD,gBAAAvM,EAAAyI,IAAA,EACG,UAAA6V,EAAM,IAAI,CAACvb,GAAMwJ,MAAM;AACtB,cAAI,CAACxJ,EAAK,SAAS,CAACA,EAAK,GAAI,QAAO;AACpC,gBAAMgoB,IAAOP,EAAgB,KAAK,CAAC9oB,MAAMA,EAAE,SAASqB,EAAK,KAAK;AAC9D,iBAAKgoB,IAEH,gBAAA/qB;AAAA,YAAC2rB;AAAA,YAAA;AAAA,cAEC,MAAA5oB;AAAA,cACA,MAAAgoB;AAAA,cACA,UAAU,CAACG,MAAYD,EAAgB1e,GAAG2e,CAAO;AAAA,cACjD,UAAU,MAAMC,EAAgB5e,CAAC;AAAA,YAAA;AAAA,YAJ5B,GAAGxJ,EAAK,KAAK,IAAIwJ,CAAC;AAAA,UAAA,IAHT;AAAA,QAUpB,CAAC,EAAA,CACH;AAAA;AAAA,MAkCF,gBAAAvM,EAAC,OAAA,EAAI,WAAU,gCACZ,UAAAyqB,IACC,gBAAAzqB;AAAA,QAAC+rB;AAAA,QAAA;AAAA,UACC,QAAQvB;AAAA,UACR,cAAAI;AAAA,UACA,UAAUC;AAAA,UACV,UAAU,MAAMH,EAAmB,EAAK;AAAA,QAAA;AAAA,MAAA,IAG1C,gBAAArnB,EAAAoF,IAAA,EACE,UAAA;AAAA,QAAA,gBAAApF;AAAA,UAACyE;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,MAAM4iB,EAAmB,EAAI;AAAA,YAEtC,UAAA;AAAA,cAAA,gBAAA1qB,EAACsd,IAAA,EAAK,WAAU,eAAA,CAAe;AAAA,cAAE;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGlC,CAACqN,KAAYrM,EAAM,KAAK,CAAChW,MAAMA,EAAE,KAAK,KACrC,gBAAAjF;AAAA,UAACyE;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAASsjB;AAAA,YACT,WAAU;AAAA,YAEV,UAAA;AAAA,cAAA,gBAAAprB,EAACsd,IAAA,EAAK,WAAU,eAAA,CAAe;AAAA,cAAE;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAEnC,EAAA,CAEJ,EAAA,CAEJ;AAAA,IAAA,GACF;AAAA,IAGA,gBAAAja,EAAC,OAAA,EAAI,WAAU,+EACb,UAAA;AAAA,MAAA,gBAAArD,EAAC8H,KAAO,SAAQ,SAAQ,MAAK,MAAK,SAAS2jB,GAAa,UAAA,QAAA,CAExD;AAAA,wBACC3jB,GAAA,EAAO,MAAK,MAAK,SAASyjB,GAAa,UAAA,QAAA,CAExC;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAMA,SAASI,GAAU;AAAA,EACjB,MAAA5oB;AAAA,EACA,MAAAgoB;AAAA,EACA,UAAAiB;AAAA,EACA,UAAAnC;AACF,GAKG;AACD,QAAMoC,IAAYrD,GAAa,IAAI7lB,EAAK,EAAc;AAEtD,SACE,gBAAAM,EAAC,OAAA,EAAI,WAAU,iCACb,UAAA;AAAA,IAAA,gBAAArD,EAAC,QAAA,EAAK,WAAU,8CACb,UAAA+qB,EAAK,OACR;AAAA,IACA,gBAAA1nB;AAAA,MAAC8R;AAAA,MAAA;AAAA,QACC,OAAOpS,EAAK;AAAA,QACZ,eAAe,CAACmiB,MAAO8G,EAAS,EAAE,IAAA9G,GAAoB;AAAA,QAEtD,UAAA;AAAA,UAAA,gBAAAllB,EAACsV,IAAA,EAAc,WAAU,yBACvB,UAAA,gBAAAtV,EAACqV,MAAY,GACf;AAAA,4BACCK,IAAA,EACE,UAAAqV,EAAK,UAAU,IAAI,CAAC7F,MACnB,gBAAAllB,EAAC4V,IAAA,EAAoB,OAAOsP,GAAI,WAAU,WACvC,UAAA2D,GAAU3D,CAAE,KAAKA,EAAA,GADHA,CAEjB,CACD,EAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGD,CAAC+G,MACAlB,EAAK,UACH,gBAAA1nB;AAAA,MAAC8R;AAAA,MAAA;AAAA,QACC,OAAO,OAAOpS,EAAK,SAAS,EAAE;AAAA,QAC9B,eAAe,CAACoP,MAAM6Z,EAAS,EAAE,OAAO7Z,GAAG;AAAA,QAE3C,UAAA;AAAA,UAAA,gBAAAnS,EAACsV,MAAc,WAAU,sBACvB,4BAACD,IAAA,EAAY,aAAY,aAAY,EAAA,CACvC;AAAA,4BACCK,IAAA,EACE,UAAAqV,EAAK,QAAQ,IAAI,CAACmB,MACjB,gBAAAlsB,EAAC4V,IAAA,EAA2B,OAAOsW,EAAI,OAAO,WAAU,WACrD,UAAAA,EAAI,SADUA,EAAI,KAErB,CACD,EAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA,IAGF,gBAAAlsB;AAAA,MAACoO;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,OAAOrL,EAAK,SAAS,EAAE;AAAA,QAC9B,UAAU,CAACyG,MAAMwiB,EAAS,EAAE,OAAOxiB,EAAE,OAAO,OAAO;AAAA,QACnD,aAAY;AAAA,MAAA;AAAA,IAAA;AAAA,IAKlB,gBAAAxJ;AAAA,MAAC8H;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS+hB;AAAA,QAET,UAAA,gBAAA7pB,EAACyJ,IAAA,EAAE,WAAU,UAAA,CAAU;AAAA,MAAA;AAAA,IAAA;AAAA,EACzB,GACF;AAEJ;AAEA,SAASmiB,GAAc;AAAA,EACrB,QAAA5Z;AAAA,EACA,iBAAAwY;AAAA,EACA,UAAA/V;AACF,GAIG;AACD,SACE,gBAAApR,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,IAAA2O,EAAO,IAAI,CAACC,GAAOgY,wBACjB,OAAA,EACE,UAAA;AAAA,MAAAA,IAAK,KACJ,gBAAA5mB,EAAC,OAAA,EAAI,WAAU,gCACb,UAAA;AAAA,QAAA,gBAAArD,EAAC,OAAA,EAAI,WAAU,yCAAA,CAAyC;AAAA,QACxD,gBAAAA,EAAC,QAAA,EAAK,WAAU,2DAA0D,UAAA,MAE1E;AAAA,QACA,gBAAAA,EAAC,OAAA,EAAI,WAAU,yCAAA,CAAyC;AAAA,MAAA,GAC1D;AAAA,MAEF,gBAAAqD,EAAC,OAAA,EAAI,WAAU,0DACb,UAAA;AAAA,QAAA,gBAAArD,EAAC,OAAA,EAAI,WAAU,2DAA0D,UAAA,aAEzE;AAAA,QACCiS,EAAM,IAAI,CAAClP,GAAMopB,MAAO;AACvB,gBAAMpB,IAAOP,EAAgB,KAAK,CAAC9oB,MAAMA,EAAE,SAASqB,EAAK,KAAK;AAC9D,iBAAKgoB,IAEH,gBAAA/qB;AAAA,YAAC2rB;AAAA,YAAA;AAAA,cAEC,MAAA5oB;AAAA,cACA,MAAAgoB;AAAA,cACA,UAAU,CAACG,MAAY;AACrB,sBAAMW,IAAY7Z,EAAO;AAAA,kBAAI,CAACyR,GAAGlX,MAC/BA,MAAM0d,IACFxG,EAAE,IAAI,CAACnb,GAAG+W,MAAOA,MAAM8M,IAAK,EAAE,GAAG7jB,GAAG,GAAG4iB,EAAA,IAAY5iB,CAAE,IACrDmb;AAAA,gBAAA;AAEN,gBAAAhP,EAASoX,CAAS;AAAA,cACpB;AAAA,cACA,UAAU,MAAM;AACd,sBAAMA,IAAY7Z,EAAO;AAAA,kBAAI,CAACyR,GAAGlX,MAC/BA,MAAM0d,IAAKxG,EAAE,OAAO,CAACrG,GAAGiC,MAAMA,MAAM8M,CAAE,IAAI1I;AAAA,gBAAA;AAG5C,gBAAAhP,EAASoX,EAAU,OAAO,CAACpI,MAAMA,EAAE,SAAS,CAAC,CAAC;AAAA,cAChD;AAAA,YAAA;AAAA,YAjBK,GAAG1gB,EAAK,KAAK,IAAIopB,CAAE;AAAA,UAAA,IAHV;AAAA,QAuBpB,CAAC;AAAA,QACD,gBAAA9oB;AAAA,UAACyE;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,WAAU;AAAA,YACV,SAAS,MAAM;AAEb,oBAAMskB,IAAiB5B,EAAgB;AAAA,gBACrC,CAAC9oB,MAAM,CAACuQ,EAAM,KAAK,CAAC3J,MAAMA,EAAE,UAAU5G,EAAE,IAAI;AAAA,cAAA;AAE9C,kBAAI0qB,GAAgB;AAClB,sBAAMP,IAAY7Z,EAAO;AAAA,kBAAI,CAACyR,GAAGlX,MAC/BA,MAAM0d,IACF,CAAC,GAAGxG,GAAG,EAAE,OAAO2I,EAAe,MAAM,IAAIA,EAAe,UAAU,CAAC,KAAM,KAAA,CAAmB,IAC5F3I;AAAA,gBAAA;AAEN,gBAAAhP,EAASoX,CAAS;AAAA,cACpB;AAAA,YACF;AAAA,YAEA,UAAA;AAAA,cAAA,gBAAA7rB,EAACsd,IAAA,EAAK,WAAU,eAAA,CAAe;AAAA,cAAE;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAEnC,EAAA,CACF;AAAA,IAAA,EAAA,GA9DQ2M,CA+DV,CACD;AAAA,IACD,gBAAA5mB;AAAA,MAACyE;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAM2M,EAAS,CAAC,GAAGzC,GAAQ,CAAA,CAAE,CAAC;AAAA,QAEvC,UAAA;AAAA,UAAA,gBAAAhS,EAACsd,IAAA,EAAK,WAAU,eAAA,CAAe;AAAA,UAAE;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAEnC,GACF;AAEJ;AAEA,SAASyO,GAAY;AAAA,EACnB,QAAAvqB;AAAA,EACA,cAAAopB;AAAA,EACA,UAAAyB;AAAA,EACA,UAAAC;AACF,GAKG;AACD,QAAM,CAAC3tB,GAAQ4tB,CAAS,IAAItqB,EAAS,EAAE,GACjCuqB,IAAWhrB,EAAO;AAAA,IACtB,CAACE,MACC,CAACkpB,EAAa,IAAIlpB,EAAE,IAAI,MACvB/C,MAAW,MAAM+C,EAAE,MAAM,cAAc,SAAS/C,EAAO,YAAA,CAAa,KAAK+C,EAAE,KAAK,cAAc,SAAS/C,EAAO,YAAA,CAAa;AAAA,EAAA;AAGhI,SACE,gBAAA0E,EAAC,OAAA,EAAI,WAAU,iEACb,UAAA;AAAA,IAAA,gBAAArD;AAAA,MAACoO;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,aAAY;AAAA,QACZ,OAAOzP;AAAA,QACP,UAAU,CAAC6K,MAAM+iB,EAAU/iB,EAAE,OAAO,KAAK;AAAA,QACzC,WAAS;AAAA,MAAA;AAAA,IAAA;AAAA,IAEX,gBAAAnG,EAAC,OAAA,EAAI,WAAU,2CACZ,UAAA;AAAA,MAAAmpB,EAAS,IAAI,CAAC9qB,MACb,gBAAA2B;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,WAAU;AAAA,UACV,SAAS,MAAMgpB,EAAS3qB,EAAE,IAAI;AAAA,UAE7B,UAAA;AAAA,YAAAA,EAAE;AAAA,YACH,gBAAA1B,EAAC,QAAA,EAAK,WAAU,uCAAuC,YAAE,KAAA,CAAK;AAAA,UAAA;AAAA,QAAA;AAAA,QALzD0B,EAAE;AAAA,MAAA,CAOV;AAAA,MACA8qB,EAAS,WAAW,uBAClB,OAAA,EAAI,WAAU,oDAAmD,UAAA,sBAAA,CAElE;AAAA,IAAA,GAEJ;AAAA,IACA,gBAAAxsB,EAAC8H,GAAA,EAAO,SAAQ,SAAQ,MAAK,MAAK,WAAU,kBAAiB,SAASwkB,GAAU,UAAA,SAAA,CAEhF;AAAA,EAAA,GACF;AAEJ;ACnbO,SAASG,GAAa;AAAA,EAC3B,kBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,UAAAC;AAAA,EACA,SAAAC;AAAA,EACA,WAAAC;AAAA,EACA,aAAAC,IAAc,CAACC,MAAMA;AACvB,GAAsB;AACpB,QAAM,CAAC7M,GAAM8M,CAAO,IAAIhrB,EAAS,EAAK;AAEtC,SACE,gBAAAoB,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,IAAA,gBAAAA;AAAA,MAACyE;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,SAAS,MAAMmlB,EAAQ,CAAC9M,CAAI;AAAA,QAC5B,WAAU;AAAA,QAEV,UAAA;AAAA,UAAA,gBAAAngB,EAACktB,IAAA,EAAS,WAAU,iBAAA,CAAiB;AAAA,UAAE;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAIxC/M,KACC,gBAAA9c,EAAAoF,IAAA,EAEE,UAAA;AAAA,MAAA,gBAAAzI;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,SAAS,MAAMitB,EAAQ,EAAK;AAAA,QAAA;AAAA,MAAA;AAAA,MAG9B,gBAAA5pB,EAAC,OAAA,EAAI,WAAU,gIACb,UAAA;AAAA,QAAA,gBAAArD,EAAC,SAAI,WAAU,+BACZ,UAAA0sB,EAAiB,IAAI,CAACS,MAAQ;AAC7B,gBAAMC,IAAYT,EAAe,SAASQ,CAAG;AAC7C,iBACE,gBAAA9pB;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,WAAU;AAAA,cACV,SAAS,MAAMupB,EAASO,CAAG;AAAA,cAE3B,UAAA;AAAA,gBAAA,gBAAAntB,EAAC,QAAA,EAAK,WAAU,iDACb,UAAAotB,uBAAc7lB,IAAA,EAAM,WAAU,iCAAgC,EAAA,CACjE;AAAA,gBACA,gBAAAvH,EAAC,UAAK,WAAWotB,IAAY,KAAK,kCAC/B,UAAAL,EAAYI,CAAG,EAAA,CAClB;AAAA,cAAA;AAAA,YAAA;AAAA,YATKA;AAAA,UAAA;AAAA,QAYX,CAAC,EAAA,CACH;AAAA,QACA,gBAAA9pB,EAAC,OAAA,EAAI,WAAU,uEACb,UAAA;AAAA,UAAA,gBAAAA,EAACyE,GAAA,EAAO,SAAQ,SAAQ,MAAK,MAAK,WAAU,sBAAqB,SAAS+kB,GACxE,UAAA;AAAA,YAAA,gBAAA7sB,EAACqtB,IAAA,EAAU,WAAU,eAAA,CAAe;AAAA,YAAE;AAAA,UAAA,GAExC;AAAA,UACA,gBAAArtB,EAAC8H,GAAA,EAAO,SAAQ,SAAQ,MAAK,MAAK,WAAU,sBAAqB,SAASglB,GAAW,UAAA,WAAA,CAErF;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;AC1CO,SAASQ,GAAa;AAAA,EAC3B,OAAAC;AAAA,EACA,cAAAC;AAAA,EACA,SAAAC;AAAA,EACA,UAAApB;AAAA,EACA,QAAAqB;AAAA,EACA,UAAAC;AAAA,EACA,cAAAC;AACF,GAAsB;AACpB,QAAM,CAACzN,GAAM8M,CAAO,IAAIhrB,EAAS,EAAK,GAEhC4rB,IAAaN,EAAM,KAAK,CAACpb,MAAMA,EAAE,OAAOqb,CAAY,GACpDM,IAAcP,EAAM,OAAO,CAACpb,MAAMA,EAAE,WAAW,QAAQ,GACvD4b,IAAgBR,EAAM,OAAO,CAACpb,MAAMA,EAAE,WAAW,UAAU,GAC3D6b,IAAcT,EAAM,OAAO,CAACpb,MAAMA,EAAE,WAAW,QAAQ,GAEvDjO,IAAc2pB,IAChB1tB,EAAI0tB,EAAW,IAAI,IACnB;AAEJ,SACE,gBAAAxqB,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,MAAA,gBAAAA;AAAA,QAACyE;AAAA,QAAA;AAAA,UACC,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,SAAS,MAAMmlB,EAAQ,CAAC9M,CAAI;AAAA,UAC5B,WAAU;AAAA,UAET,UAAA;AAAA,YAAAjc;AAAA,YACAupB,KACC,gBAAAztB,EAAC,QAAA,EAAK,WAAU,2CAAA,CAA2C;AAAA,YAE7D,gBAAAA,EAACwD,IAAA,EAAY,WAAU,UAAA,CAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAGlC2c,KACC,gBAAA9c,EAAAoF,IAAA,EACE,UAAA;AAAA,QAAA,gBAAAzI;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAS,MAAMitB,EAAQ,EAAK;AAAA,UAAA;AAAA,QAAA;AAAA,QAE9B,gBAAA5pB,EAAC,OAAA,EAAI,WAAU,+HAEb,UAAA;AAAA,UAAA,gBAAArD;AAAA,YAACiuB;AAAA,YAAA;AAAA,cACC,OAAM;AAAA,cACN,UAAU,CAACT;AAAA,cACX,SAAS,MAAM;AACb,gBAAAnB,EAAS,EAAE,IAAI,IAAI,MAAM,EAAE,IAAI,UAAA,GAAa,QAAQ,UAAU,GAC9DY,EAAQ,EAAK;AAAA,cACf;AAAA,YAAA;AAAA,UAAA;AAAA,UAGDa,EAAY,SAAS,KACpB,gBAAAzqB,EAAAoF,IAAA,EACE,UAAA;AAAA,YAAA,gBAAAzI,EAAC,OAAA,EAAI,WAAU,gEAA+D,UAAA,WAE9E;AAAA,YACC8tB,EAAY,IAAI,CAAC3b,MAChB,gBAAAnS;AAAA,cAACiuB;AAAA,cAAA;AAAA,gBAEC,OAAO9tB,EAAIgS,EAAE,IAAI;AAAA,gBACjB,UAAUqb,MAAiBrb,EAAE;AAAA,gBAC7B,SAAS,MAAM;AACb,kBAAAka,EAASla,CAAC,GACV8a,EAAQ,EAAK;AAAA,gBACf;AAAA,cAAA;AAAA,cANK9a,EAAE;AAAA,YAAA,CAQV;AAAA,UAAA,GACH;AAAA,UAGD4b,EAAc,SAAS,KACtB,gBAAA1qB,EAAAoF,IAAA,EACE,UAAA;AAAA,YAAA,gBAAAzI,EAAC,OAAA,EAAI,WAAU,gEAA+D,UAAA,YAE9E;AAAA,YACC+tB,EAAc,IAAI,CAAC5b,MAClB,gBAAAnS;AAAA,cAACiuB;AAAA,cAAA;AAAA,gBAEC,OAAO9tB,EAAIgS,EAAE,IAAI;AAAA,gBACjB,UAAUqb,MAAiBrb,EAAE;AAAA,gBAC7B,WAAWA,EAAE;AAAA,gBACb,cAAcyb,IAAe,MAAMA,EAAazb,EAAE,EAAE,IAAI;AAAA,gBACxD,SAAS,MAAM;AACb,kBAAAka,EAASla,CAAC,GACV8a,EAAQ,EAAK;AAAA,gBACf;AAAA,cAAA;AAAA,cARK9a,EAAE;AAAA,YAAA,CAUV;AAAA,UAAA,GACH;AAAA,UAGD6b,EAAY,SAAS,KACpB,gBAAA3qB,EAAAoF,IAAA,EACE,UAAA;AAAA,YAAA,gBAAAzI,EAAC,OAAA,EAAI,WAAU,gEAA+D,UAAA,UAE9E;AAAA,YACCguB,EAAY,IAAI,CAAC7b,MAChB,gBAAAnS;AAAA,cAACiuB;AAAA,cAAA;AAAA,gBAEC,OAAO9tB,EAAIgS,EAAE,IAAI;AAAA,gBACjB,UAAUqb,MAAiBrb,EAAE;AAAA,gBAC7B,UAAQ;AAAA,gBACR,SAAS,MAAM;AACb,kBAAAka,EAASla,CAAC,GACV8a,EAAQ,EAAK;AAAA,gBACf;AAAA,cAAA;AAAA,cAPK9a,EAAE;AAAA,YAAA,CASV;AAAA,UAAA,GACH;AAAA,UAIDwb,KACC,gBAAA3tB,EAAAyI,IAAA,EACE,UAAA,gBAAAzI,EAAC,OAAA,EAAI,WAAU,6CACb,UAAA,gBAAAqD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,SAAS,MAAM;AACb,gBAAAsqB,EAAA,GACAV,EAAQ,EAAK;AAAA,cACf;AAAA,cAEA,UAAA;AAAA,gBAAA,gBAAAjtB,EAACsd,IAAA,EAAK,WAAU,8CAAA,CAA8C;AAAA,gBAAE;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA,GAGpE,EAAA,CACF;AAAA,QAAA,EAAA,CAEJ;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,GAEJ;AAAA,IAGCmQ,KAAWD,KAAgBE,KAC1B,gBAAArqB,EAACyE,GAAA,EAAO,SAAQ,WAAU,MAAK,MAAK,WAAU,OAAM,SAAS4lB,GAC3D,UAAA;AAAA,MAAA,gBAAA1tB,EAACkuB,IAAA,EAAK,WAAU,eAAA,CAAe;AAAA,MAAE;AAAA,IAAA,EAAA,CAEnC;AAAA,EAAA,GAEJ;AAEJ;AAEA,SAASD,GAAW;AAAA,EAClB,OAAAvX;AAAA,EACA,UAAAvT;AAAA,EACA,WAAAgrB;AAAA,EACA,UAAAC;AAAA,EACA,SAAA/D;AAAA,EACA,cAAcgE;AAChB,GAOG;AACD,SACE,gBAAAhrB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,0FACTF,IAAW,kCAAkC,EAC/C;AAAA,MACA,SAAAknB;AAAA,MAEA,UAAA;AAAA,QAAA,gBAAArqB,EAAC,QAAA,EAAK,WAAU,6BAA6B,UAAA0W,GAAM;AAAA,QAClDyX,KACC,gBAAAnuB,EAACsuB,IAAA,EAAK,WAAU,6CAAA,CAA6C;AAAA,QAE9DF,KACC,gBAAApuB,EAACuuB,IAAA,EAAM,WAAU,yCAAA,CAAyC;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIlE;ACtNO,SAASC,GAAUC,GAAoD;AAC5E,QAAM,EAAE,MAAMnsB,EAAA,IAAWpF,GAAA;AACzB,MAAI,GAACoF,KAAU,CAACmsB;AAChB,WAAOnsB,EAAO,QAAQmsB,CAAU;AAClC;ACEO,SAASC,GAASD,GAAoBE,GAAiB;AAC5D,QAAMprB,IAASirB,GAAUC,CAAU,GAG7B,EAAE,MAAMG,MAAe1b,GAAc,QAAQ;AAAA,IACjD,SAAS;AAAA,MACP,EAAE,OAAO,eAAe,IAAI,MAAM,OAAOub,EAAA;AAAA;AAAA,MAEzC,GAAIE,IAAS,CAAC,EAAE,IAAI;AAAA,QAClB,CAAC,EAAE,OAAO,WAAW,IAAI,MAAM,OAAOA,GAAQ;AAAA,QAC9C,CAAC,EAAE,OAAO,aAAa,IAAI,MAAM,OAAO,QAAQ;AAAA,MAAA,EAClD,CAAG,IAAI,CAAA;AAAA,IAAC;AAAA,IAEV,UAAU;AAAA,EAAA,CACX;AAwCD,SAtCc5uB,EAAoB,MAAM;AACtC,UAAM+C,IAAoB,CAAA;AAG1B,QAAIS,KAAA,QAAAA,EAAQ;AACV,iBAAW4O,KAAK5O,EAAO;AACrB,QAAAT,EAAM,KAAK;AAAA,UACT,IAAIqP,EAAE;AAAA,UACN,MAAMA,EAAE;AAAA,UACR,MAAMA,EAAE;AAAA,UACR,QAAQ;AAAA,UACR,SAASA,EAAE;AAAA,UACX,SAASA,EAAE;AAAA,UACX,MAAMA,EAAE;AAAA,QAAA,CACT;AAKL,QAAIyc,KAAA,QAAAA,EAAY;AACd,iBAAWjM,KAAOiM,EAAW,MAAM;AACjC,cAAMC,IAAQF,KAAU,OAAOhM,EAAI,OAAO,MAAMgM;AAChD,QAAA7rB,EAAM,KAAK;AAAA,UACT,IAAI,OAAO6f,EAAI,EAAE;AAAA,UACjB,MAAM,OAAOA,EAAI,QAAS,YAAYA,EAAI,SAAS,OAAOA,EAAI,OAAiC,EAAE,IAAI,OAAOA,EAAI,QAAQ,EAAE,EAAA;AAAA,UAC1H,MAAMA,EAAI;AAAA,UACV,QAAQkM,IAAQ,aAAa;AAAA,UAC7B,YAAYlM,EAAI,eAAe;AAAA,UAC/B,SAASA,EAAI;AAAA,UACb,SAASA,EAAI;AAAA,UACb,MAAMA,EAAI;AAAA,QAAA,CACX;AAAA,MACH;AAGF,WAAO7f;AAAA,EACT,GAAG,CAACS,KAAA,gBAAAA,EAAQ,OAAOqrB,KAAA,gBAAAA,EAAY,MAAMD,CAAM,CAAC;AAG9C;ACwBO,SAASG,GACdC,GACAnxB,GACAyD,GACA2tB,GACe;AACf,MAAID,EAAK,kBAAkB7uB,GAAoB,QAAO;AACtD,QAAMzE,IAAOszB,EAAK,kBAAiB1tB,KAAA,gBAAAA,EAAQ;AAC3C,MAAI,CAAC5F,EAAM,QAAO;AAClB,QAAM2mB,IAAS4M,KAAA,gBAAAA,EAAavzB;AAC5B,SAAK2mB,KAAA,QAAAA,EAAQ,QACNA,EAAO,MAAM,QAAQ,OAAO,mBAAmBxkB,CAAE,CAAC,IAD9B;AAE7B;AAEO,SAASqxB,GAAc,EAAE,YAAAR,KAAkC;;AAChE,QAAMlsB,IAAc3D,GAAA,GACd,CAACoQ,GAAcua,CAAe,IAAIta,GAAA,GAClC,EAAE,MAAM3M,EAAA,IAAWpF,GAAA,GACnB,CAACgyB,GAAaC,CAAc,IAAIltB,EAA0D,IAAI,GAE9F,CAACmtB,GAAcC,CAAe,IAAIptB,EAA4B,CAAA,CAAE,GAChE,CAACqtB,GAAYC,CAAa,IAAIttB,EAA0G,EAAE,WAAW,IAAO,WAAW,IAAO,SAAS,IAAO,WAAW,IAAO,OAAO,GAAG,GAC1N,CAACutB,GAAkBC,CAAmB,IAAIxtB,EAAS,EAAK,GACxD,EAAE,SAASytB,GAAa,aAAaC,GAAa,YAAYC,GAAgB,cAAAjG,EAAA,IAAiBL,GAAA,GAC/FtkB,IAAOD,GAAa,CAACjH,MAAMA,EAAE,IAAI,GACjC+xB,IAAWnB,GAASD,GAAYzpB,KAAA,gBAAAA,EAAM,EAAE,GAExCzB,IAASjB,KAAA,gBAAAA,EAAQ,QAAQmsB,IACzBptB,IAASkC,KAAA,QAAAA,EAAQ,SAASjB,KAAA,gBAAAA,EAAQ,SAASiB,EAAO,UAAU,QAC5D4N,IAAa5N,KAAA,gBAAAA,EAAQ,QAGrBsiB,IAAgBvjB,KAAA,gBAAAA,EAAQ,SACxBwtB,IAAiB/vB;AAAA,IACrB,MAAM0lB,GAAiBpkB,KAAA,gBAAAA,EAAQ,SAASkC,KAAA,gBAAAA,EAAQ,SAAS,gBAAgBsiB,CAAa;AAAA,IACtF,CAACxkB,KAAA,gBAAAA,EAAQ,SAASkC,KAAA,gBAAAA,EAAQ,SAASsiB,CAAa;AAAA,EAAA,GAE5CkK,IAAahwB;AAAA,IACjB,MAAM0lB,GAAiBpkB,KAAA,gBAAAA,EAAQ,SAASkC,KAAA,gBAAAA,EAAQ,aAAa,YAAYsiB,CAAa;AAAA,IACtF,CAACxkB,KAAA,gBAAAA,EAAQ,SAASkC,KAAA,gBAAAA,EAAQ,aAAasiB,CAAa;AAAA,EAAA,GAGhDmK,KAAwBzsB,KAAA,gBAAAA,EAAQ,iBAAgB,QAGhD0sB,IAAkBlwB;AAAA,IACtB,MAAM+vB,EAAe,KAAK,CAAC1e,OAAOA,EAAE,OAAO,cAAc,CAAA,GAAI,SAAS,cAAc,CAAC;AAAA,IACrF,CAAC0e,CAAc;AAAA,EAAA,GAIXI,IAAgB,CAAC,EAAC7uB,KAAA,QAAAA,EAAQ,cAC1B8uB,IAAiBD,OAAkBlrB,KAAA,gBAAAA,EAAM,gBAAe,CAAA,GAAI,KAAK,CAACorB,MAAMA,MAAM,0BAA0BA,MAAM,eAAeA,MAAM,GAAG,GACtIC,IAAiBF,KAAkBnhB,EAAa,IAAI,iBAAiB,MAAM,QAG3E,EAAE,SAAAjQ,GAAS,iBAAAuxB,GAAiB,mBAAArxB,GAAA,IAAsB5B,GAAA;AACxD,EAAA+P,GAAU,MAAM;;AACd,QAAI7J,KAAA,QAAAA,EAAQ,SAASlC,GAAQ;AAC3B,YAAMkvB,IAAUpwB,GAAIQ,IAAA4C,EAAO,YAAP,gBAAA5C,EAAgB,IAAI,KAAKR,EAAIkB,EAAO,QAAQ,WAAW,GACrEmvB,OAAU5vB,IAAA2C,EAAO,YAAP,gBAAA3C,EAAgB,SAAQS,EAAO,QAAQ;AACvD,MAAAtC,EAAQ;AAAA,QACN,UAAUwE,EAAO;AAAA,QACjB,QAAQyL,EAAa,SAAA;AAAA,QACrB,OAAOuhB;AAAA,QACP,MAAMC;AAAA,QACN,UAAU;AAAA,MAAA,CACX;AAAA,IACH;AAAA,EACF,GAAG,CAACjtB,KAAA,gBAAAA,EAAQ,QAAO3C,MAAAD,KAAA4C,KAAA,gBAAAA,EAAQ,YAAR,gBAAA5C,GAAiB,SAAjB,gBAAAC,GAAuB,KAAIG,KAAAM,KAAA,gBAAAA,EAAQ,QAAQ,gBAAhB,gBAAAN,GAA6B,KAAIia,KAAAzX,KAAA,gBAAAA,EAAQ,YAAR,gBAAAyX,GAAiB,MAAM3Z,KAAA,gBAAAA,EAAQ,QAAQ,IAAI,CAAC,GAG3H+L,GAAU,MAAM;AACd,QAAI,EAAC7J,KAAA,QAAAA,EAAQ,OAAO;AACpB,UAAM9F,IAAMwB,GAAkBsE,EAAO,KAAK;AAC1C,IAAI9F,KACF6yB,EAAgB7yB,EAAI,IAAIuR,EAAa,SAAA,CAAU;AAAA,EAEnD,GAAG,CAACA,GAAczL,KAAA,gBAAAA,EAAQ,KAAK,CAAC;AAGhC,QAAMktB,IAAO,SAASzhB,EAAa,IAAI,MAAM,KAAK,KAAK,EAAE,GACnD0hB,IAAc1hB,EAAa,IAAI,QAAQ,KAAK,IAC5C2hB,IAAY3hB,EAAa,IAAI,MAAM,MAAKzL,KAAA,gBAAAA,EAAQ,iBAAgB,IAChEqtB,IAAkB/c,GAAY6c,GAAa,GAAG,GAG9CG,IAAc9wB,EAAkB,MAAM;AAC1C,UAAMgX,IAAM/H,EAAa,IAAI,SAAS;AACtC,WAAI+H,IAAYA,EAAI,MAAM,GAAG,EAAE,OAAO,OAAO,KACtCxT,KAAA,gBAAAA,EAAQ,YAAW,CAAA;AAAA,EAC5B,GAAG,CAACyL,GAAczL,KAAA,gBAAAA,EAAQ,OAAO,CAAC,GAK5ButB,IAAS/wB,EAAQ,MAAM;AAC3B,UAAMyJ,IAAc,CAAA,GAEdunB,IAAU,CAAC,IAAIxtB,KAAA,gBAAAA,EAAQ,YAAW,CAAA,GAAK,GAAGstB,CAAW;AAC3D,WAAIE,EAAQ,KAAK,CAAC/D,MAAMA,EAAE,WAAW,UAAU,CAAC,KAAGxjB,EAAE,KAAK,UAAU,GAChEunB,EAAQ,KAAK,CAAC/D,MAAMA,EAAE,WAAW,YAAY,CAAC,KAAGxjB,EAAE,KAAK,YAAY,GACpEA,EAAE,SAAS,KAAGA,EAAE,QAAQ,MAAM,GAC3BA,EAAE,SAAS,IAAIA,IAAI;AAAA,EAC5B,GAAG,CAACjG,KAAA,gBAAAA,EAAQ,SAASstB,CAAW,CAAC,GAG3B,EAAE,MAAM3V,IAAU,WAAA5V,IAAW,SAAAgjB,GAAA,IAAYpV,GAAc/B,GAAY;AAAA,IACvE,MAAAsf;AAAA,IACA,UAAU;AAAA,IACV,MAAME,KAAa;AAAA,IACnB,QAAQC,KAAmB;AAAA,IAC3B,SAASlB,EAAY,SAAS,IAAIA,IAAc;AAAA,IAChD,iBAAiBW,KAAkB;AAAA,IACnC,QAAAS;AAAA,IACA,QAAQvtB,KAAA,QAAAA,EAAQ,gBAAgBkrB,IAAa;AAAA,EAAA,CAC9C,GAEKuC,KAAiBxd,GAAgBrC,KAAc,EAAE,GAGjD8f,KAAwBlxB,EAAQ,MAAM;AAC1C,QAAI,CAAC4wB,EAAW,QAAO,CAAA;AACvB,UAAM,CAACpwB,GAAO2wB,CAAG,IAAIP,EAAU,MAAM,GAAG;AACxC,WAAO,CAAC,EAAE,IAAIpwB,GAAO,MAAM2wB,MAAQ,QAAQ;AAAA,EAC7C,GAAG,CAACP,CAAS,CAAC,GAGRQ,KAAUpxB;AAAA,IACd,MAAA;;AAAM,eAAAY,IAAAU,KAAA,gBAAAA,EAAQ,gBAAR,gBAAAV,EAAqB,KAAK,CAACe,MAAA;;AAAM,gBAAAf,IAAAU,EAAO,OAAOK,CAAC,MAAf,gBAAAf,EAAkB;AAAA,aAAY;AAAA;AAAA,IACrE,CAACU,CAAM;AAAA,EAAA,GAGHwZ,IAAOK,MAAA,gBAAAA,GAAU,OAGjBkW,KAAUjkB,GAAO0N,CAAI;AAC3B,EAAAuW,GAAQ,UAAUvW;AAGlB,QAAMwW,KAAUtxB,EAA8B,MAAM;;AAClD,QAAI8wB,EAAY,WAAW,KAAK,CAACxvB,UAAe,CAAA;AAEhD,UAAM+d,IAA6B,CAAA;AAGnC,IAAI6Q,KACF7Q,EAAK,KAAK;AAAA,MACR,IAAI;AAAA,MACJ,QAAQ,CAAC,EAAE,OAAOkS,QAChB,gBAAAtxB;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAASsxB,EAAI,qBAAA;AAAA,UACb,UAAUA,EAAI,gCAAA;AAAA,QAAgC;AAAA,MAAA;AAAA,MAGlD,MAAM;AAAA,MACN,MAAM,CAAC,EAAE,KAAA3O,EAAA,MACP,gBAAA3iB;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS2iB,EAAI,cAAA;AAAA,UACb,UAAUA,EAAI,yBAAA;AAAA,QAAyB;AAAA,MAAA;AAAA,IACzC,CAEH;AAIH,eAAW4O,KAAUV,GAAa;AAEhC,UAAIU,EAAO,WAAW,UAAU,GAAG;AACjC,cAAMC,KAAYD,EAAO,MAAM,CAAC,GAC1Btf,MAAQtR,IAAAU,EAAO,kBAAP,gBAAAV,EAAuB6wB;AACrC,YAAI,CAACvf,GAAO;AACZ,cAAMwf,KAAY,IAAI,IAAIxf,GAAM,SAAS,IAAI,CAACnU,OAAM,CAACA,GAAE,MAAMA,EAAC,CAAC,CAAC;AAChE,QAAAshB,EAAK,KAAK;AAAA,UACR,IAAImS;AAAA,UACJ,QAAQpxB,EAAI8R,GAAM,IAAI,KAAKuf;AAAA,UAC3B,MAAM;AAAA,UACN,MAAM,CAAC,EAAE,KAAA7O,SAAU;AACjB,kBAAMW,KAAYX,GAAI,SAAqC,WACrDnH,KAAQ8H,MAAA,gBAAAA,GAAU,KAAK,CAACxlB,MAAMA,EAAE,eAAe0zB;AACrD,gBAAI,CAAChW,GAAO,0BAAQ,QAAA,EAAK,WAAU,0CAAyC,UAAA,KAAC;AAC7E,kBAAMkW,IAAMD,GAAU,IAAIjW,GAAM,WAAW;AAC3C,mBACE,gBAAAxb,EAACyQ,IAAA,EAAM,OAAOihB,KAAA,gBAAAA,EAAK,OAAQ,YAAIA,KAAA,gBAAAA,EAAK,IAAI,KAAKlW,GAAM,YAAA,CAAY;AAAA,UAEnE;AAAA,QAAA,CACD;AACD;AAAA,MACF;AAGA,UAAI+V,EAAO,WAAW,YAAY,GAAG;AACnC,cAAMI,KAAWJ,EAAO,MAAM,EAAE,GAC1BK,MAAUhxB,KAAAS,EAAO,eAAP,gBAAAT,GAAoB+wB;AACpC,YAAI,CAACC,GAAS;AACd,QAAAxS,EAAK,KAAK;AAAA,UACR,IAAImS;AAAA,UACJ,QAAQpxB,EAAIyxB,GAAQ,IAAI,KAAKD;AAAA,UAC7B,MAAM;AAAA,UACN,eAAe;AAAA,UACf,MAAM,CAAC,EAAE,KAAAhP,SAAU;AACjB,kBAAM9iB,KAAS8iB,GAAI,SAAqC,aAClDnH,KAAQ3b,MAAA,gBAAAA,GAAO,KAAK,CAACuwB,OAAMA,GAAE,kBAAkBuB;AACrD,mBAAI,CAACnW,MAASA,GAAM,SAAS,OAAa,gBAAAxb,EAAC,QAAA,EAAK,WAAU,0CAAyC,UAAA,IAAA,CAAC,sBAC5F,QAAA,EAAK,WAAU,WAAW,UAAA,OAAOwb,GAAM,KAAK,GAAE;AAAA,UACxD;AAAA,QAAA,CACD;AACD;AAAA,MACF;AAGA,YAAMjb,KAAQc,EAAO,OAAOkwB,CAAM;AAClC,UAAI,CAAChxB,GAAO;AACZ,YAAM2D,KAAc5D,GAAiBC,IAAOgxB,GAAQjvB,KAAA,gBAAAA,EAAQ,QAAQ,GAC9DuvB,MAAQ9wB,KAAAR,GAAM,YAAN,gBAAAQ,GAAe;AAC7B,MAAAqe,EAAK,KAAK;AAAA,QACR,IAAImS;AAAA,QACJ,aAAaA;AAAA,QACb,QAAQrtB;AAAA,QACR,MAAM2tB,MAAS;AAAA,QACf,MAAM,CAAC,EAAE,UAAAC,IAAU,KAAAnP,GAAA,MACjB7F,GAAY;AAAA,UACV,OAAAvc;AAAA,UACA,WAAWgxB;AAAA,UACX,OAAOO,GAAA;AAAA,UACP,MAAM;AAAA,UACN,QAAQnP,GAAI;AAAA,UACZ,MAAMyO,GAAQ;AAAA,QAAA,CACf;AAAA,MAAA,CACJ;AAAA,IACH;AAGA,UAAMW,IAAoB,CAAC/B,KAAyB,EAAC3uB,KAAA,QAAAA,EAAQ;AAC7D,YAAI0wB,KAAqBhC,EAAW,SAAS,MAC7C3Q,EAAK,KAAK;AAAA,MACR,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM,CAAC,EAAE,KAAAuD,QAAU;AACjB,cAAM/kB,KAAK,OAAO+kB,EAAI,SAASwO,EAAO,KAAK,EAAE,GACvCa,KAAWlD,GAAkBvrB,GAAS3F,IAAIyD,GAAQiB,KAAA,gBAAAA,EAAQ,OAAO;AACvE,iCACGkE,IAAA,EACC,UAAA;AAAA,UAAA,gBAAAxG,EAAC0G,MAAoB,SAAO,IAC1B,UAAA,gBAAA1G,EAAC8H,GAAA,EAAO,SAAQ,SAAQ,MAAK,QAAO,WAAU,WAC5C,UAAA,gBAAA9H,EAACiyB,IAAA,EAAe,WAAU,UAAA,CAAU,GACtC,GACF;AAAA,UACA,gBAAA5uB,EAAC6D,IAAA,EAAoB,OAAM,OACxB,UAAA;AAAA,YAAA6qB,KACC,gBAAA1uB,EAAAoF,IAAA,EACG,UAAA;AAAA,cAAAupB,MACC,gBAAA3uB;AAAA,gBAAC+D;AAAA,gBAAA;AAAA,kBACC,SAAS,MACP7E,EAAYyvB,IAAU;AAAA,oBACpB,OAAO7xB,EAAIkB,EAAQ,QAAQ,IAAI;AAAA,oBAC/B,MAAMA,EAAQ,QAAQ;AAAA,oBACtB,QAAQ;AAAA,kBAAA,CACT;AAAA,kBAGH,UAAA;AAAA,oBAAA,gBAAArB,EAACkyB,IAAA,EAAO,WAAU,eAAA,CAAe;AAAA,oBAAE;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAIvC,gBAAA7uB;AAAA,gBAAC+D;AAAA,gBAAA;AAAA,kBACC,SAAS,MAAM+nB,EAAe,EAAE,KAAK,CAACvxB,EAAE,GAAG;AAAA,kBAC3C,WAAU;AAAA,kBAEV,UAAA;AAAA,oBAAA,gBAAAoC,EAACqd,IAAA,EAAO,WAAU,eAAA,CAAe;AAAA,oBAAE;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGpC0S,EAAW,SAAS,KAAK,gBAAA/vB,EAAC2H,IAAA,CAAA,CAAsB;AAAA,YAAA,GACnD;AAAA,YAEDooB,EAAW,IAAI,CAAC,EAAE,MAAAt0B,IAAM,QAAAqW,SAAa;;AACpC,kBAAIA,GAAO,SAAS,QAAQ;AAC1B,sBAAMqV,KAAgBvC,GAAmB9S,GAAO,YAAY6Q,EAAI,QAAQ;AACxE,uBAAKqP,KAEH,gBAAA3uB;AAAA,kBAAC+D;AAAA,kBAAA;AAAA,oBAEC,UAAU,CAAC+f;AAAA,oBACX,SAAS,MACP5kB,EAAYyvB,IAAU;AAAA,sBACpB,OAAO7xB,EAAIkB,EAAQ,QAAQ,IAAI;AAAA,sBAC/B,MAAMA,EAAQ,QAAQ;AAAA,sBACtB,QAAQ;AAAA,oBAAA,CACT;AAAA,oBAGH,UAAA;AAAA,sBAAA,gBAAArB,EAACkyB,IAAA,EAAO,WAAU,eAAA,CAAe;AAAA,sBAChC/xB,GAAIQ,KAAAmR,GAAO,YAAP,gBAAAnR,GAAgB,IAAI,KAAK;AAAA,oBAAA;AAAA,kBAAA;AAAA,kBAXzBlF;AAAA,gBAAA,IAHa;AAAA,cAiBxB;AACA,kBAAIqW,GAAO,SAAS,UAAU;AAC5B,sBAAMqV,KAAgBvC,GAAmB9S,GAAO,YAAY6Q,EAAI,QAAQ;AACxE,uBACE,gBAAAtf;AAAA,kBAAC+D;AAAA,kBAAA;AAAA,oBAEC,UAAU,CAAC+f;AAAA,oBACX,SAAS,MAAMgI,EAAe,EAAE,KAAK,CAACvxB,EAAE,GAAG,cAAcuC,EAAI2R,GAAO,YAAY,KAAK,QAAW;AAAA,oBAChG,WAAU;AAAA,oBAEV,UAAA;AAAA,sBAAA,gBAAA9R,EAACqd,IAAA,EAAO,WAAU,eAAA,CAAe;AAAA,sBAChCld,GAAIS,KAAAkR,GAAO,YAAP,gBAAAlR,GAAgB,IAAI,KAAK;AAAA,oBAAA;AAAA,kBAAA;AAAA,kBANzBnF;AAAA,gBAAA;AAAA,cASX;AACA,qBACE,gBAAAuE;AAAA,gBAACioB;AAAA,gBAAA;AAAA,kBAEC,YAAYxsB;AAAA,kBACZ,QAAAqW;AAAA,kBACA,YAAAX;AAAA,kBACA,UAAUvT;AAAA,kBACV,KAAK+kB,EAAI;AAAA,gBAAA;AAAA,gBALJlnB;AAAA,cAAA;AAAA,YAQX,CAAC;AAAA,UAAA,EAAA,CACH;AAAA,QAAA,GACF;AAAA,MAEJ;AAAA,IAAA,CACD,GAGM2jB;AAAA,EACT,GAAG,CAAC7b,GAAQlC,GAAQwvB,GAAatuB,GAAa0tB,GAAiBF,GAAYC,GAAuB7e,GAAYggB,EAAO,CAAC,GAEhH1e,MAAOyI,MAAA,gBAAAA,GAAU,SAAQ,CAAA,GACzB6P,KAAO7P,MAAA,gBAAAA,GAAU,MAEjBiX,KAAQC,GAAc;AAAA,IAC1B,MAAA3f;AAAA,IACA,SAAA4e;AAAA,IACA,iBAAiBgB,GAAA;AAAA,IACjB,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,OAAO,EAAE,SAAApB,IAAS,cAAA7B,EAAA;AAAA,IAClB,iBAAiB,CAACkD,MAAY;AAC5B,YAAM/nB,IAAO,OAAO+nB,KAAY,aAAaA,EAAQrB,EAAO,IAAIqB,GAC1DztB,IAAS,IAAI,gBAAgBmK,CAAY;AAC/C,UAAIzE,EAAK,WAAW;AAClB,QAAA1F,EAAO,OAAO,MAAM;AAAA,WACf;AACL,cAAM/G,KAAIyM,EAAK,CAAC;AAChB,QAAA1F,EAAO,IAAI,QAAQ,GAAG/G,GAAE,EAAE,IAAIA,GAAE,OAAO,SAAS,KAAK,EAAE;AAAA,MACzD;AACA,MAAA+G,EAAO,IAAI,QAAQ,GAAG,GACtB0kB,EAAgB1kB,CAAM;AAAA,IACxB;AAAA,IACA,sBAAsBwqB;AAAA,IACtB,UAAU,CAAC1M,MAAQ,OAAOA,EAAIwO,EAAO,KAAK,EAAE;AAAA,IAC5C,WAAUpG,MAAA,gBAAAA,GAAM,UAAS;AAAA,EAAA,CAC1B,GAGKwH,KAAcxyB;AAAA,IAClB,MAAM,OAAO,KAAKqvB,CAAY,EAAE,OAAO,CAAC/S,MAAM+S,EAAa/S,CAAC,CAAC;AAAA,IAC7D,CAAC+S,CAAY;AAAA,EAAA;AAIf,EAAAhiB,GAAU,MAAM;AACd,IAAAiiB,EAAgB,CAAA,CAAE;AAAA,EACpB,GAAG,CAACoB,GAAMG,GAAiBD,GAAWjB,CAAW,CAAC,GAGlDtiB,GAAU,MAAM;AACd,UAAMkE,IAAU,CAAC9H,MAAqB;;AAEpC,YAAMgpB,KAAO7xB,KAAA6I,EAAE,WAAF,gBAAA7I,GAA0B;AACvC,UAAI6xB,MAAQ,WAAWA,MAAQ,cAAcA,MAAQ,UAAU;AAC7D,QAAIhpB,EAAE,QAAQ,aACXA,EAAE,OAAuB,KAAA,GAC1BimB,EAAoB,EAAK;AAE3B;AAAA,MACF;AACA,UAAIjmB,EAAE,QAAQ,OAAO,CAACA,EAAE,WAAW,CAACA,EAAE,SAAS;AAC7C,QAAAA,EAAE,eAAA;AACF,cAAMipB,KAAQ,SAAS,cAAgC,yBAAyB;AAChF,QAAAA,MAAA,QAAAA,GAAO;AAAA,MACT;AACA,MAAIjpB,EAAE,QAAQ,OAAO,CAACA,EAAE,WAAW,CAACA,EAAE,YACpCA,EAAE,eAAA,GACFimB,EAAoB,CAACvsB,OAAS,CAACA,EAAI,IAEjCsG,EAAE,QAAQ,YACZimB,EAAoB,EAAK;AAAA,IAE7B;AACA,oBAAS,iBAAiB,WAAWne,CAAO,GACrC,MAAM,SAAS,oBAAoB,WAAWA,CAAO;AAAA,EAC9D,GAAG,CAAA,CAAE,GAGLlE,GAAU,MAAM;AACd,QAAIkiB,EAAW,aAAaA,EAAW,WAAWA,EAAW,WAAW;AACtE,YAAMtb,IAAQ,WAAW,MAAMub,EAAc,EAAE,WAAW,IAAO,WAAW,IAAO,SAAS,IAAO,WAAW,IAAO,OAAO,EAAA,CAAG,GAAG,GAAI;AACtI,aAAO,MAAM,aAAavb,CAAK;AAAA,IACjC;AAAA,EACF,GAAG,CAACsb,EAAW,WAAWA,EAAW,SAASA,EAAW,SAAS,CAAC;AAGnE,QAAMoD,KAAYvlB,GAAuB,IAAI,GACvC,EAAE,MAAA+H,GAAA,IAASid,GAAM,YAAA,GAEjBQ,KAAiBC,GAAe;AAAA,IACpC,OAAO1d,GAAK;AAAA,IACZ,kBAAkB,MAAMwd,GAAU;AAAA,IAClC,cAAc,MAAM;AAAA,IACpB,UAAU;AAAA,EAAA,CACX,GAGKG,KAAe3zB;AAAA,IACnB,CAACqM,MAAkB;AACjB,MAAAge,EAAgB,CAACrmB,MAAS;AACxB,cAAMqH,IAAO,IAAI,gBAAgBrH,CAAI;AACrC,eAAIqI,IACFhB,EAAK,IAAI,UAAUgB,CAAK,IAExBhB,EAAK,OAAO,QAAQ,GAEtBA,EAAK,IAAI,QAAQ,GAAG,GACbA;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA,CAACgf,CAAe;AAAA,EAAA,GAGZuJ,KAAuB5zB,EAAY,MAAM;AAC7C,IAAAqqB,EAAgB,CAACrmB,MAAS;AACxB,YAAMqH,IAAO,IAAI,gBAAgBrH,CAAI;AACrC,aAAIqH,EAAK,IAAI,iBAAiB,IAC5BA,EAAK,OAAO,iBAAiB,IAE7BA,EAAK,IAAI,mBAAmB,MAAM,GAEpCA,EAAK,IAAI,QAAQ,GAAG,GACbA;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAACgf,CAAe,CAAC,GAEdwJ,KAAW7zB;AAAA,IACf,CAACkxB,MAAc;AACb,MAAA7G,EAAgB,CAACrmB,MAAS;AACxB,cAAMqH,IAAO,IAAI,gBAAgBrH,CAAI;AACrC,eAAAqH,EAAK,IAAI,QAAQ,OAAO6lB,CAAC,CAAC,GACnB7lB;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA,CAACgf,CAAe;AAAA,EAAA,GAGZyJ,KAAqBjzB,EAAQ,MAC7B,CAACwD,KAAU,CAAClC,IAAe,KACxBytB,GAAkBvrB,GAAQ,KAAKlC,GAAQiB,KAAA,gBAAAA,EAAQ,OAAO,MAAM,MAClE,CAACiB,GAAQlC,GAAQiB,KAAA,gBAAAA,EAAQ,OAAO,CAAC,GAE9B2wB,KAAiB/zB;AAAA,IACrB,CAACyjB,MAAiB;;AAChB,UAAI,CAACthB,KAAU,CAACkC,EAAQ;AACxB,YAAM0X,KAAKta,KAAAU,EAAO,gBAAP,gBAAAV,GAAoB,KAAK,CAACe;;AAAM,gBAAAf,KAAAU,EAAO,OAAOK,EAAC,MAAf,gBAAAf,GAAkB;AAAA,UACvD/C,IAAKqd,IAAK,OAAO0H,EAAI1H,CAAE,KAAK,EAAE,IAAI;AACxC,UAAI,CAACrd,EAAI;AACT,YAAMyZ,KAAOyX,GAAkBvrB,GAAQ3F,GAAIyD,GAAQiB,KAAA,gBAAAA,EAAQ,OAAO;AAClE,UAAI,CAAC+U,GAAM;AAEX,YAAM6b,MAAWtyB,KAAA2C,EAAO,YAAP,gBAAA3C,GAAgB;AAAA,QAC/B,CAACosB,OAAM,CAACA,GAAE,WAAW,UAAU,KAAK,CAACA,GAAE,WAAW,YAAY;AAAA,SAE1DmG,IAAWD,KACb,OAAOvQ,EAAIuQ,EAAQ,KAAK/yB,EAAIkB,EAAO,QAAQ,IAAI,CAAC,IAChDlB,EAAIkB,EAAO,QAAQ,IAAI,GACrB2d,OAAOje,KAAAwC,EAAO,YAAP,gBAAAxC,GAAgB,SAAQM,EAAO,QAAQ;AACpD,MAAAkB,EAAY8U,IAAM;AAAA,QAChB,OAAO8b;AAAA,QACP,MAAAnU;AAAA,MAAA,CACD;AAAA,IACH;AAAA,IACA,CAAC3d,GAAQkC,GAAQjB,GAAQC,CAAW;AAAA,EAAA,GAGhC6wB,KAAel0B,EAAY,YAAY;AAC3C,QAAI,CAACgwB,KAAeA,EAAY,IAAI,WAAW,EAAG;AAClD,IAAAC,EAAe,IAAI;AACnB,UAAMkE,IAAU,MAAM,QAAQ;AAAA,MAC5BnE,EAAY,IAAI,IAAI,CAACtxB,MAAOozB,GAAe,YAAYpzB,CAAE,CAAC;AAAA,IAAA,GAEtD01B,IAASD,EAAQ,OAAO,CAACl3B,MAAMA,EAAE,WAAW,UAAU,EAAE;AAC9D,QAAIm3B,MAAW;AACb,MAAAjE,EAAgB,CAAA,CAAE;AAAA,aACTiE,IAASpE,EAAY,IAAI,QAAQ;AAE1C,YAAMqE,IAAe,IAAI;AAAA,QACvBrE,EAAY,IAAI,OAAO,CAAC9R,IAAG7Q,OAAM8mB,EAAQ9mB,EAAC,EAAE,WAAW,WAAW;AAAA,MAAA;AAEpE,MAAA8iB,EAAgB,CAACnsB,OAAS;AACxB,cAAMqH,KAA0B,CAAA;AAChC,mBAAW,CAACyC,GAAK2N,EAAG,KAAK,OAAO,QAAQzX,EAAI;AAC1C,UAAKqwB,EAAa,IAAIvmB,CAAG,MAAGzC,GAAKyC,CAAG,IAAI2N;AAE1C,eAAOpQ;AAAA,MACT,CAAC,GACDpE,GAAM,QAAQ,GAAGmtB,CAAM,OAAOpE,EAAY,IAAI,MAAM,iBAAiB;AAAA,IACvE;AAAA,EACF,GAAG,CAACA,GAAa8B,EAAc,CAAC;AAEhC,MAAI,CAACztB,KAAU,CAAClC,EAAQ,QAAO;AAE/B,QAAMmyB,KAAgBnyB,EAAO,SAEvBoyB,KAAatzB,GAAIkK,KAAA9G,EAAO,YAAP,gBAAA8G,GAAgB,IAAI,KAAKlK,EAAIqzB,GAAc,IAAI,GAChEE,OAAaC,KAAApwB,EAAO,YAAP,gBAAAowB,GAAgB,SAAQH,GAAc;AAEzD,SACE,gBAAAnwB,EAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,gBAAArD;AAAA,QAACmQ;AAAA,QAAA;AAAA,UACC,OAAOsjB;AAAA,UACP,SACE,gBAAApwB,EAAAoF,IAAA,EACG,UAAA;AAAA,YAAAwnB,KACC,gBAAAjwB;AAAA,cAACmoB;AAAA,cAAA;AAAA,gBACC,OAAQmH,EAAW,aAAaA,EAAW,aAAaA,EAAW,WAAWA,EAAW,YAAaA,EAAW,QAAQiD,GAAY;AAAA,gBACrI,WAAWjD,EAAW;AAAA,gBACtB,WAAWA,EAAW;AAAA,gBACtB,SAASA,EAAW;AAAA,gBACpB,WAAWA,EAAW;AAAA,cAAA;AAAA,YAAA;AAAA,YAGzBQ,EAAe,IAAI,CAAC,EAAE,MAAAr0B,GAAM,QAAAqW,QAAa;;AACxC,kBAAIA,EAAO,SAAS;AAClB,uBAAIzQ,KAAA,QAAAA,EAAQ,WAAiB,OAE3B,gBAAAgC,EAACyE,KAAkB,SAAS,MAAMvF,EAAY,GAAGgB,EAAO,KAAK,QAAQ,EAAE,OAAO,OAAOpD,EAAIqzB,GAAc,IAAI,CAAC,IAAI,MAAME,IAAY,GAChI,UAAA;AAAA,kBAAA,gBAAA1zB,EAACsd,IAAA,EAAK,WAAU,UAAA,CAAU;AAAA,kBACzBnd,GAAIQ,IAAAmR,EAAO,YAAP,gBAAAnR,EAAgB,IAAI,KAAK,OAAOR,EAAIqzB,GAAc,IAAI,CAAC;AAAA,gBAAA,EAAA,GAFjD/3B,CAGb;AAGJ,kBAAIqW,EAAO,SAAS,UAAU;AAE5B,sBAAM8hB,KAASrB,IACTxf,IAAMjB,EAAO,cAAcA,EAAO,WAAW,SAAS,IACxD8hB,GAAO,OAAO,CAACh2B,OAAO;AACpB,wBAAM+kB,KAAMlQ,GAAK,KAAK,CAACtW,OAAM,OAAOA,GAAEg1B,EAAO,KAAK,EAAE,MAAMvzB,EAAE;AAC5D,yBAAO+kB,KAAMiC,GAAmB9S,EAAO,YAAY6Q,EAAG,IAAI;AAAA,gBAC5D,CAAC,IACDiR,IACEC,KAAa9gB,EAAI,WAAW;AAClC,uBACE,gBAAA1P;AAAA,kBAACyE;AAAA,kBAAA;AAAA,oBAEC,SAAQ;AAAA,oBACR,SAAS,MAAMqnB,EAAe,EAAE,KAAApc,GAAK,cAAc5S,EAAI2R,EAAO,YAAY,KAAK,QAAW;AAAA,oBAC1F,UAAU+hB;AAAA,oBACV,WAAU;AAAA,oBAEV,UAAA;AAAA,sBAAA,gBAAA7zB,EAACqd,IAAA,EAAO,WAAU,UAAA,CAAU;AAAA,sBAC3Bld,GAAIS,KAAAkR,EAAO,YAAP,gBAAAlR,GAAgB,IAAI,KAAK;AAAA,oBAAA;AAAA,kBAAA;AAAA,kBAPzBnF;AAAA,gBAAA;AAAA,cAUX;AACA,qBAAIqW,EAAO,SAAS,SAEX,OAGP,gBAAA9R;AAAA,gBAACimB;AAAA,gBAAA;AAAA,kBAEC,YAAYxqB;AAAA,kBACZ,QAAAqW;AAAA,kBACA,YAAAX;AAAA,kBACA,WAAWohB;AAAA,kBACX,SAAQ;AAAA,kBACR,WAAW,MAAM;AAAE,oBAAAlD,EAAgB,CAAA,CAAE,GAAGE,EAAc,EAAE,WAAW,IAAO,WAAW,IAAM,SAAS,IAAO,WAAW,IAAO,OAAOgD,GAAY,OAAA,CAAQ;AAAA,kBAAG;AAAA,kBAC3J,cAAc,CAACnK,OAAkBmH,EAAc,EAAE,WAAW,IAAM,WAAW,IAAO,SAAS,IAAO,WAAW,IAAO,OAAAnH,IAAO;AAAA,kBAC7H,cAAc,CAACA,OAAkBmH,EAAc,EAAE,WAAW,IAAO,WAAW,IAAO,SAAS,IAAM,WAAW,IAAO,OAAAnH,IAAO;AAAA,kBAC7H,gBAAgB,CAACA,IAAe0L,MAA0B;AAExD,wBADAvE,EAAc,EAAE,WAAW,IAAO,WAAW,IAAO,SAAS,IAAO,WAAW,IAAM,OAAAnH,GAAA,CAAO,GACxF0L,KAAcA,EAAW,SAAS,GAAG;AACvC,4BAAMC,KAAY,IAAI,IAAID,CAAU;AACpC,sBAAAzE,EAAgB,CAACnsB,OAAS;AACxB,8BAAMqH,KAA0B,CAAA;AAChC,mCAAW,CAACyC,IAAK2N,EAAG,KAAK,OAAO,QAAQzX,EAAI;AAC1C,0BAAK6wB,GAAU,IAAI/mB,EAAG,MAAGzC,GAAKyC,EAAG,IAAI2N;AAEvC,+BAAOpQ;AAAA,sBACT,CAAC;AAAA,oBACH;AAAA,kBACF;AAAA,gBAAA;AAAA,gBArBK9O;AAAA,cAAA;AAAA,YAwBX,CAAC;AAAA,YACA8H,EAAO,YAAY,UAAa,EAAClC,KAAA,QAAAA,EAAQ,aACxC,gBAAAgC,EAACyE,GAAA,EAAO,SAAS,MAAMvF,EAAY,GAAGgB,EAAO,KAAK,QAAQ,EAAE,OAAO,OAAOpD,EAAIqzB,GAAc,IAAI,CAAC,IAAI,MAAME,GAAA,CAAY,GACrH,UAAA;AAAA,cAAA,gBAAA1zB,EAACsd,IAAA,EAAK,WAAU,UAAA,CAAU;AAAA,cAAE;AAAA,cACvBnd,EAAIqzB,GAAc,IAAI;AAAA,YAAA,EAAA,CAC7B;AAAA,UAAA,EAAA,CAEJ;AAAA,QAAA;AAAA,MAAA;AAAA,MAKJ,gBAAAnwB,EAAC,OAAA,EAAI,WAAU,gCAEb,UAAA;AAAA,QAAA,gBAAArD;AAAA,UAACstB;AAAA,UAAA;AAAA,YACC,OAAOuC;AAAA,YACP,cAAc7gB,EAAa,IAAI,MAAM;AAAA,YACrC,SAAS;AAAA,YACT,UAAU,CAACglB,MAAS;AAClB,kBAAI,CAACA,EAAK,IAAI;AAEZ,sBAAMzpB,IAAO,IAAI,gBAAA;AACjB,gBAAIyE,EAAa,IAAI,QAAQ,KAAGzE,EAAK,IAAI,UAAUyE,EAAa,IAAI,QAAQ,CAAE,GAC9Eua,EAAgBhf,CAAI;AACpB;AAAA,cACF;AACA,oBAAMA,IAAO,IAAI,gBAAgByE,CAAY;AAC7C,cAAAzE,EAAK,IAAI,QAAQypB,EAAK,EAAE,GACpBA,EAAK,WAAW,MAAM,QAAQA,EAAK,OAAO,KAAKA,EAAK,QAAQ,SAAS,KACvEzpB,EAAK,IAAI,WAAW,KAAK,UAAUypB,EAAK,OAAO,CAAC,GAE9CA,EAAK,WAAWA,EAAK,QAAQ,SAAS,KACxCzpB,EAAK,IAAI,WAAWypB,EAAK,QAAQ,KAAK,GAAG,CAAC,GAExCA,EAAK,QACPzpB,EAAK,IAAI,QAAQypB,EAAK,IAAI,GAE5BzpB,EAAK,IAAI,QAAQ,GAAG,GACpBgf,EAAgBhf,CAAI;AAAA,YACtB;AAAA,UAAA;AAAA,QAAA;AAAA,QAGF,gBAAAlH,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,UAAA,gBAAArD,EAACi0B,IAAA,EAAO,WAAU,kFAAA,CAAkF;AAAA,UACpG,gBAAAj0B;AAAA,YAACoO;AAAA,YAAA;AAAA,cACC,aAAa,UAAUqlB,GAAW,YAAA,CAAa;AAAA,cAC/C,OAAO/C;AAAA,cACP,UAAU,CAAClnB,MAAMqpB,GAAarpB,EAAE,OAAO,KAAK;AAAA,cAC5C,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACZ,GACF;AAAA,QAEA,gBAAAnG;AAAA,UAACyE;AAAA,UAAA;AAAA,YACC,SAAS6nB,IAAc,IAAI,cAAc;AAAA,YACzC,MAAK;AAAA,YACL,SAAS,MAAMF,EAAoB,EAAI;AAAA,YACvC,WAAU;AAAA,YAEV,UAAA;AAAA,cAAA,gBAAAzvB,EAAC0rB,IAAA,EAAO,WAAU,iBAAA,CAAiB;AAAA,cAAE;AAAA,cAEpCiE,IAAc,KACb,gBAAA3vB,EAACyQ,IAAA,EAAM,SAAQ,aAAY,WAAU,wCAClC,UAAAkf,EAAA,CACH;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAIJ,gBAAA3vB;AAAA,UAACysB;AAAA,UAAA;AAAA,YACC,kBAAkBlpB,EAAO,WAAW,CAAA;AAAA,YACpC,gBAAgBstB;AAAA,YAChB,UAAU,CAAC1D,MAAQ;AACjB,oBAAM5iB,IAAO,IAAI,gBAAgByE,CAAY,GACvCiH,IAAU4a,EAAY,SAAS1D,CAAG,IACpC0D,EAAY,OAAO,CAAC7D,OAAMA,OAAMG,CAAG,IACnC,CAAC,GAAG0D,GAAa1D,CAAG;AACxB,cAAIlX,EAAQ,WAAW,MACvB1L,EAAK,IAAI,WAAW0L,EAAQ,KAAK,GAAG,CAAC,GACrCsT,EAAgBhf,CAAI;AAAA,YACtB;AAAA,YACA,SAAS,MAAM;AACb,oBAAMA,IAAO,IAAI,gBAAgByE,CAAY;AAC7C,cAAAzE,EAAK,OAAO,SAAS,GACrBgf,EAAgBhf,CAAI;AAAA,YACtB;AAAA,YACA,WAAW,MAAM;AACf,oBAAMA,IAAO,IAAI,gBAAgByE,CAAY;AAC7C,cAAAzE,EAAK,IAAI,YAAYhH,EAAO,WAAW,CAAA,GAAI,KAAK,GAAG,CAAC,GACpDgmB,EAAgBhf,CAAI;AAAA,YACtB;AAAA,YACA,aAAa,CAACyiB,MAAM;;AAClB,kBAAIA,EAAE,WAAW,UAAU,GAAG;AAC5B,sBAAMkH,KAAKlH,EAAE,MAAM,CAAC,GACdvJ,KAAI9iB,IAAAU,EAAO,kBAAP,gBAAAV,EAAuBuzB;AACjC,uBAAOzQ,IAAKtjB,EAAIsjB,EAAE,IAAI,KAAKyQ,KAAMlH;AAAA,cACnC;AACA,kBAAIA,EAAE,WAAW,YAAY,GAAG;AAC9B,sBAAMmH,KAAKnH,EAAE,MAAM,EAAE,GACfoD,KAAIxvB,KAAAS,EAAO,eAAP,gBAAAT,GAAoBuzB;AAC9B,uBAAO/D,IAAKjwB,EAAIiwB,EAAE,IAAI,KAAK+D,KAAMnH;AAAA,cACnC;AACA,oBAAMtrB,IAAIL,EAAO,OAAO2rB,CAAC;AACzB,qBAAOtrB,IAAIpB,GAAiBoB,GAAGsrB,GAAG1qB,KAAA,gBAAAA,EAAQ,QAAQ,IAAI0qB;AAAA,YACxD;AAAA,UAAA;AAAA,QAAA;AAAA,QAGDmD,KACC,gBAAA9sB;AAAA,UAACyE;AAAA,UAAA;AAAA,YACC,SAASuoB,IAAiB,cAAc;AAAA,YACxC,MAAK;AAAA,YACL,SAASyC;AAAA,YACT,WAAU;AAAA,YAET,UAAA;AAAA,cAAAzC,IAAiB,gBAAArwB,EAAC+d,MAAO,WAAU,iBAAA,CAAiB,IAAK,gBAAA/d,EAACge,IAAA,EAAI,WAAU,iBAAA,CAAiB;AAAA,cACzFqS,IAAiB,iBAAiB;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACrC,GAEJ;AAAA,MAGA,gBAAArwB;AAAA,QAAC4pB;AAAA,QAAA;AAAA,UACC,SAAS8F;AAAA,UACT,UAAU,CAACnvB,MAAUqvB,EAAexG,GAAasG,GAAanvB,CAAK,CAAC;AAAA,UACpE,YAAYopB;AAAA,UACZ,aAAa,MAAM8F,EAAoB,EAAI;AAAA,UAC3C,YAAY,CAAC/tB,MAAM;;AACjB,gBAAIA,EAAE,WAAW,UAAU,GAAG;AAC5B,oBAAM8vB,KAAY9vB,EAAE,MAAM,CAAC,GACrBuQ,KAAQtR,IAAAU,EAAO,kBAAP,gBAAAV,EAAuB6wB;AACrC,qBAAOvf,IAAS9R,EAAI8R,EAAM,IAAI,KAAKuf,KAAa9vB;AAAA,YAClD;AACA,gBAAIA,EAAE,WAAW,YAAY,GAAG;AAC9B,oBAAMiwB,KAAWjwB,EAAE,MAAM,EAAE,GACrBT,KAAOL,KAAAS,EAAO,eAAP,gBAAAT,GAAoB+wB;AACjC,qBAAO1wB,IAAQd,EAAIc,EAAK,IAAI,KAAK0wB,KAAYjwB;AAAA,YAC/C;AACA,kBAAMnB,IAAQc,EAAO,OAAOK,CAAC;AAC7B,mBAAOnB,IAAQD,GAAiBC,GAAOmB,GAAGY,KAAA,gBAAAA,EAAQ,QAAQ,IAAIZ;AAAA,UAChE;AAAA,QAAA;AAAA,MAAA;AAAA,IACF,GACF;AAAA,IAGC4D,KACC,gBAAAtF,EAACmf,IAAA,EAAc,QAAMiV,KAAA7wB,EAAO,YAAP,gBAAA6wB,GAAgB,WAAU,EAAA,CAAG,IAChD9L,KACF,gBAAAtoB,EAAC,OAAA,EAAI,WAAU,QACb,UAAA,gBAAAA;AAAA,MAAC+e;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAM;AAAA,QACN,aAAY;AAAA,MAAA;AAAA,IAAA,EACd,CACF,IACEtM,GAAK,WAAW,IAClB,gBAAAzS,EAAC,OAAA,EAAI,WAAU,QACb,UAAA,gBAAAA;AAAA,MAAC+e;AAAA,MAAA;AAAA,QACC,MAAM2U;AAAA,QACN,OAAO9C,KAAmBjB,IAAc,IAAI,qBAAqB,MAAM8D,GAAW,aAAa;AAAA,QAC/F,aACE7C,KAAmBjB,IAAc,IAC7B,yCACA,qBAAqBxvB,EAAIqzB,GAAc,IAAI,EAAE,YAAA,CAAa;AAAA,QAEhE,QACE,CAAC5C,KAAmBjB,MAAgB,KAAK,EAACtuB,KAAA,QAAAA,EAAQ,YAChD,gBAAAgC,EAACyE,GAAA,EAAO,SAAS,MAAMvF,EAAY,GAAGgB,EAAO,KAAK,QAAQ,EAAE,OAAO,OAAOpD,EAAIqzB,GAAc,IAAI,CAAC,IAAI,MAAME,GAAA,CAAY,GACrH,UAAA;AAAA,UAAA,gBAAA1zB,EAACsd,IAAA,EAAK,WAAU,UAAA,CAAU;AAAA,UAAE;AAAA,UACvBnd,EAAIqzB,GAAc,IAAI;AAAA,QAAA,EAAA,CAC7B,IACE;AAAA,MAAA;AAAA,IAAA,EAER,CACF,IAEA,gBAAAxzB,EAAC,OAAA,EAAI,KAAK0yB,IAAW,WAAU,6BAC7B,UAAA,gBAAArvB,EAAC,SAAA,EAAM,WAAU,kBACf,UAAA;AAAA,MAAA,gBAAArD,EAAC,WAAM,WAAU,4CACd,UAAAmyB,GAAM,kBAAkB,IAAI,CAACkC,MAC5B,gBAAAr0B,EAAC,QAAwB,WAAU,YAChC,YAAY,QAAQ,IAAI,CAACs0B,MAAW;AACnC,cAAMC,IAAUD,EAAO,OAAO,YACxBE,KAASF,EAAO,OAAO,YAAA;AAE7B,eACE,gBAAAt0B;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAU;AAAA,YACV,OAAO,EAAE,OAAOs0B,EAAO,UAAQ;AAAA,YAE9B,UAAAA,EAAO,gBAAgB,OAAOC,IAC7B,gBAAAlxB;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,SAASixB,EAAO,OAAO,wBAAA;AAAA,gBAEtB,UAAA;AAAA,kBAAAG;AAAA,oBACCH,EAAO,OAAO,UAAU;AAAA,oBACxBA,EAAO,WAAA;AAAA,kBAAW;AAAA,kBAEnBE,OAAW,QACV,gBAAAx0B,EAAC00B,IAAA,EAAQ,WAAU,WAAU,IAC3BF,OAAW,SACb,gBAAAx0B,EAAC20B,MAAU,WAAU,UAAA,CAAU,IAE/B,gBAAA30B,EAAC40B,IAAA,EAAY,WAAU,qBAAA,CAAqB;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA,IAIhDH;AAAA,cACEH,EAAO,OAAO,UAAU;AAAA,cACxBA,EAAO,WAAA;AAAA,YAAW;AAAA,UACpB;AAAA,UAzBGA,EAAO;AAAA,QAAA;AAAA,MA6BlB,CAAC,EAAA,GApCMD,EAAY,EAqCrB,CACD,EAAA,CACH;AAAA,wBACC,SAAA,EACE,UAAA;AAAA,QAAA1B,GAAe,gBAAA,EAAkB,SAAS,uBACxC,MAAA,EACC,UAAA,gBAAA3yB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO,EAAE,UAAQ60B,KAAAlC,GAAe,kBAAkB,CAAC,MAAlC,gBAAAkC,GAAqC,UAAS,EAAA;AAAA,YAC/D,SAASxD,GAAQ;AAAA,UAAA;AAAA,QAAA,GAErB;AAAA,QAEDsB,GAAe,gBAAA,EAAkB,IAAI,CAACmC,MAAe;AACpD,gBAAMnS,IAAMzN,GAAK4f,EAAW,KAAK,GAC3BC,IAAY7E,KAAiBvN,EAAI,SAASthB,EAAQ,WAAY,KAAK;AACzE,iBACE,gBAAArB;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,cAAY80B,EAAW;AAAA,cACvB,KAAK,CAAC/xB,OAAS4vB,GAAe,eAAe5vB,EAAI;AAAA,cACjD,WAAW7H;AAAA,gBACT;AAAA,gBACA83B,MAAsB;AAAA,gBACtB+B,KAAa;AAAA,cAAA;AAAA,cAEf,SAAS/B,KAAqB,MAAMC,GAAetQ,EAAI,QAAQ,IAAI;AAAA,cAElE,UAAAA,EAAI,gBAAA,EAAkB,IAAI,CAACqS,OAC1B,gBAAAh1B;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAU;AAAA,kBACV,OAAO,EAAE,OAAOg1B,GAAK,OAAO,UAAQ;AAAA,kBACpC,SACEA,GAAK,OAAO,OAAO,cAAcA,GAAK,OAAO,OAAO,YAChD,CAACxrB,OAAMA,GAAE,oBACT;AAAA,kBAGL,UAAAirB;AAAA,oBACCO,GAAK,OAAO,UAAU;AAAA,oBACtBA,GAAK,WAAA;AAAA,kBAAW;AAAA,gBAClB;AAAA,gBAZKA,GAAK;AAAA,cAAA,CAcb;AAAA,YAAA;AAAA,YA1BIrS,EAAI;AAAA,UAAA;AAAA,QA6Bf,CAAC;AAAA,QACAgQ,GAAe,gBAAA,EAAkB,SAAS,uBACxC,MAAA,EACC,UAAA,gBAAA3yB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,QACE2yB,GAAe,aAAA,OACdsC,KAAAtC,GAAe,kBAAkB,GAAG,EAAE,MAAtC,gBAAAsC,GAAyC,QAAO;AAAA,YAAA;AAAA,YAErD,SAAS5D,GAAQ;AAAA,UAAA;AAAA,QAAA,EACnB,CACF;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,IAIDtG,MAAQA,GAAK,cAAc,KAC1B,gBAAA1nB,EAAC,OAAA,EAAI,WAAU,+EACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,0CACb,UAAA;AAAA,QAAA0nB,GAAK;AAAA,QAAM;AAAA,QAAEA,GAAK,UAAU,IAAI,WAAW;AAAA,MAAA,GAC9C;AAAA,MACA,gBAAA1nB,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,QAAA,gBAAAA;AAAA,UAACyE;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,MAAMirB,GAAStC,IAAO,CAAC;AAAA,YAChC,UAAUA,KAAQ;AAAA,YAElB,UAAA;AAAA,cAAA,gBAAAzwB,EAAC4D,IAAA,EAAY,WAAU,UAAA,CAAU;AAAA,cAAE;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGrC,gBAAAP,EAAC,QAAA,EAAK,WAAU,0CAAyC,UAAA;AAAA,UAAA;AAAA,UACjD0nB,GAAK;AAAA,UAAK;AAAA,UAAKA,GAAK;AAAA,QAAA,GAC5B;AAAA,QACA,gBAAA1nB;AAAA,UAACyE;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,MAAMirB,GAAStC,IAAO,CAAC;AAAA,YAChC,UAAUA,KAAQ1F,GAAK;AAAA,YACxB,UAAA;AAAA,cAAA;AAAA,cAEC,gBAAA/qB,EAAC2D,IAAA,EAAa,WAAU,UAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACpC,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAIF,gBAAA3D;AAAA,MAACsqB;AAAA,MAAA;AAAA,QACC,MAAMkF;AAAA,QACN,SAAS,MAAMC,EAAoB,EAAK;AAAA,QACxC,SAASC;AAAA,QACT,SAASE;AAAA,QACT,iBAAiBsF,GAAqB3xB,GAAQlC,GAAQiB,KAAA,gBAAAA,EAAQ,QAAQ;AAAA,MAAA;AAAA,IAAA;AAAA,IAIxE,gBAAAtC;AAAA,MAACkgB;AAAA,MAAA;AAAA,QACC,MAAMgP,MAAgB;AAAA,QACtB,cAAc,CAAC/O,MAAS,CAACA,KAAQgP,EAAe,IAAI;AAAA,QACpD,OAAO,UAAUhvB,EAAIqzB,GAAc,IAAI,CAAC;AAAA,QACxC,aACEtE,KAAA,QAAAA,EAAa,eACTA,EAAY,eACZgB,IACE,wCAAwC/vB,EAAIqzB,GAAc,IAAI,EAAE,aAAa,4CAC7E,wCAAwCrzB,EAAIqzB,GAAc,IAAI,EAAE,aAAa;AAAA,QAErF,cAAa;AAAA,QACb,WAAWJ;AAAA,QACX,aAAW;AAAA,MAAA;AAAA,IAAA;AAAA,EACb,GACF;AAEJ;AAGA,SAAS8B,GACP3xB,GACAlC,GACAZ,GACmB;;AACnB,MAAI,CAAC8C,KAAU,CAAClC,UAAe,CAAA;AAC/B,QAAM8zB,IAAe5xB,EAAO,WAAW,OAAO,KAAKlC,EAAO,MAAM,GAC1D0pB,IAA0B,CAAA;AAEhC,aAAWrpB,KAAKyzB,GAAc;AAC5B,QAAIzzB,EAAE,WAAW,UAAU,GAAG;AAC5B,YAAM8vB,IAAY9vB,EAAE,MAAM,CAAC,GACrBuQ,KAAQtR,IAAAU,EAAO,kBAAP,gBAAAV,EAAuB6wB;AACrC,UAAI,CAACvf,EAAO;AACZ,MAAA8Y,EAAK,KAAK;AAAA,QACR,MAAMrpB;AAAA,QACN,OAAOvB,EAAI8R,EAAM,IAAI,KAAKuf;AAAA,QAC1B,MAAM;AAAA,QACN,WAAW,CAAC,MAAM,UAAU,MAAM,QAAQ;AAAA,QAC1C,SAASvf,EAAM,SAAS,IAAI,CAACnU,OAAO;AAAA,UAClC,OAAOA,EAAE;AAAA,UACT,OAAOqC,EAAIrC,EAAE,IAAI,KAAKA,EAAE;AAAA,UACxB,OAAOA,EAAE;AAAA,QAAA,EACT;AAAA,MAAA,CACH;AACD;AAAA,IACF;AACA,QAAI4D,EAAE,WAAW,YAAY,GAAG;AAC9B,YAAMiwB,IAAWjwB,EAAE,MAAM,EAAE,GACrBT,KAAOL,IAAAS,EAAO,eAAP,gBAAAT,EAAoB+wB;AACjC,UAAI,CAAC1wB,EAAM;AACX,MAAA8pB,EAAK,KAAK;AAAA,QACR,MAAMrpB;AAAA,QACN,OAAOvB,EAAIc,EAAK,IAAI,KAAK0wB;AAAA,QACzB,MAAM;AAAA,QACN,WAAW,CAAC,MAAM,UAAU,YAAY,YAAY,cAAc;AAAA,MAAA,CACnE;AACD;AAAA,IACF;AACA,UAAMpxB,IAAQc,EAAO,OAAOK,CAAC;AAC7B,QAAI,CAACnB,EAAO;AACZ,UAAMmW,IAAQpW,GAAiBC,GAAOmB,GAAGjB,CAAQ,GAC3C20B,IAAMC,GAAqB90B,EAAM,IAAI,GACrC9D,KAAUsE,IAAAR,EAAM,WAAN,gBAAAQ,EAAc,IAAI,CAACoR,OAAO;AAAA,MACxC,OAAOA,EAAE;AAAA,MACT,OAAOhS,EAAIgS,EAAE,IAAI,KAAKA,EAAE;AAAA,MACxB,OAAOA,EAAE;AAAA,IAAA;AAEX,IAAA4Y,EAAK,KAAK,EAAE,MAAMrpB,GAAG,OAAAgV,GAAO,MAAMnW,EAAM,MAAM,WAAW60B,GAAK,SAAA34B,EAAA,CAAS;AAAA,EACzE;AAEA,SAAOsuB;AACT;AAGA,SAASsK,GAAqBhnB,GAAkD;AAC9E,UAAQA,GAAA;AAAA,IACN,KAAK;AAAA,IAAU,KAAK;AAAA,IAAQ,KAAK;AAAA,IAAS,KAAK;AAAA,IAAO,KAAK;AACzD,aAAO,CAAC,MAAM,UAAU,YAAY,eAAe,YAAY,cAAc;AAAA,IAC/E,KAAK;AACH,aAAO,CAAC,MAAM,UAAU,MAAM,UAAU,YAAY,cAAc;AAAA,IACpE,KAAK;AAAA,IAAO,KAAK;AAAA,IAAS,KAAK;AAC7B,aAAO,CAAC,MAAM,UAAU,MAAM,OAAO,MAAM,OAAO,WAAW,YAAY,cAAc;AAAA,IACzF,KAAK;AACH,aAAO,CAAC,MAAM,UAAU,MAAM,OAAO,MAAM,OAAO,WAAW,SAAS,aAAa,cAAc,eAAe,gBAAgB,YAAY,cAAc;AAAA,IAC5J,KAAK;AACH,aAAO,CAAC,MAAM,UAAU,MAAM,OAAO,MAAM,OAAO,WAAW,SAAS,aAAa,cAAc,eAAe,gBAAgB,aAAa,iBAAiB,YAAY,cAAc;AAAA,IAC1L,KAAK;AACH,aAAO,CAAC,MAAM,UAAU;AAAA,IAC1B,KAAK;AAAA,IAAO,KAAK;AACf,aAAO,CAAC,MAAM,UAAU,YAAY,cAAc;AAAA,IACpD;AACE,aAAO,CAAC,MAAM,UAAU,YAAY,cAAc;AAAA,EAAA;AAExD;AC1kCO,SAASinB,GAAsBve,GAAqB;AACzD,QAAMmB,IAAcnB,EAAI,MAAM,oBAAoB,GAC5CoB,IAAQpB,EAAI,SAAS,GAAG;AAE9B,MAAImB,KAAeC,GAAO;AACxB,UAAMC,IAAO,IAAI,KAAKrB,CAAG;AACzB,QAAI,MAAMqB,EAAK,QAAA,CAAS,EAAG,QAAOrB;AAElC,QAAIsB;AACJ,QAAIF;AACF,MAAAE,IAAK;AAAA,aACIH,GAAa;AACtB,YAAMI,IAAOJ,EAAY,CAAC,EAAE,OAAO,CAAC,GAC9BK,IAAQ,SAASL,EAAY,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE;AAEzD,MADgB,SAASA,EAAY,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE,MAC3C,MACdG,IAAKE,MAAU,IAAI,QAAQ,UAAUD,MAAS,MAAM,MAAM,GAAG,GAAGC,CAAK;AAAA,IAEzE;AAEA,QAAIF;AACF,UAAI;AACF,eAAO,IAAI,KAAK,eAAe,QAAW;AAAA,UACxC,WAAW;AAAA,UACX,WAAW;AAAA,UACX,UAAUA;AAAA,QAAA,CACX,EAAE,OAAOD,CAAI;AAAA,MAChB,QAAQ;AAAA,MAER;AAIF,QAAIF,GAAa;AACf,YAAMI,IAAOJ,EAAY,CAAC,EAAE,OAAO,CAAC,MAAM,MAAM,IAAI,IAC9CK,IAAQ,SAASL,EAAY,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE,GACnDM,IAAU,SAASN,EAAY,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE,GACrDO,IAAWH,KAAQC,IAAQ,KAAKC,KAAW,KAAK,KAChDE,IAAUN,EAAK,QAAA,IAAYK,GAC3BE,IAAY,IAAI,KAAKD,CAAO;AAClC,aAAO,IAAI,KAAK,eAAe,QAAW;AAAA,QACxC,WAAW;AAAA,QACX,WAAW;AAAA,QACX,UAAU;AAAA,MAAA,CACX,EAAE,OAAOC,CAAS;AAAA,IACrB;AAAA,EACF;AAGA,QAAMP,IAAO,IAAI,KAAKrB,CAAG;AACzB,SAAI,MAAMqB,EAAK,QAAA,CAAS,IAAUrB,IAC3B,IAAI,KAAK,eAAe,QAAW;AAAA,IACxC,WAAW;AAAA,IACX,WAAW;AAAA,EAAA,CACZ,EAAE,OAAOqB,CAAI;AAChB;ACrDO,SAASmd,GAAcl0B,GAA4BO,GAAyC;AAGjG,QAAM4zB,IAAW5zB,MAAa,UAAaA,MAAa,QACpD,SACA,OAAOA,KAAa,WAClBA,IACA,OAAO,KAAKA,CAAQ,EAAE,KAAA,EAAO,IAAI,CAACya,MAAM,GAAGA,CAAC,IAAIza,EAASya,CAAC,CAAC,EAAE,EAAE,KAAK,GAAG;AAE7E,SAAOlf,GAAS;AAAA,IACd,UAAU,CAAC,eAAekE,GAAQm0B,CAAQ;AAAA,IAC1C,SAAS,MAAMjjB,GAAUlR,GAASO,CAAS;AAAA,IAC3C,SAAS,CAAC,CAACP,KAAU,CAAC,CAACO,KAAYA,MAAa,SAAS4zB,MAAa;AAAA,EAAA,CACvE;AACH;ACDO,SAASC,GAAgB;AAAA,EAC9B,YAAAtkB;AAAA,EACA,UAAAukB;AAAA,EACA,cAAAC;AAAA,EACA,QAAArzB;AACF,GAAyB;AACvB,QAAMszB,IAAe71B;AAAA,IACnB,MAAM,OAAO,QAAQ41B,CAAY;AAAA,IACjC,CAACA,CAAY;AAAA,EAAA,GAET,CAAC9kB,GAAWC,CAAY,IAAI7O,EAAS,CAAC;AAE5C,MAAI2zB,EAAa,WAAW,EAAG,QAAO;AAEtC,QAAM,CAACC,GAAWC,CAAW,IAAIF,EAAa/kB,CAAS;AAEvD,2BACGpC,IAAA,EACC,UAAA;AAAA,IAAA,gBAAAzO,EAAC0O,IAAA,EAAW,WAAU,QACpB,UAAA,gBAAA1O,EAAC,SAAI,WAAU,2DACZ,UAAA41B,EAAa,IAAI,CAAC,CAAC5oB,GAAK+oB,CAAK,GAAG/3B;;AAC/B,6BAAAqF;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,WAAWnI;AAAA,YACT;AAAA,YACA8C,MAAQ6S,IACJ,wDACA;AAAA,UAAA;AAAA,UAEN,SAAS,MAAMC,EAAa9S,CAAG;AAAA,UAE9B,UAAA;AAAA,cAAA2C,IAAAo1B,EAAM,YAAN,gBAAAp1B,EAAe,SACd,gBAAAX,EAACJ,IAAA,EAAY,MAAMm2B,EAAM,QAAQ,MAAM,WAAU,UAAA,CAAU;AAAA,YAE5D51B,GAAIS,IAAAm1B,EAAM,YAAN,gBAAAn1B,EAAe,IAAI,KAAKoM;AAAA,UAAA;AAAA,QAAA;AAAA,QAZxBA;AAAA,MAAA;AAAA,KAcR,GACH,EAAA,CACF;AAAA,IACA,gBAAAhN,EAAC6O,IAAA,EAAY,WAAU,QACrB,UAAA,gBAAA7O;AAAA,MAACg2B;AAAA,MAAA;AAAA,QACC,YAAA7kB;AAAA,QACA,UAAAukB;AAAA,QACA,UAAUG;AAAA,QACV,aAAaC;AAAA,QACb,QAAAxzB;AAAA,MAAA;AAAA,IAAA,EACF,CACF;AAAA,EAAA,GACF;AAEJ;AAEA,SAAS0zB,GAAmB;AAAA,EAC1B,YAAA7kB;AAAA,EACA,UAAAukB;AAAA,EACA,UAAAO;AAAA,EACA,aAAAC;AAAA,EACA,QAAA5zB;AACF,GAMG;AACD,QAAMC,IAAc3D,GAAA,GACd2oB,IAAY,GAAGpW,CAAU,IAAI8kB,CAAQ,IAGrC,EAAE,MAAME,GAAa,WAAWC,EAAA,IAAcj5B,GAAS;AAAA,IAC3D,UAAU,CAAC,eAAeoqB,GAAWmO,CAAQ;AAAA,IAC7C,SAAS,MAAMziB,GAAmBsU,GAAW,CAACmO,CAAQ,CAAC;AAAA,EAAA,CACxD,GAEKW,KAAmBF,KAAA,gBAAAA,EAAa,kBAAiBD,EAAY,QAC7DzO,IAAenlB,EAAO,SAAS+zB,CAAgB,GAC/CC,KAAYH,KAAA,gBAAAA,EAAa,QAAO,CAAA,GAGhClb,IAAKlb;AAAA,IACT,MAAA;;AAAM,eAAAY,IAAA8mB,KAAA,gBAAAA,EAAc,gBAAd,gBAAA9mB,EAA2B,KAAK,CAACe,MAAA;;AAAM,gBAAAf,IAAA8mB,EAAa,OAAO/lB,CAAC,MAArB,gBAAAf,EAAwB;AAAA,aAAY;AAAA;AAAA,IACjF,CAAC8mB,CAAY;AAAA,EAAA,GAKT8O,IAAYx2B,EAAQ,MAAMu2B,EAAU,MAAM,GAAG,EAAE,GAAG,CAACA,CAAS,CAAC,GAE7D,EAAE,MAAME,GAAc,WAAWC,EAAA,IAAmBt5B,GAAS;AAAA,IACjE,UAAU,CAAC,uBAAuBk5B,GAAkBE,CAAS;AAAA,IAC7D,SAAS,MACPjkB,GAAa+jB,GAAkB;AAAA,MAC7B,UAAU;AAAA,MACV,SAAS,CAAC,EAAE,OAAOpb,GAAI,IAAI,MAAM,OAAOsb,EAAA,CAAW;AAAA,IAAA,CACpD;AAAA,IACH,SAASA,EAAU,SAAS,KAAK,CAAC,CAAC9O;AAAA,EAAA,CACpC,GAEKvS,KAAOshB,KAAA,gBAAAA,EAAc,SAAQ,CAAA,GAC7B3b,IAAO2b,KAAA,gBAAAA,EAAc,OAGrBnF,IAAUtxB,EAAQ,MACjB0nB,IACEA,EAAa,YACjB,OAAO,CAACnoB,MAAS;;AAChB,UAAMoC,IAAI+lB,EAAa,OAAOnoB,CAAI;AAClC,WAAOoC,KAAK,CAACA,EAAE,WAAW,CAACA,EAAE,UAAQf,IAAAe,EAAE,YAAF,gBAAAf,EAAW,iBAAgB;AAAA,EAClE,CAAC,EACA,MAAM,GAAG,CAAC,IANa,CAAA,GAOzB,CAAC8mB,CAAY,CAAC,GAEXiP,IAAgB,MAAM;;AAC1B,UAAMlP,IAAexB,GAAwB1jB,GAAQ+zB,CAAgB;AACrE,QAAI,CAAC7O,EAAc;AACnB,UAAMtjB,IAAc/D,GAAIQ,IAAAu1B,EAAY,YAAZ,gBAAAv1B,EAAqB,IAAI,KAAKs1B,GAChDt3B,IAAS,IAAI,gBAAA;AACnB,IAAAA,EAAO,IAAI,WAAW,KAAK,UAAU,CAAC,EAAE,OAAOsc,GAAI,IAAI,MAAM,OAAOqb,EAAA,CAAW,CAAC,CAAC,GACjF/zB,EAAYilB,EAAa,OAAO;AAAA,MAC9B,OAAOtjB;AAAA,MACP,QAAMtD,IAAAs1B,EAAY,YAAZ,gBAAAt1B,EAAqB,SAAQ4mB,EAAa;AAAA,MAChD,QAAQ7oB,EAAO,SAAA;AAAA,IAAS,CACzB;AAAA,EACH;AAEA,MAAIy3B,KAAaK;AACf,WACE,gBAAAz2B,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA,cAE7D;AAIJ,MAAI,CAACynB;AACH,WACE,gBAAAznB,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA,qBAE7D;AAIJ,MAAIs2B,EAAU,WAAW;AACvB,WACE,gBAAAt2B,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA,uBAE7D;AAIJ,QAAMwnB,IAAexB,GAAwB1jB,GAAQ+zB,CAAgB;AAErE,2BACG,OAAA,EACC,UAAA;AAAA,IAAA,gBAAAhzB,EAAC,SAAA,EAAM,WAAU,kBACf,UAAA;AAAA,MAAA,gBAAArD,EAAC,SAAA,EACC,4BAAC,MAAA,EAAG,WAAU,YACX,UAAAqxB,EAAQ,IAAI,CAAClE,MACZ,gBAAAntB;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,WAAU;AAAA,UAET,aAAiBynB,EAAa,OAAO0F,CAAG,GAAGA,GAAK7qB,EAAO,QAAQ;AAAA,QAAA;AAAA,QAH3D6qB;AAAA,MAAA,CAKR,GACH,EAAA,CACF;AAAA,MACA,gBAAAntB,EAAC,SAAA,EACE,UAAAkV,EAAK,IAAI,CAACyN,GAAKpW,MACd,gBAAAvM,EAAC,MAAA,EAAW,WAAU,0BACnB,UAAAqxB,EAAQ,IAAI,CAAClE,MAAQ;AACpB,cAAM5sB,IAAQknB,EAAa,OAAO0F,CAAG;AACrC,eAAK5sB,IAEH,gBAAAP,EAAC,MAAA,EAAa,WAAU,0BACrB,UAAA8c,GAAY;AAAA,UACX,OAAAvc;AAAA,UACA,WAAW4sB;AAAA,UACX,OAAOxK,EAAIwK,CAAG;AAAA,UACd,MAAM;AAAA,UACN,QAAQxK;AAAA,UACR,MAAA9H;AAAA,QAAA,CACD,KARMsS,CAST,IAXiB,gBAAAntB,EAAC,UAAQmtB,CAAK;AAAA,MAanC,CAAC,EAAA,GAhBM5gB,CAiBT,CACD,EAAA,CACH;AAAA,IAAA,GACF;AAAA,IACCib,KAAgB2O,KAAeA,EAAY,QAAQjhB,EAAK,UACvD,gBAAAlV,EAAC,OAAA,EAAI,WAAU,oBACb,4BAAC8H,GAAA,EAAO,SAAQ,WAAU,MAAK,MAAK,SAAS4uB,GAC3C,UAAA;AAAA,MAAA,gBAAA12B,EAAC8X,IAAA,EAAa,WAAU,iBAAA,CAAiB;AAAA,MAAE;AAAA,MACjCqe,EAAY;AAAA,MAAM;AAAA,IAAA,EAAA,CAC9B,EAAA,CACF;AAAA,IAED3O,KAAgBtS,EAAK,SAAS,KAAKihB,KAAeA,EAAY,SAASjhB,EAAK,UAC3E,gBAAAlV,EAAC,SAAI,WAAU,oBACb,4BAAC8H,GAAA,EAAO,SAAQ,SAAQ,MAAK,MAAK,SAAS4uB,GACzC,UAAA;AAAA,MAAA,gBAAA12B,EAAC8X,IAAA,EAAa,WAAU,iBAAA,CAAiB;AAAA,MAAE;AAAA,IAAA,EAAA,CAE7C,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;AC5NA,MAAM6e,KAAa;AAIZ,SAASC,GAAe7f,GAAoD;AACjF,MAAIA,KAAO,QAAQA,MAAQ,GAAI,QAAO;AAEtC,MAAIA,MAAQ,OAAQ,QAAO,EAAE,MAAM,OAAA;AACnC,MAAIA,MAAQ,OAAQ,QAAO,EAAE,MAAM,OAAA;AAGnC,QAAM8f,IAAUF,GAAW,KAAK5f,CAAG;AACnC,MAAI8f,GAAS;AACX,UAAMvuB,IAAI,SAASuuB,EAAQ,CAAC,GAAG,EAAE;AACjC,WAAIvuB,IAAI,IAAU,EAAE,MAAM,MAAM,OAAOA,EAAA,IAChC;AAAA,EACT;AAGA,QAAMwuB,IAAS,SAAS/f,GAAK,EAAE;AAC/B,SAAI,CAAC,MAAM+f,CAAM,KAAK,OAAOA,CAAM,MAAM/f,KAAO+f,IAAS,IAChD,EAAE,MAAM,UAAU,OAAOA,EAAA,IAG3B;AACT;ACnBO,SAASC,GAAU,EAAE,QAAAC,GAAQ,KAAAzV,KAAuB;AACzD,QAAM,EAAE,OAAAze,GAAO,KAAAm0B,IAAM,GAAG,WAAAC,IAAY,IAAO,aAAAC,MAAgBH,GACrDI,IAAUD,MAAgB,UAAU,IAAKA,KAAe,KACxD,CAACE,GAASC,CAAU,IAAIr1B,EAAS,EAAK,GACtCs1B,IAAepqB,GAAuB,IAAI;AAGhD,EAAAC,GAAU,MAAM;AACd,QAAIgqB,MAAY,EAAG;AACnB,UAAMI,IAAKD,EAAa;AACxB,QAAI,CAACC,EAAI;AAET,UAAMC,IAAW,IAAI,eAAe,CAACrU,MAAY;AAC/C,iBAAWsU,KAAStU;AAClB,QAAAkU,EAAWI,EAAM,YAAY,QAAQN,CAAO;AAAA,IAEhD,CAAC;AACD,WAAAK,EAAS,QAAQD,CAAE,GACZ,MAAMC,EAAS,WAAA;AAAA,EACxB,GAAG,CAACL,CAAO,CAAC;AAGZ,QAAM,CAACO,GAAWC,CAAY,IAAI31B,EAA0B,IAAI,GAC1D41B,IAAW1qB,GAAuE,IAAI,GAEtF2qB,IAAkB54B,EAAY,MAC3B4D,EAAM,IAAI,CAACW,MAAS;;AAGzB,UAAMs0B,IAAIt0B,EAAK,WAAS9C,IAAA8C,EAAK,WAAL,gBAAA9C,EAAa,YAASC,IAAA6C,EAAK,QAAL,gBAAA7C,EAAU,UAASo2B,EAAO,OAClEtrB,IAASkrB,GAAemB,CAAC;AAC/B,WAAIrsB,KAAUA,EAAO,SAAS,WAAiBA,EAAO,QAC/C;AAAA,EACT,CAAC,GACA,CAAC5I,GAAOk0B,EAAO,KAAK,CAAC,GAElBgB,IAAc94B;AAAA,IAClB,CAACxD,GAAe8N,MAAwB;AACtC,MAAAA,EAAE,eAAA;AACF,YAAMyuB,IAAQN,KAAaG,EAAA;AAC3B,MAAAD,EAAS,UAAU,EAAE,OAAAn8B,GAAO,QAAQ8N,EAAE,SAAS,YAAY,CAAC,GAAGyuB,CAAK,EAAA;AAEpE,YAAMC,IAAS,CAACrrB,MAAmB;AACjC,cAAMoL,IAAI4f,EAAS;AACnB,YAAI,CAAC5f,KAAK,CAACsf,EAAa,QAAS;AACjC,cAAMY,IAAaZ,EAAa,QAAQ,sBAAA,EAAwB,OAC1Da,IAAQvrB,EAAG,UAAUoL,EAAE,QACvBogB,IAAYpgB,EAAE,WAAW,OAAO,CAAC7G,GAAGC,MAAMD,IAAIC,GAAG,CAAC,GAClDinB,IAAaF,IAAQD,IAAcE,GACnCE,IAAW,CAAC,GAAGtgB,EAAE,UAAU;AACjC,QAAAsgB,EAAStgB,EAAE,KAAK,IAAI,KAAK,IAAI,KAAKA,EAAE,WAAWA,EAAE,KAAK,IAAIqgB,CAAS,GACnEC,EAAStgB,EAAE,QAAQ,CAAC,IAAI,KAAK,IAAI,KAAKA,EAAE,WAAWA,EAAE,QAAQ,CAAC,IAAIqgB,CAAS,GAC3EV,EAAaW,CAAQ;AAAA,MACvB,GAEMC,IAAO,MAAM;AACjB,QAAAX,EAAS,UAAU,MACnB,SAAS,oBAAoB,aAAaK,CAAM,GAChD,SAAS,oBAAoB,WAAWM,CAAI;AAAA,MAC9C;AAEA,eAAS,iBAAiB,aAAaN,CAAM,GAC7C,SAAS,iBAAiB,WAAWM,CAAI;AAAA,IAC3C;AAAA,IACA,CAACb,GAAWG,CAAe;AAAA,EAAA,GAGvBG,IAAQN,KAAaG,EAAA,GAGrBW,IAAczB,EAAO,SAAS0B,GAAY1B,EAAO,MAAM,IAAI;AAEjE,SACE,gBAAAh3B;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAKu3B;AAAA,MACL,WAAWr8B,EAAG,QAAQm8B,KAAW,UAAU;AAAA,MAC3C,OAAO,EAAE,KAAKJ,IAAM,GAAGA,CAAG,OAAO,QAAW,GAAGwB,EAAA;AAAA,MAE9C,UAAA31B,EAAM,IAAI,CAACW,GAAM8I,MAAA;;AAChB,+BAAAlJ;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAWnI,EAAG,8BAA8Bm8B,KAAW,QAAQ;AAAA,YAC/D,OAAOA,IAAU,SAAYsB,GAAUl1B,EAAK,WAAS9C,IAAA8C,EAAK,WAAL,gBAAA9C,EAAa,YAASC,IAAA6C,EAAK,QAAL,gBAAA7C,EAAU,UAASo2B,EAAO,OAAOiB,EAAM1rB,CAAC,GAAG9I,EAAK,WAAWA,EAAK,SAAS;AAAA,YAEpJ,UAAA;AAAA,cAAA,gBAAAzD,EAAC,OAAA,EAAI,WAAW9E,EAAG,gCAAgCu9B,KAAe,mCAAmC,GACnG,UAAA,gBAAAz4B,EAAC44B,IAAA,EAAmB,MAAMn1B,GAAM,KAAA8d,EAAA,CAAU,GAC5C;AAAA,cACC2V,KAAa,CAACG,KAAW9qB,IAAIzJ,EAAM,SAAS,KAC3C,gBAAA9C;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,aAAa,CAACwJ,MAAMwuB,EAAYzrB,GAAG/C,CAAC;AAAA,gBAAA;AAAA,cAAA;AAAA,YACtC;AAAA,UAAA;AAAA,UAXG+C;AAAA,QAAA;AAAA,OAcR;AAAA,IAAA;AAAA,EAAA;AAGP;AAEA,SAASosB,GACP9G,GACAgH,GACAC,GACAC,GACqB;AACrB,QAAMrtB,IAASkrB,GAAe/E,CAAK;AACnC,MAAImH;AACJ,SAAI,CAACttB,KAAUA,EAAO,SAAS,WAC7BstB,IAAO,GAAGH,CAAS,UACVntB,EAAO,SAAS,OACzBstB,IAAO,OAAOttB,EAAO,KAAK,OACjBA,EAAO,SAAS,SACzBstB,IAAO,WAEPA,IAAO,YAEF,EAAE,MAAAA,GAAM,UAAAF,GAAU,UAAAC,EAAA;AAC3B;AAEA,SAASL,GAAYO,GAAoD;AACvE,MAAI,CAACA,EAAQ;AACb,QAAMvtB,IAASkrB,GAAeqC,CAAM;AACpC,OAAIvtB,KAAA,gBAAAA,EAAQ,UAAS,KAAM,QAAO,EAAE,QAAQ,GAAGA,EAAO,KAAK,MAAM,UAAU,SAAA;AAG3E,MAAI,OAAOutB,KAAW,aAAaA,EAAO,SAAS,IAAI,KAAKA,EAAO,SAAS,MAAM,KAAKA,EAAO,SAAS,GAAG;AACxG,WAAO,EAAE,QAAAA,GAAQ,UAAU,SAAA;AAG/B;ACtIO,SAASC,GAAa,EAAE,QAAAlC,GAAQ,KAAAzV,KAA0B;AAC/D,QAAM,EAAE,OAAAze,GAAO,KAAAm0B,IAAM,GAAA,IAAOD;AAE5B,SACE,gBAAAh3B;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,KAAKi3B,IAAM,GAAGA,CAAG,OAAO,OAAA;AAAA,MAEhC,UAAAn0B,EAAM,IAAI,CAACW,GAAM8I,MAChB,gBAAAvM,EAAC44B,IAAA,EAA2B,MAAMn1B,GAAM,KAAA8d,EAAA,GAAfhV,CAAyB,CACnD;AAAA,IAAA;AAAA,EAAA;AAGP;ACTA,SAAS4sB,GAAYp2B,GAAkBwe,GAA4B;;AAEjE,MAAIxe,EAAK,UAAU;AACjB,QAAIA,EAAK,MAAO,QAAO5C,EAAI4C,EAAK,KAAK;AACrC,UAAMq2B,KAAgBz4B,IAAA4gB,EAAI,OAAO,aAAX,gBAAA5gB,EAAqB,KAAK,CAACqsB,MAAMA,EAAE,WAAWjqB,EAAK;AACzE,SAAInC,IAAAw4B,KAAA,gBAAAA,EAAe,YAAf,QAAAx4B,EAAwB,aAAaT,EAAIi5B,EAAc,QAAQ,IAAI;AACvE,UAAMC,IAAc9X,EAAI,OAAO,SAASxe,EAAK,QAAQ;AACrD,WAAIs2B,KAAoBl5B,EAAIk5B,EAAY,QAAQ,WAAW,KAAKt2B,EAAK;AAAA,EAEvE;AAEA,SAAIA,EAAK,UACA5C,EAAI4C,EAAK,QAAQ,IAAI,IAEvB;AACT;AAGA,SAASu2B,GAAWv2B,GAAkBwe,GAAwC;;AAC5E,MAAIxe,EAAK,KAAM,QAAOA,EAAK;AAC3B,MAAIA,EAAK,UAAU;AACjB,UAAMq2B,KAAgBz4B,IAAA4gB,EAAI,OAAO,aAAX,gBAAA5gB,EAAqB,KAAK,CAACqsB,MAAMA,EAAE,WAAWjqB,EAAK;AACzE,SAAInC,IAAAw4B,KAAA,gBAAAA,EAAe,YAAf,QAAAx4B,EAAwB,KAAM,QAAOw4B,EAAc,QAAQ;AAC/D,UAAMC,IAAc9X,EAAI,OAAO,SAASxe,EAAK,QAAQ;AACrD,QAAIs2B,EAAa,QAAOA,EAAY,QAAQ;AAAA,EAC9C;AAEF;AAIO,SAASE,GAAW,EAAE,QAAAvC,GAAQ,KAAAzV,KAAwB;AAC3D,QAAM,EAAE,OAAAze,MAAUk0B,GACZ,CAACnmB,GAAWC,CAAY,IAAI7O,EAAS,CAAC;AAE5C,SAAIa,EAAM,WAAW,IAAU,yBAG5B2L,IAAA,EACC,UAAA;AAAA,IAAA,gBAAAzO,EAAC0O,IAAA,EAAW,WAAU,QACpB,UAAA,gBAAA1O,EAAC,OAAA,EAAI,WAAU,2DACZ,UAAA8C,EAAM,IAAI,CAACW,GAAMzF,MAAQ;AACxB,YAAM0Y,IAAQyiB,GAAY11B,GAAM8d,CAAG,GAC7BvC,IAAOsa,GAAW71B,GAAM8d,CAAG;AACjC,aACE,gBAAAle;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,WAAWnI;AAAA,YACT;AAAA,YACA8C,MAAQ6S,IACJ,wDACA;AAAA,UAAA;AAAA,UAEN,SAAS,MAAMC,EAAa9S,CAAG;AAAA,UAE9B,UAAA;AAAA,YAAAghB,KAAQ,gBAAAhf,EAACJ,IAAA,EAAY,MAAMof,GAAM,WAAU,WAAU;AAAA,YACrDtI;AAAA,UAAA;AAAA,QAAA;AAAA,QAVI1Y;AAAA,MAAA;AAAA,IAaX,CAAC,GACH,GACF;AAAA,IACA,gBAAAgC,EAAC6O,IAAA,EAAY,WAAU,QACrB,UAAA,gBAAA7O;AAAA,MAAC44B;AAAA,MAAA;AAAA,QAEC,MAAM91B,EAAM+N,CAAS;AAAA,QACrB,KAAA0Q;AAAA,MAAA;AAAA,MAFK1Q;AAAA,IAAA,EAGP,CACF;AAAA,EAAA,GACF;AAEJ;ACtEO,SAAS2oB,GAAa,EAAE,QAAAxC,GAAQ,KAAAzV,KAA0B;AAC/D,QAAM,EAAE,MAAAjiB,GAAM,OAAAwD,GAAO,WAAW22B,IAAmB,IAAO,SAAApI,MAAY2F,GAChE,CAACj1B,GAAWC,CAAY,IAAIC,EAASw3B,CAAgB,GACrDC,IAAWrI,IAAU,EAAE,GAAG9P,GAAK,SAAA8P,MAAY9P;AAEjD,2BACG9S,IAAA,EACC,UAAA;AAAA,IAAA,gBAAAzO;AAAA,MAAC0O;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,SAAS,MAAM1M,EAAa,CAACgrB,MAAM,CAACA,CAAC;AAAA,QAErC,UAAA,gBAAA3pB,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,UAAA,gBAAArD,EAAC2O,IAAA,EAAU,WAAU,aAAa,UAAAxO,EAAIb,CAAI,GAAE;AAAA,UAC5C,gBAAAU;AAAA,YAACwD;AAAA,YAAA;AAAA,cACC,WAAWtI;AAAA,gBACT;AAAA,gBACA6G,KAAa;AAAA,cAAA;AAAA,YACf;AAAA,UAAA;AAAA,QACF,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,IAED,CAACA,KACA,gBAAA/B,EAAC6O,IAAA,EACC,UAAA,gBAAA7O,EAAC25B,MAAe,OAAO72B,GAAO,KAAK42B,EAAA,CAAU,EAAA,CAC/C;AAAA,EAAA,GAEJ;AAEJ;ACLO,SAASE,GACdC,GACAR,GACAS,GACqB;AACrB,QAAM34B,IAAU04B,EAAS,SAGnB7zB,IAA8B;AAAA,IAClC,QAAQ6zB,EAAS;AAAA,IACjB,aAAaA,EAAS;AAAA,IACtB,MAAME,GAAaD,KAAA,gBAAAA,EAAY,OAAO34B,KAAA,gBAAAA,EAAS,MAAM64B,GAAUX,CAAW,CAAC;AAAA,IAC3E,MAAMU,GAAaD,KAAA,gBAAAA,EAAY,MAAM34B,KAAA,gBAAAA,EAAS,MAAMk4B,EAAY,QAAQ,IAAI,KAAK;AAAA,IACjF,MAAMU,GAAaD,KAAA,gBAAAA,EAAY,MAAM34B,KAAA,gBAAAA,EAAS,MAAM,OAAO;AAAA,IAC3D,SAAS44B,GAAaD,KAAA,gBAAAA,EAAY,SAAS34B,KAAA,gBAAAA,EAAS,SAAS84B,GAAaZ,GAAaQ,EAAS,WAAW,CAAC;AAAA,IAC5G,MAAME,GAAaD,KAAA,gBAAAA,EAAY,MAAM34B,KAAA,gBAAAA,EAAS,MAAM+4B,GAAUb,CAAW,CAAC;AAAA,IAC1E,OAAOU,GAAaD,KAAA,gBAAAA,EAAY,OAAO34B,KAAA,gBAAAA,EAAS,OAAO,EAAE;AAAA,IACzD,UAAU44B,GAAaD,KAAA,gBAAAA,EAAY,UAAU34B,KAAA,gBAAAA,EAAS,UAAU,EAAI;AAAA,EAAA,GAIhEg5B,IAAWJ,GAAaD,KAAA,gBAAAA,EAAY,gBAAgB34B,KAAA,gBAAAA,EAAS,gBAAgB,MAA+B;AAClH,EAAIg5B,MACFn0B,EAAO,iBAAiBm0B,GAExBn0B,EAAO,OAAOm0B,IAAW;AAI3B,QAAMC,KAAiBN,KAAA,gBAAAA,EAAY,cAAY34B,KAAA,gBAAAA,EAAS;AACxD,EAAI6E,EAAO,SAAS,aAClBA,EAAO,WAAWq0B,GAAoBD,KAAkB,CAAA,GAAIf,CAAW,IAC9De,MACTp0B,EAAO,WAAWo0B;AAIpB,QAAME,KAAcR,KAAA,gBAAAA,EAAY,WAAS34B,KAAA,gBAAAA,EAAS;AAClD,EAAIm5B,MACFt0B,EAAO,QAAQs0B;AAIjB,QAAMC,KAAWT,KAAA,gBAAAA,EAAY,cAAaD,EAAS;AACnD,SAAIU,MACFv0B,EAAO,YAAYu0B,IAGdv0B;AACT;AAGA,SAAS+zB,GAAgBS,GAA+BC,GAA8BC,GAAmB;AACvG,SAAIF,KACAC,KACGC;AACT;AAEA,SAASV,GAAU34B,GAAiC;AAClD,SAAIA,EAAO,QAAQ,eAAe,OAAO,KAAKA,EAAO,QAAQ,WAAW,EAAE,SAAS,IAC1EA,EAAO,QAAQ,cAEjBA,EAAO,QAAQ;AACxB;AAKO,SAAS64B,GAAU74B,GAAwB;;AAChD,QAAIV,IAAAU,EAAO,OAAO,eAAd,gBAAAV,EAA6B,UAAS;AACxC,WAAO;AAET,QAAIC,IAAAS,EAAO,OAAO,eAAd,gBAAAT,EAA6B,UAAS;AACxC,WAAO;AAET,aAAWtB,KAAQ+B,EAAO,aAAa;AACrC,UAAMK,IAAIL,EAAO,OAAO/B,CAAI;AAC5B,QAAIoC,KAAKA,EAAE,SAAS;AAClB,aAAOpC,IAAO;AAAA,EAElB;AACA,aAAWA,KAAQ+B,EAAO,aAAa;AACrC,UAAMK,IAAIL,EAAO,OAAO/B,CAAI;AAC5B,QAAIoC,KAAKA,EAAE,SAAS;AAClB,aAAOpC,IAAO;AAAA,EAElB;AAEA,QAAM2b,IAAK0f,GAAet5B,CAAM;AAChC,SAAI4Z,IAAWA,IAAK,SACb;AACT;AAIO,SAASgf,GAAa54B,GAAgBiL,GAAiC;;AAC5E,QAAMsuB,IAAQ,IAAI,IAAI,MAAM,QAAQtuB,CAAE,IAAIA,IAAK,CAACA,CAAE,CAAC,GAC7C8S,IAAiB,CAAA;AACvB,aAAW9f,KAAQ+B,EAAO,aAAa;AACrC,QAAI+d,EAAK,UAAU,EAAG;AACtB,UAAM1d,IAAIL,EAAO,OAAO/B,CAAI;AAC5B,IAAKoC,MACDA,EAAE,WAAWA,EAAE,UACff,IAAAe,EAAE,YAAF,gBAAAf,EAAW,iBAAgB,OAC3Bi6B,EAAM,IAAIt7B,CAAI,KAClB8f,EAAK,KAAK9f,CAAI;AAAA,EAChB;AACA,SAAO8f;AACT;AAIO,SAASib,GAAoBQ,GAAoBx5B,GAAgC;AACtF,QAAM2E,IAAyB,EAAE,GAAG60B,EAAA;AAEpC,SAAK70B,EAAO,eACVA,EAAO,aAAa80B,GAAez5B,CAAM,IAEtC2E,EAAO,eACVA,EAAO,aAAa+0B,GAAsB15B,GAAQ,MAAM,IAErD2E,EAAO,kBACVA,EAAO,gBAAgBg1B,GAAuB35B,GAAQ,UAAU,MAAM,IAEnE2E,EAAO,kBACVA,EAAO,gBAAgB+0B,GAAsB15B,GAAQ,MAAM,IAExD2E,EAAO,gBACN3E,EAAO,OAAO,eAChB2E,EAAO,eAAe,eAGrBA,EAAO,oBACVA,EAAO,kBAAkBi1B,GAAoB55B,CAAM,IAEhD2E,EAAO,iBACVA,EAAO,eAAek1B,GAAiB75B,CAAM,IAGxC2E;AACT;AAEA,SAASi1B,GAAoB55B,GAAoC;AAC/D,QAAM85B,IAAY95B,EAAO,OAAO;AAChC,MAAI85B,KAAaA,EAAU,SAAS,OAAQ,QAAO;AACnD,aAAW77B,KAAQ,CAAC,eAAe,YAAY,cAAc,SAAS,GAAG;AACvE,UAAMoC,IAAIL,EAAO,OAAO/B,CAAI;AAC5B,QAAIoC,KAAKA,EAAE,SAAS,OAAQ,QAAOpC;AAAA,EACrC;AAEF;AAEA,SAAS47B,GAAiB75B,GAAoC;AAC5D,QAAM+5B,IAAS/5B,EAAO,OAAO;AAC7B,MAAI+5B,KAAUA,EAAO,SAAS,OAAQ,QAAO;AAE/C;AAEA,SAASN,GAAez5B,GAAoC;;AAE1D,aAAW/B,KAAQ+B,EAAO,aAAa;AACrC,UAAMK,IAAIL,EAAO,OAAO/B,CAAI;AAC5B,QAAIoC,KAAKA,EAAE,SAAS,eAAe,CAACA,EAAE;AACpC,aAAOpC;AAAA,EAEX;AAEA,QAAIqB,IAAAU,EAAO,OAAO,eAAd,gBAAAV,EAA6B,UAAS,YAAa,QAAO;AAC9D,QAAIC,IAAAS,EAAO,OAAO,eAAd,gBAAAT,EAA6B,UAAS,YAAa,QAAO;AAC9D,aAAWtB,KAAQ+B,EAAO,aAAa;AACrC,UAAMK,IAAIL,EAAO,OAAO/B,CAAI;AAC5B,QAAIoC,KAAKA,EAAE,SAAS,YAAa,QAAOpC;AAAA,EAC1C;AAEF;AAEA,SAASy7B,GAAsB15B,GAAgBgN,GAAkC;AAC/E,aAAW/O,KAAQ+B,EAAO,aAAa;AACrC,UAAMK,IAAIL,EAAO,OAAO/B,CAAI;AAC5B,QAAIoC,KAAKA,EAAE,SAAS2M;AAClB,aAAO/O;AAAA,EAEX;AAEF;AAEA,SAAS07B,GAAuB35B,MAAmBg6B,GAAqC;AACtF,aAAW/7B,KAAQ+B,EAAO,aAAa;AACrC,UAAMK,IAAIL,EAAO,OAAO/B,CAAI;AAC5B,QAAKoC;AACL,iBAAW/D,KAAK09B;AACd,YAAI35B,EAAE,SAAS/D,EAAG,QAAO2B;AAAA;AAAA,EAE7B;AAEF;AAMO,SAASq7B,GAAet5B,GAAoC;AACjE,QAAMi6B,IAAMl6B,GAAoBC,CAAM;AACtC,SAAOi6B,EAAI,SAAS,IAAIA,EAAI,CAAC,IAAI;AACnC;AASO,SAASC,GAAkB1vB,GAAsBE,GAA8C;;AACpG,UAAOpL,IAAAkL,EAAa,aAAb,gBAAAlL,EAAuB,KAAK,CAACqsB,MAAMA,EAAE,WAAWjhB;AACzD;ACpPO,SAASyvB,GACdC,GACAC,GACA1vB,GACAF,GACyB;AACzB,QAAM9F,IAAkC;AAAA,IACtC,GAAI01B,KAAY,CAAA;AAAA,IAChB,GAAGD;AAAA,EAAA;AAEL,MAAI,MAAM,QAAQzvB,CAAU,GAAG;AAE7B,UAAM+G,IAAM,MAAM,QAAQjH,CAAQ,IAAIA,IAAW,OAAOA,CAAQ,EAAE,MAAM,GAAG;AAC3E,aAASS,IAAI,GAAGA,IAAIP,EAAW,QAAQO;AACrC,MAAAvG,EAAOgG,EAAWO,CAAC,CAAC,IAAIwG,EAAIxG,CAAC;AAAA,EAEjC;AACE,IAAAvG,EAAOgG,CAAU,IAAI,MAAM,QAAQF,CAAQ,IAAIA,EAAS,CAAC,IAAIA;AAE/D,SAAO9F;AACT;AAKO,SAAS21B,GACdF,GACAG,GACS;AACT,aAAWt8B,KAAQs8B,GAAgB;AACjC,UAAMjhB,IAAM8gB,EAAYn8B,CAAI;AAC5B,QAAIqb,KAAO,QAAQA,MAAQ,GAAI,QAAO;AAAA,EACxC;AACA,SAAO;AACT;AClCA,SAASkhB,KAAyB;AAChC,QAAMC,wBAAU,KAAA,GACV9iB,IAAI8iB,EAAI,YAAA,GACRjjB,IAAI,OAAOijB,EAAI,SAAA,IAAa,CAAC,EAAE,SAAS,GAAG,GAAG,GAC9C7jB,IAAI,OAAO6jB,EAAI,QAAA,CAAS,EAAE,SAAS,GAAG,GAAG,GACzC5qB,IAAI,OAAO4qB,EAAI,SAAA,CAAU,EAAE,SAAS,GAAG,GAAG,GAC1CC,IAAM,OAAOD,EAAI,WAAA,CAAY,EAAE,SAAS,GAAG,GAAG;AACpD,SAAO,GAAG9iB,CAAC,IAAIH,CAAC,IAAIZ,CAAC,IAAI/G,CAAC,IAAI6qB,CAAG;AACnC;AAuBO,SAASC,GACdhF,GACAnrB,GACAC,GACAxJ,GACmB;AACnB,QAAM,CAACb,GAAQw6B,CAAS,IAAIh6B,EAAkC,MAAM;;AAClE,UAAMi6B,IAAMlF,EAAO,WACbmF,IAAK75B,EAAO,SAAS00B,EAAO,MAAM,GAClCoF,IAAyC,CAAA;AAC/C,QAAIF,KAAA,QAAAA,EAAK;AACP,iBAAWx6B,KAAKw6B,EAAI;AAClB,UAAIv7B,IAAAu7B,EAAI,aAAJ,gBAAAv7B,EAAee,OAAM,OACvB06B,EAAc16B,CAAC,IAAIw6B,EAAI,SAASx6B,CAAC,MACxBd,IAAAu7B,KAAA,gBAAAA,EAAI,OAAOz6B,OAAX,gBAAAd,EAAe,UAAS,gBAGjCw7B,EAAc16B,CAAC,IAAIm6B,GAAA;AAIzB,WAAOO;AAAA,EACT,CAAC,GACKz2B,IAAcC,GAAA,GACd,EAAE,QAAAy2B,GAAQ,WAAAxY,GAAW,OAAAyY,GAAO,OAAAC,EAAA,IAAUz2B,GAAY;AAAA,IACtD,YAAY,CAAC02B,MAAqChqB,GAAawkB,EAAO,QAAQwF,CAAO;AAAA,IACrF,WAAW,MAAM;;AAGf,YAAMC,IAAKzF,EAAO,WACZmF,IAAK75B,EAAO,SAAS00B,EAAO,MAAM,GAClC0F,IAAuC,CAAA;AAC7C,UAAID,KAAA,QAAAA,EAAI;AACN,mBAAW/6B,KAAK+6B,EAAG;AACjB,YAAI97B,IAAA87B,KAAA,gBAAAA,EAAI,aAAJ,gBAAA97B,EAAee,OAAM,OACvBg7B,EAAYh7B,CAAC,IAAI+6B,EAAG,SAAS/6B,CAAC,MACrBd,IAAAu7B,KAAA,gBAAAA,EAAI,OAAOz6B,OAAX,gBAAAd,EAAe,UAAS,cACjC87B,EAAYh7B,CAAC,IAAIm6B,GAAA,IAEjBa,EAAYh7B,CAAC,IAAI;AAIvB,MAAAu6B,EAAUS,CAAW;AACrB,YAAMC,IAAqB,MAAM,QAAQ7wB,CAAQ,IAAIA,EAAS,KAAK,GAAG,IAAIA;AAC1E,MAAAnG,EAAY,kBAAkB;AAAA,QAC5B,UAAU,CAACgG,IAAqBE,GAAc8wB,GAAoB3F,EAAO,MAAM;AAAA,MAAA,CAChF;AAAA,IACH;AAAA,EAAA,CACD,GAEKuD,IAAWvD,EAAO,WAClBqC,IAAc/2B,EAAO,SAAS00B,EAAO,MAAM,GAI3C4E,KAAiBrB,KAAA,gBAAAA,EAAU,OAAO;AAAA,IACtC,CAAC74B,MAAA;;AAAM,cAAAf,IAAA04B,KAAA,gBAAAA,EAAa,OAAO33B,OAApB,gBAAAf,EAAwB;AAAA;AAAA,QAC5B,CAAA,GACCi8B,IAAUjB,GAAgBl6B,GAAQm6B,CAAc;AAEtD,WAASlsB,EAAalG,GAAc;AAElC,QADAA,EAAE,eAAA,GACE,CAAC+wB,EAAU;AACf,UAAMiC,IAAUhB,GAAqB/5B,GAAQ84B,EAAS,UAAUvD,EAAO,aAAalrB,CAAQ;AAC5F,IAAAuwB,EAAOG,CAAO;AAAA,EAChB;AAEA,WAASzf,EAAkBvc,GAAmBma,GAAc;AAC1D,IAAI2hB,KAAOC,EAAA,GACXN,EAAU,CAAC/4B,OAAmC,EAAE,GAAGA,GAAM,CAAC1C,CAAS,GAAGma,EAAA,EAAM;AAAA,EAC9E;AAEA,SAAO;AAAA,IACL,QAAAlZ;AAAA,IACA,UAAA84B;AAAA,IACA,aAAAlB;AAAA,IACA,WAAAxV;AAAA,IACA,OAAAyY;AAAA,IACA,SAAAM;AAAA,IACA,cAAAltB;AAAA,IACA,mBAAAqN;AAAA,EAAA;AAEJ;ACzGO,SAAS8f,GAAa,EAAE,QAAA7F,GAAQ,cAAAnrB,GAAc,UAAAC,GAAU,QAAAxJ,KAA6B;AAE1F,QAAM,EAAE,QAAAb,GAAQ,UAAA84B,GAAU,aAAAlB,GAAa,WAAAxV,GAAW,OAAAyY,GAAO,SAAAM,GAAS,cAAAltB,GAAc,mBAAAqN,EAAA,IAC9Eif,GAAYhF,GAAQnrB,GAAcC,GAAUxJ,CAAM;AAGpD,SADI,CAACi4B,KAAYA,EAAS,OAAO,WAAW,KACxC,CAAClB,IAAoB,OAGvB,gBAAAh2B;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,UAAUqM;AAAA,MACV,WAAU;AAAA,MAET,UAAA;AAAA,QAAA6qB,EAAS,OAAO,IAAI,CAAC/5B,MAAc;AAClC,gBAAMD,IAAQ84B,EAAY,OAAO74B,CAAS;AAC1C,iBAAKD,IAEH,gBAAA8C,EAAC,OAAA,EAAoB,WAAU,kBAC7B,UAAA;AAAA,YAAA,gBAAArD,EAAC,SAAA,EAAM,WAAU,qDACd,UAAAM,GAAiBC,GAAOC,GAAW8B,EAAO,QAAQ,EAAA,CACrD;AAAA,YACCwa,GAAY;AAAA,cACX,OAAAvc;AAAA,cACA,WAAAC;AAAA,cACA,OAAOiB,EAAOjB,CAAS,KAAK;AAAA,cAC5B,MAAM;AAAA,cACN,UAAU,CAACma,MAAQoC,EAAkBvc,GAAWma,CAAG;AAAA,cACnD,QAAQlZ;AAAA,YAAA,CACT;AAAA,UAAA,EAAA,GAXOjB,CAYV,IAdiB;AAAA,QAgBrB,CAAC;AAAA,QACD,gBAAAR,EAAC8H,GAAA,EAAO,MAAK,UAAS,MAAK,MAAK,UAAU+b,KAAa,CAAC+Y,GAAS,WAAU,mBAAkB,UAAA,MAAA,CAE7F;AAAA,QACCN,KAAS,QACR,gBAAAt8B,EAAC,UAAK,WAAU,mDACb,YAAM,QAAA,CACT;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR;AClDO,SAAS88B,GAAc,EAAE,QAAA9F,GAAQ,cAAAnrB,GAAc,UAAAC,GAAU,QAAAxJ,KAA6B;AAC3F,QAAM+2B,IAAc/2B,EAAO,SAAS00B,EAAO,MAAM,GAC3C,EAAE,MAAM9b,GAAU,WAAA5V,GAAW,SAAAgjB,EAAA,IAAY1c,GAAgBC,GAAcC,GAAUkrB,EAAO,QAAQA,EAAO,aAAaA,EAAO,MAAMA,EAAO,KAAK,GAC7I9hB,KAAOgG,KAAA,gBAAAA,EAAU,SAAQ,CAAA,GACzBL,IAAOK,KAAA,gBAAAA,EAAU,OACjBmW,IAAU2F,EAAO;AAEvB,MAAI,CAACqC;AACH,WAAO,gBAAAr5B,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA,qBAAiB;AAGvF,QAAM+8B,IACJ,gBAAA/8B;AAAA,IAAC68B;AAAA,IAAA;AAAA,MACC,QAAA7F;AAAA,MACA,cAAAnrB;AAAA,MACA,UAAAC;AAAA,MACA,QAAAxJ;AAAA,IAAA;AAAA,EAAA;AAIJ,SAAIgmB,sBAEC,OAAA,EACE,UAAA;AAAA,IAAAyU;AAAA,IACD,gBAAA/8B,EAAC,OAAA,EAAI,WAAU,0CAAyC,UAAA,6BAAA,CAA0B;AAAA,EAAA,GACpF,IAKAsF,sBAEC,OAAA,EACE,UAAA;AAAA,IAAAy3B;AAAA,IACD,gBAAA15B,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,MAAA,gBAAArD,EAACkf,IAAA,EAAS,WAAU,aAAA,CAAa;AAAA,MACjC,gBAAAlf,EAACkf,IAAA,EAAS,WAAU,aAAA,CAAa;AAAA,MACjC,gBAAAlf,EAACkf,IAAA,EAAS,WAAU,aAAA,CAAa;AAAA,IAAA,EAAA,CACnC;AAAA,EAAA,GACF,IAIAhK,EAAK,WAAW,sBAEf,OAAA,EACE,UAAA;AAAA,IAAA6nB;AAAA,IACD,gBAAA/8B,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA,kBAAA,CAE7D;AAAA,EAAA,GACF,sBAKD,OAAA,EACE,UAAA;AAAA,IAAA+8B;AAAA,sBACA,OAAA,EAAI,WAAU,mBACf,UAAA,gBAAA15B,EAAC,SAAA,EAAM,WAAU,kBACf,UAAA;AAAA,MAAA,gBAAArD,EAAC,SAAA,EACC,4BAAC,MAAA,EAAG,WAAU,YACX,UAAAqxB,EAAQ,IAAI,CAAClE,MAAQ;AACpB,cAAM5sB,IAAQ84B,EAAY,OAAOlM,CAAG;AACpC,eACE,gBAAAntB;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAU;AAAA,YAET,cAAQM,GAAiBC,GAAO4sB,GAAK7qB,EAAO,QAAQ,IAAI6qB;AAAA,UAAA;AAAA,UAHpDA;AAAA,QAAA;AAAA,MAMX,CAAC,GACH,GACF;AAAA,MACA,gBAAAntB,EAAC,SAAA,EACE,UAAAkV,EAAK,IAAI,CAACyN,GAAKqa,MACd,gBAAAh9B,EAAC,MAAA,EAAkE,WAAU,qDAC1E,UAAAqxB,EAAQ,IAAI,CAAClE,MAAQ;AACpB,cAAM5sB,IAAQ84B,EAAY,OAAOlM,CAAG;AACpC,eACE,gBAAAntB,EAAC,MAAA,EAAa,WAAU,0BACrB,cACG8c,GAAY;AAAA,UACV,OAAAvc;AAAA,UACA,WAAW4sB;AAAA,UACX,OAAOxK,EAAIwK,CAAG;AAAA,UACd,MAAM;AAAA,UACN,QAAQxK;AAAA,UACR,MAAA9H;AAAA,QAAA,CACD,IACD,OAAO8H,EAAIwK,CAAG,KAAK,EAAE,KAVlBA,CAWT;AAAA,MAEJ,CAAC,KAjBM,OAAQxK,EAAgC,MAASqa,CAAM,CAkBhE,CACD,EAAA,CACH;AAAA,IAAA,EAAA,CACF,EAAA,CACA;AAAA,EAAA,GACF;AAEJ;ACtGO,SAASC,GAAa,EAAE,QAAAjG,GAAQ,cAAAnrB,GAAc,UAAAC,GAAU,QAAAxJ,KAA6B;AAC1F,QAAM+2B,IAAc/2B,EAAO,SAAS00B,EAAO,MAAM,GAC3C,EAAE,MAAM9b,GAAU,WAAA5V,GAAW,SAAAgjB,EAAA,IAAY1c,GAAgBC,GAAcC,GAAUkrB,EAAO,QAAQA,EAAO,aAAaA,EAAO,MAAMA,EAAO,KAAK,GAC7I9hB,KAAOgG,KAAA,gBAAAA,EAAU,SAAQ,CAAA,GACzBL,IAAOK,KAAA,gBAAAA,EAAU,OACjBmW,IAAU2F,EAAO;AAEvB,MAAI,CAACqC;AACH,WAAO,gBAAAr5B,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA,qBAAiB;AAGvF,QAAM+8B,IACJ,gBAAA/8B;AAAA,IAAC68B;AAAA,IAAA;AAAA,MACC,QAAA7F;AAAA,MACA,cAAAnrB;AAAA,MACA,UAAAC;AAAA,MACA,QAAAxJ;AAAA,IAAA;AAAA,EAAA;AAIJ,MAAIgmB;AACF,6BACG,OAAA,EACE,UAAA;AAAA,MAAAyU;AAAA,MACD,gBAAA/8B,EAAC,OAAA,EAAI,WAAU,0CAAyC,UAAA,6BAAA,CAA0B;AAAA,IAAA,GACpF;AAKJ,MAAIsF;AACF,6BACG,OAAA,EACE,UAAA;AAAA,MAAAy3B;AAAA,MACD,gBAAA15B,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,QAAA,gBAAArD,EAACkf,IAAA,EAAS,WAAU,aAAA,CAAa;AAAA,QACjC,gBAAAlf,EAACkf,IAAA,EAAS,WAAU,aAAA,CAAa;AAAA,QACjC,gBAAAlf,EAACkf,IAAA,EAAS,WAAU,YAAA,CAAY;AAAA,MAAA,EAAA,CAClC;AAAA,IAAA,GACF;AAIJ,MAAIhK,EAAK,WAAW;AAClB,6BACG,OAAA,EACE,UAAA;AAAA,MAAA6nB;AAAA,MACD,gBAAA/8B,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA,kBAAA,CAE7D;AAAA,IAAA,GACF;AAMJ,QAAM+a,IAAesW,EAAQ,SAAS,IACjCgI,EAAY,QAAQ,iBAAiBhI,EAAQ,CAAC,IAC/CgI,EAAY,QAAQ;AAExB,2BACG,OAAA,EACE,UAAA;AAAA,IAAA0D;AAAA,sBACA,OAAA,EAAI,WAAU,mCACd,UAAA7nB,EAAK,IAAI,CAACyN,GAAK3kB,MACd,gBAAAgC,EAAC,SAAgE,WAAU,gEACzE,UAAA,gBAAAqD,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,MAAA,gBAAArD,EAAC,OAAA,EAAI,WAAU,oBACZ,UAAA+a,KAAgBse,EAAY,OAAOte,CAAY,IAC5C+B,GAAY;AAAA,QACV,OAAOuc,EAAY,OAAOte,CAAY;AAAA,QACtC,WAAWA;AAAA,QACX,OAAO4H,EAAI5H,CAAY;AAAA,QACvB,MAAM;AAAA,QACN,QAAQ4H;AAAA,QACR,MAAA9H;AAAA,MAAA,CACD,IACDE,KAAgB4H,EAAI5H,CAAY,KAAK,OACnC,OAAO4H,EAAI5H,CAAY,CAAC,IACxB,KAAA,CACR;AAAA,MACCsW,EAAQ,SAAS,MAAM,MAAM;AAC5B,cAAM6L,IAAU7L,EAAQ,MAAM,GAAG,CAAC,EAAE,OAAO,CAAClE,MAAQxK,EAAIwK,CAAG,KAAK,IAAI;AACpE,eAAI+P,EAAQ,WAAW,IAAU,OAE/B,gBAAAl9B,EAAC,OAAA,EAAI,WAAU,mDACZ,UAAAk9B,EAAQ,IAAI,CAAC/P,GAAK5gB,MACjB,gBAAAlJ,EAAC,QAAA,EACE,UAAA;AAAA,UAAAkJ,IAAI,KAAK;AAAA,UACT8sB,EAAY,OAAOlM,CAAG,IACnBrQ,GAAY;AAAA,YACV,OAAOuc,EAAY,OAAOlM,CAAG;AAAA,YAC7B,WAAWA;AAAA,YACX,OAAOxK,EAAIwK,CAAG;AAAA,YACd,MAAM;AAAA,YACN,QAAQxK;AAAA,YACR,MAAA9H;AAAA,UAAA,CACD,IACD,OAAO8H,EAAIwK,CAAG,CAAC;AAAA,QAAA,KAXVA,CAYX,CACD,GACH;AAAA,MAEJ,GAAA;AAAA,IAAG,EAAA,CACL,EAAA,GAvCQ,OAAQxK,EAAgC,MAAS3kB,CAAG,CAwC9D,CACD,EAAA,CACD;AAAA,EAAA,GACF;AAEJ;AC5GO,SAASm/B,GAAc,EAAE,QAAAnG,GAAQ,cAAAnrB,GAAc,UAAAC,GAAU,QAAAxJ,KAA6B;AAC3F,QAAM+2B,IAAc/2B,EAAO,SAAS00B,EAAO,MAAM,GAC3C,EAAE,MAAM9b,GAAU,WAAA5V,GAAW,SAAAgjB,EAAA,IAAY1c,GAAgBC,GAAcC,GAAUkrB,EAAO,QAAQA,EAAO,aAAaA,EAAO,MAAMA,EAAO,KAAK,GAC7I9hB,KAAOgG,KAAA,gBAAAA,EAAU,SAAQ,CAAA,GACzBL,IAAOK,KAAA,gBAAAA,EAAU,OACjBmW,IAAU2F,EAAO,SACjBoG,IAAcpG,EAAO,OACrBqG,KAAcD,KAAA,gBAAAA,EAAa,iBAAgB/L,EAAQ,CAAC,GACpDiM,IAAaF,KAAA,gBAAAA,EAAa,aAC1BG,IAAWH,KAAA,gBAAAA,EAAa;AAE9B,MAAI,CAAC/D;AACH,WAAO,gBAAAr5B,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA,qBAAiB;AAGvF,QAAM+8B,IACJ,gBAAA/8B;AAAA,IAAC68B;AAAA,IAAA;AAAA,MACC,QAAA7F;AAAA,MACA,cAAAnrB;AAAA,MACA,UAAAC;AAAA,MACA,QAAAxJ;AAAA,IAAA;AAAA,EAAA;AAIJ,MAAIgmB;AACF,6BACG,OAAA,EACE,UAAA;AAAA,MAAAyU;AAAA,MACD,gBAAA/8B,EAAC,OAAA,EAAI,WAAU,0CAAyC,UAAA,6BAAA,CAA0B;AAAA,IAAA,GACpF;AAKJ,MAAIsF;AACF,6BACG,OAAA,EACE,UAAA;AAAA,MAAAy3B;AAAA,MACD,gBAAA15B,EAAC,OAAA,EAAI,WAAWm6B,GAAUD,CAAQ,GAChC,UAAA;AAAA,QAAA,gBAAAv9B,EAACkf,IAAA,EAAS,WAAU,yBAAA,CAAyB;AAAA,QAC7C,gBAAAlf,EAACkf,IAAA,EAAS,WAAU,yBAAA,CAAyB;AAAA,QAC7C,gBAAAlf,EAACkf,IAAA,EAAS,WAAU,yBAAA,CAAyB;AAAA,MAAA,EAAA,CAC/C;AAAA,IAAA,GACF;AAIJ,MAAIhK,EAAK,WAAW;AAClB,6BACG,OAAA,EACE,UAAA;AAAA,MAAA6nB;AAAA,MACD,gBAAA/8B,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA,kBAAA,CAE7D;AAAA,IAAA,GACF;AAKJ,QAAMy9B,IAAepM,EAAQ,OAAO,CAACrE,MAAMA,MAAMqQ,KAAerQ,MAAMsQ,CAAU;AAEhF,2BACG,OAAA,EACE,UAAA;AAAA,IAAAP;AAAA,IACD,gBAAA/8B,EAAC,OAAA,EAAI,WAAWw9B,GAAUD,CAAQ,GAC/B,UAAAroB,EAAK,IAAI,CAACyN,GAAK3kB,MACd,gBAAAqF,EAACoL,IAAA,EAAiE,WAAU,mBAC1E,UAAA;AAAA,MAAA,gBAAAzO,EAAC0O,MAAW,WAAU,aACpB,UAAA,gBAAArL,EAAC,OAAA,EAAI,WAAU,2CACb,UAAA;AAAA,QAAA,gBAAArD,EAAC2O,IAAA,EAAU,WAAU,oBAClB,UAAA0uB,KAAehE,EAAY,OAAOgE,CAAW,IAC1CvgB,GAAY;AAAA,UACV,OAAOuc,EAAY,OAAOgE,CAAW;AAAA,UACrC,WAAWA;AAAA,UACX,OAAO1a,EAAI0a,CAAW;AAAA,UACtB,MAAM;AAAA,UACN,QAAQ1a;AAAA,UACR,MAAA9H;AAAA,QAAA,CACD,IACD,UAAU7c,IAAM,CAAC,GAAA,CACvB;AAAA,QACCs/B,KAAc3a,EAAI2a,CAAU,KAAK,QAChC,gBAAAt9B,EAACyQ,IAAA,EAAM,SAAQ,aAAY,WAAU,oBAClC,UAAA4oB,EAAY,OAAOiE,CAAU,IAC1BxgB,GAAY;AAAA,UACV,OAAOuc,EAAY,OAAOiE,CAAU;AAAA,UACpC,WAAWA;AAAA,UACX,OAAO3a,EAAI2a,CAAU;AAAA,UACrB,MAAM;AAAA,UACN,QAAQ3a;AAAA,UACR,MAAA9H;AAAA,QAAA,CACD,IACD,OAAO8H,EAAI2a,CAAU,CAAC,EAAA,CAC5B;AAAA,MAAA,EAAA,CAEJ,EAAA,CACF;AAAA,MACCG,EAAa,SAAS,uBACpB5uB,IAAA,EAAY,WAAU,kBACrB,UAAA,gBAAA7O,EAAC,OAAA,EAAI,WAAU,aACZ,YAAa,MAAM,GAAG,CAAC,EAAE,IAAI,CAACmtB,MAAQ;;AACrC,cAAM5sB,IAAQ84B,EAAY,OAAOlM,CAAG;AACpC,eAAK5sB,IAEH,gBAAA8C,EAAC,OAAA,EAAc,WAAU,qCACvB,UAAA;AAAA,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,2CACb,UAAA;AAAA,aAAAtC,KAAAH,KAAAD,IAAA2B,EAAO,SAAS00B,EAAO,MAAM,MAA7B,gBAAAr2B,EAAgC,OAAOwsB,OAAvC,gBAAAvsB,EAA6C,YAA7C,QAAAG,EAAsD,OACnD,OAAO,OAAOuB,EAAO,SAAS00B,EAAO,MAAM,EAAE,OAAO7J,CAAG,EAAE,QAAS,IAAI,EAAE,CAAC,IACzEA;AAAA,YAAI;AAAA,UAAA,GACV;AAAA,UACA,gBAAAntB,EAAC,QAAA,EAAK,WAAU,YACb,UAAA8c,GAAY;AAAA,YACX,OAAAvc;AAAA,YACA,WAAW4sB;AAAA,YACX,OAAOxK,EAAIwK,CAAG;AAAA,YACd,MAAM;AAAA,YACN,QAAQxK;AAAA,YACR,MAAA9H;AAAA,UAAA,CACD,EAAA,CACH;AAAA,QAAA,EAAA,GAfQsS,CAgBV,IAlBiB;AAAA,MAoBrB,CAAC,GACH,EAAA,CACF;AAAA,IAAA,EAAA,GA1DO,OAAQxK,EAAgC,MAAS3kB,CAAG,CA4D/D,CACD,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;AAEA,SAASw/B,GAAUD,GAAsC;AACvD,UAAQA,GAAA;AAAA,IACN,KAAK;AAAG,aAAO;AAAA,IACf,KAAK;AAAG,aAAO;AAAA,IACf,KAAK;AAAG,aAAO;AAAA,IACf,KAAK;AAAG,aAAO;AAAA,IACf;AAAS,aAAO;AAAA,EAAA;AAEpB;AC9IA,MAAMG,KAAqB,eASrBC,KAAa,KACbC,KAAiB,KAKjBC,KAAa;AAIZ,SAASC,GAAiB,EAAE,QAAA9G,GAAQ,cAAAnrB,GAAc,UAAAC,GAAU,QAAAxJ,KAAiC;AAClG,QAAM,EAAE,QAAAb,GAAQ,UAAA84B,GAAU,aAAAlB,GAAa,WAAAxV,GAAW,OAAAyY,GAAO,SAAAM,GAAS,cAAAltB,GAAc,mBAAAqN,EAAA,IAC9Eif,GAAYhF,GAAQnrB,GAAcC,GAAUxJ,CAAM,GAE9C,CAAC22B,GAAQ8E,CAAS,IAAI97B,EAAS27B,EAAc,GAC7C/F,IAAW1qB,GAAuD,IAAI,GAItE6wB,IAAY7wB,GAAO1L,CAAM;AAC/B,EAAAu8B,EAAU,UAAUv8B;AACpB,QAAMw8B,IAAuB9wB,GAAO4P,CAAiB;AACrD,EAAAkhB,EAAqB,UAAUlhB;AAC/B,QAAMmhB,IAAgB/wB,GAA2C,EAAE,GAE7DgU,IAASphB,EAAQ,OAAO;AAAA,IAC5B,UAAU,CAACS,MAAsBw9B,EAAU,QAAQx9B,CAAS;AAAA,IAC5D,UAAU,CAACA,GAAmB+K,MAAmB;AAC/C,MAAA0yB,EAAqB,QAAQz9B,GAAW+K,CAAK;AAAA,IAC/C;AAAA,IACA,YAAY,CAAC/K,MAAsB;AACjC,YAAMuC,IAAOm7B,EAAc,QAAQ19B,CAAS;AAC5C,UAAI,CAACuC,EAAM;AAEX,OADkBA,EAAK,cAA2B,4CAA4C,KAChFA,GAAM,MAAA;AAAA,IACtB;AAAA,EAAA,IACE,CAAA,CAAE;AAEN,EAAAqK,GAAU,MAAM8T,GAAoBwc,IAAoBvc,CAAM,GAAG,CAACA,CAAM,CAAC;AAEzE,QAAM6W,IAAc94B;AAAA,IAClB,CAACsK,MAAwB;AACvB,MAAAA,EAAE,eAAA,GACFquB,EAAS,UAAU,EAAE,QAAQruB,EAAE,SAAS,aAAayvB,EAAA;AAErD,YAAMf,IAAS,CAACrrB,MAAmB;AACjC,YAAI,CAACgrB,EAAS,QAAS;AACvB,cAAMO,IAAQP,EAAS,QAAQ,SAAShrB,EAAG,SACrCtC,IAAO,KAAK,IAAIszB,IAAY,KAAK,IAAIF,IAAY9F,EAAS,QAAQ,cAAcO,CAAK,CAAC;AAC5F,QAAA2F,EAAUxzB,CAAI;AAAA,MAChB,GAEMiuB,IAAO,MAAM;AACjB,QAAAX,EAAS,UAAU,MACnB,SAAS,oBAAoB,aAAaK,CAAM,GAChD,SAAS,oBAAoB,WAAWM,CAAI;AAAA,MAC9C;AAEA,eAAS,iBAAiB,aAAaN,CAAM,GAC7C,SAAS,iBAAiB,WAAWM,CAAI;AAAA,IAC3C;AAAA,IACA,CAACS,CAAM;AAAA,EAAA;AAIT,MADI,CAACsB,KAAYA,EAAS,OAAO,WAAW,KACxC,CAAClB,EAAa,QAAO;AAOzB,QAAM8E,IAAe5D,EAAS,OAAO,KAAK,CAAC74B,MAAM;AAC/C,UAAMnB,IAAQ84B,EAAY,OAAO33B,CAAC;AAClC,WAAOnB,MAAUA,EAAM,SAAS,UAAUA,EAAM,SAAS;AAAA,EAC3D,CAAC,GACK69B,IAAsB,CAAA,GACtBC,IAAyB,CAAA;AAC/B,aAAW38B,KAAK64B,EAAS,QAAQ;AAC/B,QAAI74B,MAAMy8B,EAAc;AACxB,UAAM59B,IAAQ84B,EAAY,OAAO33B,CAAC;AAClC,IAAKnB,MACDA,EAAM,SAAS,SACjB69B,EAAU,KAAK18B,CAAC,IAEhB28B,EAAa,KAAK38B,CAAC;AAAA,EAEvB;AAEA,QAAM48B,IAAkB,CAAC99B,MAAsB;AAC7C,UAAMD,IAAQ84B,EAAY,OAAO74B,CAAS;AAC1C,WAAKD,IAEH,gBAAAP,EAAC,OAAA,EAAoB,KAAK,CAACw3B,MAAO;AAAE,MAAA0G,EAAc,QAAQ19B,CAAS,IAAIg3B;AAAA,IAAI,GACxE,UAAA1a,GAAY;AAAA,MACX,OAAAvc;AAAA,MACA,WAAAC;AAAA,MACA,OAAOiB,EAAOjB,CAAS,KAAK;AAAA,MAC5B,MAAM;AAAA,MACN,UAAU,CAACma,MAAQoC,EAAkBvc,GAAWma,CAAG;AAAA,MACnD,QAAQlZ;AAAA,IAAA,CACT,KAROjB,CASV,IAXiB;AAAA,EAarB;AAEA,SACE,gBAAA6C;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,QAAQ,GAAG41B,CAAM,KAAA;AAAA,MAK1B,UAAA;AAAA,QAAA,gBAAAj5B;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,aAAag4B;AAAA,YACb,OAAM;AAAA,YAEN,UAAA,gBAAAh4B,EAAC,OAAA,EAAI,WAAU,sGAAA,CAAsG;AAAA,UAAA;AAAA,QAAA;AAAA,QAGvH,gBAAAqD,EAAC,QAAA,EAAK,UAAUqM,GAAc,WAAU,kDAIrC,UAAA;AAAA,UAAA0uB,EAAU,SAAS,KAClB,gBAAAp+B,EAAC,OAAA,EAAI,WAAU,8CACZ,UAAAo+B,EAAU,IAAIE,CAAe,EAAA,CAChC;AAAA,UAIDH,KAAgB9E,EAAY,OAAO8E,CAAY,KAC9C,gBAAAn+B;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,KAAK,CAACw3B,MAAO;AAAE,gBAAA0G,EAAc,QAAQC,CAAY,IAAI3G;AAAA,cAAI;AAAA,cAExD,UAAA1a,GAAY;AAAA,gBACX,OAAOuc,EAAY,OAAO8E,CAAY;AAAA,gBACtC,WAAWA;AAAA,gBACX,OAAO18B,EAAO08B,CAAY,KAAK;AAAA,gBAC/B,MAAM;AAAA,gBACN,UAAU,CAACxjB,MAAQoC,EAAkBohB,GAAcxjB,CAAG;AAAA,gBACtD,QAAQlZ;AAAA,cAAA,CACT;AAAA,YAAA;AAAA,UAAA;AAAA,UAOL,gBAAA4B,EAAC,OAAA,EAAI,WAAU,8CACZ,UAAA;AAAA,YAAAg7B,EAAa,IAAIC,CAAe;AAAA,YACjC,gBAAAt+B,EAAC,OAAA,EAAI,WAAU,WACb,4BAAC8H,GAAA,EAAO,MAAK,UAAS,MAAK,MAAK,UAAU+b,KAAa,CAAC+Y,GAAS,sBAEjE,EAAA,CACF;AAAA,UAAA,GACF;AAAA,UAECN,KAAS,QACR,gBAAAt8B,EAAC,OAAE,WAAU,8CAA8C,YAAM,QAAA,CAAQ;AAAA,QAAA,EAAA,CAE7E;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AC1KO,SAASu+B,GAAiB,EAAE,QAAAvH,GAAQ,cAAAnrB,GAAc,UAAAC,GAAU,QAAAxJ,KAA6B;;AAC9F,QAAM+2B,IAAc/2B,EAAO,SAAS00B,EAAO,MAAM,GAC3C,EAAE,MAAM9b,GAAU,WAAA5V,GAAW,SAAAgjB,EAAA,IAAY1c,GAAgBC,GAAcC,GAAUkrB,EAAO,QAAQA,EAAO,aAAaA,EAAO,MAAMA,EAAO,KAAK,GAC7I9hB,KAAOgG,KAAA,gBAAAA,EAAU,SAAQ,CAAA,GACzBL,IAAOK,KAAA,gBAAAA,EAAU,OACjBsjB,IAAWxH,EAAO,UAClByH,KAASD,KAAA,gBAAAA,EAAU,WAAU,IAE7BE,KAAaF,KAAA,gBAAAA,EAAU,gBAAe,QACtCG,IAAYxxB,GAAuB,IAAI,GACvCyxB,IAAkBzxB,GAAO,EAAK,GAE9B0xB,IAAe1xB,GAAO,CAAC;AAE7B,EAAAC,GAAU,MAAM;AACd,IAAAwxB,EAAgB,UAAU,IAC1BC,EAAa,UAAU;AAAA,EACzB,GAAG,CAAC/yB,CAAQ,CAAC,GAGbsB,GAAU,MAAM;AACd,QAAI,CAACuxB,EAAU,WAAWzpB,EAAK,WAAW,EAAG;AAC7C,UAAM4pB,IAAgB,CAACF,EAAgB,SACjCG,IAAa7pB,EAAK,SAAS2pB,EAAa,WAAWA,EAAa,UAAU;AAChF,IAAAA,EAAa,UAAU3pB,EAAK,SAEvB4pB,KAAiBJ,MAAe,YAAaK,OAChDJ,EAAU,QAAQ,YAAYA,EAAU,QAAQ,cAChDC,EAAgB,UAAU;AAAA,EAE9B,GAAG,CAAC1pB,GAAMwpB,CAAU,CAAC;AAErB,QAAM,CAACM,GAAWC,CAAY,IAAIh9B,EAAwB,IAAI;AAE9D,MAAI,CAACo3B;AACH,WAAO,gBAAAr5B,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA,qBAAiB;AAGvF,QAAMk/B,MAAiBv+B,IAAAq2B,EAAO,cAAP,gBAAAr2B,EAAkB,WACpC,CAAC69B,KAAA,gBAAAA,EAAU,aAAa,EAAE,OAAO,OAAO,GAEvC9/B,IAAQyB,GAAIS,IAAAy4B,EAAY,YAAZ,gBAAAz4B,EAAqB,WAAW,KAAKT,GAAIY,IAAAs4B,EAAY,YAAZ,gBAAAt4B,EAAqB,IAAI,KAAKi2B,EAAO;AAGhG,MAAI5T;AAuCJ,SAtCIkF,IACFlF,IAAU,gBAAApjB,EAAC,OAAA,EAAI,WAAU,yCAAwC,UAAA,mBAAe,IACvEsF,IACT8d,IACE,gBAAA/f,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,IAAA,gBAAArD,EAACkf,IAAA,EAAS,WAAU,yBAAA,CAAyB;AAAA,IAC7C,gBAAAlf,EAACkf,IAAA,EAAS,WAAU,yBAAA,CAAyB;AAAA,EAAA,GAC/C,IAEOhK,EAAK,WAAW,IACzBkO,IAAU,gBAAApjB,EAAC,OAAA,EAAI,WAAU,8CAA6C,UAAA,oBAAgB,IAEtFojB,IAAUlO,EAAK,IAAI,CAACyN,GAAK3kB,MAAQ;AAC/B,UAAMmhC,IAAQ,OAAQxc,EAAgB,MAAS3kB,CAAG;AAClD,WACE,gBAAAgC;AAAA,MAACo/B;AAAA,MAAA;AAAA,QAEC,KAAAzc;AAAA,QACA,OAAAwc;AAAA,QACA,aAAA9F;AAAA,QACA,YAAYrC,EAAO;AAAA,QACnB,cAAAnrB;AAAA,QACA,UAAAC;AAAA,QACA,UAAA0yB;AAAA,QACA,gBAAAU;AAAA,QACA,MAAArkB;AAAA,QACA,WAAWmkB,MAAcG;AAAA,QACzB,aAAa,MAAMF,EAAaE,CAAK;AAAA,QACrC,cAAc,MAAMF,EAAa,IAAI;AAAA,QACrC,SAAS,MAAMA,EAAa,IAAI;AAAA,QAChC,QAAA38B;AAAA,MAAA;AAAA,MAdK68B;AAAA,IAAA;AAAA,EAiBX,CAAC,GAKCV,IAEA,gBAAAp7B,EAAC,OAAA,EAAI,WAAU,2GAEb,UAAA;AAAA,IAAA,gBAAArD,EAAC,OAAA,EAAI,WAAU,8DACb,UAAA,gBAAAA,EAAC,QAAG,WAAU,yBAAyB,aAAM,EAAA,CAC/C;AAAA,sBAEC,OAAA,EAAI,KAAK2+B,GAAW,WAAU,wCAC5B,UAAAvb,GACH;AAAA,IAEA,gBAAApjB,EAAC89B,IAAA,EAAiB,QAAA9G,GAAgB,cAAAnrB,GAA4B,UAAAC,GAAoB,QAAAxJ,EAAA,CAAgB;AAAA,EAAA,GACpG,sBAMD,OAAA,EACC,UAAA;AAAA,IAAA,gBAAAtC,EAAC,OAAA,EAAI,WAAU,aAAa,UAAAojB,GAAQ;AAAA,IACpC,gBAAApjB,EAAC89B,IAAA,EAAiB,QAAA9G,GAAgB,cAAAnrB,GAA4B,UAAAC,GAAoB,QAAAxJ,EAAA,CAAgB;AAAA,EAAA,GACpG;AAEJ;AAqBA,SAAS88B,GAAc;AAAA,EACrB,KAAAzc;AAAA,EAAK,OAAAwc;AAAA,EAAO,aAAA9F;AAAA,EAAa,YAAAloB;AAAA,EAAY,cAAAtF;AAAA,EAAc,UAAAC;AAAA,EACnD,UAAA0yB;AAAA,EAAU,gBAAAU;AAAA,EAAgB,MAAArkB;AAAA,EAAM,WAAAwkB;AAAA,EAAW,aAAAC;AAAA,EAAa,cAAAC;AAAA,EAAc,SAAAC;AAAA,EAAS,QAAAl9B;AACjF,GAAuB;AACrB,QAAMqD,IAAcC,GAAA,GACd,CAACkd,GAAUsB,CAAW,IAAIniB,EAAkC,CAAA,CAAE,GAE9Dw9B,IAAavgC,EAAY,MAAM;AACnC,IAAAyG,EAAY,kBAAkB,EAAE,UAAU,CAACgG,IAAqBE,GAAcC,GAAUqF,CAAU,GAAG;AAAA,EACvG,GAAG,CAACxL,GAAakG,GAAcC,GAAUqF,CAAU,CAAC,GAE9CuuB,IAAY55B,GAAY;AAAA,IAC5B,YAAY,CAAC2M,MAAkCC,GAAavB,GAAYguB,GAAO1sB,CAAI;AAAA,IACnF,WAAW,MAAM;AAAE,MAAAgtB,EAAA,GAAct5B,GAAM,QAAQ,SAAS,GAAGq5B,EAAA;AAAA,IAAW;AAAA,IACtE,SAAS,CAACt5B,MAAeC,GAAM,MAAMD,EAAI,OAAO;AAAA,EAAA,CACjD,GAEKy5B,IAAY75B,GAAY;AAAA,IAC5B,YAAY,MAAM8M,GAAazB,GAAYguB,CAAK;AAAA,IAChD,WAAW,MAAM;AAAE,MAAAM,EAAA,GAAct5B,GAAM,QAAQ,SAAS;AAAA,IAAG;AAAA,IAC3D,SAAS,CAACD,MAAeC,GAAM,MAAMD,EAAI,OAAO;AAAA,EAAA,CACjD,GAEK05B,IAAY1gC,EAAY,MAAM;AAClC,UAAMuT,IAAgC,CAAA;AACtC,eAAW/Q,KAAKw9B,EAAgB,CAAAzsB,EAAK/Q,CAAC,IAAIihB,EAAIjhB,CAAC,KAAK;AACpD,IAAA0iB,EAAY3R,CAAI,GAChB6sB,EAAA;AAAA,EACF,GAAG,CAAC3c,GAAKuc,GAAgBI,CAAW,CAAC,GAE/BviB,IAAoB7d,EAAY,CAACsB,GAAmBma,MAAiB;AACzE,IAAAyJ,EAAY,CAAClhB,OAAU,EAAE,GAAGA,GAAM,CAAC1C,CAAS,GAAGma,EAAA,EAAM;AAAA,EACvD,GAAG,CAAA,CAAE,GAECklB,IAAYrB,KAAA,gBAAAA,EAAU,YACtBsB,IAAYtB,KAAA,gBAAAA,EAAU,YACtBuB,IAAevB,KAAA,gBAAAA,EAAU,eACzBL,IAAeK,KAAA,gBAAAA,EAAU,eACzBwB,IAAcxB,KAAA,gBAAAA,EAAU,cACxByB,IAAiBzB,KAAA,gBAAAA,EAAU,iBAC3B0B,IAAc1B,KAAA,gBAAAA,EAAU;AAG9B,SAAIa,IAEA,gBAAAh8B,EAAC,OAAA,EAAI,WAAU,iFACZ,UAAA;AAAA,IAAA67B,EAAe,IAAI,CAAC1+B,MAAc;AACjC,YAAMD,IAAQ84B,EAAY,OAAO74B,CAAS;AAC1C,aAAKD,sBAEF,OAAA,EACC,UAAA;AAAA,QAAA,gBAAAP,EAAC,SAAA,EAAM,WAAU,qDACd,UAAAM,GAAiBC,GAAOC,GAAW8B,EAAO,QAAQ,EAAA,CACrD;AAAA,QACCwa,GAAY,EAAE,OAAAvc,GAAO,WAAAC,GAAW,OAAOsiB,EAAStiB,CAAS,KAAK,IAAI,MAAM,QAAQ,UAAU,CAACma,MAAQoC,EAAkBvc,GAAWma,CAAG,GAAG,QAAQmI,GAAU;AAAA,MAAA,EAAA,GAJjJtiB,CAKV,IAPiB;AAAA,IASrB,CAAC;AAAA,IACD,gBAAA6C,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,MAAA,gBAAAA,EAACyE,GAAA,EAAO,MAAK,MAAK,SAAS,MAAM43B,EAAU,OAAO5c,CAAQ,GAAG,UAAU4c,EAAU,WAAW,WAAU,qBACpG,UAAA;AAAA,QAAA,gBAAA1/B,EAACuH,IAAA,EAAM,WAAU,UAAA,CAAU;AAAA,QAAE;AAAA,QAAEm4B,EAAU,YAAY,cAAc;AAAA,MAAA,GACrE;AAAA,wBACC53B,GAAA,EAAO,MAAK,MAAK,SAAQ,WAAU,SAAS,MAAM;AAAE,QAAAsc,EAAY,CAAA,CAAE,GAAGmb,EAAA;AAAA,MAAgB,GAAG,UAAUG,EAAU,WAAW,WAAU,qBAChI,UAAA;AAAA,QAAA,gBAAA1/B,EAACyJ,IAAA,EAAE,WAAU,UAAA,CAAU;AAAA,QAAE;AAAA,MAAA,EAAA,CAC3B;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF,IAMF,gBAAApG,EAAC,OAAA,EAAI,WAAU,mIAEb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,4EACZ,UAAA;AAAA,MAAAw8B,KAAald,EAAIkd,CAAS,KAAK,QAAQxG,EAAY,OAAOwG,CAAS,KAClE,gBAAA7/B,EAAC,QAAA,EAAK,WAAU,eACb,aAAY,EAAE,OAAOq5B,EAAY,OAAOwG,CAAS,GAAG,WAAWA,GAAW,OAAOld,EAAIkd,CAAS,GAAG,MAAM,WAAW,QAAQld,GAAK,MAAA9H,EAAA,CAAM,GACxI;AAAA,MAEDilB,KAAand,EAAImd,CAAS,KAAK,QAAQzG,EAAY,OAAOyG,CAAS,KAClE,gBAAA9/B,EAAC,QAAA,EAAK,WAAU,6FACb,aAAY,EAAE,OAAOq5B,EAAY,OAAOyG,CAAS,GAAG,WAAWA,GAAW,OAAOnd,EAAImd,CAAS,GAAG,MAAM,WAAW,QAAQnd,GAAK,MAAA9H,EAAA,CAAM,GACxI;AAAA,MAEDolB,KAAkBtd,EAAIsd,CAAc,KAAK,QAAQ5G,EAAY,OAAO4G,CAAc,uBAChFE,IAAA,EAAc,OAAOxd,EAAIsd,CAAc,GAAG,OAAO5G,EAAY,OAAO4G,CAAc,GAAG;AAAA,MAEvFC,KAAevd,EAAIud,CAAW,KAAK,QAAQ7G,EAAY,OAAO6G,CAAW,KACxE,gBAAAlgC,EAAC,QAAA,EAAK,WAAU,2FACb,aAAY,EAAE,OAAOq5B,EAAY,OAAO6G,CAAW,GAAG,WAAWA,GAAa,OAAOvd,EAAIud,CAAW,GAAG,MAAM,WAAW,QAAQvd,GAAK,MAAA9H,EAAA,CAAM,GAC9I;AAAA,MAEDmlB,KAAerd,EAAIqd,CAAW,KAAK,QAAQ3G,EAAY,OAAO2G,CAAW,KACxE,gBAAA38B,EAAC,QAAA,EAAK,UAAA;AAAA,QAAA;AAAA,QAAIyZ,GAAY,EAAE,OAAOuc,EAAY,OAAO2G,CAAW,GAAG,WAAWA,GAAa,OAAOrd,EAAIqd,CAAW,GAAG,MAAM,WAAW,QAAQrd,GAAK,MAAA9H,GAAM;AAAA,MAAA,GAAE;AAAA,MAEzJ,gBAAAxX,EAAC,OAAA,EAAI,WAAU,0FACb,UAAA;AAAA,QAAA,gBAAArD,EAAC,UAAA,EAAO,SAAS4/B,GAAW,WAAU,uCAAsC,OAAM,QAAO,UAAA,gBAAA5/B,EAACkyB,IAAA,EAAO,WAAU,UAAA,CAAU,GAAE;AAAA,0BACtH,UAAA,EAAO,SAAS,MAAMyN,EAAU,OAAA,GAAU,UAAUA,EAAU,WAAW,WAAU,gFAA+E,OAAM,UAAS,4BAACtiB,IAAA,EAAO,WAAU,WAAU,EAAA,CAAE;AAAA,MAAA,EAAA,CAClN;AAAA,IAAA,GACF;AAAA,IAEC0iB,KAAgBpd,EAAIod,CAAY,KAAK,QAAQ1G,EAAY,OAAO0G,CAAY,KAC3E,gBAAA//B,EAAC,OAAA,EAAI,WAAU,8BACZ,aAAY,EAAE,OAAOq5B,EAAY,OAAO0G,CAAY,GAAG,WAAWA,GAAc,OAAOpd,EAAIod,CAAY,GAAG,MAAM,WAAW,QAAQpd,GAAK,MAAA9H,EAAA,CAAM,GACjJ;AAAA,IAODsjB,KAAgBxb,EAAIwb,CAAY,KAAK,QAAQA,MAAiB4B,KAAgB1G,EAAY,OAAO8E,CAAY,KAC5G,gBAAAn+B,EAAC,OAAA,EAAI,WAAU,8BAA6B,OAAO,EAAE,YAAY,IAAA,GAC9D,UAAA8c,GAAY,EAAE,OAAOuc,EAAY,OAAO8E,CAAY,GAAG,WAAWA,GAAc,OAAOxb,EAAIwb,CAAY,GAAG,MAAM,WAAW,QAAQxb,GAAK,MAAA9H,EAAA,CAAM,EAAA,CACjJ;AAAA,EAAA,GAEJ;AAEJ;AAKA,SAASslB,GAAc,EAAE,OAAA50B,GAAO,OAAAhL,KAAiD;AAC/E,QAAM6/B,IAAWC,GAAW90B,GAAOhL,CAAK;AACxC,SAAI6/B,MAAa,OAAa,OAI5B,gBAAA/8B,EAAC,QAAA,EAAK,WAAU,4HACd,UAAA;AAAA,IAAA,gBAAArD,EAJSogC,IAAWE,KAAeC,IAIlC,EAAK,WAAU,UAAA,CAAU;AAAA,IAHhBH,IAAW,QAAQ;AAAA,EAI5B,GACH;AAEJ;AAEA,SAASC,GAAW90B,GAAgBhL,GAAoC;AACtE,MAAIA,EAAM,SAAS;AAQjB,WAAOgL,MAAU;AAEnB,MAAI,OAAOA,KAAU,UAAU;AAC7B,UAAM4G,IAAI5G,EAAM,YAAA;AAChB,QAAI4G,MAAM,cAAcA,MAAM,MAAO,QAAO;AAC5C,QAAIA,MAAM,aAAaA,MAAM,KAAM,QAAO;AAAA,EAC5C;AACA,SAAO;AACT;ACpRO,SAASquB,GAAsB;AAAA,EACpC,QAAAxJ;AAAA,EACA,aAAAqC;AAAA,EACA,QAAA/2B;AAAA,EACA,MAAA4S;AAAA,EACA,UAAAT;AAAA,EACA,kBAAAgsB;AAAA,EACA,MAAA5lB;AACF,GAA+B;;AAC7B,QAAM6lB,IAAWvzB,GAAyB,IAAI,GACxCkkB,IAAU2F,EAAO,SAGjB4D,IAAQ,IAAI,IAAI,MAAM,QAAQ5D,EAAO,WAAW,IAAIA,EAAO,cAAc,CAACA,EAAO,WAAW,CAAC,GAC7F2J,IAAkBtP,EAAQ,OAAO,CAAClE,MAAQ;AAE9C,QADIyN,EAAM,IAAIzN,CAAG,KACb6J,EAAO,kBAAkB7J,MAAQ6J,EAAO,eAAgB,QAAO;AACnE,UAAMz2B,IAAQ84B,EAAY,OAAOlM,CAAG;AAEpC,WADI,GAAC5sB,KACDA,EAAM,QAAQA,EAAM;AAAA,EAE1B,CAAC,GAGKqgC,IAAqB,IAAI;AAAA,IAC7BvP,EAAQ,OAAO,CAAClE,MAAQ;AACtB,UAAI6J,EAAO,kBAAkB7J,MAAQ6J,EAAO,eAAgB,QAAO;AACnE,YAAMz2B,IAAQ84B,EAAY,OAAOlM,CAAG;AACpC,aAAO5sB,MAAUA,EAAM,QAAQA,EAAM;AAAA,IACvC,CAAC;AAAA,EAAA,GAGGsgC,IAAmB3hC;AAAA,IACvB,CAAC4hC,GAAgBtgC,GAAmB+K,MAAmB;AACrD,YAAM6Q,IAAUlH,EAAK;AAAA,QAAI,CAACyN,MACxBA,EAAI,SAASme,IACT,EAAE,GAAGne,GAAK,CAACniB,CAAS,GAAG+K,GAAO,QAAQ,OACtCoX;AAAA,MAAA;AAEN,MAAAlO,EAAS2H,CAAO;AAAA,IAClB;AAAA,IACA,CAAClH,GAAMT,CAAQ;AAAA,EAAA,GAGXssB,IAAe7hC,EAAY,MAAM;;AACrC,UAAM8hC,IAA0B;AAAA,MAC9B,MAAM,OAAO,WAAA;AAAA,MACb,QAAQ;AAAA,IAAA,GAGJC,MAAgBtgC,IAAAq2B,EAAO,cAAP,gBAAAr2B,EAAkB,aAAY,CAAA;AACpD,eAAWwsB,KAAOwT,GAAiB;AACjC,YAAMpgC,IAAQ84B,EAAY,OAAOlM,CAAG;AACpC,MAAK5sB,MACD0gC,EAAc9T,CAAG,MAAM,SACzB6T,EAAO7T,CAAG,IAAI8T,EAAc9T,CAAG,IACtB5sB,EAAM,YAAY,SAC3BygC,EAAO7T,CAAG,IAAI5sB,EAAM,UACXA,EAAM,SAAS,WACxBygC,EAAO7T,CAAG,IAAI;AAAA,IAElB;AACA,IAAA1Y,EAAS,CAAC,GAAGS,GAAM8rB,CAAM,CAAC;AAAA,EAC5B,GAAG,CAAC9rB,GAAMT,GAAUksB,GAAiBtH,IAAa14B,IAAAq2B,EAAO,cAAP,gBAAAr2B,EAAkB,QAAQ,CAAC,GAEvEugC,IAAkBhiC;AAAA,IACtB,CAAC4hC,MAAmB;AAClB,YAAM1kB,IAAUlH,EAAK;AAAA,QAAI,CAACyN,MACxBA,EAAI,SAASme,IAAS,EAAE,GAAGne,GAAK,UAAU,OAASA;AAAA,MAAA;AAErD,MAAAlO,EAAS2H,CAAO;AAAA,IAClB;AAAA,IACA,CAAClH,GAAMT,CAAQ;AAAA,EAAA,GAGX0sB,IAAmBjiC;AAAA,IACvB,CAAC4hC,MAAmB;AAClB,YAAM1kB,IAAUlH,EAAK;AAAA,QAAI,CAACyN,MACxBA,EAAI,SAASme,IAAS,EAAE,GAAGne,GAAK,UAAU,OAAUA;AAAA,MAAA;AAEtD,MAAAlO,EAAS2H,CAAO;AAAA,IAClB;AAAA,IACA,CAAClH,GAAMT,CAAQ;AAAA,EAAA,GAGXiK,IAAgBxf;AAAA,IACpB,CAACsK,MAA6C;;AAC5C,YAAM4Y,IAAS5Y,EAAE,QACXwrB,IAAO5S,EAAO,QAAQ,IAAI;AAChC,UAAI,CAAC4S,EAAM;AACX,YAAMrS,IAAMqS,EAAK,QAAQ,IAAI;AAC7B,UAAI,CAACrS,EAAK;AACV,YAAMye,IAAQze,EAAI,QAAQ,OAAO;AACjC,UAAI,CAACye,EAAO;AAEZ,YAAMC,IAAY,MAAM,KAAK1e,EAAI,KAAK,EAAE,QAAQqS,CAA4B,GACtEsM,IAAW,MAAM,KAAKF,EAAM,IAAI,EAAE,QAAQze,CAA0B;AAE1E,UAAInZ,EAAE,QAAQ,OAAO;AAEnB,cAAM2xB,IAAY3xB,EAAE,WAAW,KAAK,GAC9B+3B,IAAU,MAAM,KAAKH,EAAM,IAAI;AACrC,YAAII,IAAUF,GACVG,IAAWJ,IAAYlG;AAG3B,eAAOqG,KAAW,KAAKA,IAAUD,EAAQ;AACvC,cAAIE,KAAY,KAAKA,IAAWF,EAAQC,CAAO,EAAE,MAAM,QAAQ;AAE7D,kBAAM/O,KADS8O,EAAQC,CAAO,EAAE,MAAMC,CAAQ,EACzB,cAAc,qCAAqC;AACxE,gBAAIhP,IAAO;AACT,cAAAjpB,EAAE,eAAA,GACFipB,GAAM,MAAA;AACN;AAAA,YACF;AACA,YAAAgP,KAAYtG;AAAA,UACd;AAEE,YAAAqG,KAAWrG,GACXsG,IAAWtG,IAAY,IAAI,OAAKx6B,IAAA4gC,EAAQC,CAAO,MAAf,gBAAA7gC,EAAkB,MAAM,WAAU,KAAK;AAAA,MAI7E,WAAW6I,EAAE,QAAQ,SAAS;AAE5B,QAAAA,EAAE,eAAA;AACF,cAAM+3B,IAAU,MAAM,KAAKH,EAAM,IAAI;AACrC,YAAIE,IAAWC,EAAQ,SAAS,GAAG;AACjC,gBAAMG,IAASH,EAAQD,IAAW,CAAC,EAAE,MAAMD,CAAS,GAC9C5O,IAAQiP,KAAA,gBAAAA,EAAQ,cAAc;AACpC,UAAIjP,OAAa,MAAA;AAAA,QACnB;AAEE,UAAAsO,EAAA,GAEA,sBAAsB,MAAM;AAC1B,kBAAMY,IAAUP,EAAM,iBAAiB,IAAI,GACrCQ,IAAUD,EAAQA,EAAQ,SAAS,CAAC;AAC1C,gBAAIC,GAAS;AACX,oBAAMC,IAAaD,EAAQ,cAAc,qCAAqC;AAC9E,cAAIC,OAAuB,MAAA;AAAA,YAC7B;AAAA,UACF,CAAC;AAAA,MAEL,MAAA,CAAWr4B,EAAE,QAAQ,cAElB5I,IAAAwhB,EAAuB,SAAvB,QAAAxhB,EAAA,KAAAwhB;AAAA,IAEL;AAAA,IACA,CAAC2e,CAAY;AAAA,EAAA;AAGf,2BACG,OAAA,EACC,UAAA;AAAA,IAAA,gBAAA/gC,EAAC,OAAA,EAAI,WAAU,mBACb,UAAA,gBAAAqD,EAAC,SAAA,EAAM,KAAKq9B,GAAU,WAAU,kBAAiB,WAAWhiB,GAC1D,UAAA;AAAA,MAAA,gBAAA1e,EAAC,SAAA,EACC,UAAA,gBAAAqD,EAAC,MAAA,EAAG,WAAU,YACX,UAAA;AAAA,QAAAguB,EAAQ,IAAI,CAAClE,MAAQ;AACpB,gBAAM5sB,IAAQ84B,EAAY,OAAOlM,CAAG;AACpC,iBACE,gBAAAntB;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,WAAU;AAAA,cAET,cAAQM,GAAiBC,GAAO4sB,GAAK7qB,EAAO,QAAQ,IAAI6qB;AAAA,YAAA;AAAA,YAHpDA;AAAA,UAAA;AAAA,QAMX,CAAC;AAAA,QACD,gBAAAntB,EAAC,MAAA,EAAG,WAAU,gBAAA,CAAgB;AAAA,MAAA,EAAA,CAChC,EAAA,CACF;AAAA,MACA,gBAAAA,EAAC,SAAA,EACE,UAAAkV,EAAK,IAAI,CAACyN,MAAQ;AACjB,cAAMoS,IAAY,CAAC,CAACpS,EAAI,UAClBmf,IAAYrB,KAAA,gBAAAA,EAAmB9d,EAAI;AACzC,eACE,gBAAAtf;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAW,0BAA0B0xB,IAAY,eAAe,EAAE;AAAA,YAEjE,UAAA;AAAA,cAAA1D,EAAQ,IAAI,CAAClE,MAAQ;AACpB,sBAAM5sB,IAAQ84B,EAAY,OAAOlM,CAAG,GAC9B4U,IAAWD,KAAA,gBAAAA,EAAW,SAAS3U,IAC/B6U,IAAgBpB,EAAmB,IAAIzT,CAAG;AAEhD,uBAAI4H,KAAaiN,IAEb,gBAAAhiC;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBAEC,WAAW,0BAA0B+0B,IAAY,iBAAiB,EAAE;AAAA,oBAEnE,cACGjY,GAAY;AAAA,sBACV,OAAAvc;AAAA,sBACA,WAAW4sB;AAAA,sBACX,OAAOxK,EAAIwK,CAAG;AAAA,sBACd,MAAM;AAAA,sBACN,QAAQxK;AAAA,sBACR,MAAA9H;AAAA,oBAAA,CACD,IACD,OAAO8H,EAAIwK,CAAG,KAAK,EAAE;AAAA,kBAAA;AAAA,kBAZpBA;AAAA,gBAAA,IAkBT,gBAAAntB;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBAEC,WAAW,0BAA0B+hC,IAAW,wDAAwD,EAAE;AAAA,oBAC1G,OAAOA,IAAW,GAAG5U,CAAG,iBAAiB;AAAA,oBAExC,cACGrQ,GAAY;AAAA,sBACV,OAAAvc;AAAA,sBACA,WAAW4sB;AAAA,sBACX,OAAOxK,EAAIwK,CAAG;AAAA,sBACd,MAAM;AAAA,sBACN,UAAU,CAACxS,MAAQkmB,EAAiBle,EAAI,MAAMwK,GAAKxS,CAAG;AAAA,sBACtD,QAAQgI;AAAA,sBACR,MAAA9H;AAAA,oBAAA,CACD,IACD,OAAO8H,EAAIwK,CAAG,KAAK,EAAE;AAAA,kBAAA;AAAA,kBAdpBA;AAAA,gBAAA;AAAA,cAiBX,CAAC;AAAA,cACD,gBAAAntB,EAAC,MAAA,EAAG,WAAU,0BACX,UAAA+0B,IACC,gBAAA/0B;AAAA,gBAAC8H;AAAA,gBAAA;AAAA,kBACC,SAAQ;AAAA,kBACR,MAAK;AAAA,kBACL,WAAU;AAAA,kBACV,SAAS,MAAMq5B,EAAiBxe,EAAI,IAAI;AAAA,kBACxC,OAAM;AAAA,kBAEN,UAAA,gBAAA3iB,EAACiiC,IAAA,EAAM,WAAU,UAAA,CAAU;AAAA,gBAAA;AAAA,cAAA,IAG7B,gBAAAjiC;AAAA,gBAAC8H;AAAA,gBAAA;AAAA,kBACC,SAAQ;AAAA,kBACR,MAAK;AAAA,kBACL,WAAU;AAAA,kBACV,SAAS,MAAMo5B,EAAgBve,EAAI,IAAI;AAAA,kBACvC,OAAM;AAAA,kBAEN,UAAA,gBAAA3iB,EAACqd,IAAA,EAAO,WAAU,UAAA,CAAU;AAAA,gBAAA;AAAA,cAAA,EAC9B,CAEJ;AAAA,YAAA;AAAA,UAAA;AAAA,UAtEKsF,EAAI;AAAA,QAAA;AAAA,MAyEf,CAAC,EAAA,CACH;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,IACA,gBAAAtf;AAAA,MAACyE;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAASi5B;AAAA,QAET,UAAA;AAAA,UAAA,gBAAA/gC,EAACsd,IAAA,EAAK,WAAU,eAAA,CAAe;AAAA,UAAE;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAEnC,GACF;AAEJ;AC5PO,SAAS4kB,GAAuB;AAAA,EACrC,QAAAlL;AAAA,EACA,aAAAqC;AAAA,EACA,QAAA/2B;AAAA,EACA,MAAA4S;AAAA,EACA,UAAAT;AAAA,EACA,kBAAAgsB;AAAA,EACA,MAAA5lB;AACF,GAAgC;;AAC9B,QAAM6lB,IAAWvzB,GAAyB,IAAI,GACxCg1B,IAAgBnL,EAAO,gBACvB3F,IAAU2F,EAAO,SAGjBltB,IAAUC;AAAA,IACdC,GAAUC,IAAe,EAAE,sBAAsB,EAAE,UAAU,EAAA,GAAK;AAAA,EAAA,GAI9D2wB,IAAQ,IAAI,IAAI,MAAM,QAAQ5D,EAAO,WAAW,IAAIA,EAAO,cAAc,CAACA,EAAO,WAAW,CAAC,GAC7F2J,IAAkBtP,EAAQ,OAAO,CAAClE,MAAQ;AAE9C,QADIyN,EAAM,IAAIzN,CAAG,KACbA,MAAQgV,EAAe,QAAO;AAClC,UAAM5hC,IAAQ84B,EAAY,OAAOlM,CAAG;AAEpC,WADI,GAAC5sB,KACDA,EAAM,QAAQA,EAAM;AAAA,EAE1B,CAAC,GAGKqgC,IAAqB,IAAI;AAAA,IAC7BvP,EAAQ,OAAO,CAAClE,MAAQ;AACtB,UAAIA,MAAQgV,EAAe,QAAO;AAClC,YAAM5hC,IAAQ84B,EAAY,OAAOlM,CAAG;AACpC,aAAO5sB,MAAUA,EAAM,QAAQA,EAAM;AAAA,IACvC,CAAC;AAAA,EAAA,GAIGosB,IAAiB0E,EAAQ,OAAO,CAAClE,MAAQA,MAAQgV,CAAa,GAG9DC,IAASriC;AAAA,IACb,MAAMmV,EAAK,OAAO,CAAC/Y,MAAM,CAACA,EAAE,QAAQ,EAAE,IAAI,CAACA,MAAMA,EAAE,IAAI;AAAA,IACvD,CAAC+Y,CAAI;AAAA,EAAA,GAGD2rB,IAAmB3hC;AAAA,IACvB,CAAC4hC,GAAgBtgC,GAAmB+K,MAAmB;AACrD,YAAM6Q,IAAUlH,EAAK;AAAA,QAAI,CAACyN,MACxBA,EAAI,SAASme,IACT,EAAE,GAAGne,GAAK,CAACniB,CAAS,GAAG+K,GAAO,QAAQ,OACtCoX;AAAA,MAAA;AAEN,MAAAlO,EAAS2H,CAAO;AAAA,IAClB;AAAA,IACA,CAAClH,GAAMT,CAAQ;AAAA,EAAA,GAGXssB,IAAe7hC,EAAY,MAAM;;AACrC,UAAMmjC,IAAcntB,EACjB,OAAO,CAAC/Y,MAAM,CAACA,EAAE,QAAQ,EACzB,OAAO,CAACmmC,GAAKnmC,MAAM;AAClB,YAAMomC,IAAM,OAAOpmC,EAAEgmC,CAAa,KAAM,WAAYhmC,EAAEgmC,CAAa,IAAe;AAClF,aAAO,KAAK,IAAIG,GAAKC,CAAG;AAAA,IAC1B,GAAG,EAAE,GAEDvB,IAA0B;AAAA,MAC9B,MAAM,OAAO,WAAA;AAAA,MACb,QAAQ;AAAA,MACR,CAACmB,CAAa,GAAGE,IAAc;AAAA,IAAA,GAG3BpB,MAAgBtgC,IAAAq2B,EAAO,cAAP,gBAAAr2B,EAAkB,aAAY,CAAA;AACpD,eAAWwsB,KAAOwT,GAAiB;AACjC,YAAMpgC,IAAQ84B,EAAY,OAAOlM,CAAG;AACpC,MAAK5sB,MACD0gC,EAAc9T,CAAG,MAAM,SACzB6T,EAAO7T,CAAG,IAAI8T,EAAc9T,CAAG,IACtB5sB,EAAM,YAAY,SAC3BygC,EAAO7T,CAAG,IAAI5sB,EAAM,UACXA,EAAM,SAAS,WACxBygC,EAAO7T,CAAG,IAAI;AAAA,IAElB;AACA,IAAA1Y,EAAS,CAAC,GAAGS,GAAM8rB,CAAM,CAAC;AAAA,EAC5B,GAAG,CAAC9rB,GAAMT,GAAUksB,GAAiBtH,IAAa14B,IAAAq2B,EAAO,cAAP,gBAAAr2B,EAAkB,UAAUwhC,CAAa,CAAC,GAEtFjB,IAAkBhiC;AAAA,IACtB,CAAC4hC,MAAmB;AAClB,YAAM1kB,IAAUlH,EAAK;AAAA,QAAI,CAACyN,MACxBA,EAAI,SAASme,IAAS,EAAE,GAAGne,GAAK,UAAU,OAASA;AAAA,MAAA;AAErD,MAAAlO,EAAS2H,CAAO;AAAA,IAClB;AAAA,IACA,CAAClH,GAAMT,CAAQ;AAAA,EAAA,GAGX0sB,IAAmBjiC;AAAA,IACvB,CAAC4hC,MAAmB;AAClB,YAAM1kB,IAAUlH,EAAK;AAAA,QAAI,CAACyN,MACxBA,EAAI,SAASme,IAAS,EAAE,GAAGne,GAAK,UAAU,OAAUA;AAAA,MAAA;AAEtD,MAAAlO,EAAS2H,CAAO;AAAA,IAClB;AAAA,IACA,CAAClH,GAAMT,CAAQ;AAAA,EAAA,GAGXjK,IAAgBtL;AAAA,IACpB,CAACuL,MAAwB;AACvB,YAAM,EAAE,QAAA/G,GAAQ,MAAAgH,EAAA,IAASD;AACzB,UAAI,CAACC,KAAQhH,EAAO,OAAOgH,EAAK,GAAI;AAGpC,YAAM83B,IAAattB,EAAK,OAAO,CAAC/Y,MAAM,CAACA,EAAE,QAAQ,GAC3CsmC,IAAUvtB,EAAK,OAAO,CAAC/Y,MAAMA,EAAE,QAAQ,GAEvCumC,IAAWF,EAAW,UAAU,CAACrmC,MAAMA,EAAE,SAAS,OAAOuH,EAAO,EAAE,CAAC,GACnEi/B,IAAWH,EAAW,UAAU,CAACrmC,MAAMA,EAAE,SAAS,OAAOuO,EAAK,EAAE,CAAC;AACvE,UAAIg4B,MAAa,MAAMC,MAAa,GAAI;AAGxC,YAAMC,IAAY,CAAC,GAAGJ,CAAU,GAC1B,CAAChkC,CAAK,IAAIokC,EAAU,OAAOF,GAAU,CAAC;AAC5C,MAAAE,EAAU,OAAOD,GAAU,GAAGnkC,CAAK;AAGnC,YAAMqkC,KAAgBD,EAAU,IAAI,CAACjgB,GAAKjnB,OAAW;AAAA,QACnD,GAAGinB;AAAA,QACH,CAACwf,CAAa,GAAGzmC;AAAA,QACjB,QAAQinB,EAAIwf,CAAa,MAAMzmC,IAAQ,KAAOinB,EAAI;AAAA,MAAA,EAClD;AAGF,MAAAlO,EAAS,CAAC,GAAGouB,IAAe,GAAGJ,CAAO,CAAC;AAAA,IACzC;AAAA,IACA,CAACvtB,GAAMT,GAAU0tB,CAAa;AAAA,EAAA,GAG1BzjB,IAAgBxf;AAAA,IACpB,CAACsK,MAA6C;;AAC5C,YAAM4Y,IAAS5Y,EAAE,QACXwrB,IAAO5S,EAAO,QAAQ,IAAI;AAChC,UAAI,CAAC4S,EAAM;AACX,YAAMrS,IAAMqS,EAAK,QAAQ,IAAI;AAC7B,UAAI,CAACrS,EAAK;AACV,YAAMye,IAAQze,EAAI,QAAQ,OAAO;AACjC,UAAI,CAACye,EAAO;AAEZ,YAAMC,IAAY,MAAM,KAAK1e,EAAI,KAAK,EAAE,QAAQqS,CAA4B,GACtEsM,IAAW,MAAM,KAAKF,EAAM,IAAI,EAAE,QAAQze,CAA0B;AAE1E,UAAInZ,EAAE,QAAQ,OAAO;AACnB,cAAM2xB,KAAY3xB,EAAE,WAAW,KAAK,GAC9B+3B,IAAU,MAAM,KAAKH,EAAM,IAAI;AACrC,YAAII,IAAUF,GACVG,IAAWJ,IAAYlG;AAE3B,eAAOqG,KAAW,KAAKA,IAAUD,EAAQ;AACvC,cAAIE,KAAY,KAAKA,IAAWF,EAAQC,CAAO,EAAE,MAAM,QAAQ;AAE7D,kBAAM/O,IADS8O,EAAQC,CAAO,EAAE,MAAMC,CAAQ,EACzB,cAAc,qCAAqC;AACxE,gBAAIhP,GAAO;AACT,cAAAjpB,EAAE,eAAA,GACFipB,EAAM,MAAA;AACN;AAAA,YACF;AACA,YAAAgP,KAAYtG;AAAA,UACd;AACE,YAAAqG,KAAWrG,IACXsG,IAAWtG,KAAY,IAAI,OAAKx6B,IAAA4gC,EAAQC,CAAO,MAAf,gBAAA7gC,EAAkB,MAAM,WAAU,KAAK;AAAA,MAG7E,WAAW6I,EAAE,QAAQ,SAAS;AAC5B,QAAAA,EAAE,eAAA;AACF,cAAM+3B,KAAU,MAAM,KAAKH,EAAM,IAAI;AACrC,YAAIE,IAAWC,GAAQ,SAAS,GAAG;AACjC,gBAAMG,IAASH,GAAQD,IAAW,CAAC,EAAE,MAAMD,CAAS,GAC9C5O,IAAQiP,KAAA,gBAAAA,EAAQ,cAAc;AACpC,UAAIjP,OAAa,MAAA;AAAA,QACnB;AACE,UAAAsO,EAAA,GACA,sBAAsB,MAAM;AAC1B,kBAAMY,IAAUP,EAAM,iBAAiB,IAAI,GACrCQ,IAAUD,EAAQA,EAAQ,SAAS,CAAC;AAC1C,gBAAIC,GAAS;AACX,oBAAMC,IAAaD,EAAQ,cAAc,qCAAqC;AAC9E,cAAIC,OAAuB,MAAA;AAAA,YAC7B;AAAA,UACF,CAAC;AAAA,MAEL,MAAA,CAAWr4B,EAAE,QAAQ,cAClB5I,IAAAwhB,EAAuB,SAAvB,QAAAxhB,EAAA,KAAAwhB;AAAA,IAEL;AAAA,IACA,CAAC2e,CAAY;AAAA,EAAA;AAGf,2BACG,OAAA,EACC,UAAA;AAAA,IAAA,gBAAA/gC,EAAC,OAAA,EAAI,WAAU,mBACb,UAAA,gBAAAA;AAAA,MAAC2K;AAAA,MAAA;AAAA,QACC,SAAAb;AAAA,QACA,oBAAoBc;AAAA,QACpB,WAAWJ;AAAA,QAEX,4BAAC,SAAA,EAAM,KAAKk2B,GAAU,WAAU,kBAAiB,WAAWhiB,GAC1D,UAAA;AAAA,UAAA,gBAAA1e,EAAC,SAAA,EACC,UAAA,gBAAAqD,EAAC,MAAA,EAAG,WAAU,YACZ,UAAA;AAAA,YAAA,gBAAArD,EAAC,MAAA,EAAG,WAAU,eAAA,CAAe;AAAA,YAC5B2sB,EAAe,IAAI,CAACQ,MAAQ;AAC3B,oBAAM5sB,IAAQ84B,EAAY,OAAOlM,CAAG;AACpC,qBACE,gBAAAntB;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAU;AAAA,kBAET,cAAQM,GAAiBC,GAAO4sB,GAAK7qB,EAAO,QAAQ,IAAI6qB;AAAA,gBAAA;AAAA,gBAHpDA;AAAA,cAAA;AAAA,YAMX,CAAC;AAAA,YACD,gBAAAntB,EAAC,MAAA,EAAG,WAAU,gBAAA,CAAgB;AAAA,UAAA,EAAA,CAChC,EAAA,CACF;AAAA,UACA,gBAAAA,EAAC6K,IAAA,EAAgB,OAAOu3B,GAAQ,UAAUU,IACxC,UAAA,gBAAA9iC,EAAC,SAAA,EACE,UAAAkV,EAAK,IAAI,CAACyN,MACT,gBAAA3iB;AAAA,YAAC+iC;AAAA,YAAA;AAAA,cAEC,KAAApgB;AAAA,cACA,SAASgK;AAAA,cACT,iBAAAgU;AAAA,cACA,oBAAAC;AAAA,cACA,aAAAvH;AAAA,cACA,kBAAAoH;AAAA,cACA,MAAA5lB;AAAA,cACA,cAAcgmB;AAAA,cACd,UAAUK;AAAA,cACV,cAAcC;AAAA,YAAA;AAAA,YAVTxe,EAAI;AAAA,UAAA,CAYZ,GACH,EAAA,CACF;AAAA,QAAA,EAAA,CACF;AAAA,MAAA;AAAA,IAAA,GAEJ;AAAA,IACA,gBAAAtf;AAAA,MAACyE;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAASi5B;AAAA,QAET,UAAA;AAAA,UAAA,gBAAA/gC,EAACsd,IAAA,EAAK,WAAU,eAAA,CAAe;AAAA,UAAE;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAEnC,GACF;AAEJ;AAgBA,SAASylB,GAAY;AAAA,EACnB,KAAApgB;AAAA,EACA,SAAA0O;AAAA,EACA,iBAAAsP;AAAA,EACA,oBAAAC;AAAA,EACA,aAAAvH;AAAA,EACA,kBAAAoH;AAAA,EACA,MAAA5lB;AAAA,EACA,cAAAmoB;AAAA,EACA,UAAAC;AAAA,EACA,cAAAC;AACF,GAAqB;AACnB,QAAMnO,IAAY,CAAC,CAACpS,EAAI,UAClBmf,IAAYrB,KAAA,gBAAAA,EAAmB9d,EAAI,OAEnC;AAAA,IACJ,YAAA5Z;AAAA,IACA,WAAAC;AAAA,IACA,YAAAC;AAAA,IACA,WAAAC;AAAA,IACA,YAAAC;AAAA,IACA,YAAAC;AAAA,EAAA,IACEC,GAAY,EAAE,IAAIsZ,EAAI,MAAM,UAAUoS,GAAW,GAE/CzrB,IAAQ;AAAA,IACZ,WAAWC,GAAI,UAAU,SAASL,CAAS;AAAA,IAC3C,YAAAC;AAAA,IACA,QAAQC,IAAa,KAAK;AAAA,IAC1B,SAASA,IAAa,MAAM;AAAA,EAAA;AAG9B,SACE,gBAAA/F;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK4F;AAAA,MACL,OAAAK;AAAA,MACA,WAAW,0BAA0ByrB,IAAY,eAAe,EAAE;AAAA,MAElE,UAAA;AAAA,QAAA,gBAAA/0B,EAAC,MAAA,EAAG,WAAU,8BACX,UAAA,CAAC+0B,KACA,gBAAA/0B;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACT,GAAG+I;AAAA,YACH,GAAGC;AAAA,YAEJ,UAAA,gBAAAhJ,EAACmjC,IAAA,EAAa,WAAU,UAAA,CAAU;AAAA,UAAA;AAAA,QAAA,GAGxC;AAAA,QACC9R,EAAQ,IAAI,CAAClE,MAAQ;AACpB,gBAAM5sB,IAAQ84B,EAAY,OAAOlM,CAAG,GAC9B4U,IAAWD,KAAA,gBAAAA,EAAW,SAAS3U,IAC/B6U,IAAgBpB,EAAmB,IAAIzT,CAAG,GAC1CiW,IAAazC,EAAgB,SAASxT,CAAG;AAE/C,iBAAI4H,KAAaiN,KAAiB,CAACoB,IAE/B,gBAAApjC;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,WAAW,0BAA0B+0B,IAAY,iBAAiB,EAAE;AAAA,cAEnE,cACGjY,GAAY;AAAA,gBACV,OAAAvc;AAAA,gBACA,WAAW4sB;AAAA,gBACX,OAAOxK,EAAIwK,CAAG;AAAA,gBACd,MAAM;AAAA,gBACN,QAAQxK;AAAA,gBACR,MAAA9H;AAAA,cAAA,CACD,IACD,OAAO8H,EAAIwK,CAAG,KAAK,EAAE;AAAA,YAAA;AAAA,YAZpBA;AAAA,UAAA,IAkBT,gBAAAntB;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,WAAW,0BAA0B+hC,IAAW,wDAAwD,EAAE;AAAA,cAC1G,OAAOA,IAAW,GAAG5U,CAAG,iBAAiB;AAAA,cAExC,cACGrQ,GAAY;AAAA,gBACV,OAAAvc;AAAA,gBACA,WAAW4sB;AAAA,gBACX,OAAOxK,EAAIwK,CAAG;AAAA,gBACd,MAAM;AAAA,gBACN,UAAU,CAACxS,MAAQqoB,EAAargB,EAAI,MAAMwK,GAAKxS,CAAG;AAAA,gBAClD,QAAQgI;AAAA,gBACR,MAAA9H;AAAA,cAAA,CACD,IACD,OAAO8H,EAAIwK,CAAG,KAAK,EAAE;AAAA,YAAA;AAAA,YAdpBA;AAAA,UAAA;AAAA,QAiBX,CAAC;AAAA,QACD,gBAAAntB,EAAC,MAAA,EAAG,WAAU,0BACX,UAAA+0B,IACC,gBAAA/0B;AAAA,UAAC8H;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,WAAU;AAAA,YACV,SAAS,MAAMo7B,EAAavgB,EAAI,IAAI;AAAA,YACpC,OAAM;AAAA,YAEN,UAAA,gBAAA3iB,EAACiiC,IAAA,EAAM,WAAU,UAAA,CAAU;AAAA,UAAA;AAAA,QAAA,IAG7B,gBAAAjiC;AAAA,UAAC8H;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,WAAU;AAAA,YACV,SAAS,MAAMm7B,EAAStgB,EAAI,IAAI;AAAA,YAChC,OAAM;AAAA,YAEN,UAAA,gBAAA3iB,EAACqd,IAAA,EAAO,WAAU,UAAA,CAAU;AAAA,UAAA;AAAA,QAAA,EAC9B,CAEJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;ACnZO,SAASgmB,GAAc,EAAE,MAAAtgC,GAAM,KAAAwe,KAA2B;;AAC/D,QAAMxV,IAAYhJ,EAAK;AAKvB,MAJI,CAACgJ,KAIDwV,EAAI,SAASA,EAAI,SAAS,OAAQ,QAAO;AAE7C,QAAMsY,IAAW0B,GAAkBha,EAAI,QAAQxV,CAAS;AACxD,MAAI,CAAC8tB;AACH,WACE,gBAAAx2B,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA;AAAA,MAAA;AAAA,MAClC0I;AAAA,IAAA,GAC3B;AAIJ,QAAMstB,IAAc9X,EAAI,OAAO,SAASsY,EAAS,MAAM;AACvD,MAAI,CAACR;AACH,WACE,gBAAAh2B,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA;AAAA,MAAA;AAAA,MACxCw2B,EAAS;AAAA,IAAA,GAC9B;AAIJ,QAAM7C,IAAS4C,GAAmBC,GAAUR,GAAat2B,CAAI;AAI7D,MACEwe,EAAI,SAAS,UACbyV,EAAO,YACP,CAACqC,EAAY,YACbrC,EAAO,SAAS,WAChBzV,EAAI,oBAAoB,UACxBA,EAAI,kBACJ;AACA,UAAM+hB,IAAc/hB,EAAI,gBAAgBxV,CAAS,KAAK,CAAA,GAChD00B,KAAmB9/B,IAAA4gB,EAAI,0BAAJ,gBAAA5gB,EAA4BoL,IAC/Cw3B,IAAiBvM,EAAO,iBAC1BkL,KACA1B;AACJ,WACE,gBAAAxgC;AAAA,MAACujC;AAAA,MAAA;AAAA,QACC,QAAAvM;AAAA,QACA,aAAAqC;AAAA,QACA,QAAQ9X,EAAI;AAAA,QACZ,MAAM+hB;AAAA,QACN,UAAU,CAACpuB,MAASqM,EAAI,iBAAkBxV,GAAWmJ,CAAI;AAAA,QACzD,kBAAAurB;AAAA,QACA,MAAMlf,EAAI;AAAA,MAAA;AAAA,IAAA;AAAA,EAGhB;AAGA,MAAIA,EAAI,MAAO,QAAO;AAEtB,QAAMiiB,IAAkC;AAAA,IACtC,QAAAxM;AAAA,IACA,cAAczV,EAAI;AAAA,IAClB,UAAUA,EAAI;AAAA,IACd,QAAQA,EAAI;AAAA,EAAA;AAGd,UAAQyV,EAAO,MAAA;AAAA,IACb,KAAK;AACH,aAAO,gBAAAh3B,EAAC88B,IAAA,EAAe,GAAG0G,EAAA,CAAc;AAAA,IAC1C,KAAK;AACH,aAAO,gBAAAxjC,EAACi9B,IAAA,EAAc,GAAGuG,EAAA,CAAc;AAAA,IACzC,KAAK;AACH,aAAO,gBAAAxjC,EAACm9B,IAAA,EAAe,GAAGqG,EAAA,CAAc;AAAA,IAC1C,KAAK;AACH,aAAO,gBAAAxjC,EAACu+B,IAAA,EAAkB,GAAGiF,EAAA,CAAc;AAAA,IAC7C;AACE,aAAO,gBAAAxjC,EAAC88B,IAAA,EAAe,GAAG0G,EAAA,CAAc;AAAA,EAAA;AAE9C;AC3FO,SAASC,GACd53B,GACAC,GACAqF,GACAnF,GACAC,GACAC,GACAvN,GACA0N,GACA;AAEA,QAAMq3B,IAAgBr3B,IAClB,KAAK,UAAU,OAAO,QAAQA,CAAO,EAAE,KAAA,CAAM,IAC7C;AAEJ,SAAOs3B,GAAiB;AAAA,IACtB,UAAU;AAAA,MACRh4B;AAAA,MACAE;AAAA,MACAC;AAAA,MACAqF;AAAA,MACAlF;AAAA,MACAC;AAAA,MACAvN;AAAA,MACA+kC;AAAA,IAAA;AAAA,IAEF,SAAS,CAAC,EAAE,WAAAE,QAAgB;AAC1B,YAAM/+B,IAAS,IAAI,gBAAA,GAEbg/B,IAAoE;AAAA,QACxE,EAAE,OAAO73B,GAAY,IAAI,MAAM,OAAOF,EAAA;AAAA,MAAS;AAEjD,UAAIO;AACF,mBAAW,CAAC9L,GAAOgL,CAAK,KAAK,OAAO,QAAQc,CAAO;AACjD,UAAId,KAASA,MAAU,aACrBs4B,EAAY,KAAK,EAAE,OAAAtjC,GAAO,IAAI,MAAM,OAAAgL,GAAO;AAIjD,aAAA1G,EAAO,IAAI,WAAW,KAAK,UAAUg/B,CAAW,CAAC,GAC7C53B,KAAMpH,EAAO,IAAI,QAAQoH,CAAI,GAE7BtN,KAAQkG,EAAO,IAAI,UAAUlG,CAAM,GACnCilC,KAAW/+B,EAAO,IAAI,SAAS++B,CAAS,GACrCrnC;AAAA,QACL,aAAa4U,CAAU,IAAItM,EAAO,UAAU;AAAA,MAAA;AAAA,IAEhD;AAAA,IACA,kBAAkB,CAACi/B,MAAA;;AACjB,cAAAnjC,IAAAmjC,EAAS,SAAT,QAAAnjC,EAAe,WAAWmjC,EAAS,KAAK,SAAS;AAAA;AAAA,IACnD,kBAAkB;AAAA,IAClB,SACE,CAAC,CAACj4B,KAAgB,CAAC,CAACC,KAAY,CAAC,CAACqF,KAAc,CAAC,CAACnF;AAAA,EAAA,CACrD;AACH;ACzCO,SAAS+3B,GAAkB;AAAA,EAChC,QAAA1iC;AAAA,EACA,YAAA2iC;AAAA,EACA,cAAA7O;AAAA,EACA,aAAAzE;AAAA,EACA,gBAAAuT;AAAA,EACA,SAAA53B;AAAA,EACA,gBAAA63B;AAAA,EACA,aAAAC;AACF,GAA2B;AACzB,QAAMC,IAAYJ,MAAe,IAC3BK,IAAalP,KAAgBA,EAAa,SAAS;AAEzD,SAAI,CAACiP,KAAa,CAACC,IAAmB,OAGpC,gBAAAhhC,EAAC,OAAA,EAAI,WAAU,gCACZ,UAAA;AAAA,IAAA+gC,KACC,gBAAA/gC,EAAC,OAAA,EAAI,WAAU,iCACb,UAAA;AAAA,MAAA,gBAAArD,EAACi0B,IAAA,EAAO,WAAU,sFAAA,CAAsF;AAAA,MACxG,gBAAAj0B;AAAA,QAACoO;AAAA,QAAA;AAAA,UACC,aAAY;AAAA,UACZ,OAAOsiB;AAAA,UACP,UAAU,CAAClnB,MAAMy6B,EAAez6B,EAAE,OAAO,KAAK;AAAA,UAC9C,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,IACZ,GACF;AAAA,IAED66B,KACClP,EAAa,IAAI,CAACmP,MAAgB;;AAChC,YAAM/jC,IAAQc,EAAO,OAAOijC,CAAW;AACvC,UAAI,CAAC/jC,EAAO,QAAO;AACnB,YAAMgkC,IAAal4B,EAAQi4B,CAAW,KAAK,WACrC5tB,IAAQpW,GAAiBC,GAAO+jC,GAAaH,CAAW;AAE9D,aAAI5jC,EAAM,SAAS,WAASI,IAAAJ,EAAM,QAAN,QAAAI,EAAW,UAEnC,gBAAAX;AAAA,QAACwkC;AAAA,QAAA;AAAA,UAEC,OAAAjkC;AAAA,UACA,OAAAmW;AAAA,UACA,OAAO6tB;AAAA,UACP,UAAU,CAACpyB,MAAM+xB,EAAeI,GAAanyB,CAAC;AAAA,QAAA;AAAA,QAJzCmyB;AAAA,MAAA,IASN/jC,EAAM,SAET,gBAAA8C;AAAA,QAAC8R;AAAA,QAAA;AAAA,UAEC,OAAOovB;AAAA,UACP,eAAe,CAACpyB,MAAM+xB,EAAeI,GAAanyB,CAAC;AAAA,UAEnD,UAAA;AAAA,YAAA,gBAAAnS,EAACsV,MAAc,WAAU,yBACvB,4BAACD,IAAA,EAAY,aAAaqB,GAAO,EAAA,CACnC;AAAA,8BACChB,IAAA,EACC,UAAA;AAAA,cAAA,gBAAArS,EAACuS,IAAA,EAAW,OAAM,WAAU,UAAA;AAAA,gBAAA;AAAA,gBAAKc;AAAA,cAAA,GAAM;AAAA,cACtCnW,EAAM,OAAO,IAAI,CAAC4R,wBAChByD,IAAA,EAAwB,OAAOzD,EAAE,MAC/B,YAAIA,EAAE,IAAI,EAAA,GADIA,EAAE,IAEnB,CACD;AAAA,YAAA,EAAA,CACH;AAAA,UAAA;AAAA,QAAA;AAAA,QAdKmyB;AAAA,MAAA,IAHiB;AAAA,IAoB5B,CAAC;AAAA,EAAA,GACL;AAEJ;AAEA,SAASE,GAAkB;AAAA,EACzB,OAAAjkC;AAAA,EACA,OAAAmW;AAAA,EACA,OAAAnL;AAAA,EACA,UAAAkJ;AACF,GAKG;;AACD,QAAM5T,IAAY4Z,IAAU9Z,IAAAJ,EAAM,QAAN,gBAAAI,EAAW,MAAM,GACvCoa,MACJna,IAAAL,EAAM,YAAN,gBAAAK,EAAe,wBAAqBG,IAAAF,KAAA,gBAAAA,EAAW,YAAX,gBAAAE,EAAoB,gBACpDka,IAAKlb;AAAA,IACT,MAAA;;AACE,aAAAc,MACIF,IAAA,OAAO,QAAQE,EAAU,MAAM,EAAE,KAAK,CAAC,CAAA,EAAGa,CAAC,MAAMA,EAAE,OAAO,MAA1D,gBAAAf,EAA8D,OAC9D,OACA;AAAA;AAAA,IACN,CAACE,CAAS;AAAA,EAAA,GAGN,EAAE,MAAMqa,EAAA,IAAahI,IAAc8H,IAAAza,EAAM,QAAN,gBAAAya,EAAW,QAAQ;AAAA,IAC1D,UAAU;AAAA,IACV,MAAMD,IAAe,GAAGA,CAAY,SAAS;AAAA,EAAA,CAC9C,GACKte,KAAUye,KAAA,gBAAAA,EAAU,SAAQ,CAAA,GAE5BR,IAAiB,CAACC,MAAyB;AAC/C,QAAIA,KAAO,KAAM,QAAO;AACxB,QAAI,OAAOA,KAAQ,YAAY,CAAC,MAAM,QAAQA,CAAG,GAAG;AAClD,YAAMrX,IAAQ,OAAO,OAAOqX,CAA8B,EAAE,CAAC;AAC7D,aAAOrX,KAAS,OAAO,OAAOA,CAAK,IAAI;AAAA,IACzC;AACA,WAAO,OAAOqX,CAAG;AAAA,EACnB;AAEA,SACE,gBAAAtX,EAAC8R,IAAA,EAAO,OAAA5J,GAAc,eAAekJ,GACnC,UAAA;AAAA,IAAA,gBAAAzU,EAACsV,MAAc,WAAU,yBACvB,4BAACD,IAAA,EAAY,aAAaqB,GAAO,EAAA,CACnC;AAAA,sBACChB,IAAA,EACC,UAAA;AAAA,MAAA,gBAAArS,EAACuS,IAAA,EAAW,OAAM,WAAU,UAAA;AAAA,QAAA;AAAA,QAAKc;AAAA,MAAA,GAAM;AAAA,MACtCja,EAAQ,IAAI,CAACN,MAAM;AAClB,cAAMyB,IAAK,OAAOzB,EAAE8e,CAAE,CAAC,GACjBwpB,IAAW1pB,IACbL,EAAeve,EAAE4e,CAAY,KAAKnd,CAAE,IACpCA;AACJ,eACE,gBAAAoC,EAAC4V,IAAA,EAAoB,OAAOhY,GACzB,eADcA,CAEjB;AAAA,MAEJ,CAAC;AAAA,IAAA,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;ACtHO,SAAS8mC,GAAgB,EAAE,MAAA3hC,GAAM,KAAAwe,KAA6B;;AACnE,QAAMgG,IAAYxkB,EAAK;AAEvB,MADI,CAACwkB,KACDhG,EAAI,MAAO,QAAO;AAEtB,QAAMojB,IAAcpjB,EAAI,OAAO,SAASgG,CAAS;AACjD,MAAI,CAACod;AACH,WACE,gBAAAthC,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA;AAAA,MAAA;AAAA,MACxCkkB;AAAA,IAAA,GACrB;AAKJ,MAAIqd,IAAyB;AAC7B,aAAW,CAACpkC,GAAWD,CAAK,KAAK,OAAO,QAAQokC,EAAY,MAAM;AAChE,UAAIhkC,IAAAJ,EAAM,QAAN,gBAAAI,EAAW,YAAW4gB,EAAI,YAAY;AACxC,MAAAqjB,IAAUpkC;AACV;AAAA,IACF;AAGF,MAAI,CAACokC;AACH,WACE,gBAAAvhC,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA;AAAA,MAAA;AAAA,MAC1CkkB;AAAA,MAAU;AAAA,MAAQhG,EAAI;AAAA,IAAA,GACzC;AAKJ,QAAM8P,IAAUtuB,EAAK,WAAWA,EAAK,QAAQ,SAAS,IAClDA,EAAK,QAAQ,OAAO,CAACoqB,MACfA,MAAQyX,IAAgB,KAErB,CAAC,CADMD,EAAY,OAAOxX,CAAG,CAErC,KACAwX,EAAY,eAAe,OAAO,KAAKA,EAAY,MAAM,GAAG;AAAA,IAC3D,CAACxX,MAAQ;;AACP,UAAIA,MAAQyX,EAAS,QAAO;AAC5B,YAAMrkC,IAAQokC,EAAY,OAAOxX,CAAG;AAGpC,aAFI,GAAC5sB,KACDA,EAAM,aACNI,IAAAJ,EAAM,YAAN,gBAAAI,EAAe,iBAAgB;AAAA,IAErC;AAAA,EAAA,GAKAkkC,IAAWF,EAAY,WAAW,KAAS5hC,EAAK,aAAa,IAE7D2T,IAAQvW,GAAIS,IAAA+jC,EAAY,YAAZ,gBAAA/jC,EAAqB,WAAW,KAAKT,GAAIY,IAAA4jC,EAAY,YAAZ,gBAAA5jC,EAAqB,IAAI,KAAKwmB,GAGnFud,IAAa/hC,EAAK,eAAe,MAASA,EAAK,WAAWA,EAAK,QAAQ,SAAS;AAEtF,2BACG,OAAA,EACC,UAAA;AAAA,IAAA,gBAAA/C,EAAC,MAAA,EAAG,WAAU,2DAA2D,UAAA0W,GAAM;AAAA,IAC9EouB,IACC,gBAAA9kC;AAAA,MAAC+kC;AAAA,MAAA;AAAA,QACC,YAAYxd;AAAA,QACZ,QAAQod;AAAA,QACR,cAAcpjB,EAAI;AAAA,QAClB,UAAUA,EAAI;AAAA,QACd,YAAYqjB;AAAA,QACZ,SAAAvT;AAAA,QACA,UAAAwT;AAAA,QACA,KAAAtjB;AAAA,QACA,YAAYxe,EAAK;AAAA,QACjB,cAAcA,EAAK;AAAA,QACnB,MAAMA,EAAK;AAAA,MAAA;AAAA,IAAA,IAGb,gBAAA/C;AAAA,MAACglC;AAAA,MAAA;AAAA,QACC,YAAYzd;AAAA,QACZ,QAAQod;AAAA,QACR,cAAcpjB,EAAI;AAAA,QAClB,UAAUA,EAAI;AAAA,QACd,YAAYqjB;AAAA,QACZ,SAAAvT;AAAA,QACA,UAAAwT;AAAA,QACA,KAAAtjB;AAAA,QACA,MAAMxe,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,EACb,GAEJ;AAEJ;AAeA,SAASiiC,GAAsB;AAAA,EAC7B,YAAA7zB;AAAA,EACA,QAAA9P;AAAA,EACA,cAAAwK;AAAA,EACA,UAAAC;AAAA,EACA,YAAAE;AAAA,EACA,SAAAqlB;AAAA,EACA,UAAAwT;AAAA,EACA,KAAAtjB;AAAA,EACA,MAAAtV;AACF,GAAqB;AACnB,QAAMtG,IAAcC,GAAA,GACd,EAAE,MAAMsV,GAAU,WAAA5V,GAAW,SAAAgjB,MAAY1c;AAAA,IAC7CC;AAAA,IACAC;AAAA,IACAqF;AAAA,IACAnF;AAAA,IACAC;AAAA,EAAA,GAEIiJ,KAAOgG,KAAA,gBAAAA,EAAU,SAAQ,CAAA,GACzBL,IAAOK,KAAA,gBAAAA,EAAU,OAEjB+pB,IAAkB/lC,EAAY,MAAM;AACxC,IAAAyG,EAAY,kBAAkB;AAAA,MAC5B,UAAU,CAACgG,IAAqBE,GAAcC,GAAUqF,CAAU;AAAA,IAAA,CACnE;AAAA,EACH,GAAG,CAACxL,GAAakG,GAAcC,GAAUqF,CAAU,CAAC;AAEpD,SACE,gBAAAnR;AAAA,IAACklC;AAAA,IAAA;AAAA,MACC,YAAA/zB;AAAA,MACA,QAAA9P;AAAA,MACA,UAAAyK;AAAA,MACA,YAAAE;AAAA,MACA,SAAAqlB;AAAA,MACA,UAAAwT;AAAA,MACA,KAAAtjB;AAAA,MACA,MAAArM;AAAA,MACA,MAAA2F;AAAA,MACA,WAAAvV;AAAA,MACA,SAAAgjB;AAAA,MACA,iBAAA2c;AAAA,IAAA;AAAA,EAAA;AAGN;AAQA,SAASF,GAAyB;AAAA,EAChC,YAAA5zB;AAAA,EACA,QAAA9P;AAAA,EACA,cAAAwK;AAAA,EACA,UAAAC;AAAA,EACA,YAAAE;AAAA,EACA,SAAAqlB;AAAA,EACA,UAAAwT;AAAA,EACA,KAAAtjB;AAAA,EACA,YAAAyiB;AAAA,EACA,cAAA7O;AAAA,EACA,MAAAlpB;AACF,GAAwB;AACtB,QAAMtG,IAAcC,GAAA,GAGd,CAAC8qB,GAAayU,CAAc,IAAIljC,EAAS,EAAE,GAC3C,CAAC2uB,GAAiBwU,CAAkB,IAAInjC,EAAS,EAAE,GACnD,CAACoK,GAASod,CAAU,IAAIxnB,EAAiC,CAAA,CAAE,GAC3DojC,IAAiBl4B,GAAsC,MAAS;AAGtE,EAAAC,GAAU,OACJi4B,EAAe,WAAS,aAAaA,EAAe,OAAO,GAC/DA,EAAe,UAAU,WAAW,MAAM;AACxC,IAAAD,EAAmB1U,CAAW;AAAA,EAChC,GAAG,GAAG,GACC,MAAM;AACX,IAAI2U,EAAe,WAAS,aAAaA,EAAe,OAAO;AAAA,EACjE,IACC,CAAC3U,CAAW,CAAC;AAEhB,QAAM4U,IAAqBpmC,EAAY,CAACqB,GAAegL,MAAkB;AACvE,IAAAke,EAAW,CAACvmB,OAAS;AACnB,UAAIqI,MAAU,WAAW;AACvB,cAAM,EAAE,CAAChL,CAAK,GAAG6c,GAAG,GAAGwE,MAAS1e;AAChC,eAAO0e;AAAA,MACT;AACA,aAAO,EAAE,GAAG1e,IAAM,CAAC3C,CAAK,GAAGgL,EAAA;AAAA,IAC7B,CAAC;AAAA,EACH,GAAG,CAAA,CAAE,GAGCg6B,IAAgBxlC,EAAQ,MACrB,OAAO,KAAKsM,CAAO,EAAE,SAAS,IAAIA,IAAU,QAClD,CAACA,CAAO,CAAC,GAEN;AAAA,IACJ,MAAMm5B;AAAA,IACN,WAAAlgC;AAAA,IACA,SAAAgjB;AAAA,IACA,aAAAmd;AAAA,IACA,eAAAC;AAAA,IACA,oBAAAC;AAAA,EAAA,IACElC;AAAA,IACF53B;AAAA,IACAC;AAAA,IACAqF;AAAA,IACAnF;AAAA,IACAC;AAAA,IACA;AAAA;AAAA,IACA2kB,KAAmB;AAAA,IACnB2U;AAAA,EAAA,GAII,EAAE,MAAArwB,GAAM,MAAA2F,EAAA,IAAS9a,EAAQ,MAAM;AACnC,QAAI,EAACylC,KAAA,QAAAA,EAAc,OAAO,QAAO,EAAE,MAAM,CAAA,GAAiC,MAAM,OAAA;AAChF,UAAMjE,IAAqC,CAAA;AAC3C,QAAIqE;AACJ,eAAWnV,MAAQ+U,EAAa;AAE9B,UADAjE,EAAQ,KAAK,GAAG9Q,GAAK,IAAI,GACrBA,GAAK;AACP,YAAI,CAACmV;AACH,UAAAA,IAAa,EAAE,GAAGnV,GAAK,MAAA;AAAA;AAEvB,qBAAW,CAACoV,GAAWC,CAAO,KAAK,OAAO,QAAQrV,GAAK,KAAK;AAC1D,YAAAmV,EAAWC,CAAS,IAAI,EAAE,GAAGD,EAAWC,CAAS,GAAG,GAAGC,EAAA;AAK/D,WAAO,EAAE,MAAMvE,GAAS,MAAMqE,EAAA;AAAA,EAChC,GAAG,CAACJ,CAAY,CAAC,GAEXP,IAAkB/lC,EAAY,MAAM;AACxC,IAAAyG,EAAY,kBAAkB;AAAA,MAC5B,WAAW,CAACoH,MAAU;AACpB,cAAMC,IAAMD,EAAM;AAClB,eAAOC,EAAI,CAAC,MAAMrB,MAAuBqB,EAAI,CAAC,MAAMmE;AAAA,MACtD;AAAA,IAAA,CACD;AAAA,EACH,GAAG,CAACxL,GAAawL,CAAU,CAAC;AAE5B,2BACG,OAAA,EACC,UAAA;AAAA,IAAA,gBAAAnR;AAAA,MAAC+jC;AAAA,MAAA;AAAA,QACC,QAAA1iC;AAAA,QACA,YAAA2iC;AAAA,QACA,cAAA7O;AAAA,QACA,aAAAzE;AAAA,QACA,gBAAgByU;AAAA,QAChB,SAAA94B;AAAA,QACA,gBAAgBi5B;AAAA,QAChB,aAAa/jB,EAAI,OAAO;AAAA,MAAA;AAAA,IAAA;AAAA,IAE1B,gBAAAvhB;AAAA,MAACklC;AAAA,MAAA;AAAA,QACC,YAAA/zB;AAAA,QACA,QAAA9P;AAAA,QACA,UAAAyK;AAAA,QACA,YAAAE;AAAA,QACA,SAAAqlB;AAAA,QACA,UAAAwT;AAAA,QACA,KAAAtjB;AAAA,QACA,MAAArM;AAAA,QACA,MAAA2F;AAAA,QACA,WAAAvV;AAAA,QACA,SAAAgjB;AAAA,QACA,iBAAA2c;AAAA,MAAA;AAAA,IAAA;AAAA,IAEDQ,KACC,gBAAApiC;AAAA,MAACyE;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAM49B,EAAA;AAAA,QACf,UAAUC;AAAA,QAET,UAAA;AAAA,UAAAA,IACC,gBAAA3lC,EAACwoB,IAAA,EAAQ,WAAU,4BAAA,CAA4B,IAC7C;AAAA,UAAK;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAEX,GAEJ;AAEJ;AAkBA,SAAS0c,GAAqB;AAAA,EAC5B,YAAA/zB;AAAA,EACA,QAAA9P;AAAA,EACA,UAAAyK;AAAA,EACA,YAAAE;AAAA,EACA,SAAAqlB;AAAA,EACA,UAAAwT;AAAA,EACA,KAAAtjB;AAAA,EACA,MAAArM;AAAA,EACA,MAAA2F;AAAA,EACA,WAAAvV;AAAA,EACA,SAAAgjB;AAAA,EACA,iBAAA2c;AACF,GAAoB;AAElB,QAAMtE,IAAkB5gC,EAAQ,MACzB8kC,IACE,IAAI;AAAA,IACTxT,EAAQ,OAAO,CAAClE,MAAQ;AACtB,UAAIA,MAAQnhB,EAAY,QAAO;AAC/B,YAAMzL,IAAQc,EAAO,OAAO8rB,CAAG;AAE/B,aADI,GAAC5sB,KACDA,EAAM,QAAQA,EAAM;AAAA,IAE1B,CAAC;AAAA,EAAA,IARmB,oBAAI,IAAA,GAUzB,CAAC8wB,GAASrlB,GAAY3K,EAAO,QAAQwjC,CAAQ,CAAC,GAG3C,CAACkB,GAAYC,CAAa,IAAI/jC,EAAgD,IAAI,GAElF,CAACgkC,GAAWC,CAAY,IAAIjkC,EAA6C,CAAA,CAAE,GAC3EkkC,IAAeh5B,GAAO84B,CAAS;AACrC,EAAAE,EAAa,UAAUF;AACvB,QAAMG,IAAiBj5B,GAAsD,EAAE;AAG/E,EAAAC,GAAU,MAAM;AACd,UAAMi5B,IAASD,EAAe;AAC9B,WAAO,MAAM;AACX,iBAAWzoC,KAAK,OAAO,OAAO0oC,CAAM,gBAAgB1oC,CAAC;AAAA,IACvD;AAAA,EACF,GAAG,CAAA,CAAE;AAGL,QAAM,CAAC2oC,GAAUC,CAAW,IAAItkC,EAAyC,IAAI,GACvE,CAACukC,GAAaC,CAAc,IAAIxkC,EAAmB,CAAA,CAAE,GACrD,CAACykC,GAAaC,CAAc,IAAI1kC,EAAS,EAAK,GAG9C,CAAC2kC,GAAeC,CAAgB,IAAI5kC,EAAiE,IAAI,GACzG,CAAC6kC,GAAaC,CAAc,IAAI9kC,EAAsB,oBAAI,KAAK,GAG/D+kC,IAAW9nC;AAAA,IACf,OAAOigC,GAAeh0B,GAAiC87B,MAAoB;AACzE,MAAAf,EAAa,CAAChjC,OAAU;AAAA,QACtB,GAAGA;AAAA,QACH,CAACi8B,CAAK,GAAG,EAAE,GAAGj8B,EAAKi8B,CAAK,GAAG,QAAQ,IAAM,OAAO,OAAA;AAAA,MAAU,EAC1D;AACF,UAAI;AACF,cAAMzsB,GAAavB,GAAYguB,GAAOh0B,CAAM,GAC5C+6B,EAAa,CAAChjC,MAAS;AACrB,gBAAM+S,KAAU/S,EAAKi8B,CAAK;AAC1B,cAAI,CAAClpB,GAAS,QAAO/S;AAErB,cAAI+S,GAAQ,MAAMgxB;AAChB,mBAAO,EAAE,GAAG/jC,GAAM,CAACi8B,CAAK,GAAG,EAAE,GAAGlpB,IAAS,QAAQ,KAAM;AAGzD,gBAAM,EAAE,CAACkpB,CAAK,GAAG/hB,IAAG,GAAGwE,OAAS1e;AAChC,iBAAO0e;AAAA,QACT,CAAC,GACDqjB,EAAA;AAAA,MACF,SAAS/+B,GAAK;AACZ,cAAMic,KAAMjc,aAAe,QAAQA,EAAI,UAAU;AACjD,QAAAggC,EAAa,CAAChjC,QAAU;AAAA,UACtB,GAAGA;AAAA,UACH,CAACi8B,CAAK,GAAG,EAAE,GAAGj8B,GAAKi8B,CAAK,GAAG,QAAQ,IAAO,OAAOhd,GAAA;AAAA,QAAI,EACrD;AAAA,MACJ;AAAA,IACF;AAAA,IACA,CAAChR,GAAY8zB,CAAe;AAAA,EAAA,GAIxBpE,IAAmB3hC;AAAA,IACvB,CAACigC,GAAe3+B,GAAmB+K,MAAmB;AACpD,MAAA26B,EAAa,CAAChjC,MAAS;AACrB,cAAM+S,KAAU/S,EAAKi8B,CAAK,KAAK,EAAE,QAAQ,CAAA,GAAI,KAAK,GAAG,QAAQ,GAAA,GACvD+H,KAAUjxB,GAAQ,MAAM;AAC9B,eAAO;AAAA,UACL,GAAG/S;AAAA,UACH,CAACi8B,CAAK,GAAG;AAAA,YACP,GAAGlpB;AAAA,YACH,QAAQ,EAAE,GAAGA,GAAQ,QAAQ,CAACzV,CAAS,GAAG+K,EAAA;AAAA,YAC1C,KAAK27B;AAAA,UAAA;AAAA,QACP;AAAA,MAEJ,CAAC,GAEGd,EAAe,QAAQjH,CAAK,KAC9B,aAAaiH,EAAe,QAAQjH,CAAK,CAAC,GAE5CiH,EAAe,QAAQjH,CAAK,IAAI,WAAW,MAAM;AAC/C,cAAMlpB,IAAUkwB,EAAa,QAAQhH,CAAK;AAC1C,QAAIlpB,KAAW,OAAO,KAAKA,EAAQ,MAAM,EAAE,SAAS,KAClD+wB,EAAS7H,GAAO,EAAE,GAAGlpB,EAAQ,OAAA,GAAUA,EAAQ,GAAG;AAAA,MAEtD,GAAG,GAAG;AAAA,IACR;AAAA,IACA,CAAC+wB,CAAQ;AAAA,EAAA,GAILG,IAAmBjoC,EAAY,MAAM;AACzC,UAAMof,IAAiC,CAAA;AAEvC,IAAAA,EAAMtS,CAAU,IAAIF;AAEpB,eAAWqhB,KAAOkE,GAAS;AACzB,YAAM9wB,IAAQc,EAAO,OAAO8rB,CAAG;AAC/B,MAAK5sB,MACDA,EAAM,YAAY,SACpB+d,EAAM6O,CAAG,IAAI5sB,EAAM,UACVA,EAAM,SAAS,WACxB+d,EAAM6O,CAAG,IAAI;AAAA,IAEjB;AACA,IAAAoZ,EAAYjoB,CAAK,GACjBmoB,EAAe,CAAA,CAAE;AAAA,EACnB,GAAG,CAACz6B,GAAYF,GAAUulB,GAAShwB,EAAO,MAAM,CAAC,GAG3C+lC,KAAqBloC,EAAY,YAAY;AACjD,QAAI,CAAConC,EAAU;AAEf,UAAMe,IAAmB,CAAA;AACzB,eAAWla,KAAOkE,GAAS;AACzB,YAAM9wB,IAAQc,EAAO,OAAO8rB,CAAG;AAG/B,UAFI,CAAC5sB,KAAS,CAACA,EAAM,YACjBA,EAAM,QAAQA,EAAM,WACpB4sB,MAAQnhB,EAAY;AACxB,YAAM2O,IAAM2rB,EAASnZ,CAAG;AACxB,OAAIxS,KAAO,QAAQA,MAAQ,OACzB0sB,EAAO,KAAKla,CAAG;AAAA,IAEnB;AACA,QAAIka,EAAO,SAAS,GAAG;AACrB,MAAAZ,EAAeY,CAAM;AACrB;AAAA,IACF;AACA,IAAAV,EAAe,EAAI;AACnB,QAAI;AACF,YAAMn0B,GAAarB,GAAYm1B,CAAQ,GACvCC,EAAY,IAAI,GAChBE,EAAe,CAAA,CAAE,GACjBxB,EAAA;AAAA,IACF,SAAS/+B,GAAK;AACZ,YAAMic,IAAMjc,aAAe,QAAQA,EAAI,UAAU;AACjD,MAAAugC,EAAe,CAAC,UAAUtkB,CAAG,EAAE,CAAC;AAAA,IAClC,UAAA;AACE,MAAAwkB,EAAe,EAAK;AAAA,IACtB;AAAA,EACF,GAAG,CAACL,GAAUjV,GAAShwB,EAAO,QAAQ2K,GAAYmF,GAAY8zB,CAAe,CAAC,GAGxE/D,IAAkBhiC;AAAA,IACtB,OAAOigC,MAAkB;AACvB,MAAA0H,EAAiB,IAAI,GACrBE,EAAe,CAAC7jC,MAAS,IAAI,IAAIA,CAAI,EAAE,IAAIi8B,CAAK,CAAC;AACjD,UAAI;AACF,cAAMvsB,GAAazB,GAAYguB,CAAK,GACpC8F,EAAA;AAAA,MACF,QAAQ;AAAA,MAER,UAAA;AACE,QAAA8B,EAAe,CAAC7jC,MAAS;AACvB,gBAAMqH,IAAO,IAAI,IAAIrH,CAAI;AACzB,iBAAAqH,EAAK,OAAO40B,CAAK,GACV50B;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,CAAC4G,GAAY8zB,CAAe;AAAA,EAAA;AAG9B,MAAI3c;AACF,WAAO,gBAAAtoB,EAAC,OAAA,EAAI,WAAU,0CAAyC,UAAA,mBAAe;AAGhF,MAAIsF;AACF,WACE,gBAAAjC,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,MAAA,gBAAArD,EAACkf,IAAA,EAAS,WAAU,aAAA,CAAa;AAAA,MACjC,gBAAAlf,EAACkf,IAAA,EAAS,WAAU,aAAA,CAAa;AAAA,IAAA,GACnC;AAIJ,QAAMooB,IAAYpyB,EAAK,WAAW,KAAK,CAACoxB;AAExC,2BACG,OAAA,EACE,UAAA;AAAA,IAAAgB,KAAa,CAACzC,KACb,gBAAA7kC,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA,mBAE7D;AAAA,KAEA,CAACsnC,KAAazC,MACd,gBAAA7kC,EAAC,OAAA,EAAI,WAAU,mBACb,UAAA,gBAAAqD,EAAC,SAAA,EAAM,WAAU,kBACf,UAAA;AAAA,MAAA,gBAAArD,EAAC,SAAA,EACC,UAAA,gBAAAqD,EAAC,MAAA,EAAG,WAAU,YACX,UAAA;AAAA,QAAAguB,EAAQ,IAAI,CAAClE,MAAQ;AACpB,gBAAM5sB,IAAQc,EAAO,OAAO8rB,CAAG;AAC/B,iBACE,gBAAAntB;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,WAAU;AAAA,cAET,cAAQM,GAAiBC,GAAO4sB,GAAK5L,EAAI,OAAO,QAAQ,IAAI4L;AAAA,YAAA;AAAA,YAHxDA;AAAA,UAAA;AAAA,QAMX,CAAC;AAAA,QACA0X,KAAY,gBAAA7kC,EAAC,MAAA,EAAG,WAAU,gBAAA,CAAgB;AAAA,MAAA,EAAA,CAC7C,EAAA,CACF;AAAA,wBACC,SAAA,EACE,UAAA;AAAA,QAAAkV,EAAK,IAAI,CAACyN,MAAQ;AACjB,gBAAMwc,IAAQ,OAAQxc,EAAgC,MAAS,EAAE,GAC3D4kB,IAAaT,EAAY,IAAI3H,CAAK,GAClCqI,IAAWvB,EAAU9G,CAAK;AAChC,iBACE,gBAAAn/B;AAAA,YAACynC;AAAA,YAAA;AAAA,cAEC,OAAAtI;AAAA,cACA,KAAAxc;AAAA,cACA,QAAAthB;AAAA,cACA,SAAAgwB;AAAA,cACA,iBAAAsP;AAAA,cACA,UAAAkE;AAAA,cACA,YAAA0C;AAAA,cACA,YAAAxB;AAAA,cACA,eAAAC;AAAA,cACA,UAAAwB;AAAA,cACA,cAAc3G;AAAA,cACd,eAAe,CAACjjC,OAAO;;AACrB,sBAAMmd,MAAepa,KAAAU,EAAO,YAAP,gBAAAV,GAAgB,eAC/B+V,KAAQqE,KAAe,OAAO4H,EAAI5H,EAAY,KAAK,EAAE,IAAI;AAC/D,gBAAA8rB,EAAiB,EAAE,MAAM,IAAM,OAAOjpC,IAAI,OAAA8Y,IAAO;AAAA,cACnD;AAAA,cACA,MAAAmE;AAAA,YAAA;AAAA,YAjBKskB;AAAA,UAAA;AAAA,QAoBX,CAAC;AAAA,QACAmH,KACC,gBAAAtmC;AAAA,UAAC0nC;AAAA,UAAA;AAAA,YACC,UAAApB;AAAA,YACA,QAAAjlC;AAAA,YACA,SAAAgwB;AAAA,YACA,iBAAAsP;AAAA,YACA,YAAA30B;AAAA,YACA,aAAAw6B;AAAA,YACA,aAAAE;AAAA,YACA,UAAU,CAACnmC,GAAOgL,MAChBg7B,EAAY,CAACrjC,MAAUA,KAAO,EAAE,GAAGA,GAAM,CAAC3C,CAAK,GAAGgL,EAAA,CAAe;AAAA,YAEnE,WAAW67B;AAAA,YACX,UAAU,MAAM;AACd,cAAAb,EAAY,IAAI,GAChBE,EAAe,CAAA,CAAE;AAAA,YACnB;AAAA,YACA,MAAA5rB;AAAA,UAAA;AAAA,QAAA;AAAA,MACF,EAAA,CAEJ;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,IAEDgqB,KACC,gBAAAxhC;AAAA,MAACyE;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAASq/B;AAAA,QACT,UAAU,CAAC,CAACb;AAAA,QAEZ,UAAA;AAAA,UAAA,gBAAAtmC,EAACsd,IAAA,EAAK,WAAU,eAAA,CAAe;AAAA,UAAE;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAIpCspB,KACC,gBAAA5mC;AAAA,MAACkgB;AAAA,MAAA;AAAA,QACC,MAAM0mB,EAAc;AAAA,QACpB,cAAc,CAACzmB,MAAS,CAACA,KAAQ0mB,EAAiB,IAAI;AAAA,QACtD,OAAM;AAAA,QACN,aACED,EAAc,QACV,oCAAoCA,EAAc,KAAK,OACvD;AAAA,QAEN,cAAa;AAAA,QACb,WAAW,MAAM1F,EAAgB0F,EAAc,KAAK;AAAA,QACpD,aAAW;AAAA,MAAA;AAAA,IAAA;AAAA,EACb,GAEJ;AAEJ;AAmBA,SAASa,GAAc;AAAA,EACrB,OAAAtI;AAAA,EACA,KAAAxc;AAAA,EACA,QAAAthB;AAAA,EACA,SAAAgwB;AAAA,EACA,iBAAAsP;AAAA,EACA,UAAAkE;AAAA,EACA,YAAA0C;AAAA,EACA,YAAAxB;AAAA,EACA,eAAAC;AAAA,EACA,UAAAwB;AAAA,EACA,cAAAxE;AAAA,EACA,eAAA2E;AAAA,EACA,MAAA9sB;AACF,GAAuB;AAErB,QAAM+sB,IAAa7nC,EAAQ,MACrB,CAACynC,KAAY,OAAO,KAAKA,EAAS,MAAM,EAAE,WAAW,IAAU7kB,IAC5D,EAAE,GAAGA,GAAK,GAAG6kB,EAAS,OAAA,GAC5B,CAAC7kB,GAAK6kB,CAAQ,CAAC;AAElB,SACE,gBAAAnkC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,qDAAqDkkC,IAAa,eAAe,EAAE;AAAA,MAE7F,UAAA;AAAA,QAAAlW,EAAQ,IAAI,CAAClE,MAAQ;AACpB,gBAAM5sB,IAAQc,EAAO,OAAO8rB,CAAG,GACzBiW,IAAazC,EAAgB,IAAIxT,CAAG;AAG1C,kBAFiB4Y,KAAA,gBAAAA,EAAY,WAAU5G,MAAS4G,KAAA,gBAAAA,EAAY,SAAQ5Y,KAEpDiW,IAEZ,gBAAApjC;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,WAAU;AAAA,cAET,cACG8c,GAAY;AAAA,gBACV,OAAAvc;AAAA,gBACA,WAAW4sB;AAAA,gBACX,OAAOya,EAAWza,CAAG;AAAA,gBACrB,MAAM;AAAA,gBACN,UAAU,CAACxS,MAAQqoB,EAAa7D,GAAOhS,GAAKxS,CAAG;AAAA,gBAC/C,QAAQitB;AAAA,gBACR,MAAA/sB;AAAA,cAAA,CACD,IACD,OAAO+sB,EAAWza,CAAG,KAAK,EAAE;AAAA,YAAA;AAAA,YAb3BA;AAAA,UAAA,IAmBT,gBAAAntB;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,WAAW,0BAA0BojC,IAAa,mBAAmB,EAAE;AAAA,cACvE,SACEA,KAAc,CAACmE,IACX,MAAMvB,EAAc,EAAE,OAAA7G,GAAO,KAAAhS,EAAA,CAAK,IAClC;AAAA,cAGL,cACGrQ,GAAY;AAAA,gBACV,OAAAvc;AAAA,gBACA,WAAW4sB;AAAA,gBACX,OAAOya,EAAWza,CAAG;AAAA,gBACrB,MAAM;AAAA,gBACN,QAAQya;AAAA,gBACR,MAAA/sB;AAAA,cAAA,CACD,IACD,OAAO+sB,EAAWza,CAAG,KAAK,EAAE;AAAA,YAAA;AAAA,YAjB3BA;AAAA,UAAA;AAAA,QAoBX,CAAC;AAAA,QACA0X,uBACE,MAAA,EAAG,WAAU,0BACZ,UAAA,gBAAAxhC,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,WAAAmkC,KAAA,gBAAAA,EAAU,WACT,gBAAAxnC,EAACwoB,IAAA,EAAQ,WAAU,uDAAsD;AAAA,WAE1Egf,KAAA,gBAAAA,EAAU,UACT,gBAAAxnC,EAAC,QAAA,EAAK,WAAU,qCAAoC,OAAOwnC,EAAS,OAAO,UAAA,IAAA,CAAC;AAAA,UAE9E,gBAAAxnC;AAAA,YAAC8H;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAM6/B,EAAcxI,CAAK;AAAA,cAClC,UAAUoI;AAAA,cACV,OAAM;AAAA,cAEN,UAAA,gBAAAvnC,EAACqd,IAAA,EAAO,WAAU,UAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QAC9B,EAAA,CACF,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR;AAiBA,SAASqqB,GAAS;AAAA,EAChB,UAAApB;AAAA,EACA,QAAAjlC;AAAA,EACA,SAAAgwB;AAAA,EACA,iBAAAsP;AAAA,EACA,YAAA30B;AAAA,EACA,aAAAw6B;AAAA,EACA,aAAAE;AAAA,EACA,UAAAjyB;AAAA,EACA,WAAA6L;AAAA,EACA,UAAAgM;AAAA,EACA,MAAAzR;AACF,GAAkB;AAChB,QAAMgtB,IAAWrB,EAAY,KAAK,CAACh9B,MAAMA,EAAE,WAAW,SAAS,CAAC,GAC1Ds+B,IAAc,IAAI,IAAItB,EAAY,OAAO,CAACh9B,MAAM,CAACA,EAAE,WAAW,SAAS,CAAC,CAAC;AAE/E,SACE,gBAAAnG,EAAC,MAAA,EAAG,WAAU,6DACX,UAAA;AAAA,IAAAguB,EAAQ,IAAI,CAAClE,MAAQ;AACpB,YAAM5sB,IAAQc,EAAO,OAAO8rB,CAAG,GACzBiW,IAAazC,EAAgB,IAAIxT,CAAG,KAAKA,MAAQnhB,GACjD+1B,IAAW+F,EAAY,IAAI3a,CAAG;AAEpC,aAAKiW,IASH,gBAAApjC;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,WAAW,0BAA0B+hC,IAAW,wDAAwD,EAAE;AAAA,UAC1G,OAAOA,IAAW,GAAG5U,CAAG,iBAAiB;AAAA,UAExC,cACGrQ,GAAY;AAAA,YACV,OAAAvc;AAAA,YACA,WAAW4sB;AAAA,YACX,OAAOmZ,EAASnZ,CAAG;AAAA,YACnB,MAAM;AAAA,YACN,UAAU,CAACxS,MAAQlG,EAAS0Y,GAAKxS,CAAG;AAAA,YACpC,QAAQ2rB;AAAA,YACR,MAAAzrB;AAAA,UAAA,CACD,IACD,OAAOyrB,EAASnZ,CAAG,KAAK,EAAE;AAAA,QAAA;AAAA,QAdzBA;AAAA,MAAA,IARL,gBAAAntB,EAAC,MAAA,EAAa,WAAU,yDACrB,UAAAO,KAAA,QAAAA,EAAO,OAAO,MAAM,OAAO+lC,EAASnZ,CAAG,KAAK,EAAE,KADxCA,CAET;AAAA,IAuBN,CAAC;AAAA,sBACA,MAAA,EAAG,WAAU,0BACZ,UAAA,gBAAA9pB,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,MAAAwkC,KACC,gBAAA7nC,EAAC,UAAK,WAAU,qCAAoC,OAAO6nC,EAAS,MAAM,CAAC,GAAG,UAAA,IAAA,CAAC;AAAA,MAEjF,gBAAA7nC;AAAA,QAAC8H;AAAA,QAAA;AAAA,UACC,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAASwY;AAAA,UACT,UAAUomB;AAAA,UACV,OAAM;AAAA,UAEL,UAAAA,sBAAele,IAAA,EAAQ,WAAU,wBAAuB,IAAK,gBAAAxoB,EAACuH,IAAA,EAAM,WAAU,UAAA,CAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAE3F,gBAAAvH;AAAA,QAAC8H;AAAA,QAAA;AAAA,UACC,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAASwkB;AAAA,UACT,UAAUoa;AAAA,UACV,OAAM;AAAA,UAEN,UAAA,gBAAA1mC,EAACyJ,IAAA,EAAE,WAAU,UAAA,CAAU;AAAA,QAAA;AAAA,MAAA;AAAA,IACzB,EAAA,CACF,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;ACv1BO,SAASs+B,GAAY,EAAE,QAAAvmC,GAAQ,KAAA+f,KAAyB;AAC7D,QAAM,EAAE,QAAAlgB,GAAQ,YAAA8P,GAAY,QAAA5P,GAAQ,MAAAiT,GAAM,eAAAwzB,GAAe,QAAA1lC,MAAWif,GAC9D8P,IAAU9P,EAAI,WAAW,GAGzB0mB,IAAa5W,MAAY,KAAK7vB,EAAO,WAAW;AAEtD,SACE,gBAAAxB,EAAC,SAAI,WAAW9E;AAAA,IACd;AAAA,IACAm2B,MAAY,IAAI,gBAAgB;AAAA,EAAA,GAE/B,UAAA7vB,EAAO,IAAI,CAAC0mC,MAAgB;AAC3B,UAAM1nC,IAAY0nC,EAAY,MACxB3nC,IAAQc,EAAO,OAAOb,CAAS;AACrC,QAAI,CAACD,EAAO,QAAO;AACnB,UAAMgL,IAAQhK,EAAOf,CAAS,GACxB2nC,IAAa3zB,MAAS,aAAa0zB,EAAY,WAAWA,EAAY,QAAQ,SAAS;AAC7F,WACE,gBAAA7kC;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAWguB,MAAY,IAAI,wBAAwB;AAAA,QAElD,UAAA;AAAA,UAAA,CAAC4W,KACA,gBAAAjoC,EAAC,OAAA,EAAI,WAAW9E;AAAA,YACd;AAAA,YACAm2B,MAAY,KAAK;AAAA,UAAA,GAEhB,UAAA/wB,GAAiBC,GAAOC,GAAW8B,EAAO,QAAQ,GACrD;AAAA,4BAED,OAAA,EAAI,WAAU,kBACb,UAAA,gBAAAe,EAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,YAAA,gBAAArD,EAAC,OAAA,EAAI,WAAU,kBACZ,UAAA8c,GAAY;AAAA,cACX,OAAAvc;AAAA,cACA,WAAAC;AAAA,cACA,OAAA+K;AAAA,cACA,MAAAiJ;AAAA,cACA,UAAUwzB,IACN,CAAC71B,MAAe61B,EAAcxnC,GAAW2R,CAAC,IAC1C;AAAA,cACJ,QAAA5Q;AAAA,cACA,MAAMggB,EAAI;AAAA,YAAA,CACX,GACH;AAAA,YACC4mB,KACC,gBAAAnoC,EAAC,OAAA,EAAI,WAAU,oCACZ,YAAY,QAAS,IAAI,CAAC8R,GAAQvF,MACjC,gBAAAvM;AAAA,cAACimB;AAAA,cAAA;AAAA,gBAEC,YAAY,GAAGzlB,CAAS,WAAW+L,CAAC;AAAA,gBACpC,QAAAuF;AAAA,gBACA,YAAAX;AAAA,gBACA,KAAK5P;AAAA,gBACL,SAAQ;AAAA,gBACR,MAAK;AAAA,cAAA;AAAA,cANAgL;AAAA,YAAA,CAQR,EAAA,CACH;AAAA,UAAA,EAAA,CAEJ,EAAA,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,MA1CK/L;AAAA,IAAA;AAAA,EA6CX,CAAC,EAAA,CACH;AAEJ;AC1EA,MAAM4nC,KAAiB,oBAAI,IAAI,CAAC,UAAU,QAAQ,OAAO,SAAS,WAAW,SAAS,KAAK,CAAC,GACtFC,KAAc;AAGb,SAASC,GAAgB,EAAE,MAAAvlC,GAAM,KAAAwe,KAA6B;AACnE,QAAM,EAAE,QAAAlgB,GAAQ,kBAAAknC,GAAkB,eAAAC,GAAe,OAAAC,GAAO,MAAAj0B,GAAM,MAAAqG,MAAS0G,GACjEmnB,IAAernC,EAAO,cAAc,CAAA;AAM1C,MAAIonC,EAAO,QAAO;AAGlB,QAAME,IAA0B5lC,EAAK,eAAe,KAAO,KAAQA,EAAK,YAGlEqgB,IAA4DulB,MAAW,KACzE,OAAO,QAAQD,CAAY,EAAE,KAAK,CAAC,CAACt3B,CAAC,GAAG,CAACC,CAAC,MAAMD,EAAE,cAAcC,CAAC,CAAC,IACjEs3B,EACE,OAAO,CAACltC,MAASitC,EAAajtC,CAAI,KAAK,IAAI,EAC3C,IAAI,CAACA,MAAS,CAACA,GAAMitC,EAAajtC,CAAI,CAAC,CAAC;AAE/C,SAAI2nB,EAAQ,WAAW,IAAU,OAG/B,gBAAApjB,EAAC,OAAA,EAAI,WAAU,mDACZ,UAAAojB,EAAQ,IAAI,CAAC,CAACuO,GAAU1wB,CAAI,MAAM;AACjC,UAAM2nC,IAAUL,KAAA,gBAAAA,EAAkB,KAAK,CAACnY,MAAMA,EAAE,kBAAkBuB,IAC5DpxB,IAAQS,GAAgBC,CAAI,GAI5B4nC,IAAiB5nC,EAAK,YAAY,CAACunC,IAAiB,YAAYh0B;AAEtE,WACE,gBAAAxU;AAAA,MAAC8oC;AAAA,MAAA;AAAA,QAEC,UAAAnX;AAAA,QACA,MAAA1wB;AAAA,QACA,OAAAV;AAAA,QACA,OAAOqoC,KAAA,gBAAAA,EAAS;AAAA,QAChB,MAAMC;AAAA,QACN,eAAAL;AAAA,QACA,MAAA3tB;AAAA,MAAA;AAAA,MAPK8W;AAAA,IAAA;AAAA,EAUX,CAAC,EAAA,CACH;AAEJ;AAKA,SAASmX,GAAkB;AAAA,EACzB,UAAAnX;AAAA,EACA,MAAA1wB;AAAA,EACA,OAAAV;AAAA,EACA,OAAAgL;AAAA,EACA,MAAAiJ;AAAA,EACA,eAAAg0B;AAAA,EACA,MAAA3tB;AACF,GAQG;;AACD,QAAMkuB,IAAW57B,GAA6C,IAAI;AAElE,EAAAC,GAAU,MACD,MAAM;AACX,IAAI27B,EAAS,WAAS,aAAaA,EAAS,OAAO;AAAA,EACrD,GACC,CAAA,CAAE;AAEL,QAAMt0B,IAAWvV;AAAA,IACf,CAACiT,MAAe;AACd,MAAKq2B,MACDJ,GAAe,IAAInnC,EAAK,IAAI,KAC1B8nC,EAAS,WAAS,aAAaA,EAAS,OAAO,GACnDA,EAAS,UAAU,WAAW,MAAMP,EAAc7W,GAAUxf,CAAC,GAAGk2B,EAAW,KAE3EG,EAAc7W,GAAUxf,CAAC;AAAA,IAE7B;AAAA,IACA,CAACwf,GAAU1wB,EAAK,MAAMunC,CAAa;AAAA,EAAA;AAGrC,SACE,gBAAAnlC,EAAC,OAAA,EAAI,WAAU,mCACb,UAAA;AAAA,IAAA,gBAAArD,EAAC,OAAA,EAAI,WAAU,4DACZ,UAAAG,IAAIQ,IAAAM,EAAK,YAAL,gBAAAN,EAAc,SAAQM,EAAK,IAAI,EAAA,CACtC;AAAA,IACA,gBAAAjB,EAAC,OAAA,EAAI,WAAU,kBACZ,UAAA8c,GAAY;AAAA,MACX,OAAAvc;AAAA,MACA,WAAWoxB;AAAA,MACX,OAAApmB;AAAA,MACA,MAAAiJ;AAAA,MACA,UAAUA,MAAS,SAASC,IAAW;AAAA,MACvC,MAAAoG;AAAA,IAAA,CACD,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;ACrGO,SAASmuB,GAAoB;AAAA,EAClC,cAAA7lB;AAAA,EACA,gBAAA8lB;AAAA,EACA,aAAAC;AAAA,EACA,WAAArlB;AAAA,EACA,MAAArP,IAAO;AACT,GAA6B;AAC3B,SACE,gBAAAxU,EAAC,OAAA,EAAI,WAAU,qCACZ,UAAA,OAAO,QAAQmjB,CAAY,EAAE,IAAI,CAAC,CAACgmB,GAAQC,CAAE,MAAM;AAClD,UAAMnzB,IAAUgzB,KAAA,gBAAAA,EAAgB,KAAK,CAACnrC,MAAMA,EAAE,eAAeqrC,IACvDE,IAAcpzB,KAAA,gBAAAA,EAAS,aACvBqzB,IAAgBD,IAAcD,EAAG,SAAS,KAAK,CAACtrC,MAAMA,EAAE,SAASurC,CAAW,IAAI;AAGtF,QAAI70B,MAAS;AACX,aACE,gBAAAnR,EAAC,OAAA,EAAiB,WAAU,2BAC1B,UAAA;AAAA,QAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,0CAA0C,UAAA;AAAA,UAAAlD,EAAIipC,EAAG,IAAI;AAAA,UAAE;AAAA,QAAA,GAAC;AAAA,QACvEE,IACC,gBAAAtpC;AAAA,UAACyQ;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,iBAAiB64B,EAAc,SAAS;AAAA,cACxC,OAAOA,EAAc,QAAQ,SAAS;AAAA,YAAA;AAAA,YAGvC,UAAAnpC,EAAImpC,EAAc,IAAI;AAAA,UAAA;AAAA,QAAA,IAGzB,gBAAAtpC,EAAC,QAAA,EAAK,WAAU,0CAAyC,UAAA,IAAA,CAAC;AAAA,MAAA,EAAA,GAbpDmpC,CAeV;AAKJ,UAAMI,IAAYH,EAAG,eAAeC,IAChCD,EAAG,SAAS;AAAA,MACV,CAACtrC,MAAA;;AACC,eAAAA,EAAE,SAASurC,QACV1oC,IAAAyoC,EAAG,YAAaC,CAAW,MAA3B,gBAAA1oC,EAA8B,SAAS7C,EAAE,UAAS;AAAA;AAAA,IAAA,IAEvDsrC,EAAG;AAEP,WACE,gBAAA/lC,EAAC,OAAA,EAAiB,WAAU,2BAC1B,UAAA;AAAA,MAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,0CAA0C,UAAA;AAAA,QAAAlD,EAAIipC,EAAG,IAAI;AAAA,QAAE;AAAA,MAAA,GAAC;AAAA,MACxE,gBAAA/lC;AAAA,QAAC8R;AAAA,QAAA;AAAA,UACC,OAAOk0B,KAAe;AAAA,UACtB,eAAe,CAACG,MAAeN,EAAYC,GAAQK,CAAU;AAAA,UAC7D,UAAU3lB;AAAA,UAEV,UAAA;AAAA,YAAA,gBAAA7jB,EAACsV,IAAA,EAAc,WAAU,aACvB,UAAA,gBAAAtV,EAACqV,MACE,UAAAi0B,IACC,gBAAAtpC;AAAA,cAACyQ;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,iBAAiB64B,EAAc,SAAS;AAAA,kBACxC,OAAOA,EAAc,QAAQ,SAAS;AAAA,gBAAA;AAAA,gBAGvC,UAAAnpC,EAAImpC,EAAc,IAAI;AAAA,cAAA;AAAA,YAAA,IAGzB,aAEJ,GACF;AAAA,YACA,gBAAAtpC,EAAC0V,IAAA,EACE,UAAA6zB,EAAU,IAAI,CAACzrC,MACd,gBAAAkC,EAAC4V,IAAA,EAAwB,OAAO9X,EAAE,MAChC,UAAA,gBAAAuF,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,cAAAvF,EAAE,SACD,gBAAAkC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO,EAAE,iBAAiBlC,EAAE,MAAA;AAAA,gBAAM;AAAA,cAAA;AAAA,cAGrCqC,EAAIrC,EAAE,IAAI;AAAA,YAAA,EAAA,CACb,EAAA,GATeA,EAAE,IAUnB,CACD,EAAA,CACH;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACF,EAAA,GAvCQqrC,CAwCV;AAAA,EAEJ,CAAC,EAAA,CACH;AAEJ;AC7GA,MAAMM,KAAO,MAAM;AAAC;AASb,SAASC,GAAc,EAAE,MAAA3mC,GAAM,KAAAwe,KAA2B;AAC/D,QAAM,EAAE,QAAAlgB,GAAQ,gBAAA4nC,GAAgB,aAAAC,GAAa,iBAAAS,GAAiB,OAAAlB,MAAUlnB,GAClE4B,IAAe9hB,EAAO,iBAAiB,CAAA;AAE7C,MAAIonC,EAAO,QAAO;AAGlB,QAAME,IAA0B5lC,EAAK,aAAa,KAAO,KAAQA,EAAK,UAEhEypB,IAAW,OAAO;AAAA,IACtB,OAAO,QAAQrJ,CAAY,EAAE;AAAA,MAC3B,CAAC,CAAC1nB,CAAI,MAAMktC,MAAW,MAASA,EAAoB,SAASltC,CAAI;AAAA,IAAA;AAAA,EACnE;AAGF,SAAI,OAAO,KAAK+wB,CAAQ,EAAE,WAAW,IAAU,OAG7C,gBAAAxsB;AAAA,IAACgpC;AAAA,IAAA;AAAA,MACC,cAAcxc;AAAA,MACd,gBAAAyc;AAAA,MACA,aAAaC,KAAeO;AAAAA,MAC5B,WAAWE,KAAmB;AAAA,MAC9B,MAAMpoB,EAAI;AAAA,IAAA;AAAA,EAAA;AAGhB;ACoBO,SAASoY,GAAe,EAAE,OAAAn3B,GAAO,KAAA+e,KAA4B;AAClE,SACE,gBAAAvhB,EAAAyI,IAAA,EACG,UAAAjG,EAAM,IAAI,CAACO,GAAMwJ,MAChB,gBAAAvM,EAAC44B,IAAA,EAA2B,MAAA71B,GAAY,KAAAwe,EAAA,GAAfhV,CAAyB,CACnD,GACH;AAEJ;AAQO,SAASqsB,GAAmB,EAAE,MAAA71B,GAAM,KAAAwe,KAAgC;AAEzE,SAAIxe,EAAK,MACA,gBAAA/C,EAAC+2B,IAAA,EAAU,QAAQh0B,EAAK,KAAK,KAAAwe,GAAU,IAE5Cxe,EAAK,2BACCm2B,IAAA,EAAa,QAAQn2B,EAAK,QAAQ,MAAAA,GAAY,KAAAwe,GAAU,IAE9Dxe,EAAK,OACA,gBAAA/C,EAACu5B,IAAA,EAAW,QAAQx2B,EAAK,MAAM,KAAAwe,GAAU,IAE9Cxe,EAAK,UACA,gBAAA/C,EAACw5B,IAAA,EAAa,QAAQz2B,EAAK,SAAS,KAAAwe,GAAU,IAEnDxe,EAAK,WACA,gBAAA/C,EAACqjC,IAAA,EAAc,MAAAtgC,GAAY,KAAAwe,EAAA,CAAU,IAE1Cxe,EAAK,aACA,gBAAA/C,EAAC0kC,IAAA,EAAgB,MAAA3hC,GAAY,KAAAwe,EAAA,CAAU,IAE5Cxe,EAAK,SACA,gBAAA/C,EAAC+nC,IAAA,EAAY,QAAQhlC,EAAK,QAAQ,KAAAwe,GAAU,IAEjDxe,EAAK,cAAc,OACd,gBAAA/C,EAACsoC,IAAA,EAAgB,MAAAvlC,GAAY,KAAAwe,EAAA,CAAU,IAE5Cxe,EAAK,YAAY,OACZ,gBAAA/C,EAAC0pC,IAAA,EAAc,MAAA3mC,GAAY,KAAAwe,EAAA,CAAU,IAGvC;AACT;ACrGA,SAASqoB,GAAgB79B,GAAmBzJ,GAA6B;AACvE,QAAMunC,wBAAU,IAAA;AAChB,aAAWxoC,KAAU,OAAO,OAAOiB,EAAO,QAAQ;AAChD,QAAKjB,EAAO;AACZ,iBAAWyoC,KAAOzoC,EAAO;AACvB,YAAIyoC,EAAI,WAAW/9B,KAAa+9B,EAAI,aAAa;AAC/C,gBAAM39B,IAAQ,MAAM,QAAQ29B,EAAI,WAAW,IAAIA,EAAI,cAAc,CAACA,EAAI,WAAW;AACjF,qBAAWx9B,KAAMH;AACf,YAAA09B,EAAI,IAAIv9B,CAAE;AAAA,QAEd;AAAA;AAGJ,SAAOu9B;AACT;AAMO,SAASE,GACdC,GACA1nC,GAC0C;AAC1C,MAAI,CAAC0nC,KAAmB,CAAC1nC,UAAe,CAAA;AAExC,QAAM+kC,IAAmD,CAAA;AAEzD,aAAW,CAACt7B,GAAWmJ,CAAI,KAAK,OAAO,QAAQ80B,CAAe,GAAG;AAC/D,UAAM3Q,IAAc/2B,EAAO,SAASyJ,CAAS;AAC7C,QAAI,CAACstB,EAAa;AAGlB,UAAM4Q,IAAWL,GAAgB79B,GAAWzJ,CAAM,GAG5Cs5B,IAA2B,CAAA;AACjC,eAAW,CAACp7B,GAAWD,CAAK,KAAK,OAAO,QAAQ84B,EAAY,MAAM;AAChE,MAAI94B,EAAM,YAAY,CAACA,EAAM,QAAQ,CAACA,EAAM,WAAW,CAAC0pC,EAAS,IAAIzpC,CAAS,KAC5Eo7B,EAAe,KAAKp7B,CAAS;AAGjC,QAAIo7B,EAAe,WAAW;AAE9B,iBAAWjZ,KAAOzN,GAAM;AACtB,YAAIyN,EAAI,SAAU;AAElB,cAAMunB,IAA0B,CAAA;AAChC,mBAAW1pC,KAAao7B,GAAgB;AACtC,gBAAMjhB,IAAMgI,EAAIniB,CAAS;AACzB,WAAIma,KAAO,QAAQA,MAAQ,OACzBuvB,EAAc,KAAK1pC,CAAS;AAAA,QAEhC;AACA,QAAI0pC,EAAc,SAAS,MACpB7C,EAAOt7B,CAAS,MAAGs7B,EAAOt7B,CAAS,IAAI,CAAA,IAC5Cs7B,EAAOt7B,CAAS,EAAE4W,EAAI,IAAI,IAAIunB;AAAA,MAElC;AAAA,EACF;AAEA,SAAO7C;AACT;AC5CA,MAAMoC,KAAO,MAAM;AAAC;AAGpB,SAASU,GAAY/4B,GAA8BC,GAAuC;AACxF,SAAID,EAAE,WAAWC,EAAE,SAAe,KAC3B,KAAK,UAAUD,CAAC,MAAM,KAAK,UAAUC,CAAC;AAC/C;AAMO,SAAS+4B,GAAgB,EAAE,YAAA3b,KAAoC;;AACpE,QAAM,EAAE,IAAI4b,EAAA,IAAUC,GAAA,GAChBzrC,IAAWC,GAAA,GACX,CAACkQ,GAAcua,CAAe,IAAIta,GAAA,GAClC,EAAE,MAAM3M,EAAA,IAAWpF,GAAA,GACnBqtC,IAAWxlC,GAAa,CAACjH,MAAMA,EAAE,IAAI,GAErCyF,IAASjB,KAAA,gBAAAA,EAAQ,QAAQmsB,IACzBptB,IAASkC,KAAA,QAAAA,EAAQ,SAASjB,KAAA,gBAAAA,EAAQ,SAASiB,EAAO,UAAU,QAC5D4N,IAAa5N,KAAA,gBAAAA,EAAQ,QAGrBinC,KAASjnC,KAAA,gBAAAA,EAAQ,UAAS,IAC1B3F,IAAK4sC,IAASD,KAAA,gBAAAA,EAAU,KAAKF,GAE7B5B,IAAQ,CAAC+B,KAAU5sC,MAAO,OAG1BgE,IAA0C7B,EAAQ,MAAM;AAC5D,QAAI,CAACnC,KAAM6qC,EAAO;AAClB,QAAI,CAACpnC,EAAQ,QAAOzD;AACpB,UAAM+U,IAAWvR,GAAoBC,CAAM;AAC3C,QAAIsR,EAAS,WAAW;AACtB,aAAO,EAAE,CAACA,EAAS,CAAC,CAAC,GAAG/U,EAAA;AAG1B,UAAM8jB,IAAQ9jB,EAAG,MAAM,GAAG,GACpB6D,IAAmB,CAAA;AACzB,aAAS8K,KAAI,GAAGA,KAAIoG,EAAS,QAAQpG;AACnC,MAAA9K,EAAOkR,EAASpG,EAAC,CAAC,IAAImV,EAAMnV,EAAC,KAAK;AAEpC,WAAO9K;AAAA,EACT,GAAG,CAAC7D,GAAI6qC,GAAOpnC,CAAM,CAAC,GAEhBopC,IAAa1qC,EAAQ,MAAM;AAC/B,QAAK6B;AACL,aAAI,OAAOA,KAAa,WAAiBA,IAClCD,GAAaC,CAAQ;AAAA,EAC9B,GAAG,CAACA,CAAQ,CAAC,GAEP,EAAE,MAAM8oC,GAAc,WAAAplC,MAAciwB,GAAcpkB,GAAYvP,CAAQ,GAEtE+oC,IAAiBv3B,GAAgBjC,KAAc,EAAE,GACjDy5B,IAAiBv3B,GAAgBlC,KAAc,EAAE,GACjD6f,IAAiBxd,GAAgBrC,KAAc,EAAE,GACjD05B,IAAkBn3B,GAAiBvC,KAAc,EAAE,GASnD25B,IAAkB,OAAO,MAAKzpC,KAAA,gBAAAA,EAAQ,kBAAiB,CAAA,CAAE,EAAE,SAAS,GACpE0pC,IAAWL,KAAA,gBAAAA,EAAc,MACzBpnB,IAAYynB,KAAA,gBAAAA,EAAW,WACvBxC,IAAoBwC,KAAA,gBAAAA,EAAW,aAC/BC,IAAah8B,EAAa,IAAI,MAAM,MAAM,QAC1C,CAACi8B,GAASC,CAAU,IAAIjpC,EAASwmC,KAASuC,CAAU,GACpD,CAACloB,GAAUsB,CAAW,IAAIniB,EAAkC,CAAA,CAAE,GAC9D,CAACkpC,GAAiBC,CAAkB,IAAInpC,EAAiC,CAAA,CAAE,GAC3E,CAACopC,IAAmBC,CAAoB,IAAIrpC,EAAkC,CAAA,CAAE,GAChF,CAAC+nC,GAAiBuB,CAAkB,IAAItpC,EAAwD,MAAS,GAEzG,CAACupC,GAAkBC,CAAmB,IAAIxpC,EAAgE,MAAS,GACnH,CAAC2kC,GAAeC,EAAgB,IAAI5kC,EAAmD,EAAE,MAAM,IAAO,GAKtG,CAACypC,IAAUC,EAAW,IAAI1pC,EAAS,MAAM;AAC7C,UAAM81B,IAAI,UAASx0B,KAAA,gBAAAA,EAAQ,kBAAiB,OAAO,EAAE;AACrD,WAAO,MAAMw0B,CAAC,IAAI,MAAMA;AAAA,EAC1B,CAAC,GACK6T,KAAaz+B,GAAuB,IAAI,GACxC0+B,KAAc1+B,GAAkD,IAAI,GACpE2+B,KAAqB5sC;AAAA,IACzB,CAACsK,MAAwB;AACvB,MAAAA,EAAE,eAAA;AACF,YAAMguB,IAAKoU,GAAW;AACtB,UAAI,CAACpU,EAAI;AACT,YAAMuU,IAASvU,EAAG;AAClB,MAAAqU,GAAY,UAAU,EAAE,QAAQriC,EAAE,SAAS,QAAAuiC,EAAA;AAC3C,YAAM7T,KAAS,CAACrrB,OAAmB;AACjC,YAAI,CAACg/B,GAAY,QAAS;AAC1B,cAAMzT,KAAQyT,GAAY,QAAQ,SAASh/B,GAAG,SACxCtC,KAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAKshC,GAAY,QAAQ,SAASzT,EAAK,CAAC;AAC5E,QAAAZ,EAAG,MAAM,QAAQ,GAAGjtB,EAAI;AAAA,MAC1B,GACMiuB,KAAO,MAAM;AACjB,QAAIqT,GAAY,WAAWrU,KACzBmU,GAAY,SAASnU,EAAG,MAAM,OAAO,EAAE,KAAKqU,GAAY,QAAQ,MAAM,GAExEA,GAAY,UAAU,MACtB,SAAS,oBAAoB,aAAa3T,EAAM,GAChD,SAAS,oBAAoB,WAAWM,EAAI;AAAA,MAC9C;AACA,eAAS,iBAAiB,aAAaN,EAAM,GAC7C,SAAS,iBAAiB,WAAWM,EAAI;AAAA,IAC3C;AAAA,IACA,CAAA;AAAA,EAAC,GAIGj3B,IAASmpC,KAAA,gBAAAA,EAAc,MAEvBsB,KAAazqC,KAAA,gBAAAA,EAAS,OAGtB2uB,KAAgB,CAAC,EAAC7uB,KAAA,QAAAA,EAAQ,cAC1B4qC,KAAkB/b,MAAiB3uB,KAAU,QAAQA,EAAOF,EAAQ,WAAY,KAAK,MAGrFe,KAAWC,GAAA,GACX,EAAE,SAAAtD,IAAS,gBAAAmtC,IAAgB,mBAAAjtC,GAAA,IAAsB5B,GAAA;AACvD,EAAA+P,GAAU,MAAM;;AACd,QAAI,CAAC/L,KAAUmpC,EAAQ;AACvB,UAAM/rC,IAAW2D,GAAS,UACpBmuB,IAAUpwB,GAAIQ,KAAA4C,KAAA,gBAAAA,EAAQ,YAAR,gBAAA5C,GAAiB,IAAI,KAAKR,EAAIkB,EAAO,QAAQ,IAAI,GAC/DmvB,MAAU5vB,KAAA2C,KAAA,gBAAAA,EAAQ,YAAR,gBAAA3C,GAAiB,SAAQS,EAAO,QAAQ;AAExD,IADiBpC,GAAkBR,CAAQ,KAEzCM,GAAQ;AAAA,MACN,UAAAN;AAAA,MACA,QAAQ;AAAA,MACR,OAAOgqC,IAAQ,OAAOlY,CAAO,KAAKA;AAAA,MAClC,MAAMC;AAAA,MACN,UAAU;AAAA,IAAA,CACX;AAAA,EAEL,GAAG,CAACpuB,GAAS,WAAUxB,MAAAD,KAAA4C,KAAA,gBAAAA,EAAQ,YAAR,gBAAA5C,GAAiB,SAAjB,gBAAAC,GAAuB,KAAIG,KAAAM,KAAA,gBAAAA,EAAQ,QAAQ,SAAhB,gBAAAN,GAAsB,KAAIia,KAAAzX,KAAA,gBAAAA,EAAQ,YAAR,gBAAAyX,GAAiB,MAAM3Z,KAAA,gBAAAA,EAAQ,QAAQ,MAAMonC,GAAO+B,CAAM,CAAC,GAEvIp9B,GAAU,MAAM;;AACd,QAAI,CAAC7L,KAAU,CAACF,KAAUmpC,EAAQ;AAClC,UAAM/sC,IAAMwB,GAAkBmD,GAAS,QAAQ;AAC/C,QAAI3E,GAAK;AACP,YAAM0uC,MAAQxrC,IAAAU,EAAO,YAAP,gBAAAV,EAAgB,eACxByrC,KAASD,KAAQ5qC,EAAO4qC,EAAK,IAAI,QACjCE,KACJD,MAAU,OAAOA,MAAW,YAAY,CAAC,MAAM,QAAQA,EAAM,IACzDjsC,EAAIisC,EAAyB,IAC7BA,IACAE,KAAeD,KACjB,OAAOA,EAAW,IACjBlsC,GAAIS,IAAA2C,KAAA,gBAAAA,EAAQ,YAAR,gBAAA3C,EAAiB,IAAI,KAAKT,EAAIkB,EAAO,QAAQ,IAAI;AAC1D,MAAA6qC,GAAezuC,EAAI,IAAI6uC,EAAY;AAAA,IACrC;AAAA,EACF,GAAG,CAAC/qC,IAAQ8I,KAAAhJ,KAAA,gBAAAA,EAAQ,QAAQ,SAAhB,gBAAAgJ,GAAsB,IAAIhJ,KAAA,gBAAAA,EAAQ,QAAQ,eAAee,GAAS,UAAUooC,CAAM,CAAC;AAG/F,QAAMtL,KAAiBn/B,EAAQ,MAAM;AACnC,QAAI,CAACsB,EAAQ,QAAO,oBAAI,IAAA;AACxB,UAAMwjC,wBAAe,IAAA;AACrB,eAAW,CAACvlC,GAAMiB,CAAK,KAAK,OAAO,QAAQc,EAAO,MAAM;AACtD,MAAI,CAACd,EAAM,QAAQ,CAACA,EAAM,WACxBskC,EAAS,IAAIvlC,CAAI;AAGrB,WAAOulC;AAAA,EACT,GAAG,CAACxjC,CAAM,CAAC;AAIX,EAAA+L,GAAU,MAAM;AACd,QAAI,GAAC49B,KAAc,CAACzpC,KAAU29B,GAAe,SAAS,IAItD;AAAA,UAFK+L,KAASC,EAAW,EAAI,GAEzB,OAAO,KAAKpoB,CAAQ,EAAE,WAAW,GAAG;AACtC,cAAMrQ,IAAgC,CAAA;AACtC,QAAAysB,GAAe,QAAQ,CAAC5/B,MAAS;AAC/B,UAAAmT,EAAKnT,CAAI,IAAIiC,EAAOjC,CAAI,KAAK;AAAA,QAC/B,CAAC,GACD8kB,EAAY3R,CAAI;AAAA,MAClB;AAEA,MAAA8W,EAAgB,CAACrmB,MAAS;AACxB,cAAMqH,IAAO,IAAI,gBAAgBrH,CAAI;AACrC,eAAAqH,EAAK,OAAO,MAAM,GACXA;AAAA,MACT,GAAG,EAAE,SAAS,IAAM;AAAA;AAAA,EACtB,GAAG,CAACygC,GAAYzpC,GAAQ29B,EAAc,CAAC,GAGvC9xB,GAAU,MAAM;AACd,IAAI,CAACq7B,KAAS,EAACpnC,KAAA,QAAAA,EAAQ,aAAYA,EAAO,SAAS,WAAW,KAC1D2oC,MAAoB,WACxBuB,EAAmB,CAAA,CAAE,GACrBE,EAAoB,CAAA,CAAE;AAAA,EACxB,GAAG,CAAChD,GAAOpnC,KAAA,gBAAAA,EAAQ,QAAQ,CAAC;AAG5B,QAAMkrC,KAAertC,EAAY,MAAM;AACrC,QAAIqC,GAAQ;AACV,YAAMkR,IAAgC,CAAA;AACtC,MAAAysB,GAAe,QAAQ,CAAC5/B,MAAS;AAC/B,QAAAmT,EAAKnT,CAAI,IAAIiC,EAAOjC,CAAI,KAAK;AAAA,MAC/B,CAAC,GACD8kB,EAAY3R,CAAI;AAAA,IAClB;AAEA,UAAM+5B,IAAiBjrC,KAAA,gBAAAA,EAAS;AAChC,QAAIirC,KAAkB,OAAO,KAAKA,CAAc,EAAE,SAAS,GAAG;AAC5D,YAAMj/B,IAA6C,CAAA;AACnD,iBAAW,CAACxB,GAAWmJ,EAAI,KAAK,OAAO,QAAQs3B,CAAc;AAC3D,QAAAj/B,EAAQxB,CAAS,IAAImJ,GAAK,IAAI,CAACyN,QAAS;AAAA,UACtC,GAAGA;AAAA,UACH,MAAM,OAAOA,GAAI,MAAM,OAAO,YAAY;AAAA,QAAA,EAC1C;AAEJ,MAAA4oB,EAAmBh+B,CAAO,GAC1Bk+B,EAAoBe,CAAc;AAAA,IACpC,OAAWnrC,KAAA,QAAAA,EAAQ,YAAYA,EAAO,SAAS,SAAS,MAEtDkqC,EAAmB,CAAA,CAAE,GACrBE,EAAoB,CAAA,CAAE;AAExB,IAAAP,EAAW,EAAI;AAAA,EACjB,GAAG,CAAC3pC,GAAQ29B,IAAgB79B,KAAA,gBAAAA,EAAQ,QAAQ,CAAC,GAEvCorC,KAAgBvtC,EAAY,MAAM;;AACtC,QAAIupC,GAAO;AACT,YAAMiE,MAAY/rC,IAAA4C,KAAA,gBAAAA,EAAQ,UAAR,gBAAA5C,EAAe,QAAQ,QAAQ,QAAO;AACxD,MAAA9B,EAAS6tC,CAAS;AAAA,IACpB;AACE,MAAAxB,EAAW,EAAK,GAChB9mB,EAAY,CAAA,CAAE,GACdgnB,EAAmB,CAAA,CAAE,GACrBE,EAAqB,CAAA,CAAE,GACvBC,EAAmB,MAAS,GAC5BE,EAAoB,MAAS;AAAA,EAEjC,GAAG,CAAChD,GAAOllC,GAAQ1E,CAAQ,CAAC,GAEtBke,KAAoB7d,EAAY,CAACsB,GAAmB+K,MAAmB;AAC3E,IAAA6Y,EAAY,CAAClhB,OAAU,EAAE,GAAGA,GAAM,CAAC1C,CAAS,GAAG+K,EAAA,EAAQ;AAAA,EACzD,GAAG,CAAA,CAAE,GAGCmhC,KAAY3sC,EAAQ,MAAM;AAC9B,QAAI,EAACwD,KAAA,QAAAA,EAAQ,OAAO,QAAO;AAE3B,UAAMme,IAAQne,EAAO,MAAM,MAAM,GAAG;AACpC,WAAAme,EAAM,IAAA,GACCA,EAAM,KAAK,GAAG,KAAK;AAAA,EAC5B,GAAG,CAACne,CAAM,CAAC,GAELopC,KAAkB5sC,EAAQ,MAC1B,EAACuC,KAAA,QAAAA,EAAQ,YAAW,CAACoqC,MAAaA,OAAc,MAAY,KACzD,OAAO,OAAOpqC,EAAO,OAAO,EAAE,KAAK,CAACxE,MAAMA,EAAE,UAAU4uC,EAAS,GACrE,CAACpqC,GAAQoqC,EAAS,CAAC,GAEhBE,KAAa1tC,EAAY,MAAM;AACnC,QAAI,CAACiS,EAAY;AAGjB,UAAMqrB,IAAmC,CAAA;AACzC,QAAIiM;AAEF,iBAAW,CAACz7B,GAAK2N,EAAG,KAAK,OAAO,QAAQmI,CAAQ;AAC9C,QAAInI,OAAQ,MAAMA,OAAQ,QAAQA,OAAQ,WACxC6hB,EAAQxvB,CAAG,IAAI2N;AAAA;AAKnB,iBAAW,CAAC3N,GAAK2N,EAAG,KAAK,OAAO,QAAQmI,CAAQ,GAAG;AACjD,cAAM+pB,KAAWtrC,KAAA,gBAAAA,EAASyL;AAI1B,SAFsB2N,OAAQ,KAAK,OAAOA,SACnBkyB,OAAa,MAAMA,OAAa,SAAY,OAAOA,QAExErQ,EAAQxvB,CAAG,IAAI2N;AAAA,MAEnB;AAeF,QAZI,OAAO,KAAKwwB,CAAe,EAAE,SAAS,MACxC3O,EAAQ,YAAe,OAAO,QAAQ2O,CAAe,EAAE;AAAA,MACrD,CAAC,CAAC3Z,GAAWgY,EAAU,OAAO,EAAE,mBAAmBhY,GAAW,aAAagY,GAAA;AAAA,IAAW,IAItF,OAAO,KAAK6B,EAAiB,EAAE,SAAS,MAC1C7O,EAAQ,cAAiB,OAAO,QAAQ6O,EAAiB,EAAE;AAAA,MACzD,CAAC,CAACyB,GAAcvhC,EAAK,OAAO,EAAE,eAAeuhC,GAAc,OAAAvhC,GAAA;AAAA,IAAM,IAIjEy+B,GAAiB;AACnB,YAAM+C,IAA6D,CAAA;AACnE,iBAAW,CAAChhC,IAAWmJ,EAAI,KAAK,OAAO,QAAQ80B,CAAe,GAAG;AAE/D,cAAM3gB,KAAUnU,GACb,OAAO,CAAC/Y,OAAM,CAACA,GAAE,QAAQ,EACzB,IAAI,CAACA,OAAM;AACV,gBAAM,EAAE,MAAA6wC,IAAM,UAAAC,IAAU,QAAAC,IAAQ,GAAG1rC,OAAWrF;AAC9C,iBAAOqF;AAAA,QACT,CAAC,GAEGqrC,MAAWrB,KAAA,gBAAAA,EAAmBz/B,QAAc,CAAA;AAClD,SAAI08B,KAAS,CAAC0B,GAAY9gB,IAASwjB,EAAQ,OACzCE,EAAgBhhC,EAAS,IAAIsd;AAAA,MAEjC;AACA,MAAI,OAAO,KAAK0jB,CAAe,EAAE,SAAS,MACxCvQ,EAAQ,YAAeuQ;AAAA,IAE3B;AAGA,QAAI,CAACtE,KAAS,OAAO,KAAKjM,CAAO,EAAE,WAAW,GAAG;AAC/C,MAAA0O,EAAW,EAAK,GAChBE,EAAmB,CAAA,CAAE,GACrBE,EAAqB,CAAA,CAAE,GACvBC,EAAmB,MAAS,GAC5BE,EAAoB,MAAS;AAC7B;AAAA,IACF;AAEA,UAAM0B,IAAe,MAAM;AACzB,MAAAjC,EAAW,EAAK,GAChBE,EAAmB,CAAA,CAAE,GACrBE,EAAqB,CAAA,CAAE,GACvBC,EAAmB,MAAS,GAC5BE,EAAoB,MAAS;AAAA,IAG/B;AAEA,IAAIhD,IACFkC,EAAe,OAAOnO,GAAS;AAAA,MAC7B,WAAW,CAACthB,MAAa;AACvB,cAAMkyB,KAAYlyB,EAAS,MACrBmyB,KAAchsC,IAASC,GAAgBD,GAAQ+rC,EAAS,IAAI,CAAA,GAC5DE,KAAQ3rC,GAAa0rC,EAAW;AACtC,QAAIC,KACFzuC,EAAS,GAAG6tC,EAAS,IAAI,mBAAmBY,EAAK,CAAC,IAAI,EAAE,SAAS,IAAM,IAEvEzuC,EAAS6tC,IAAW,EAAE,SAAS,GAAA,CAAM,GAEvCS,EAAA;AAAA,MACF;AAAA,IAAA,CACD,IACQvrC,KACTgpC,EAAe;AAAA,MACb,EAAE,UAAAhpC,GAAU,MAAM46B,EAAA;AAAA,MAClB,EAAE,WAAW2Q,EAAA;AAAA,IAAa;AAAA,EAGhC,GAAG,CAAC1E,GAAO7qC,GAAIuT,GAAY2R,GAAUqoB,GAAiBE,IAAmBrB,GAAiBwB,GAAkBb,GAAgBC,GAAgBvpC,GAAQxC,GAAU6tC,IAAWnrC,CAAM,CAAC,GAE1KgsC,KAAuBruC,EAAY,CAAC6M,GAAmBmJ,MAA4B;AACvF,IAAAq2B,EAAmB,CAACroC,OAAU,EAAE,GAAIA,KAAQ,CAAA,GAAK,CAAC6I,CAAS,GAAGmJ,EAAA,EAAO;AAAA,EACvE,GAAG,CAAA,CAAE,GAECke,KAAel0B,EAAY,MAAM;AACrC,IAAI,CAAC0C,KAAY6mC,KACjBzX,EAAe,OAAOpvB,GAAU;AAAA,MAC9B,WAAW,MAAM/C,EAAS6tC,IAAW,EAAE,SAAS,IAAM;AAAA,IAAA,CACvD;AAAA,EACH,GAAG,CAAC9qC,GAAU6mC,GAAOzX,GAAgBnyB,GAAU6tC,EAAS,CAAC,GAEnDc,KAAgBtuC,EAAY,MAAM;AACtC,IAAI,CAAC0C,KAAY6mC,KACjBoC,EAAgB,OAAOjpC,CAAQ;AAAA,EACjC,GAAG,CAACA,GAAU6mC,GAAOoC,CAAe,CAAC,GAG/B4C,KAAwB1tC;AAAA,IAC5B,MAAMgqC,GAAwBC,GAAiB1nC,CAAM;AAAA,IACrD,CAAC0nC,GAAiB1nC,CAAM;AAAA,EAAA,GAEpBorC,KAAiB,OAAO,KAAKD,EAAqB,EAAE,SAAS;AAEnE,MAAI,CAAClqC,KAAU,CAAClC,EAAQ,QAAO;AAC/B,MAAI,CAAConC,KAASnjC,EAAW,0BAAQga,IAAA,CAAA,CAAe;AAChD,MAAI,CAACmpB,KAAS,CAAClnC;AACb,WACE,gBAAA8B,EAAC,OAAA,EAAI,WAAU,OACb,UAAA;AAAA,MAAA,gBAAArD,EAACmQ,MAAW,OAAM,aAAY,QAAQw8B,KAAkBD,KAAY,QAAW;AAAA,MAC/E,gBAAA1sC,EAAC,KAAA,EAAE,WAAU,kCAAiC,UAAA,oBAAA,CAAiB;AAAA,IAAA,GACjE;AAIJ,QAAMwzB,KAAgBnyB,EAAO,SAEvBssC,KAAaxtC,GAAIwzB,KAAApwB,EAAO,YAAP,gBAAAowB,GAAgB,IAAI,KAAKxzB,EAAIqzB,GAAc,IAAI,GAChEoa,MAAkBxZ,KAAA/yB,EAAO,YAAP,gBAAA+yB,GAAgB,eAClCyZ,KAAkBD,KAAkBrsC,KAAA,gBAAAA,EAASqsC,MAAmB,QAEhExyB,KACJyyB,MAAmB,OAAOA,MAAoB,YAAY,CAAC,MAAM,QAAQA,EAAe,IACpF1tC,EAAI0tC,EAAkC,IACtCA,IACAnvC,KAAQ+pC,IACV,OAAOkF,EAAU,KACjBvyB,KAAe,OAAOA,EAAY,IAAIuyB,IAEpCG,KAAWnD,EAAe,aAAaC,EAAe,WAUtDmD,KAAqBxqC,EAAO,YAAY,QACxCyqC,IAAgBD,KAClBtoB,GAAiBpkB,EAAO,SAASkC,EAAO,SAAS,UAAUjB,KAAA,gBAAAA,EAAQ,OAAO,IAC1EijB,GAAuBlkB,EAAO,SAAS,QAAQ,GAE7C4sC,IAA2B;AAAA,IAC/B,QAAA3rC;AAAA,IACA,QAAAjB;AAAA,IACA,YAAA8P;AAAA,IACA,UAAUs5B,KAAc7sC,KAAM;AAAA,IAC9B,QAAQqtC,IAAU,EAAE,GAAI1pC,KAAU,CAAA,GAAK,GAAGuhB,EAAA,IAAcvhB,KAAU,CAAA;AAAA,IAClE,OAAAknC;AAAA,IACA,MAAMwC,IAAU,SAAS;AAAA,IACzB,eAAeA,IAAUluB,KAAoB;AAAA,IAC7C,MAAMivB;AAAA,IACN,mBAAmB,MAAM;AACvB,YAAMkC,IAAO3F,KAAoB,CAAA;AACjC,UAAI,CAAC0C,KAAW,OAAO,KAAKI,EAAiB,EAAE,WAAW,EAAG,QAAO6C,EAAK,SAAS,IAAIA,IAAO;AAC7F,YAAMC,IAASD,EAAK;AAAA,QAAI,CAAC9d,MACvBib,GAAkBjb,EAAE,aAAa,MAAM,SACnC,EAAE,GAAGA,GAAG,OAAOib,GAAkBjb,EAAE,aAAa,MAChDA;AAAA,MAAA;AAEN,iBAAW,CAAC30B,GAAM8P,EAAK,KAAK,OAAO,QAAQ8/B,EAAiB;AAC1D,QAAK6C,EAAK,KAAK,CAAC9d,OAAMA,GAAE,kBAAkB30B,CAAI,KAC5C0yC,EAAO,KAAK,EAAE,eAAe1yC,GAAM,MAAM,CAAA,GAAI,MAAM,UAAU,OAAA8P,IAAO;AAGxE,aAAO4iC;AAAA,IACT,GAAA;AAAA,IACA,eAAgB1F,KAASpnC,KAAA,QAAAA,EAAQ,WAC7B,SACA4pC,IACE,CAAC6B,GAAcvhC,MAAU+/B,EAAqB,CAACpoC,OAAU,EAAE,GAAGA,GAAM,CAAC4pC,CAAY,GAAGvhC,EAAA,EAAQ,IAC5F;AAAA,IACN,mBAAmB;AAAA;AAAA;AAAA,IAGnB,iBAAiB,MAAM;AACrB,YAAM2iC,IAAO5qB,KAAY,CAAA;AACzB,UAAI,CAAC2nB,KAAW,OAAO,KAAKE,CAAe,EAAE,WAAW,EAAG,QAAO+C,EAAK,SAAS,IAAIA,IAAO;AAE3F,YAAMC,IAASD,EAAK;AAAA,QAAI,CAACpwC,MACvBqtC,EAAgBrtC,EAAE,UAAU,MAAM,SAC9B,EAAE,GAAGA,GAAG,aAAaqtC,EAAgBrtC,EAAE,UAAU,MACjDA;AAAA,MAAA;AAGN,iBAAW,CAACo2B,GAAIka,EAAE,KAAK,OAAO,QAAQjD,CAAe;AACnD,QAAK+C,EAAK,KAAK,CAACpwC,OAAMA,GAAE,eAAeo2B,CAAE,KACvCia,EAAO,KAAK,EAAE,YAAYja,GAAI,aAAaka,IAAI,aAAa,CAAA,GAAI,SAAQ,oBAAI,KAAA,GAAO,YAAA,GAAe;AAGtG,aAAOD;AAAA,IACT,GAAA;AAAA,IACA,aAAc1F,KAASpnC,KAAA,QAAAA,EAAQ,WAC3B,SACA4pC,IACE,CAACzZ,GAAWgY,MAAe4B,EAAmB,CAACloC,OAAU,EAAE,GAAGA,GAAM,CAACsuB,CAAS,GAAGgY,EAAA,EAAa,IAC9F;AAAA,IACN,iBAAiB;AAAA;AAAA,IAEjB,iBAAiByB,IAAUjB,IAAkB;AAAA,IAC7C,kBAAkBiB,IAAUsC,KAAuB;AAAA,IACnD,uBAAuBtC,IAAUwC,KAAwB;AAAA,EAAA,GAGrDY,IAAa9qC,EAAO,WAAWA,EAAO,QAAQ,SAAS,GAEvD+qC,KACJ,gBAAAtuC;AAAA,IAACmQ;AAAA,IAAA;AAAA,MACC,OAAAzR;AAAA,MACA,QAAQ8rC,KAAU,CAACmC,KAAkB,SAAYD;AAAA,MACjD,SACET,KACE,gBAAA5oC,EAACyE,GAAA,EAAO,SAAS0lC,IAAe,UAAU3C,EAAgB,WACxD,UAAA;AAAA,QAAA,gBAAA7qC,EAACqtB,IAAA,EAAU,WAAU,UAAA,CAAU;AAAA,QAC9Bwd,EAAgB,YAAY,iBAAiB;AAAA,MAAA,EAAA,CAChD,IACEI,IACF,gBAAA5nC,EAAAoF,IAAA,EACE,UAAA;AAAA,QAAA,gBAAApF,EAACyE,KAAO,SAAQ,WAAU,SAAS2kC,IAAe,UAAUqB,IAC1D,UAAA;AAAA,UAAA,gBAAA9tC,EAACyJ,IAAA,EAAE,WAAU,UAAA,CAAU;AAAA,UAAE;AAAA,QAAA,GAE3B;AAAA,QACA,gBAAApG;AAAA,UAACyE;AAAA,UAAA;AAAA,YACC,SAAS8kC;AAAA,YACT,UAAUkB,MAAYJ;AAAA,YACtB,OAAOA,KAAiB,6BAA6B;AAAA,YAErD,UAAA;AAAA,cAAA,gBAAA1tC,EAACkuB,IAAA,EAAK,WAAU,UAAA,CAAU;AAAA,cACzB4f,KAAW,cAAc;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAC5B,EAAA,CACF,IAEA,gBAAAzqC,EAAAoF,IAAA,EACG,UAAA;AAAA,QAAA,CAACggC,KAAS7qC,KAAMowC,EAAc,IAAI,CAAC,EAAE,MAAAvyC,GAAM,QAAAqW,QAAa;;AACvD,cAAIA,EAAO,SAAS,QAAQ;AAC1B,kBAAMqV,KAAgB5lB,IAASqjB,GAAmB9S,EAAO,YAAYvQ,CAAM,IAAI;AAC/E,mBACE,gBAAAvB,EAAC8H,GAAA,EAAkB,SAAQ,WAAU,SAASykC,IAAc,UAAU,CAACplB,IACpE,aAAIxmB,IAAAmR,EAAO,YAAP,gBAAAnR,EAAgB,IAAI,KAAK,UADnBlF,CAEb;AAAA,UAEJ;AACA,cAAIqW,EAAO,SAAS,YAAY,CAAC04B,GAAQ;AACvC,kBAAMrjB,KAAgB5lB,IAASqjB,GAAmB9S,EAAO,YAAYvQ,CAAM,IAAI;AAC/E,mBACE,gBAAA8B;AAAA,cAACyE;AAAA,cAAA;AAAA,gBAEC,SAAQ;AAAA,gBACR,SAAS,MAAM++B,GAAiB,EAAE,MAAM,IAAM,cAAc1mC,EAAI2R,EAAO,YAAY,KAAK,OAAA,CAAW;AAAA,gBACnG,UAAU,CAACqV;AAAA,gBACX,WAAU;AAAA,gBAEV,UAAA;AAAA,kBAAA,gBAAAnnB,EAACqd,IAAA,EAAO,WAAU,UAAA,CAAU;AAAA,kBAC3Bld,GAAIS,KAAAkR,EAAO,YAAP,gBAAAlR,GAAgB,IAAI,KAAK;AAAA,gBAAA;AAAA,cAAA;AAAA,cAPzBnF;AAAA,YAAA;AAAA,UAUX;AACA,iBACE,gBAAAuE;AAAA,YAACimB;AAAA,YAAA;AAAA,cAEC,YAAYxqB;AAAA,cACZ,QAAAqW;AAAA,cACA,YAAAX;AAAA,cACA,WAAW,CAACvT,CAAE;AAAA,cACd,KAAK2D;AAAA,cACL,SAAQ;AAAA,YAAA;AAAA,YANH9F;AAAA,UAAA;AAAA,QASX,CAAC;AAAA,QACA,CAACsyC,MAAsB,EAAC1sC,KAAA,QAAAA,EAAQ,aAC/B,gBAAArB,EAAC8H,GAAA,EAAO,SAAQ,WAAU,SAASykC,IAAc,UAAA,OAAA,CAEjD;AAAA,QAED,CAACwB,MAAsB,CAACtF,KAAS,CAAC+B,KAAU,EAACnpC,KAAA,QAAAA,EAAQ,aACpD,gBAAAgC;AAAA,UAACyE;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,SAAS,MAAM++B,GAAiB,EAAE,MAAM,IAAM;AAAA,YAC9C,WAAU;AAAA,YAEV,UAAA;AAAA,cAAA,gBAAA7mC,EAACqd,IAAA,EAAO,WAAU,UAAA,CAAU;AAAA,cAAE;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAEhC,EAAA,CAEJ;AAAA,IAAA;AAAA,EAAA,GAMFkxB,KAAgBtC,MACpB,gBAAA5oC,EAAC,OAAA,EAAI,WAAU,wJACb,UAAA;AAAA,IAAA,gBAAArD,EAAC0oB,IAAA,EAAc,WAAU,mBAAA,CAAmB;AAAA,sBAC3C,QAAA,EAAK,UAAA;AAAA,MAAA;AAAA,MACuB;AAAA,MAC1B4M,GAAsB,OAAO/zB,EAAQF,EAAO,WAAY,CAAC,CAAC;AAAA,IAAA,EAAA,CAC7D;AAAA,EAAA,GACF,GAGImtC,IAAa1D,KAAmB,CAACrC,KAAS,EAAEllC,EAAO,SAASA,EAAO,MAAM,SAAS,MACtF,gBAAAvD,EAAC,OAAA,EAAI,WAAU,QACb,UAAA,gBAAAA;AAAA,IAACgpC;AAAA,IAAA;AAAA,MACC,cAAc3nC,EAAO,iBAAiB,CAAA;AAAA,MACtC,gBAAgB4sC,EAAU;AAAA,MAC1B,aAAa5sC,KAAA,QAAAA,EAAQ,WAAWooC,KAAOwB,IACnC,CAACzZ,GAAWgY,MAAe4B,EAAmB,CAACloC,OAAU,EAAE,GAAGA,GAAM,CAACsuB,CAAS,GAAGgY,EAAA,EAAa,IAC9FC;AAAA,MAEJ,WAAW;AAAA,MACX,MAAMwB,KAAW,EAAC5pC,KAAA,QAAAA,EAAQ,YAAW,SAAS;AAAA,IAAA;AAAA,EAAA,GAElD,GAGIotC,KACJ,gBAAAprC,EAAAoF,IAAA,EACG,UAAA;AAAA,IAAAlF,EAAO,SAASA,EAAO,MAAM,SAAS,MAAMhC,KAAUknC,MAAUnmC,KAC/D,gBAAAtC,EAAC25B,IAAA,EAAe,OAAOp2B,EAAO,OAAO,KAAK0qC,GAAW;AAAA,IAEtD,CAACxF,KAAS7qC,KAAMuT,KAAc9P,EAAO,gBAAgB,OAAO,KAAKA,EAAO,YAAY,EAAE,SAAS,KAAKiB,KACnG,gBAAAtC,EAACy1B,IAAA,EAAgB,YAAAtkB,GAAwB,UAAUs5B,KAAc7sC,KAAM,IAAI,cAAcyD,EAAO,cAAc,QAAAiB,EAAA,CAAgB;AAAA,IAE/H,CAACmmC,KAASlnC,KACT,gBAAA8B,EAAC,OAAA,EAAI,WAAU,+DACZ,UAAA;AAAA,MAAA9B,EAAO,cAAc,QACpB,gBAAA8B,EAAC,QAAA,EAAK,UAAA;AAAA,QAAA;AAAA,QAAUiyB,GAAsB,OAAO/zB,EAAO,UAAU,CAAC;AAAA,MAAA,GAAE;AAAA,MAElEA,EAAO,cAAc,QACpB,gBAAA8B,EAAC,QAAA,EAAK,UAAA;AAAA,QAAA;AAAA,QAAUiyB,GAAsB,OAAO/zB,EAAO,UAAU,CAAC;AAAA,MAAA,EAAA,CAAE;AAAA,IAAA,EAAA,CAErE;AAAA,EAAA,GAEJ,GAGImtC,KACJ,gBAAA1uC;AAAA,IAACkgB;AAAA,IAAA;AAAA,MACC,MAAM0mB,EAAc;AAAA,MACpB,cAAc,CAACzmB,MAAS,CAACA,KAAQ0mB,GAAiB,EAAE,MAAM,IAAO;AAAA,MACjE,OAAO,UAAU8G,EAAU;AAAA,MAC3B,aACE/G,EAAc,eACVA,EAAc,eACd1W,KACE,wCAAwCyd,GAAW,YAAA,CAAa,4CAChE,wCAAwCA,GAAW,aAAa;AAAA,MAExE,cAAa;AAAA,MACb,WAAWva;AAAA,MACX,aAAW;AAAA,IAAA;AAAA,EAAA;AAOf,SAAIib,IAEA,gBAAAhrC,EAAC,OAAA,EAAI,WAAU,+BAEb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,uCAEb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,QAAAirC;AAAA,QACAC;AAAA,QACAC;AAAA,MAAA,GACH;AAAA,MAEA,gBAAAxuC,EAAC,OAAA,EAAI,WAAU,sDACZ,UAAAyuC,GAAA,CACH;AAAA,IAAA,GACF;AAAA,IAEA,gBAAAzuC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,aAAa8rC;AAAA,MAAA;AAAA,IAAA;AAAA,IAGf,gBAAA9rC,EAAC,SAAI,KAAK4rC,IAAY,WAAU,mBAAkB,OAAO,EAAE,OAAO,GAAGF,EAAQ,QACzE,WAAAnqC,KAAUknC,MAAUnmC,KACpB,gBAAAtC,EAAC25B,IAAA,EAAe,OAAOp2B,EAAO,SAAU,KAAK0qC,EAAA,CAAW,EAAA,CAE5D;AAAA,IACCS;AAAA,EAAA,GACH,IAMF,gBAAArrC,EAAC,OAAA,EAAI,WAAU,wCACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,MAAAirC;AAAA,MACAC;AAAA,MACAC;AAAA,IAAA,GACH;AAAA,IACA,gBAAAxuC,EAAC,OAAA,EAAI,WAAU,sDACZ,UAAAyuC,IACH;AAAA,IACCC;AAAA,EAAA,GACH;AAEJ;ACjsBA,eAAsBC,GACpBttC,GACAzD,GACA4zB,GACAgY,GACAoF,GACqB;AACrB,QAAMC,IAAuC;AAAA,IAC3C,mBAAmBrd;AAAA,IACnB,aAAagY;AAAA,EAAA;AAEf,EAAIoF,KAAQ,SAAMC,EAAY,OAAOD;AASrC,QAAMjsB,KAPU,MAAMpmB;AAAA,IACpB,aAAa8E,CAAM;AAAA,IACnB;AAAA,MACE,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,CAAC,EAAE,IAAAzD,GAAI,WAAW,CAACixC,CAAW,GAAG,CAAC;AAAA,IAAA;AAAA,EACzD,GAEkB,CAAC,GACfvrB,KAAYX,KAAA,gBAAAA,EAAM,cAAgB,CAAA;AACxC,SAAOW,EAAS,KAAK,CAACxlB,MAAMA,EAAE,eAAe0zB,CAAS,KAAKlO,EAAS,CAAC;AACvE;ACvBO,SAASwrB,GAAaztC,GAA4BzD,GAAwB;AAC/E,QAAM+H,IAAcC,GAAA;AAEpB,SAAOE,GAAY;AAAA,IACjB,YAAY,CAAC,EAAE,WAAA0rB,GAAW,YAAAgY,GAAY,MAAAoF,EAAA,MACpCG,GAA0B1tC,GAASzD,GAAK4zB,GAAWgY,GAAYoF,CAAI;AAAA,IACrE,WAAW,MAAM;AAGf,MAAAjpC,EAAY,kBAAkB;AAAA,QAC5B,UAAU,CAAC,eAAetE,CAAM;AAAA,MAAA,CACjC;AAAA,IACH;AAAA,IACA,SAAS,CAAC6E,MAAe;AACvB,MAAAC,GAAM,MAAMD,EAAI,OAAO;AAAA,IACzB;AAAA,EAAA,CACD;AACH;ACjBA,eAAsB8oC,GACpB3tC,GACAzD,GACAkvC,GACAvhC,GACwB;AAQxB,QAAMoX,KAPU,MAAMpmB;AAAA,IACpB,aAAa8E,CAAM;AAAA,IACnB;AAAA,MACE,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,CAAC,EAAE,IAAAzD,GAAI,aAAa,CAAC,EAAE,eAAekvC,GAAc,OAAAvhC,EAAA,CAAO,EAAA,CAAG,CAAC;AAAA,IAAA;AAAA,EACtF,GAEkB,CAAC,GACf1L,KAAS8iB,KAAA,gBAAAA,EAAM,gBAAkB,CAAA;AACvC,SAAO9iB,EAAM,KAAK,CAACuwB,MAAMA,EAAE,kBAAkB0c,CAAY,KAAKjtC,EAAM,CAAC;AACvE;AAEA,eAAsBovC,GACpB5tC,GACAzD,GACAkvC,GACe;AACf,QAAMvwC;AAAA,IACJ,aAAa8E,CAAM;AAAA,IACnB;AAAA,MACE,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,CAAC,EAAE,IAAAzD,GAAI,aAAa,CAAC,EAAE,eAAekvC,GAAc,OAAO,KAAA,CAAM,EAAA,CAAG,CAAC;AAAA,IAAA;AAAA,EAC5F;AAEJ;AC9BO,SAASoC,GAAe7tC,GAA4BzD,GAAwB;AACjF,QAAM+H,IAAcC,GAAA;AAEpB,SAAOE,GAAY;AAAA,IACjB,YAAY,CAAC,EAAE,cAAAgnC,GAAc,OAAAvhC,EAAA,MAC3B4jC,GAA2B9tC,GAASzD,GAAKkvC,GAAcvhC,CAAK;AAAA,IAC9D,WAAW,MAAM;AACf,MAAA5F,EAAY,kBAAkB;AAAA,QAC5B,UAAU,CAAC,eAAetE,CAAM;AAAA,MAAA,CACjC;AAAA,IACH;AAAA,IACA,SAAS,CAAC6E,MAAe;AACvB,MAAAC,GAAM,MAAMD,EAAI,OAAO;AAAA,IACzB;AAAA,EAAA,CACD;AACH;AAEO,SAASkpC,GAAkB/tC,GAA4BzD,GAAwB;AACpF,QAAM+H,IAAcC,GAAA;AAEpB,SAAOE,GAAY;AAAA,IACjB,YAAY,CAACgnC,MACXuC,GAA8BhuC,GAASzD,GAAKkvC,CAAY;AAAA,IAC1D,WAAW,MAAM;AACf,MAAAnnC,EAAY,kBAAkB;AAAA,QAC5B,UAAU,CAAC,eAAetE,CAAM;AAAA,MAAA,CACjC;AAAA,IACH;AAAA,IACA,SAAS,CAAC6E,MAAe;AACvB,MAAAC,GAAM,MAAMD,EAAI,OAAO;AAAA,IACzB;AAAA,EAAA,CACD;AACH;ACGO,SAASopC,GAAoB,EAAE,YAAA7gB,KAAwC;;AAC5E,QAAM,CAACzf,GAAcua,CAAe,IAAIta,GAAA,GAClC,EAAE,MAAM3M,EAAA,IAAWpF,GAAA,GAEnBqG,IAASjB,KAAA,gBAAAA,EAAQ,QAAQmsB,IACzBptB,IAASkC,KAAA,QAAAA,EAAQ,SAASjB,KAAA,gBAAAA,EAAQ,SAASiB,EAAO,UAAU,QAC5D4N,IAAa5N,KAAA,gBAAAA,EAAQ,QAGrB,EAAE,SAAAxE,EAAA,IAAY1B,GAAA;AACpB,EAAA+P,GAAU,MAAM;;AACd,QAAI7J,KAAA,QAAAA,EAAQ,SAASlC,GAAQ;AAC3B,YAAMkvB,IAAUpwB,GAAIQ,IAAA4C,EAAO,YAAP,gBAAA5C,EAAgB,IAAI,KAAKR,EAAIkB,EAAO,QAAQ,WAAW,GACrEmvB,MAAU5vB,IAAA2C,EAAO,YAAP,gBAAA3C,EAAgB,SAAQS,EAAO,QAAQ;AACvD,MAAAtC,EAAQ;AAAA,QACN,UAAUwE,EAAO;AAAA,QACjB,QAAQyL,EAAa,SAAA;AAAA,QACrB,OAAOuhB;AAAA,QACP,MAAMC;AAAA,QACN,UAAU;AAAA,MAAA,CACX;AAAA,IACH;AAAA,EACF,GAAG,CAACjtB,KAAA,gBAAAA,EAAQ,QAAO3C,MAAAD,IAAA4C,KAAA,gBAAAA,EAAQ,YAAR,gBAAA5C,EAAiB,SAAjB,gBAAAC,GAAuB,KAAIG,IAAAM,KAAA,gBAAAA,EAAQ,QAAQ,gBAAhB,gBAAAN,EAA6B,EAAE,CAAC;AAG9E,QAAMwuC,IAAavgC,EAAa,IAAI,UAAU,KAAK,MAG7C0hB,IAAc1hB,EAAa,IAAI,QAAQ,KAAK,IAC5C4hB,IAAkB/c,GAAY6c,GAAa,GAAG,GAG9CC,IAAY3hB,EAAa,IAAI,MAAM,MAAKzL,KAAA,gBAAAA,EAAQ,iBAAgB,IAGhEsgC,IAAc9jC,EAAQ,MAAM;AAChC,UAAMgX,IAAM/H,EAAa,IAAI,SAAS;AACtC,QAAK+H;AACL,UAAI;AACF,cAAMrL,IAAS,KAAK,MAAMqL,CAAG;AAC7B,eAAO,MAAM,QAAQrL,CAAM,KAAKA,EAAO,SAAS,IAAIA,IAAS;AAAA,MAC/D,QAAQ;AAAE;AAAA,MAAkB;AAAA,EAC9B,GAAG,CAACsD,CAAY,CAAC,GAGX,EAAE,MAAMwnB,GAAc,WAAWgZ,EAAA,IAAgBt8B,GAAc/B,GAAY;AAAA,IAC/E,MAAM;AAAA,IACN,UAAU;AAAA,IACV,MAAMwf,KAAa;AAAA,IACnB,QAAQC,KAAmB;AAAA,IAC3B,SAASiT;AAAA,EAAA,CACV,GAEKiC,KAAUtP,KAAA,gBAAAA,EAAc,SAAQ,CAAA,GAChCiZ,IAAWjZ,KAAA,gBAAAA,EAAc,OAEzBrF,IAAUpxB;AAAA,IACd,MAAA;;AAAM,eAAAY,IAAAU,KAAA,gBAAAA,EAAQ,gBAAR,gBAAAV,EAAqB,KAAK,CAACe,MAAA;;AAAM,gBAAAf,IAAAU,EAAO,OAAOK,CAAC,MAAf,gBAAAf,EAAkB;AAAA,aAAY;AAAA;AAAA,IACrE,CAACU,CAAM;AAAA,EAAA,GAGHquC,IAAexwC;AAAA,IACnB,CAACtB,MAAsB;AACrB,MAAA2rB;AAAA,QACE,CAACrmB,MAAS;AACR,gBAAMqH,IAAO,IAAI,gBAAgBrH,CAAI;AACrC,iBAAItF,IAAI2M,EAAK,IAAI,YAAY3M,CAAE,IAC1B2M,EAAK,OAAO,UAAU,GACpBA;AAAA,QACT;AAAA,QACA,EAAE,SAAS,GAAA;AAAA,MAAK;AAAA,IAEpB;AAAA,IACA,CAACgf,CAAe;AAAA,EAAA,GAGZsJ,IAAe3zB;AAAA,IACnB,CAACqM,MAAkB;AACjB,MAAAge;AAAA,QACE,CAACrmB,MAAS;AACR,gBAAMqH,IAAO,IAAI,gBAAgBrH,CAAI;AACrC,iBAAIqI,IAAOhB,EAAK,IAAI,UAAUgB,CAAK,IAC9BhB,EAAK,OAAO,QAAQ,GAClBA;AAAA,QACT;AAAA,QACA,EAAE,SAAS,GAAA;AAAA,MAAK;AAAA,IAEpB;AAAA,IACA,CAACgf,CAAe;AAAA,EAAA,GAGZomB,IAAezwC;AAAA,IACnB,CAACqB,GAAegL,MAAkB;AAChC,MAAAge;AAAA,QACE,CAACrmB,MAAS;AACR,gBAAMqH,IAAO,IAAI,gBAAgBrH,CAAI,GAC/B+S,IAAU6S,GAAoB5lB,CAAI;AACxC,cAAIkZ;AACJ,iBAAI7Q,KAASA,MAAU,YACrB6Q,KAAU,CAAC,GAAGgN,GAAanT,GAAS1V,CAAK,GAAG4oB,GAAS5oB,GAAOgL,CAAK,CAAC,IAElE6Q,KAAUgN,GAAanT,GAAS1V,CAAK,GAEvCwoB,GAAgB3M,IAAS7R,CAAI,GACtBA;AAAA,QACT;AAAA,QACA,EAAE,SAAS,GAAA;AAAA,MAAK;AAAA,IAEpB;AAAA,IACA,CAACgf,CAAe;AAAA,EAAA,GAIZqmB,KAAgBrsC,KAAA,gBAAAA,EAAQ,mBAAkB,IAC1Cg0B,IAAepqB,GAAuB,IAAI,GAC1C,CAAC0iC,GAAYC,CAAa,IAAI7tC,EAAwB,IAAI,GAC1DmH,IAAa+D,GAAO,EAAK,GAKzB4iC,IAAexsC,KAAA,gBAAAA,EAAQ;AAC7B,EAAA6J,GAAU,MAAM;AACd,QAAI,CAACwiC,KAAiBC,MAAe,KAAM;AAC3C,UAAMG,IAAYzY,EAAa;AAC/B,QAAKyY;AACL,UAAID,KAAgBA,EAAa,SAAS,GAAG,GAAG;AAC9C,cAAME,IAAM,WAAWF,CAAY,IAAI;AACvC,QAAAD,EAAc,KAAK,MAAME,EAAU,wBAAwB,QAAQC,CAAG,CAAC;AAAA,MACzE,OACEH,EADSC,KACK,SAASA,GAAc,EAAE,KAAK,GAAG;AAAA,EAMnD,GAAG,CAACH,GAAeG,GAAcF,GAAYxuC,CAAM,CAAC;AAGpD,QAAM6uC,IAAc/iC,GAA4B,IAAI;AAEpD,EAAAC,GAAU,MACD,MAAM;;AAAE,KAAAzM,IAAAuvC,EAAY,YAAZ,QAAAvvC,EAAA,KAAAuvC;AAAA,EAAyB,GACvC,CAAA,CAAE;AAEL,QAAMC,IAAkBjxC,EAAY,CAACsK,MAAwB;AAC3D,IAAAA,EAAE,eAAA,GACFJ,EAAW,UAAU;AACrB,UAAMgnC,IAAS5mC,EAAE,SACX6mC,IAAaR,KAAc,KAE3BS,IAAc,CAACzjC,OAAmB;;AACtC,UAAI,CAACzD,EAAW,QAAS;AACzB,YAAMmnC,OAAiB5vC,KAAA42B,EAAa,YAAb,gBAAA52B,GAAsB,wBAAwB,UAAS,OAAO,YAC/Em4B,KAAW,KACXC,KAAWwX,KAAiB,KAC5BC,KAAW,KAAK,IAAI1X,IAAU,KAAK,IAAIC,IAAUsX,IAAaxjC,GAAG,UAAUujC,CAAM,CAAC;AACxF,MAAAN,EAAcU,EAAQ;AAAA,IACxB,GAEMC,IAAU,MAAM;AACpB,MAAArnC,EAAW,UAAU,IACrB,SAAS,oBAAoB,aAAaknC,CAAW,GACrD,SAAS,oBAAoB,WAAWG,CAAO,GAC/C,SAAS,KAAK,MAAM,SAAS,IAC7B,SAAS,KAAK,MAAM,aAAa,IACjCP,EAAY,UAAU;AAAA,IACxB;AAEA,aAAS,KAAK,MAAM,SAAS,cAC7B,SAAS,KAAK,MAAM,aAAa,QACjC,SAAS,iBAAiB,aAAaI,CAAW,GAClD,SAAS,iBAAiB,WAAWG,CAAO,GAC5CP,EAAY,UAAUO;AAAA,EACxB,GAAG,CAACZ,CAAU,CAAC;AAEf,MAAI,CAACvtC,KAAU,CAACiB,KAAU,CAAClC,EAAQ,QAAO;AAE1C,QAAMqvC,IACJntC,EAAO,WACPlC,EAAO,YACJ;AAAA,IACC,CAACK,MAAA;;AACC,gBAACf,IAAAU,EAAO,OAAOK,CAAC,MAAf,QAAAf,EAAkB,YACnB,GAACC,IAAAS,EAAO,OAAOK,CAAC,MAAf,QAAAd,EAAkB,WACnBoa,KAAAja,IAAAM,EAAO,OAAOK,CAAC,MAAf,gBAAAX,EAAkB,YAAlB,gBAAAia,EAA2B,iBAAgB;AAAA;AAAA,EAAA,EAE9C,MAAM,GAAG,CAAC,GAET21B,KAAoB9M,KAAA,gBAAAA,EAAa,WAAU;AAEjD,SACE,gBAAAxgC,EAAC,OAAA,EAAI,KAAKk0B,GAAc,WAAU,+BAEhC,UAAA;AAAA,IAAA,gBAAAl0B;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWnI,EAAG,2CAA2C,CAAC00C,KAAiB,UAAU;AAAA,QACrF,OAAO,EAAE,OAAOA,KAAiBC,MAAe,OAAOA,IAActsC,EAAO,cAAc,QAAA;AAAA,QAG1F,UAAA;AAAA,UAAA,gBAAAF,EAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,YAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,cAAA,gBAAArD,EAACi0B,IAAA,EAAO,WAAU,0DAAA,CAA0D;AAAA,cAC5E,gBAAAj0B;AAAA,gBAACoO;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,aAAa,UAAUjO,EAAIkB,EAAO,QAAQ,WAAW,CAAC;AAAA,kBACtD,OAAOqvB;AAAA,kBACP,UAAU,CAAClnB,MAAMqpB,EAAarpB,EAAE,OAAO,KAAK;AAAA,gBAAA;AAAA,cAAA;AAAA,YAC9C,GACF;AAAA,YACCjG,EAAO,WAAWA,EAAO,QAAQ,SAAS,KACzC,gBAAAvD,EAAC,OAAA,EAAI,WAAU,0BACZ,UAAAuD,EAAO,QAAQ,IAAI,CAAC+gC,MAAgB;AACnC,oBAAMsM,IAAWvvC,EAAO,OAAOijC,CAAW;AAC1C,kBAAI,EAACsM,KAAA,QAAAA,EAAU,QAAQ,QAAO;AAC9B,oBAAMC,IAAahN,KAAA,gBAAAA,EAAa;AAAA,gBAC9B,CAACv7B,MAAMA,EAAE,UAAUg8B,KAAeh8B,EAAE,OAAO;AAAA,iBAEvC6N,KAAgB06B,KAAA,gBAAAA,EAAY,UAAoB;AACtD,qBACE,gBAAAxtC;AAAA,gBAAC8R;AAAA,gBAAA;AAAA,kBAEC,OAAOgB;AAAA,kBACP,eAAe,CAAChE,MAAMw9B,EAAarL,GAAanyB,CAAC;AAAA,kBAEjD,UAAA;AAAA,oBAAA,gBAAAnS,EAACsV,IAAA,EAAc,WAAU,wCACvB,UAAA,gBAAAtV;AAAA,sBAACqV;AAAA,sBAAA;AAAA,wBACC,aAAa/U,GAAiBswC,GAAUtM,GAAahiC,EAAO,QAAQ;AAAA,sBAAA;AAAA,oBAAA,GAExE;AAAA,sCACCoT,IAAA,EACC,UAAA;AAAA,sBAAA,gBAAArS,EAACuS,IAAA,EAAW,OAAM,WAAU,UAAA;AAAA,wBAAA;AAAA,wBACrBtV,GAAiBswC,GAAUtM,GAAahiC,EAAO,QAAQ;AAAA,sBAAA,GAC9D;AAAA,sBACCsuC,EAAS,OAAO,IAAI,CAACz+B,wBACnByD,IAAA,EAAwB,OAAOzD,EAAE,MAC/B,YAAIA,EAAE,IAAI,EAAA,GADIA,EAAE,IAEnB,CACD;AAAA,oBAAA,EAAA,CACH;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAlBKmyB;AAAA,cAAA;AAAA,YAqBX,CAAC,EAAA,CACH;AAAA,YAEF,gBAAAjhC,EAAC,OAAA,EAAI,WAAU,mEACb,UAAA;AAAA,cAAA,gBAAArD,EAAC,QAAA,EACE,UAAAwvC,IACG,eACA,GAAG1J,EAAQ,MAAM,IAAI3lC,EAAIkB,EAAO,QAAQ,WAAW,CAAC,IAC1D;AAAA,cACCsvC,IAAoB,KACnB,gBAAA3wC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,SAAS,MACPupB;AAAA,oBACE,CAACrmB,MAAS;AACR,4BAAMqH,IAAO,IAAI,gBAAgBrH,CAAI;AACrC,6BAAAqH,EAAK,OAAO,SAAS,GACdA;AAAA,oBACT;AAAA,oBACA,EAAE,SAAS,GAAA;AAAA,kBAAK;AAAA,kBAGrB,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YAED,EAAA,CAEJ;AAAA,UAAA,GACF;AAAA,4BAGC,OAAA,EAAI,WAAU,0BACZ,UAAAilC,IACC,gBAAAxvC,EAAC,SAAI,WAAU,iBACZ,UAAA,MAAM,KAAK,EAAE,QAAQ,EAAA,CAAG,EAAE,IAAI,CAACod,GAAG7Q,MACjC,gBAAAvM,EAAC,OAAA,EAAY,WAAU,sCAAA,GAAbuM,CAAmD,CAC9D,EAAA,CACH,IACEu5B,EAAQ,WAAW,IACrB,gBAAA9lC,EAAC,OAAA,EAAI,WAAU,iDAAgD,UAAA,oBAAgB,IAE/E8lC,EAAQ,IAAI,CAACvkC,MACX,gBAAAvB;AAAA,YAAC8wC;AAAA,YAAA;AAAA,cAEC,QAAAvvC;AAAA,cACA,QAAAF;AAAA,cACA,SAASqvC;AAAA,cACT,SAAAvf;AAAA,cACA,MAAMse;AAAA,cACN,YAAYluC,EAAO4vB,CAAO,MAAMoe;AAAA,cAChC,SAAS,MAAMG,EAAa,OAAOnuC,EAAO4vB,CAAO,KAAK,EAAE,CAAC;AAAA,YAAA;AAAA,YAPpD,OAAO5vB,EAAO4vB,CAAO,KAAK,EAAE;AAAA,UAAA,CASpC,EAAA,CAEL;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAIDye,KACC,gBAAA5vC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,aAAamwC;AAAA,MAAA;AAAA,IAAA;AAAA,IAKjB,gBAAAnwC,EAAC,OAAA,EAAI,WAAU,kCACZ,UAAAuvC,IACC,gBAAAvvC;AAAA,MAAC+wC;AAAA,MAAA;AAAA,QAEC,YAAA5/B;AAAA,QACA,UAAUo+B;AAAA,QACV,OAAOhsC,EAAO;AAAA,QACd,QAAAjB;AAAA,QACA,QAAAjB;AAAA,MAAA;AAAA,MALKkuC;AAAA,IAAA,sBAQN,OAAA,EAAI,WAAU,iEACb,UAAA,gBAAAlsC,EAAC,KAAA,EAAE,WAAU,WAAU,UAAA;AAAA,MAAA;AAAA,MAAUlD,EAAIkB,EAAO,QAAQ,IAAI;AAAA,MAAE;AAAA,IAAA,EAAA,CAAgB,GAC5E,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ;AAcA,SAASyvC,GAAc;AAAA,EACrB,QAAAvvC;AAAA,EACA,QAAAF;AAAA,EACA,SAAAgwB;AAAA,EACA,SAAS2f;AAAA,EACT,MAAAn2B;AAAA,EACA,YAAAo2B;AAAA,EACA,SAAA5mB;AACF,GAAuB;AACrB,QAAM6mB,IAAa7f,EAAQ,CAAC,GACtB8f,IAAe9f,EAAQ,CAAC,GACxB+f,IAAY/f,EAAQ,MAAM,GAAG,CAAC;AAEpC,SACE,gBAAAhuB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWnI;AAAA,QACT;AAAA,QACA+1C,KAAc;AAAA,MAAA;AAAA,MAEhB,SAAA5mB;AAAA,MAEC,UAAA;AAAA,QAAA6mB,KACC,gBAAAlxC,EAAC,OAAA,EAAI,WAAU,gCACZ,UAAA8c,GAAY;AAAA,UACX,OAAOzb,EAAO,OAAO6vC,CAAU;AAAA,UAC/B,WAAWA;AAAA,UACX,OAAO3vC,EAAO2vC,CAAU;AAAA,UACxB,MAAM;AAAA,UACN,QAAA3vC;AAAA,UACA,MAAAsZ;AAAA,QAAA,CACD,GACH;AAAA,QAEF,gBAAAxX,EAAC,OAAA,EAAI,WAAU,oCACZ,UAAA;AAAA,UAAA8tC,KACC,gBAAAnxC,EAAC,OAAA,EAAI,WAAU,iDACZ,UAAA8c,GAAY;AAAA,YACX,OAAOzb,EAAO,OAAO8vC,CAAY;AAAA,YACjC,WAAWA;AAAA,YACX,OAAO5vC,EAAO4vC,CAAY;AAAA,YAC1B,MAAM;AAAA,YACN,QAAA5vC;AAAA,YACA,MAAAsZ;AAAA,UAAA,CACD,GACH;AAAA,UAEF,gBAAA7a,EAAC,OAAA,EAAI,WAAU,yCACZ,UAAAoxC,EAAU;AAAA,YACT,CAACjkB,MACC5rB,EAAO4rB,CAAG,KAAK,QACb,gBAAAntB,EAAC,OAAA,EAAc,WAAU,WACtB,UAAA8c,GAAY;AAAA,cACX,OAAOzb,EAAO,OAAO8rB,CAAG;AAAA,cACxB,WAAWA;AAAA,cACX,OAAO5rB,EAAO4rB,CAAG;AAAA,cACjB,MAAM;AAAA,cACN,QAAA5rB;AAAA,cACA,MAAAsZ;AAAA,YAAA,CACD,KAROsS,CASV;AAAA,UAAA,EAEN,CACF;AAAA,QAAA,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAYA,SAAS4jB,GAAkB;AAAA,EACzB,YAAA5/B;AAAA,EACA,UAAAukB;AAAA,EACA,OAAA5yB;AAAA,EACA,QAAAR;AAAA,EACA,QAAAjB;AACF,GAA2B;;AACzB,QAAM,EAAE,MAAMqpC,GAAc,WAAAplC,MAAciwB,GAAcpkB,GAAYukB,CAAQ,GACtEkV,IAAiBv3B,GAAgBlC,CAAU,GAE3C,CAAC85B,GAASC,CAAU,IAAIjpC,EAAS,EAAK,GACtC,CAAC6gB,GAAUsB,CAAW,IAAIniB,EAAkC,CAAA,CAAE,GAE9DV,IAASmpC,KAAA,gBAAAA,EAAc,MAKvBpnB,IAAW/hB,KAAA,gBAAAA,EAAS,WACpBgnC,IAAmBhnC,KAAA,gBAAAA,EAAS,aAC5B8vC,IAAoBvC,GAAa39B,GAAYukB,CAAQ,GACrD4b,IAAsBpC,GAAe/9B,GAAYukB,CAAQ,GAEzDwJ,IAAiBn/B,EAAQ,MAAM;AACnC,UAAM8kC,wBAAe,IAAA;AACrB,eAAW,CAACvlC,GAAMiB,CAAK,KAAK,OAAO,QAAQc,EAAO,MAAM;AACtD,MAAI,CAACd,EAAM,QAAQ,CAACA,EAAM,WAASskC,EAAS,IAAIvlC,CAAI;AAEtD,WAAOulC;AAAA,EACT,GAAG,CAACxjC,CAAM,CAAC,GAELkrC,IAAertC,EAAY,MAAM;AACrC,QAAIqC,GAAQ;AACV,YAAMkR,IAAgC,CAAA;AACtC,MAAAysB,EAAe,QAAQ,CAAC5/B,MAAS;AAC/B,QAAAmT,EAAKnT,CAAI,IAAIiC,EAAOjC,CAAI,KAAK;AAAA,MAC/B,CAAC,GACD8kB,EAAY3R,CAAI;AAAA,IAClB;AACA,IAAAy4B,EAAW,EAAI;AAAA,EACjB,GAAG,CAAC3pC,GAAQ29B,CAAc,CAAC,GAErBuN,IAAgBvtC,EAAY,MAAM;AACtC,IAAAgsC,EAAW,EAAK,GAChB9mB,EAAY,CAAA,CAAE;AAAA,EAChB,GAAG,CAAA,CAAE,GAECwoB,IAAa1tC,EAAY,MAAM;AACnC,IAAA0rC,EAAe;AAAA,MACb,EAAE,UAAUlV,GAAU,MAAM5S,EAAA;AAAA,MAC5B;AAAA,QACE,WAAW,MAAM;AACf,UAAAooB,EAAW,EAAK,GAChB9mB,EAAY,CAAA,CAAE,GACdje,GAAM,QAAQ,OAAO;AAAA,QACvB;AAAA,QACA,SAAS,MAAMA,GAAM,MAAM,gBAAgB;AAAA,MAAA;AAAA,IAC7C;AAAA,EAEJ,GAAG,CAACykC,GAAgBlV,GAAU5S,CAAQ,CAAC,GAEjC/F,IAAoB7d,EAAY,CAACqB,GAAegL,MAAmB;AACvE,IAAA6Y,EAAY,CAAClhB,OAAU,EAAE,GAAGA,GAAM,CAAC3C,CAAK,GAAGgL,EAAA,EAAQ;AAAA,EACrD,GAAG,CAAA,CAAE;AAEL,MAAIjG,EAAW,QAAO,gBAAAtF,EAACsf,IAAA,CAAA,CAAe;AACtC,MAAI,CAAC/d,EAAQ,QAAO;AAGpB,QAAM4qC,KAAQxrC,IAAAU,EAAO,YAAP,gBAAAV,EAAgB,eACxB4wC,IAAWpF,IAAQ5qC,EAAO4qC,CAAK,IAAI5qC,EAAOF,EAAO,YAAY,CAAC,CAAC,GAC/DirC,IACJiF,KAAY,QAAQ,OAAOA,KAAa,WAAW,OAAOA,CAAQ,IAAIpxC,EAAIkB,EAAO,QAAQ,IAAI,GAEzF2qC,IAAazqC,KAAA,gBAAAA,EAAS,OAEtBggB,IAAqB;AAAA,IACzB,QAAAjf;AAAA,IACA,QAAAjB;AAAA,IACA,YAAA8P;AAAA,IACA,UAAAukB;AAAA,IACA,QAAQuV,IAAU,EAAE,GAAG1pC,GAAQ,GAAGuhB,MAAavhB;AAAA,IAC/C,OAAO;AAAA,IACP,MAAM0pC,IAAU,SAAS;AAAA,IACzB,eAAeA,IAAUluB,IAAoB;AAAA,IAC7C,MAAMivB;AAAA,IACN,kBAAkBzD,KAAoB;AAAA,IACtC,eAAelnC,EAAO,WAAW,SAAY,CAAC5F,GAAMkf,MAAQ22B,EAAoB,OAAO,EAAE,cAAc71C,GAAM,OAAOkf,GAAK;AAAA,IACzH,mBAAmB22B,EAAoB;AAAA,IACvC,gBAAgBhuB,KAAY;AAAA,IAC5B,aAAajiB,EAAO,WAAW,SAAY,CAACmwB,GAAWgY,MAAe6H,EAAkB,OAAO,EAAE,WAAA7f,GAAW,YAAAgY,EAAA,CAAY;AAAA,IACxH,iBAAiB6H,EAAkB;AAAA,EAAA;AAGrC,SACE,gBAAAhuC,EAAC,OAAA,EAAI,WAAU,wBAEb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,wFACb,UAAA;AAAA,MAAA,gBAAArD,EAAC,MAAA,EAAG,WAAU,kCAAkC,UAAAssC,GAAa;AAAA,MAC7D,gBAAAtsC,EAAC,SAAI,WAAU,6BACZ,WAACqB,EAAO,aAAa4pC,IACpB,gBAAA5nC,EAAAoF,IAAA,EACE,UAAA;AAAA,QAAA,gBAAApF;AAAA,UAACyE;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,SAAS2kC;AAAA,YACT,WAAU;AAAA,YAEV,UAAA;AAAA,cAAA,gBAAAzsC,EAACyJ,IAAA,EAAE,WAAU,UAAA,CAAU;AAAA,cAAE;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAG3B,gBAAApG;AAAA,UAACyE;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS8kC;AAAA,YACT,UAAUhC,EAAe;AAAA,YACzB,WAAU;AAAA,YAEV,UAAA;AAAA,cAAA,gBAAA5qC,EAACkuB,IAAA,EAAK,WAAU,UAAA,CAAU;AAAA,cACzB0c,EAAe,YAAY,cAAc;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAC5C,EAAA,CACF,IAEA,gBAAAvnC;AAAA,QAACyE;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAQ;AAAA,UACR,SAASykC;AAAA,UACT,WAAU;AAAA,UAEV,UAAA;AAAA,YAAA,gBAAAvsC,EAACkyB,IAAA,EAAO,WAAU,UAAA,CAAU;AAAA,YAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA,GAEhC,CAEJ;AAAA,IAAA,GACF;AAAA,sBAGC,OAAA,EAAI,WAAU,wCACZ,UAAApvB,KAASA,EAAM,SAAS,IACvB,gBAAA9C,EAAC25B,IAAA,EAAe,OAAO72B,GAAO,KAAAye,GAAU,IAExC,gBAAAle,EAAC,KAAA,EAAE,WAAU,iCAAgC,UAAA;AAAA,MAAA;AAAA,MACjB,gBAAArD,EAAC,UAAK,UAAA,SAAA,CAAM;AAAA,MAAO;AAAA,IAAA,EAAA,CAC/C,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ;AC3kBO,MAAMwxC,WAAsBC,GAAwB;AAAA,EACzD,YAAY5xC,GAAc;AACxB,UAAMA,CAAK;AAYb,IAAAlE,GAAA,qBAAc,MAAM;AAClB,WAAK,SAAS,EAAE,UAAU,IAAO,OAAO,MAAM;AAAA,IAChD;AAbE,SAAK,QAAQ,EAAE,UAAU,IAAO,OAAO,KAAA;AAAA,EACzC;AAAA,EAEA,OAAO,yBAAyB2gC,GAAqB;AACnD,WAAO,EAAE,UAAU,IAAM,OAAAA,EAAA;AAAA,EAC3B;AAAA,EAEA,kBAAkBA,GAAcoV,GAAiB;AAC/C,YAAQ,MAAM,mBAAmBpV,GAAOoV,EAAK,cAAc;AAAA,EAC7D;AAAA,EAMA,SAAS;;AACP,WAAI,KAAK,MAAM,WACT,KAAK,MAAM,WACN,KAAK,MAAM,6BAIjB,OAAA,EAAI,WAAU,sDACb,UAAA,gBAAAruC,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,MAAA,gBAAArD,EAAC,MAAA,EAAG,WAAU,yCAAwC,UAAA,wBAEtD;AAAA,MACA,gBAAAA,EAAC,OAAE,WAAU,iCACV,qBAAK,MAAM,4BAAO,YAAW,gCAAA,CAChC;AAAA,wBACC8H,GAAA,EAAO,SAAQ,WAAU,SAAS,KAAK,aAAa,UAAA,YAAA,CAErD;AAAA,IAAA,EAAA,CACF,EAAA,CACF,IAIG,KAAK,MAAM;AAAA,EACpB;AACF;AC1DA,MAAM6pC,KAAoC;AAAA,EACxC,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,oBAAoB;AAAA,EACpB,SAAS;AAAA,EACT,oBAAoB;AAAA,EACpB,WAAW;AAAA,EACX,sBAAsB;AAAA,EACtB,OAAO;AAAA,EACP,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,mBAAmB;AAAA,EACnB,aAAa;AAAA,EACb,wBAAwB;AAAA,EACxB,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,QAAQ;AACV,GAGaC,KAAe,OAAO,OAAOD,EAAS;AAG5C,SAASE,GAAiBngB,GAAuC;AACtE,QAAMogB,IAAiC,CAAA;AACvC,aAAW,CAACvxC,GAAOwxC,CAAM,KAAK,OAAO,QAAQJ,EAAS,GAAG;AACvD,UAAMpmC,IAASmmB,EAAgCnxB,CAAK;AACpD,IAAI,OAAOgL,KAAU,YAAYA,MAC/BumC,EAAOC,CAAM,IAAIxmC;AAAA,EAErB;AAEA,SAAImmB,EAAI,YACNogB,EAAO,SAAS,IAAIpgB,EAAI,UAEnBogB;AACT;AChCA,MAAME,KAAc;AAEpB,SAASC,KAAwC;AAC/C,SAAI,OAAO,SAAW,OACf,OAAO,WAAW,8BAA8B,EAAE,UADf,SACkC;AAC9E;AAEA,SAASC,GAAiBC,GAA0B;AAClD,SAAIA,MAAa,WAAiBF,GAAA,IAC3BE;AACT;AAEA,SAASC,GAAWC,GAAmBC,GAA2C;AAChF,QAAMC,IAAO,SAAS;AAGtB,EAAAA,EAAK,UAAU,OAAO,MAAM,GAG5BA,EAAK,aAAa,cAAcF,CAAS,GAGzCG,GAAsBD,CAAI;AAG1B,QAAMT,IAASQ,EAAaD,CAAS;AACrC,MAAIP,GAAQ;AACV,eAAW,CAAC9kC,GAAKzB,CAAK,KAAK,OAAO,QAAQumC,CAAM;AAC9C,MAAI9kC,EAAI,WAAW,KAAK,KACxBulC,EAAK,MAAM,YAAYvlC,GAAKzB,CAAK;AAInC,KADaumC,EAAO,SAAS,MAChB,UAAUO,MAAc,WACnCE,EAAK,UAAU,IAAI,MAAM;AAAA,EAE7B,MAAA,CAAWF,MAAc,UAEvBE,EAAK,UAAU,IAAI,MAAM;AAE7B;AAEA,SAASC,GAAsBhb,GAAiB;AAC9C,aAAWl4B,KAAQsyC;AACjB,IAAApa,EAAG,MAAM,eAAel4B,CAAI;AAEhC;AAEA,SAASmzC,KAA0B;AACjC,SAAI,OAAO,SAAW,MAAoB,UACnC,aAAa,QAAQT,EAAW,KAAK;AAC9C;AAEA,MAAMU,KAAkBD,GAAA,GAClBE,KAAmBT,GAAiBQ,EAAe;AAGrD,OAAO,SAAW,OACpBN,GAAWO,IAAkB,EAAE;AAG1B,MAAMC,KAAgBt1C,GAAmB,CAACC,GAAKC,OAAS;AAAA,EAC7D,eAAek1C;AAAA,EACf,gBAAgBC;AAAA,EAChB,iBAAiB,CAAA;AAAA,EACjB,UAAU,CAACrzC,MAAS;AAClB,UAAMuzC,IAAYX,GAAiB5yC,CAAI;AACvC,iBAAa,QAAQ0yC,IAAa1yC,CAAI,GACtC8yC,GAAWS,GAAWr1C,EAAA,EAAM,eAAe,GAC3CD,EAAI,EAAE,eAAe+B,GAAM,gBAAgBuzC,GAAW;AAAA,EACxD;AAAA,EACA,oBAAoB,CAACC,MAAW;AAC9B,IAAAv1C,EAAI,EAAE,iBAAiBu1C,GAAQ;AAE/B,UAAM,EAAE,gBAAAC,EAAA,IAAmBv1C,EAAA;AAC3B,IAAA40C,GAAWW,GAAgBD,CAAM;AAAA,EACnC;AACF,EAAE;AAGE,OAAO,SAAW,OACpB,OAAO,WAAW,8BAA8B,EAAE,iBAAiB,UAAU,MAAM;AACjF,QAAM/0C,IAAQ60C,GAAc,SAAA;AAC5B,MAAI70C,EAAM,kBAAkB,UAAU;AACpC,UAAM80C,IAAYZ,GAAA;AAClB,IAAAG,GAAWS,GAAW90C,EAAM,eAAe,GAC3C60C,GAAc,SAAS,EAAE,gBAAgBC,EAAA,CAAW;AAAA,EACtD;AACF,CAAC;ACtGH,MAAMG,yBAAe,IAAA;AAEd,SAASC,GAAex3C,GAAcy3C,GAAgC;AAC3E,EAAAF,GAAS,IAAIv3C,GAAMy3C,CAAS;AAC9B;AAEO,SAASC,GAAoB13C,GAAyC;AAC3E,SAAOu3C,GAAS,IAAIv3C,CAAI;AAC1B;ACUA,MAAMkK,KAAc,IAAIytC,GAAY;AAAA,EAClC,gBAAgB;AAAA,IACd,SAAS;AAAA,MACP,WAAW,MAAS;AAAA,MACpB,OAAO;AAAA,IAAA;AAAA,EACT;AAEJ,CAAC;AAED,SAASC,KAAyE;AAChF,QAAM,EAAE,MAAM/wC,EAAA,IAAWpF,GAAA,GAEnBo2C,IAASvzC,EAAqB,MAAM;AACxC,QAAI,CAACuC,EAAQ,QAAO,CAAA;AAEpB,UAAMixC,IAAmB,CAAA;AACzB,eAAW,CAAC93C,GAAM8H,CAAM,KAAK,OAAO,QAAQjB,EAAO,OAAO,GAAG;AAC3D,UAAIiB,EAAO,SAAS,QAAQ;AAC1B,QAAAgwC,EAAI;AAAA,UACF,gBAAAvzC;AAAA,YAACwzC;AAAA,YAAA;AAAA,cAEC,MAAMjwC,EAAO;AAAA,cACb,SAAS,gBAAAvD,EAACwxC,IAAA,EAAc,4BAACviB,IAAA,EAAc,YAAYxzB,GAAM,EAAA,CAAE;AAAA,YAAA;AAAA,YAFtDA;AAAA,UAAA;AAAA,QAGP;AAEF;AAAA,MACF;AACA,UAAI8H,EAAO,SAAS,UAAU;AAC5B,QAAAgwC,EAAI;AAAA,UACF,gBAAAvzC;AAAA,YAACwzC;AAAA,YAAA;AAAA,cAEC,MAAMjwC,EAAO;AAAA,cACb,SAAS,gBAAAvD,EAACwxC,IAAA,EAAc,4BAACpH,IAAA,EAAgB,YAAY3uC,GAAM,EAAA,CAAE;AAAA,YAAA;AAAA,YAFxDA;AAAA,UAAA;AAAA,QAGP;AAEF;AAAA,MACF;AACA,UAAI8H,EAAO,SAAS,eAAe;AACjC,QAAAgwC,EAAI;AAAA,UACF,gBAAAvzC;AAAA,YAACwzC;AAAA,YAAA;AAAA,cAEC,MAAMjwC,EAAO;AAAA,cACb,SAAS,gBAAAvD,EAACwxC,IAAA,EAAc,4BAAClC,IAAA,EAAoB,YAAY7zC,GAAM,EAAA,CAAE;AAAA,YAAA;AAAA,YAF5DA;AAAA,UAAA;AAAA,QAGP;AAEF;AAAA,MACF;AACA,UAAI8H,EAAO,SAAS,UAAU;AAC5B,cAAMkwC,IAAkBlwC,EAAO,YAC3B4vC,GAAoB5vC,EAAO,SAAS,IACpC;AACJ,QAAIkwC,KACFF,EAAI;AAAA,UACF,gBAAAvzC;AAAA,YAACwzC;AAAA,YAAA;AAAA,cAEC,MAAMjwC,EAAO;AAAA,cACb,SAAS,gBAAAvD,EAACwxC,IAAA,EAAc,UAAA,gBAAAxxC,EAACyzC,KAAgB,EAAA,CAAE;AAAA,YAAA;AAAA,YAFtCh4C;AAAA,UAAA;AAAA,QAGP;AAAA,MAGN;AAAA,IACF;AACA,WAAO83C;AAAA,EACT,GAAG,CAACjxC,CAAM,CAAC,GAELoxC,IAAe3zC,EAAQ,MAAM;AACjC,QAAI,EAACuC,KAAA,QAAAA,EAAQ,YAAY,QAAO;AAChC,eAAWS,KAAQT,EAAO,YAAY;AACpC,UAAIS,EAAK,QAAQ;AACf,cAAMQ,IAASjB,EAAO,QAAQS,EAAK,MAAM;AACzC,YAAIQ,UAAeA,EAAO;AAAA,MAC5B;AACA,UAAIR,EAAK;AACP,mBAAW4wC,KAAS5wC,EAAK;AACvB,cAAI4wC,EAAM,QAAQ;AAChB,kBAAMpwC,IAASjB,EAAO,QAAQqxC,EAAM,MAAM;AAC1C,gBAAIpwC,UAAeA,EAAO;AAAA,UAC5B;AAAA;AAAA,IAGN;AACA,WAAO;AAAA,EACT,GAAG,CAACjB,CAAM,CAAC;AAEX,SAAO,EAAE,QAAAgxC,GAAQ,cAAAI,EAAA;AACnB;AAEA,SAASE,KAAY;AACnB,QAAMC,IAAa9uC,GAAa,CAACjH,MAAMA,EAAE,UAAU,GAC7C,EAAE,MAAMwE,EAAA,IAAWpF,GAAA,GACnB42C,IAAqBlB,GAAc,CAAC90C,MAAMA,EAAE,kBAAkB,GAC9D,EAAE,QAAAw1C,GAAQ,cAAAI,EAAA,IAAiBL,GAAA;AAEjC,EAAAjmC,GAAU,MAAM;AACd,IAAAymC,EAAA;AAAA,EACF,GAAG,CAACA,CAAU,CAAC;AAIf,QAAME,IAAazxC,KAAA,QAAAA,EAAQ,SAAS,KAAK,UAAUA,EAAO,MAAM,IAAI;AACpE,SAAA8K,GAAU,MAAM;AACd,QAAI,CAAC2mC,KAAc,EAACzxC,KAAA,QAAAA,EAAQ,QAAQ;AACpC,UAAM0xC,IAAoD,CAAA;AAC1D,eAAW,CAAC10C,GAAMoyB,CAAG,KAAK,OAAO,QAAQpvB,EAAO,MAAM;AACpD,MAAA0xC,EAAU10C,CAAI,IAAIuyC,GAAiBngB,CAAG;AAExC,IAAAoiB,EAAmBE,CAAS;AAAA,EAC9B,GAAG,CAACD,GAAYD,CAAkB,CAAC,qBAGhCG,IAAA,EACC,UAAA;AAAA,IAAA,gBAAAj0C,EAACwzC,MAAM,MAAK,UAAS,SAAS,gBAAAxzC,EAAC+O,MAAU,GAAI;AAAA,sBAC5CykC,IAAA,EAAM,MAAK,uBAAsB,SAAS,gBAAAxzC,EAACiQ,MAAgB,GAAI;AAAA,sBAC/DujC,IAAA,EAAM,MAAK,WAAU,SAAS,gBAAAxzC,EAAC8P,MAAW,GAAI;AAAA,IAC/C,gBAAAzM,EAACmwC,IAAA,EAAM,SAAS,gBAAAxzC,EAACgO,MAAO,GACrB,UAAA;AAAA,MAAA0lC,KACC,gBAAA1zC,EAACwzC,IAAA,EAAM,OAAK,IAAC,SAAS,gBAAAxzC,EAACk0C,IAAA,EAAS,IAAIR,GAAc,SAAO,GAAA,CAAC,EAAA,CAAI;AAAA,MAE/DJ;AAAA,wBACAE,IAAA,EAAM,MAAK,kBAAiB,SAAS,gBAAAxzC,EAAC4Q,MAAiB,GAAI;AAAA,wBAC3D4iC,IAAA,EAAM,MAAK,KAAI,SAAS,gBAAAxzC,EAACkQ,MAAa,EAAA,CAAI;AAAA,IAAA,EAAA,CAC7C;AAAA,EAAA,GACF;AAEJ;AAEO,SAASikC,KAAM;AACpB,2BACG3C,IAAA,EACC,UAAA,gBAAAxxC,EAACo0C,MAAoB,QAAQzuC,IAC3B,4BAAC0uC,IAAA,EACC,UAAA;AAAA,IAAA,gBAAAr0C,EAAC4zC,IAAA,EAAU;AAAA,IACX,gBAAA5zC,EAACs0C,IAAA,EAAQ,YAAU,IAAC,UAAS,aAAY,cAAc,EAAE,WAAW,gBAAc,CAAG;AAAA,EAAA,EAAA,CACvF,GACF,GACF;AAEJ;ACvIA,SAASC,GACP5xB,GACA6O,GAC8B;;AAC9B,UAAO7wB,IAAAgiB,EAAI,cAAJ,gBAAAhiB,EAAe,KAAK,CAAC,MAAM,EAAE,eAAe6wB;AACrD;AAGA,SAASgjB,GACP7xB,GACAmqB,GACgC;;AAChC,UAAOnsC,IAAAgiB,EAAI,gBAAJ,gBAAAhiB,EAAiB,KAAK,CAACyvB,MAAMA,EAAE,kBAAkB0c;AAC1D;AAOA,SAAS2H,GACP9xB,GAC8B;AAC9B,QAAM+xB,IAAW,EAAE,GAAG/xB,EAAA;AACtB,SAAA+xB,EAAS,UAAU,CAACljB,MAAsB+iB,GAAWG,GAAUljB,CAAS,GACxEkjB,EAAS,YAAY,CAAC5H,MAAyB0H,GAAaE,GAAU5H,CAAY,GAC3E4H;AACT;AAaO,MAAMC,GAAS;AAAA,EAAf;AACG,IAAAh5C,GAAA,eAAc,CAAA;AAAA;AAAA;AAAA,EAGtB,MAAMkf,GAA8B;AAClC,QAAKA;AACL,iBAAW1J,KAAc,OAAO,KAAK0J,CAAI,GAAG;AAC1C,QAAK,KAAK,MAAM1J,CAAU,MACxB,KAAK,MAAMA,CAAU,IAAI,CAAA;AAE3B,cAAMyjC,IAAW/5B,EAAK1J,CAAU;AAChC,mBAAWvT,KAAM,OAAO,KAAKg3C,CAAQ;AAEnC,eAAK,MAAMzjC,CAAU,EAAEvT,CAAE,IAAI;AAAA,YAC3B,GAAG,KAAK,MAAMuT,CAAU,EAAEvT,CAAE;AAAA,YAC5B,GAAGg3C,EAASh3C,CAAE;AAAA,UAAA;AAAA,MAGpB;AAAA,EACF;AAAA;AAAA,EAGA,MAAY;AACV,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,IAAIuT,GAAoBvT,GAAiD;;AACvE,YAAO+C,IAAA,KAAK,MAAMwQ,CAAU,MAArB,gBAAAxQ,EAAyB/C;AAAA,EAClC;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,QAAQ,CAAA;AAAA,EACf;AACF;AAMA,SAASi3C,GAAexzC,GAAgBwD,GAA8B;AACpE,QAAMwN,IAAM,IAAI,IAAI,aAAahR,CAAM,IAAI,OAAO,SAAS,MAAM;AAEjE,SAAIwD,EAAO,UAAUA,EAAO,OAAO,SAAS,KAC1CwN,EAAI,aAAa,IAAI,UAAUxN,EAAO,OAAO,KAAK,GAAG,CAAC,GAEpDA,EAAO,UAAUA,EAAO,OAAO,SAAS,KAC1CwN,EAAI,aAAa,IAAI,UAAUxN,EAAO,OAAO,KAAK,GAAG,CAAC,GAEpDA,EAAO,QAAMwN,EAAI,aAAa,IAAI,QAAQxN,EAAO,IAAI,GACrDA,EAAO,UAAQwN,EAAI,aAAa,IAAI,UAAUxN,EAAO,MAAM,GAC3DA,EAAO,SAAOwN,EAAI,aAAa,IAAI,SAAS,OAAOxN,EAAO,KAAK,CAAC,GAChEA,EAAO,SAAOwN,EAAI,aAAa,IAAI,SAASxN,EAAO,KAAK,GACxDA,EAAO,mBAAiBwN,EAAI,aAAa,IAAI,mBAAmB,MAAM,GAEtExN,EAAO,WAAWA,EAAO,QAAQ,SAAS,KAC5CwN,EAAI,aAAa,IAAI,WAAW,KAAK,UAAUxN,EAAO,OAAO,CAAC,GAGzDwN,EAAI,WAAWA,EAAI;AAC5B;AAcO,MAAMyiC,GAA0E;AAAA,EAIrF,YAAYzzC,GAAgB0zC,GAAqB;AAHxC,IAAAp5C,GAAA;AACA,IAAAA,GAAA;AAGP,SAAK,SAAS0F,GACd,KAAK,OAAO0zC,KAAY,IAAIJ,GAAA;AAAA,EAC9B;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI/2C,GAAmD;AAC3D,UAAM3B,IAAM,MAAMM;AAAA,MAChB,aAAa,KAAK,MAAM,IAAIqB,CAAE;AAAA,IAAA;AAEhC,WAAO62C,GAAcx4C,EAAI,IAAI;AAAA,EAC/B;AAAA;AAAA,EAGA,MAAM,KACJ4I,IAAuB,IAC2C;AAClE,UAAM5I,IAAM,MAAMM;AAAA,MAChBs4C,GAAe,KAAK,QAAQhwC,CAAM;AAAA,IAAA;AAIpC,gBAAK,KAAK,MAAM5I,EAAI,KAAK,GAGlB,EAAE,MADIA,EAAI,KAAK,IAAI,CAAC0mB,MAAQ8xB,GAAc9xB,CAAG,CAAC,GACtC,MAAM1mB,EAAI,MAAM,OAAO,KAAK,KAAK,MAAI;AAAA,EACtD;AAAA;AAAA;AAAA,EAKA,MAAM,OACJwH,GACuC;AAEvC,YADgB,MAAM,KAAK,WAAW,CAACA,CAAI,CAAC,GAC7B,CAAC;AAAA,EAClB;AAAA;AAAA,EAGA,MAAM,WACJX,GAC2C;AAK3C,YAJY,MAAMvG;AAAA,MAChB,aAAa,KAAK,MAAM;AAAA,MACxB,EAAE,QAAQ,QAAQ,MAAM,KAAK,UAAUuG,CAAK,EAAA;AAAA,IAAE,GAErC,IAAI,CAAC6f,MAAQ8xB,GAAc9xB,CAAG,CAAC;AAAA,EAC5C;AAAA;AAAA;AAAA,EAKA,MAAM,OACJ/kB,GACA6U,GACuC;AAEvC,YADgB,MAAM,KAAK,WAAW,CAAC,EAAE,IAAA7U,GAAI,GAAG6U,EAAA,CAAM,CAAC,GACxC,CAAC;AAAA,EAClB;AAAA;AAAA,EAGA,MAAM,WACJ3P,GAC2C;AAK3C,YAJY,MAAMvG;AAAA,MAChB,aAAa,KAAK,MAAM;AAAA,MACxB,EAAE,QAAQ,SAAS,MAAM,KAAK,UAAUuG,CAAK,EAAA;AAAA,IAAE,GAEtC,IAAI,CAAC6f,MAAQ8xB,GAAc9xB,CAAG,CAAC;AAAA,EAC5C;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO/kB,GAA2B;AACtC,UAAM,KAAK,WAAW,CAACA,CAAE,CAAC;AAAA,EAC5B;AAAA;AAAA,EAGA,MAAM,WAAWmV,GAA2C;AAC1D,WAAOxW;AAAA,MACL,aAAa,KAAK,MAAM;AAAA,MACxB,EAAE,QAAQ,QAAQ,MAAM,KAAK,UAAUwW,CAAG,EAAA;AAAA,IAAE;AAAA,EAEhD;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQnV,GAA2B;AACvC,UAAM,KAAK,YAAY,CAACA,CAAE,CAAC;AAAA,EAC7B;AAAA;AAAA,EAGA,MAAM,YAAYmV,GAA2C;AAC3D,WAAOxW;AAAA,MACL,aAAa,KAAK,MAAM;AAAA,MACxB,EAAE,QAAQ,QAAQ,MAAM,KAAK,UAAUwW,CAAG,EAAA;AAAA,IAAE;AAAA,EAEhD;AAAA;AAAA;AAAA,EAKA,MAAM,OACJtP,GACAuxC,GACuC;AAEvC,YADgB,MAAM,KAAK,WAAW,CAACvxC,CAAI,GAAGuxC,CAAY,GAC3C,CAAC;AAAA,EAClB;AAAA;AAAA,EAGA,MAAM,WACJlyC,GACAkyC,GAC2C;AAC3C,UAAMC,IAAK,mBAAmBD,EAAa,KAAK,GAAG,CAAC;AAKpD,YAJY,MAAMz4C;AAAA,MAChB,aAAa,KAAK,MAAM,kBAAkB04C,CAAE;AAAA,MAC5C,EAAE,QAAQ,QAAQ,MAAM,KAAK,UAAUnyC,CAAK,EAAA;AAAA,IAAE,GAErC,IAAI,CAAC6f,MAAQ8xB,GAAc9xB,CAAG,CAAC;AAAA,EAC5C;AACF;AAWO,SAASuyB,GACd7zC,GACA0zC,GACiB;AACjB,SAAO,IAAID,GAAgBzzC,GAAQ0zC,CAAQ;AAC7C;ACpRA,eAAsBI,KAA4C;AAEhE,UADY,MAAM54C,GAAsC,oBAAoB,GACjE;AACb;AAEA,eAAsB64C,GAAW35C,GAAsC;AAIrE,UAHY,MAAMc;AAAA,IAChB,eAAe,mBAAmBd,CAAI,CAAC;AAAA,EAAA,GAE9B;AACb;ACdO,SAAS45C,KAAkB;AAChC,SAAOl4C,GAAS;AAAA,IACd,UAAU,CAAC,eAAe;AAAA,IAC1B,SAASg4C;AAAA,IACT,WAAW,MAAS;AAAA,EAAA,CACrB;AACH;AAEO,SAASG,GAAiB75C,GAAc;AAC7C,SAAO0B,GAAS;AAAA,IACd,UAAU,CAAC,UAAU1B,CAAI;AAAA,IACzB,SAAS,MAAM25C,GAAW35C,CAAI;AAAA,IAC9B,SAAS,CAAC,CAACA;AAAA,IACX,WAAW,MAAS;AAAA,EAAA,CACrB;AACH;ACXO,SAAS85C,GACd7oB,GACA8oB,GACA;AACA,QAAM,CAACxmC,GAAcua,CAAe,IAAIta,GAAA,GAElC0d,IAAiB5sB,EAAkB,MAAM;AAC7C,UAAMgX,IAAM/H,EAAa,IAAI,SAAS;AACtC,WAAI+H,IACcA,EAAI,MAAM,GAAG,EAAE,OAAO,OAAO,EAE9B,OAAO,CAACiW,MAAMN,EAAiB,SAASM,CAAC,CAAC,IAEpDwoB,EAAe,SAAS,IAAIA,IAAiB9oB;AAAA,EACtD,GAAG,CAAC1d,GAAc0d,GAAkB8oB,CAAc,CAAC,GAE7CC,IAAav2C;AAAA,IACjB,CAACkgB,MAAmB;AAClB,YAAM7U,IAAO,IAAI,gBAAgByE,CAAY;AAC7C,MAAIoQ,EAAK,WAAW,KAAK+qB,GAAY/qB,GAAMo2B,CAAc,IACvDjrC,EAAK,OAAO,SAAS,IAErBA,EAAK,IAAI,WAAW6U,EAAK,KAAK,GAAG,CAAC,GAEpCmK,EAAgBhf,CAAI;AAAA,IACtB;AAAA,IACA,CAACyE,GAAcua,GAAiBisB,CAAc;AAAA,EAAA,GAG1CE,IAAkBx2C,EAAY,MAAM;AACxC,UAAMqL,IAAO,IAAI,gBAAgByE,CAAY;AAC7C,IAAAzE,EAAK,OAAO,SAAS,GACrBgf,EAAgBhf,CAAI;AAAA,EACtB,GAAG,CAACyE,GAAcua,CAAe,CAAC,GAE5BosB,IAAUz2C,EAAY,MAAM;AAChC,IAAAu2C,EAAW/oB,CAAgB;AAAA,EAC7B,GAAG,CAACA,GAAkB+oB,CAAU,CAAC,GAE3BG,IAAkB12C;AAAA,IACtB,CAACiuB,MAAgBR,EAAe,SAASQ,CAAG;AAAA,IAC5C,CAACR,CAAc;AAAA,EAAA,GAGXkpB,IAAe32C;AAAA,IACnB,CAACiuB,MAAgB;AACf,UAAIR,EAAe,SAASQ,CAAG,GAAG;AAEhC,YAAIR,EAAe,UAAU,EAAG;AAChC,QAAA8oB,EAAW9oB,EAAe,OAAO,CAACK,MAAMA,MAAMG,CAAG,CAAC;AAAA,MACpD;AACE,QAAAsoB,EAAW,CAAC,GAAG9oB,GAAgBQ,CAAG,CAAC;AAAA,IAEvC;AAAA,IACA,CAACR,GAAgB8oB,CAAU;AAAA,EAAA;AAG7B,SAAO;AAAA,IACL,gBAAA9oB;AAAA,IACA,kBAAAD;AAAA,IACA,YAAA+oB;AAAA,IACA,iBAAAC;AAAA,IACA,SAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,cAAAC;AAAA,EAAA;AAEJ;AAEA,SAAS1L,GAAY/4B,GAAaC,GAAsB;AACtD,SAAID,EAAE,WAAWC,EAAE,SAAe,KAC3BD,EAAE,MAAM,CAACe,GAAG5F,MAAM4F,MAAMd,EAAE9E,CAAC,CAAC;AACrC;"}