@rytass/bpm-core-react 0.7.1 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/dist/chunks/orgs-BcaGmB_x.cjs +2 -0
- package/dist/chunks/orgs-BcaGmB_x.cjs.map +1 -0
- package/dist/chunks/{orgs-BywlqXaG.js → orgs-oYd1GaLX.js} +629 -530
- package/dist/chunks/orgs-oYd1GaLX.js.map +1 -0
- package/dist/pages/admin/orgs/index.cjs +1 -1
- package/dist/pages/admin/orgs/index.js +1 -1
- package/dist/views/admin/index.cjs +1 -1
- package/dist/views/admin/index.js +1 -1
- package/dist/views/admin/orgs/index.cjs +1 -1
- package/dist/views/admin/orgs/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunks/orgs-BbniWPB_.cjs +0 -2
- package/dist/chunks/orgs-BbniWPB_.cjs.map +0 -1
- package/dist/chunks/orgs-BywlqXaG.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"orgs-BbniWPB_.cjs","names":[],"sources":["../../src/lib/org-tree-draft.ts","../../src/components/org-unit-tree-draft-editor.module.scss","../../src/components/org-unit-tree-draft-editor.tsx","../../src/views/admin/orgs/orgs.module.scss","../../src/views/admin/orgs/AdminOrgsView.tsx"],"sourcesContent":["import type { OrgUnitRecord } from '@rytass/bpm-core-client/organization';\n\nexport type OrgUnitParentDraftMap = ReadonlyMap<string, string | null>;\n\nexport type OrgUnitHierarchyDraftChange = Readonly<{\n orgUnitId: string;\n parentId: string | null;\n previousParentId: string | null;\n}>;\n\nexport type OrgUnitParentAssignmentResult = Readonly<{\n message: string;\n parentDraft: OrgUnitParentDraftMap;\n status: 'INVALID' | 'UNCHANGED' | 'UPDATED';\n}>;\n\nexport function createOrgUnitParentDraftMap(\n orgUnits: readonly OrgUnitRecord[],\n): OrgUnitParentDraftMap {\n return new Map(\n orgUnits.map((orgUnit): readonly [string, string | null] => [\n orgUnit.id,\n orgUnit.parentId,\n ]),\n );\n}\n\nexport function assignOrgUnitDraftParent({\n orgUnitId,\n parentDraft,\n parentId,\n}: {\n readonly orgUnitId: string;\n readonly parentDraft: OrgUnitParentDraftMap;\n readonly parentId: string | null;\n}): OrgUnitParentAssignmentResult {\n const normalizedParentId = parentId === orgUnitId ? orgUnitId : parentId;\n const validationMessage = readOrgUnitParentValidationMessage({\n orgUnitId,\n parentDraft,\n parentId: normalizedParentId,\n });\n\n if (validationMessage) {\n return {\n message: validationMessage,\n parentDraft,\n status: 'INVALID',\n };\n }\n\n if ((parentDraft.get(orgUnitId) ?? null) === normalizedParentId) {\n return {\n message: '父子關係沒有變更。',\n parentDraft,\n status: 'UNCHANGED',\n };\n }\n\n const nextDraft = new Map(parentDraft);\n nextDraft.set(orgUnitId, normalizedParentId);\n\n return {\n message: normalizedParentId ? '已暫存新的上層組織。' : '已暫存為根節點。',\n parentDraft: nextDraft,\n status: 'UPDATED',\n };\n}\n\nexport function readOrgUnitHierarchyDraftChanges({\n orgUnits,\n parentDraft,\n}: {\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly parentDraft: OrgUnitParentDraftMap;\n}): readonly OrgUnitHierarchyDraftChange[] {\n return orgUnits\n .map((orgUnit): OrgUnitHierarchyDraftChange | null => {\n const parentId = parentDraft.get(orgUnit.id) ?? null;\n\n return parentId === orgUnit.parentId\n ? null\n : {\n orgUnitId: orgUnit.id,\n parentId,\n previousParentId: orgUnit.parentId,\n };\n })\n .filter((change): change is OrgUnitHierarchyDraftChange => Boolean(change));\n}\n\nexport function readOrgUnitParentValidationMessage({\n orgUnitId,\n parentDraft,\n parentId,\n}: {\n readonly orgUnitId: string;\n readonly parentDraft: OrgUnitParentDraftMap;\n readonly parentId: string | null;\n}): string | null {\n if (!parentDraft.has(orgUnitId)) {\n return '找不到要搬移的組織節點。';\n }\n\n if (!parentId) {\n return null;\n }\n\n if (!parentDraft.has(parentId)) {\n return '找不到新的上層組織。';\n }\n\n if (parentId === orgUnitId) {\n return '組織不可成為自己的上層。';\n }\n\n return createsOrgUnitParentCycle({ orgUnitId, parentDraft, parentId })\n ? '不可搬移到自己的下層組織。'\n : null;\n}\n\nfunction createsOrgUnitParentCycle({\n orgUnitId,\n parentDraft,\n parentId,\n}: {\n readonly orgUnitId: string;\n readonly parentDraft: OrgUnitParentDraftMap;\n readonly parentId: string;\n}): boolean {\n const visitedIds = new Set<string>();\n let currentParentId: string | null = parentId;\n\n while (currentParentId) {\n if (currentParentId === orgUnitId || visitedIds.has(currentParentId)) {\n return true;\n }\n\n visitedIds.add(currentParentId);\n currentParentId = parentDraft.get(currentParentId) ?? null;\n }\n\n return false;\n}\n",".orgTreeEditor {\n display: grid;\n gap: 12px;\n min-width: 0;\n}\n\n.orgTreeSummary {\n display: grid;\n gap: 6px;\n min-width: 0;\n padding: 10px 12px;\n border: 1px solid var(--mzn-color-border, #d9dce1);\n border-radius: 8px;\n background: var(--mzn-color-bg, #fff);\n}\n\n.orgTreeChangeList {\n display: grid;\n gap: 4px;\n max-height: 128px;\n margin: 0;\n padding-left: 18px;\n overflow: auto;\n color: var(--mzn-color-text-neutral, #5f6673);\n font-size: 13px;\n}\n\n.orgTreeCanvas {\n width: 100%;\n height: min(720px, calc(100vh - 300px));\n min-height: 520px;\n overflow: hidden;\n border: 1px solid var(--mzn-color-border, #d9dce1);\n border-radius: 8px;\n background: #f7f9fc;\n}\n\n.orgTreeNode {\n display: grid;\n gap: 6px;\n width: 232px;\n min-height: 118px;\n padding: 12px;\n border: 1px solid var(--mzn-color-border, #d9dce1);\n border-radius: 8px;\n background: #fff;\n box-shadow: 0 4px 12px rgb(20 28 44 / 8%);\n}\n\n.orgTreeNodeRoot {\n min-height: 86px;\n border-style: dashed;\n background: #eef4ff;\n}\n\n.orgTreeNodeSelected {\n border-color: var(--mzn-color-primary, #0057ff);\n box-shadow: 0 0 0 3px rgb(0 87 255 / 14%);\n}\n\n.orgTreeNodeChanged {\n border-color: var(--mzn-color-primary, #0057ff);\n}\n\n.orgTreeNodeDeleted {\n opacity: 0.58;\n}\n\n.orgTreeNodeHeader {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 8px;\n min-width: 0;\n}\n\n.orgTreeNodeHeader > :global(.mzn-typography) {\n min-width: 0;\n}\n\n.orgTreeNodeBadge {\n flex: 0 0 auto;\n padding: 2px 6px;\n border-radius: 999px;\n background: #e4f0ff;\n color: var(--mzn-color-primary, #0057ff);\n font-size: 12px;\n line-height: 18px;\n}\n\n.orgTreeNodeActions {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding-top: 2px;\n}\n","'use client';\n\nimport {\n ReactElement,\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useState,\n} from 'react';\nimport {\n Background,\n Connection,\n ConnectionMode,\n Controls,\n Edge,\n Handle,\n MiniMap,\n Node,\n NodeProps,\n NodeTypes,\n OnNodeDrag,\n OnNodesChange,\n Position,\n ReactFlow,\n applyNodeChanges,\n} from '@xyflow/react';\nimport * as dagre from 'dagre';\nimport { Button, Typography } from '@mezzanine-ui/react';\nimport { EditIcon, PlusIcon } from '@mezzanine-ui/icons';\nimport type { OrgUnitRecord, OrgUnitType } from '@rytass/bpm-core-client/organization';\nimport {\n OrgUnitHierarchyDraftChange,\n OrgUnitParentDraftMap,\n assignOrgUnitDraftParent,\n createOrgUnitParentDraftMap,\n readOrgUnitHierarchyDraftChanges,\n readOrgUnitParentValidationMessage,\n} from '../lib/org-tree-draft';\nimport styles from './org-unit-tree-draft-editor.module.scss';\n\ntype OrgUnitTreeFlowData = Readonly<{\n changed: boolean;\n code: string;\n deleted: boolean;\n isEditing: boolean;\n isSyntheticRoot: boolean;\n name: string;\n onCreateChild: (parentId: string | null) => void;\n onEdit: (orgUnitId: string) => void;\n orgUnitId: string | null;\n parentLabel: string;\n path: string;\n typeLabel: string;\n}>;\n\ntype OrgUnitTreeNode = Node<OrgUnitTreeFlowData, 'orgUnit'>;\ntype OrgUnitTreeEdge = Edge<Record<string, never>>;\n\nexport type OrgUnitTreeDraftEditorHandle = Readonly<{\n cancelEditing: () => void;\n saveDraft: () => Promise<void>;\n startEditing: () => void;\n}>;\n\nexport type OrgUnitTreeDraftEditorState = Readonly<{\n hasDraftChanges: boolean;\n isEditing: boolean;\n}>;\n\ntype OrgUnitTreeDraftEditorProps = Readonly<{\n onCreateChild: (parentId: string) => void;\n onCreateRoot: () => void;\n onEditOrgUnit: (orgUnit: OrgUnitRecord) => void;\n onSaveDraft?: (\n changes: readonly OrgUnitHierarchyDraftChange[],\n ) => Promise<void>;\n onStateChange: (state: OrgUnitTreeDraftEditorState) => void;\n orgUnits: readonly OrgUnitRecord[];\n saving: boolean;\n}>;\n\nconst ORG_TREE_ROOT_ID = '__org-tree-root__';\nconst ORG_TREE_NODE_WIDTH = 232;\nconst ORG_TREE_NODE_HEIGHT = 118;\nconst ORG_TREE_ROOT_WIDTH = 232;\nconst ORG_TREE_ROOT_HEIGHT = 86;\nconst ORG_TREE_DROP_DISTANCE = 320;\n\n// Zoom bounds for the ReactFlow canvas. `minZoom` is computed per layout so\n// that fitView can shrink a very wide/tall tree enough to reveal the whole\n// graph; a fixed minZoom (e.g. 0.25) leaves huge trees clipped off-screen.\nconst ORG_TREE_MAX_ZOOM = 1.4;\nconst ORG_TREE_BASE_MIN_ZOOM = 0.25;\n// Absolute lowest zoom; keeps even an extremely wide tree (tens of thousands of\n// px across) fully fittable while never reaching 0.\nconst ORG_TREE_MIN_ZOOM_FLOOR = 0.005;\n// Reference viewport side (px) the fit-all zoom should still work in; minZoom is\n// derived as reference / longest-graph-side, clamped between the floor and base.\n// A small reference keeps fitView from being clamped on narrow viewports.\nconst ORG_TREE_MIN_ZOOM_REFERENCE = 250;\n// Above this node count the MiniMap turns into an unreadable black block and\n// adds render cost, so it is hidden for large trees.\nconst ORG_TREE_MINIMAP_MAX_NODES = 80;\n\nconst ORG_UNIT_TYPE_LABELS: Readonly<Record<Uppercase<OrgUnitType>, string>> = {\n COMPANY: '公司',\n DEPARTMENT: '部門',\n DIVISION: '事業群',\n TEAM: '小組',\n};\n\nconst orgUnitTreeNodeTypes: NodeTypes = {\n orgUnit: OrgUnitTreeNodeCard,\n};\n\nexport const OrgUnitTreeDraftEditor = forwardRef<\n OrgUnitTreeDraftEditorHandle,\n OrgUnitTreeDraftEditorProps\n>(function OrgUnitTreeDraftEditor(\n {\n onCreateChild,\n onCreateRoot,\n onEditOrgUnit,\n onSaveDraft,\n onStateChange,\n orgUnits,\n },\n ref,\n): ReactElement {\n const [isEditing, setIsEditing] = useState(false);\n const [draftMessage, setDraftMessage] = useState<string | null>(null);\n const [selectedOrgUnitId, setSelectedOrgUnitId] = useState<string | null>(\n null,\n );\n const [parentDraft, setParentDraft] = useState<OrgUnitParentDraftMap>(() =>\n createOrgUnitParentDraftMap(orgUnits),\n );\n const [flowNodes, setFlowNodes] = useState<readonly OrgUnitTreeNode[]>([]);\n\n const orgUnitsById = useMemo(\n (): ReadonlyMap<string, OrgUnitRecord> =>\n new Map(orgUnits.map((orgUnit) => [orgUnit.id, orgUnit])),\n [orgUnits],\n );\n const draftChanges = useMemo(\n (): readonly OrgUnitHierarchyDraftChange[] =>\n readOrgUnitHierarchyDraftChanges({ orgUnits, parentDraft }),\n [orgUnits, parentDraft],\n );\n const flowElements = useMemo(\n (): Readonly<{\n bounds: Readonly<{ height: number; width: number }>;\n edges: readonly OrgUnitTreeEdge[];\n nodes: readonly OrgUnitTreeNode[];\n }> =>\n createOrgUnitTreeFlowElements({\n isEditing,\n onCreateChild: (parentId): void => {\n if (parentId) {\n onCreateChild(parentId);\n } else {\n onCreateRoot();\n }\n },\n onEditOrgUnit: (orgUnitId): void => {\n const orgUnit = orgUnitsById.get(orgUnitId);\n\n if (orgUnit) {\n onEditOrgUnit(orgUnit);\n }\n },\n orgUnits,\n orgUnitsById,\n parentDraft,\n selectedOrgUnitId,\n }),\n [\n isEditing,\n onCreateChild,\n onCreateRoot,\n onEditOrgUnit,\n orgUnits,\n orgUnitsById,\n parentDraft,\n selectedOrgUnitId,\n ],\n );\n const hasDraftChanges = draftChanges.length > 0;\n const minZoom = useMemo((): number => {\n const largestSide = Math.max(\n flowElements.bounds.width,\n flowElements.bounds.height,\n );\n\n if (largestSide <= 0) {\n return ORG_TREE_BASE_MIN_ZOOM;\n }\n\n return Math.min(\n ORG_TREE_BASE_MIN_ZOOM,\n Math.max(\n ORG_TREE_MIN_ZOOM_FLOOR,\n ORG_TREE_MIN_ZOOM_REFERENCE / largestSide,\n ),\n );\n }, [flowElements.bounds.height, flowElements.bounds.width]);\n const showMiniMap = orgUnits.length <= ORG_TREE_MINIMAP_MAX_NODES;\n\n useImperativeHandle(\n ref,\n (): OrgUnitTreeDraftEditorHandle => ({\n cancelEditing,\n saveDraft,\n startEditing,\n }),\n );\n\n useEffect((): void => {\n onStateChange({ hasDraftChanges, isEditing });\n }, [hasDraftChanges, isEditing, onStateChange]);\n\n useEffect((): void => {\n setParentDraft(createOrgUnitParentDraftMap(orgUnits));\n setSelectedOrgUnitId(null);\n setDraftMessage(null);\n setIsEditing(false);\n }, [orgUnits]);\n\n useEffect((): void => {\n setFlowNodes(flowElements.nodes);\n }, [flowElements.nodes]);\n\n const assignDraftParent = useCallback(\n (orgUnitId: string, parentId: string | null): void => {\n setParentDraft((currentDraft) => {\n const result = assignOrgUnitDraftParent({\n orgUnitId,\n parentDraft: currentDraft,\n parentId,\n });\n\n setDraftMessage(result.message);\n\n return result.parentDraft;\n });\n },\n [],\n );\n\n const handleConnect = useCallback(\n (connection: Connection): void => {\n if (!isEditing || !connection.target || !connection.source) {\n return;\n }\n\n const nextParentId =\n connection.source === ORG_TREE_ROOT_ID ? null : connection.source;\n\n if (connection.target === ORG_TREE_ROOT_ID) {\n setDraftMessage('根節點不能搬移到其他節點下。');\n return;\n }\n\n assignDraftParent(connection.target, nextParentId);\n },\n [assignDraftParent, isEditing],\n );\n\n const handleNodeChanges = useCallback<OnNodesChange<OrgUnitTreeNode>>(\n (changes): void => {\n if (!isEditing) {\n return;\n }\n\n setFlowNodes((currentNodes) =>\n applyNodeChanges(changes, [...currentNodes]),\n );\n },\n [isEditing],\n );\n\n const handleNodeDragStop = useCallback<OnNodeDrag<OrgUnitTreeNode>>(\n (event, node, nodes): void => {\n if (!isEditing || node.id === ORG_TREE_ROOT_ID) {\n return;\n }\n\n const nearestParent =\n readNearestParentNodeIdFromPointer(event, node.id) ??\n readNearestParentNodeId(node, nodes);\n\n if (nearestParent === undefined) {\n setDraftMessage('拖曳到目標父節點附近,或從父節點拉線到子節點。');\n return;\n }\n\n assignDraftParent(\n node.id,\n nearestParent === ORG_TREE_ROOT_ID ? null : nearestParent,\n );\n },\n [assignDraftParent, isEditing],\n );\n\n function startEditing(): void {\n setIsEditing(true);\n setParentDraft(createOrgUnitParentDraftMap(orgUnits));\n setDraftMessage('已進入編輯模式,拖曳節點或拉線只會更新前端草稿。');\n }\n\n function cancelEditing(): void {\n setIsEditing(false);\n setParentDraft(createOrgUnitParentDraftMap(orgUnits));\n setDraftMessage('已取消草稿變更。');\n }\n\n async function saveDraft(): Promise<void> {\n if (!onSaveDraft) {\n setDraftMessage('批次儲存 API 尚未接上,草稿仍保留在前端。');\n return;\n }\n\n await onSaveDraft(draftChanges);\n setIsEditing(false);\n setDraftMessage('組織樹草稿已儲存。');\n }\n\n return (\n <div className={styles.orgTreeEditor}>\n <div className={styles.orgTreeSummary}>\n <Typography color=\"text-neutral\" variant=\"caption\">\n {draftMessage ??\n (hasDraftChanges\n ? `目前有 ${draftChanges.length} 筆父子關係草稿變更。`\n : '目前沒有草稿變更。')}\n </Typography>\n {hasDraftChanges ? (\n <ul className={styles.orgTreeChangeList}>\n {draftChanges.map((change) => (\n <li key={change.orgUnitId}>\n {readOrgUnitName(change.orgUnitId, orgUnitsById)}\n {':'}\n {readOrgUnitName(change.previousParentId, orgUnitsById)}\n {' -> '}\n {readOrgUnitName(change.parentId, orgUnitsById)}\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n <div className={styles.orgTreeCanvas}>\n <ReactFlow\n connectionMode={ConnectionMode.Strict}\n edges={[...flowElements.edges]}\n fitView\n fitViewOptions={{ minZoom, padding: 0.18 }}\n isValidConnection={(connection): boolean =>\n isOrgTreeConnectionValid(\n { source: connection.source, target: connection.target },\n parentDraft,\n )\n }\n maxZoom={ORG_TREE_MAX_ZOOM}\n minZoom={minZoom}\n nodeTypes={orgUnitTreeNodeTypes}\n nodes={[...flowNodes]}\n nodesConnectable={isEditing}\n nodesDraggable={isEditing}\n onConnect={handleConnect}\n onNodeClick={(_, node): void => {\n setSelectedOrgUnitId(node.id === ORG_TREE_ROOT_ID ? null : node.id);\n }}\n onNodeDoubleClick={(_, node): void => {\n if (node.id !== ORG_TREE_ROOT_ID) {\n const orgUnit = orgUnitsById.get(node.id);\n\n if (orgUnit) {\n onEditOrgUnit(orgUnit);\n }\n }\n }}\n onNodeDragStop={handleNodeDragStop}\n onNodesChange={handleNodeChanges}\n onPaneClick={(): void => setSelectedOrgUnitId(null)}\n panOnDrag\n proOptions={{ hideAttribution: true }}\n >\n <Background />\n <Controls />\n {showMiniMap ? <MiniMap pannable zoomable /> : null}\n </ReactFlow>\n </div>\n </div>\n );\n});\n\nfunction OrgUnitTreeNodeCard({\n data,\n selected,\n}: NodeProps<OrgUnitTreeNode>): ReactElement {\n return (\n <div\n className={[\n styles.orgTreeNode,\n data.isSyntheticRoot ? styles.orgTreeNodeRoot : '',\n data.changed ? styles.orgTreeNodeChanged : '',\n data.deleted ? styles.orgTreeNodeDeleted : '',\n selected ? styles.orgTreeNodeSelected : '',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {data.isSyntheticRoot ? null : (\n <Handle\n id=\"target\"\n isConnectable={data.isEditing}\n position={Position.Top}\n type=\"target\"\n />\n )}\n <Handle\n id=\"source\"\n isConnectable={data.isEditing}\n position={Position.Bottom}\n type=\"source\"\n />\n <div className={styles.orgTreeNodeHeader}>\n <Typography\n component=\"span\"\n ellipsis\n title={data.name}\n variant=\"label-primary\"\n >\n {data.name}\n </Typography>\n {data.changed ? (\n <span className={styles.orgTreeNodeBadge}>草稿</span>\n ) : null}\n </div>\n <Typography\n color=\"text-neutral\"\n component=\"span\"\n ellipsis\n title={data.code}\n variant=\"caption\"\n >\n {data.isSyntheticRoot\n ? '根節點容器'\n : `${data.typeLabel} · ${data.code}`}\n </Typography>\n {data.isSyntheticRoot ? null : (\n <Typography\n color=\"text-neutral\"\n component=\"span\"\n ellipsis\n title={data.parentLabel}\n variant=\"caption\"\n >\n 上層:{data.parentLabel}\n </Typography>\n )}\n <div className={styles.orgTreeNodeActions}>\n {data.isSyntheticRoot ? (\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => data.onCreateChild(null)}\n size=\"sub\"\n variant=\"base-secondary\"\n >\n 新增根節點\n </Button>\n ) : (\n <>\n <Button\n icon={EditIcon}\n iconType=\"leading\"\n onClick={(): void => {\n if (data.orgUnitId) {\n data.onEdit(data.orgUnitId);\n }\n }}\n size=\"sub\"\n variant=\"base-secondary\"\n >\n 編輯\n </Button>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => data.onCreateChild(data.orgUnitId)}\n size=\"sub\"\n variant=\"base-secondary\"\n >\n 新增子節點\n </Button>\n </>\n )}\n </div>\n </div>\n );\n}\n\nfunction createOrgUnitTreeFlowElements({\n isEditing,\n onCreateChild,\n onEditOrgUnit,\n orgUnits,\n orgUnitsById,\n parentDraft,\n selectedOrgUnitId,\n}: {\n readonly isEditing: boolean;\n readonly onCreateChild: (parentId: string | null) => void;\n readonly onEditOrgUnit: (orgUnitId: string) => void;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly orgUnitsById: ReadonlyMap<string, OrgUnitRecord>;\n readonly parentDraft: OrgUnitParentDraftMap;\n readonly selectedOrgUnitId: string | null;\n}): Readonly<{\n bounds: Readonly<{ height: number; width: number }>;\n edges: readonly OrgUnitTreeEdge[];\n nodes: readonly OrgUnitTreeNode[];\n}> {\n const graph = new dagre.graphlib.Graph();\n graph.setDefaultEdgeLabel(() => ({}));\n graph.setGraph({ marginx: 36, marginy: 36, nodesep: 44, rankdir: 'TB' });\n graph.setNode(ORG_TREE_ROOT_ID, {\n height: ORG_TREE_ROOT_HEIGHT,\n width: ORG_TREE_ROOT_WIDTH,\n });\n orgUnits.forEach((orgUnit): void => {\n graph.setNode(orgUnit.id, {\n height: ORG_TREE_NODE_HEIGHT,\n width: ORG_TREE_NODE_WIDTH,\n });\n });\n orgUnits.forEach((orgUnit): void => {\n const parentId = parentDraft.get(orgUnit.id) ?? null;\n graph.setEdge(parentId ?? ORG_TREE_ROOT_ID, orgUnit.id);\n });\n dagre.layout(graph);\n\n const graphLabel = graph.graph();\n const bounds = {\n height: graphLabel.height ?? 0,\n width: graphLabel.width ?? 0,\n };\n\n const rootNode = createOrgUnitTreeNode({\n data: {\n changed: false,\n code: ORG_TREE_ROOT_ID,\n deleted: false,\n isEditing,\n isSyntheticRoot: true,\n name: '組織根節點',\n onCreateChild,\n onEdit: onEditOrgUnit,\n orgUnitId: null,\n parentLabel: '',\n path: '',\n typeLabel: '',\n },\n graph,\n height: ORG_TREE_ROOT_HEIGHT,\n id: ORG_TREE_ROOT_ID,\n selected: selectedOrgUnitId === null,\n width: ORG_TREE_ROOT_WIDTH,\n });\n const orgNodes = orgUnits.map((orgUnit): OrgUnitTreeNode => {\n const parentId = parentDraft.get(orgUnit.id) ?? null;\n const parentLabel = readOrgUnitName(parentId, orgUnitsById);\n\n return createOrgUnitTreeNode({\n data: {\n changed: parentId !== orgUnit.parentId,\n code: orgUnit.code,\n deleted: Boolean(orgUnit.deletedAt),\n isEditing,\n isSyntheticRoot: false,\n name: orgUnit.name,\n onCreateChild,\n onEdit: onEditOrgUnit,\n orgUnitId: orgUnit.id,\n parentLabel,\n path: orgUnit.path,\n typeLabel: readOrgUnitTypeLabel(orgUnit.type),\n },\n graph,\n height: ORG_TREE_NODE_HEIGHT,\n id: orgUnit.id,\n selected: selectedOrgUnitId === orgUnit.id,\n width: ORG_TREE_NODE_WIDTH,\n });\n });\n const edges = orgUnits.map((orgUnit): OrgUnitTreeEdge => {\n const parentId = parentDraft.get(orgUnit.id) ?? null;\n const changed = parentId !== orgUnit.parentId;\n\n return {\n animated: isEditing && changed,\n data: {},\n id: `org-tree-edge-${parentId ?? 'root'}-${orgUnit.id}`,\n source: parentId ?? ORG_TREE_ROOT_ID,\n sourceHandle: 'source',\n style: changed\n ? { stroke: 'var(--mzn-color-primary, #0057ff)', strokeWidth: 2 }\n : undefined,\n target: orgUnit.id,\n targetHandle: 'target',\n type: 'smoothstep',\n };\n });\n\n return {\n bounds,\n edges,\n nodes: [rootNode, ...orgNodes],\n };\n}\n\nfunction createOrgUnitTreeNode({\n data,\n graph,\n height,\n id,\n selected,\n width,\n}: {\n readonly data: OrgUnitTreeFlowData;\n readonly graph: dagre.graphlib.Graph;\n readonly height: number;\n readonly id: string;\n readonly selected: boolean;\n readonly width: number;\n}): OrgUnitTreeNode {\n const positionedNode = graph.node(id) as\n | Readonly<{ x: number; y: number }>\n | undefined;\n\n return {\n data,\n height,\n id,\n initialHeight: height,\n initialWidth: width,\n position: positionedNode\n ? {\n x: positionedNode.x - width / 2,\n y: positionedNode.y - height / 2,\n }\n : { x: 0, y: 0 },\n selected,\n sourcePosition: Position.Bottom,\n targetPosition: Position.Top,\n type: 'orgUnit',\n width,\n };\n}\n\nfunction readNearestParentNodeId(\n draggedNode: OrgUnitTreeNode,\n nodes: readonly OrgUnitTreeNode[],\n): string | undefined {\n const draggedCenter = readNodeCenter(draggedNode);\n const candidates = nodes\n .filter((node) => node.id !== draggedNode.id)\n .map(\n (node): Readonly<{ distance: number; id: string }> => ({\n distance: readDistance(draggedCenter, readNodeCenter(node)),\n id: node.id,\n }),\n )\n .filter((candidate) => candidate.distance <= ORG_TREE_DROP_DISTANCE)\n .sort((left, right) => left.distance - right.distance);\n\n return candidates[0]?.id;\n}\n\nfunction readNearestParentNodeIdFromPointer(\n event: unknown,\n draggedNodeId: string,\n): string | undefined {\n const point = readPointerPoint(event);\n\n if (!point) {\n return undefined;\n }\n\n const candidates = Array.from(\n document.querySelectorAll<HTMLElement>('.react-flow__node[data-id]'),\n )\n .map((element): Readonly<{ distance: number; id: string }> | null => {\n const id = element.dataset['id'];\n\n if (!id || id === draggedNodeId) {\n return null;\n }\n\n const rect = element.getBoundingClientRect();\n const center = {\n x: rect.left + rect.width / 2,\n y: rect.top + rect.height / 2,\n };\n\n return {\n distance: readDistance(point, center),\n id,\n };\n })\n .filter(\n (\n candidate,\n ): candidate is Readonly<{ distance: number; id: string }> =>\n Boolean(candidate),\n )\n .filter((candidate) => candidate.distance <= ORG_TREE_DROP_DISTANCE)\n .sort((left, right) => left.distance - right.distance);\n\n return candidates[0]?.id;\n}\n\nfunction readPointerPoint(\n event: unknown,\n): Readonly<{ x: number; y: number }> | null {\n if (!isPointerEventLike(event)) {\n return null;\n }\n\n return { x: event.clientX, y: event.clientY };\n}\n\nfunction isPointerEventLike(\n event: unknown,\n): event is Readonly<{ clientX: number; clientY: number }> {\n return (\n typeof event === 'object' &&\n event !== null &&\n 'clientX' in event &&\n 'clientY' in event &&\n typeof event.clientX === 'number' &&\n typeof event.clientY === 'number'\n );\n}\n\nfunction readNodeCenter(\n node: OrgUnitTreeNode,\n): Readonly<{ x: number; y: number }> {\n return {\n x: node.position.x + (node.width ?? ORG_TREE_NODE_WIDTH) / 2,\n y: node.position.y + (node.height ?? ORG_TREE_NODE_HEIGHT) / 2,\n };\n}\n\nfunction readDistance(\n source: Readonly<{ x: number; y: number }>,\n target: Readonly<{ x: number; y: number }>,\n): number {\n return Math.hypot(source.x - target.x, source.y - target.y);\n}\n\nfunction isOrgTreeConnectionValid(\n connection: Readonly<{ source: string | null; target: string | null }>,\n parentDraft: OrgUnitParentDraftMap,\n): boolean {\n if (!connection.source || !connection.target) {\n return false;\n }\n\n if (connection.target === ORG_TREE_ROOT_ID) {\n return false;\n }\n\n return (\n readOrgUnitParentValidationMessage({\n orgUnitId: connection.target,\n parentDraft,\n parentId:\n connection.source === ORG_TREE_ROOT_ID ? null : connection.source,\n }) === null\n );\n}\n\nfunction readOrgUnitName(\n orgUnitId: string | null,\n orgUnitsById: ReadonlyMap<string, OrgUnitRecord>,\n): string {\n if (!orgUnitId) {\n return '根節點';\n }\n\n const orgUnit = orgUnitsById.get(orgUnitId);\n\n return orgUnit ? `${orgUnit.name} · ${orgUnit.code}` : '未知組織';\n}\n\nfunction readOrgUnitTypeLabel(type: OrgUnitType): string {\n const normalizedType = type.toUpperCase() as Uppercase<OrgUnitType>;\n\n return ORG_UNIT_TYPE_LABELS[normalizedType] ?? '未知類型';\n}\n",".tableIntroActions {\n display: inline-flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n flex: 0 0 auto;\n max-width: 100%;\n}\n\n.tableIntroActions > :global(.mzn-button) {\n flex: 0 0 auto;\n}\n\n.modalFields {\n display: grid;\n gap: 12px;\n width: 100%;\n\n :global(.mzn-form-field--horizontal) {\n align-items: flex-start;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__label-area) {\n flex: 0 0 120px;\n width: 120px;\n min-width: 120px;\n white-space: nowrap;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__label) {\n flex-wrap: nowrap;\n white-space: nowrap;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__data-entry) {\n flex: 1 1 auto;\n align-items: stretch;\n min-width: 0;\n max-width: none;\n }\n\n :global(.mzn-form-field__control-field-slot--main) {\n width: 100%;\n min-width: 0;\n }\n\n :global(.mzn-auto-complete) {\n width: 100%;\n min-width: 0;\n }\n\n :global(.mzn-input),\n :global(.mzn-input-container),\n :global(.mzn-picker),\n :global(.mzn-select),\n :global(.mzn-select-trigger),\n :global(.mzn-text-field) {\n width: 100%;\n min-width: 0 !important;\n }\n\n :global(.mzn-select-trigger__input) {\n width: 100%;\n min-width: 0 !important;\n text-overflow: ellipsis;\n }\n}\n\n.tableIntro {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n min-width: 0;\n max-width: 100%;\n margin-bottom: 12px;\n}\n\n.tableIntro > div {\n min-width: 0;\n}\n\n.tableIntro > div > * {\n overflow-wrap: anywhere;\n}\n\n.tableFrame {\n width: 100%;\n min-width: 0;\n max-width: 100%;\n overflow-x: auto;\n}\n\n.orgFilterArea {\n margin-bottom: 12px;\n\n :global(.mzn-filter-line),\n :global(.mzn-filter-area__line) {\n flex-wrap: nowrap;\n }\n\n :global(.mzn-filter-area__actions) {\n display: none;\n }\n\n :global(.mzn-form-field__label-area) {\n display: none;\n }\n\n :global(.mzn-form-field__control-field-slot--main) {\n width: 100%;\n min-width: 0;\n }\n}\n\n.membershipFilterArea {\n overflow-x: auto;\n\n :global(.mzn-filter-line),\n :global(.mzn-filter-area__line) {\n align-items: center;\n flex-wrap: nowrap !important;\n min-width: 760px;\n }\n\n :global(.mzn-filter),\n :global(.mzn-filter-area__filter) {\n flex: 1 1 0;\n min-width: 0;\n }\n\n :global(.mzn-filter:nth-child(3)),\n :global(.mzn-filter-area__filter:nth-child(3)) {\n flex: 0 0 180px;\n }\n\n :global(.mzn-autocomplete) {\n width: 100%;\n min-width: 0;\n }\n}\n\n.scopeLabel {\n display: inline-flex;\n align-items: center;\n min-height: 24px;\n}\n\n@media (max-width: 960px) {\n .tableIntro {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .tableIntroActions {\n justify-content: flex-start;\n }\n\n .tableIntroActions {\n flex-wrap: wrap;\n }\n\n .orgFilterArea {\n :global(.mzn-filter-line),\n :global(.mzn-filter-area__line) {\n flex-wrap: wrap;\n }\n }\n\n .membershipFilterArea {\n :global(.mzn-filter-line),\n :global(.mzn-filter-area__line) {\n align-items: stretch;\n flex-wrap: nowrap !important;\n }\n\n :global(.mzn-form-field--horizontal) {\n align-items: center;\n }\n }\n}\n","'use client';\n\nimport {\n ChangeEvent,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n AutoComplete,\n Button,\n DatePicker,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n CloseIcon,\n EditIcon,\n PlusIcon,\n SaveIcon,\n} from '@mezzanine-ui/icons';\nimport type { IconDefinition } from '@mezzanine-ui/icons';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport {\n MemberOption,\n OrgUnitPicker,\n OrgUnitOption,\n PositionOption,\n PositionPicker,\n MemberPicker,\n readMemberOption,\n readOrgUnitOption,\n readPositionOption,\n} from '../../../components/admin-pickers';\nimport {\n commitOrgUnitTreeDraft,\n createManagerResolution,\n createMembership,\n createOrgUnit,\n createPosition,\n deleteManagerResolution,\n deleteMembership,\n deleteOrgUnit,\n ManagerResolutionRecord,\n ManagerResolutionScopeType,\n MembershipRecord,\n OrgUnitRecord,\n OrgUnitType,\n PositionRecord,\n readOrganizationDashboard,\n updateManagerResolution,\n updateMembership,\n updateOrgUnit,\n updatePosition,\n} from '@rytass/bpm-core-client/organization';\nimport { MemberProfileRecord, resolveMembers } from '@rytass/bpm-core-client';\nimport {\n OrgUnitTreeDraftEditor,\n OrgUnitTreeDraftEditorHandle,\n OrgUnitTreeDraftEditorState,\n} from '../../../components/org-unit-tree-draft-editor';\nimport type { OrgUnitHierarchyDraftChange } from '../../../lib/org-tree-draft';\nimport styles from './orgs.module.scss';\n\ntype AdminOrgTab = 'MANAGERS' | 'MEMBERSHIPS' | 'ORG_UNITS' | 'POSITIONS';\ntype OrgUnitViewMode = 'FLOW' | 'TABLE';\n\nconst INITIAL_ORG_TREE_EDITOR_STATE: OrgUnitTreeDraftEditorState = {\n hasDraftChanges: false,\n isEditing: false,\n};\n\ntype OrgUnitRow = Readonly<\n Record<string, unknown> &\n OrgUnitRecord & {\n key: string;\n parentName: string;\n typeLabel: string;\n }\n>;\n\ntype PositionRow = Readonly<\n Record<string, unknown> &\n PositionRecord & {\n key: string;\n }\n>;\n\ntype MembershipRow = Readonly<\n Record<string, unknown> &\n MembershipRecord & {\n key: string;\n memberName: string;\n orgUnitName: string;\n positionName: string;\n }\n>;\n\ntype ManagerResolutionRow = Readonly<\n Record<string, unknown> &\n ManagerResolutionRecord & {\n key: string;\n managerName: string;\n scopeLabel: string;\n }\n>;\n\ntype OrgModalState = Readonly<{\n parentId?: string | null;\n record: OrgUnitRecord | null;\n type: 'CREATE' | 'EDIT';\n}>;\n\ntype PositionModalState = Readonly<{\n record: PositionRecord | null;\n type: 'CREATE' | 'EDIT';\n}>;\n\ntype MembershipModalState = Readonly<{\n record: MembershipRecord | null;\n type: 'CREATE' | 'EDIT';\n}>;\n\ntype ManagerModalState = Readonly<{\n record: ManagerResolutionRecord | null;\n type: 'CREATE' | 'EDIT';\n}>;\n\ntype DeleteConfirmationState = Readonly<{\n confirmText: string;\n description: string;\n id: string;\n title: string;\n type: 'MANAGER_RESOLUTION' | 'MEMBERSHIP' | 'ORG_UNIT';\n}>;\n\ntype OrgUnitTypeOption = Readonly<{\n id: OrgUnitType;\n name: string;\n}>;\n\ntype OrgUnitTypeFilterOption = Readonly<{\n id: 'ALL' | OrgUnitType;\n name: string;\n}>;\n\ntype ScopeTypeOption = Readonly<{\n id: ManagerResolutionScopeType;\n name: string;\n}>;\n\ntype ScopeTypeFilterOption = Readonly<{\n id: 'ALL' | ManagerResolutionScopeType;\n name: string;\n}>;\n\ntype ActiveFilterOption = Readonly<{\n activeOnly: boolean;\n id: 'ACTIVE' | 'ALL';\n name: string;\n}>;\n\ntype PrimaryOption = Readonly<{\n id: 'false' | 'true';\n name: string;\n value: boolean;\n}>;\n\ntype TablePaginationState = Readonly<{\n onPageChange: (page: number) => void;\n onPageSizeChange: (pageSize: number) => void;\n page: number;\n pageSize: number;\n total: number;\n}>;\n\nconst ORG_UNIT_TYPES: readonly OrgUnitTypeOption[] = [\n { id: 'COMPANY', name: '公司' },\n { id: 'DIVISION', name: '事業群' },\n { id: 'DEPARTMENT', name: '部門' },\n { id: 'TEAM', name: '小組' },\n];\nconst ALL_ORG_UNIT_TYPE_FILTER: OrgUnitTypeFilterOption = {\n id: 'ALL',\n name: '全部類型',\n};\nconst ORG_UNIT_TYPE_FILTER_OPTIONS: readonly OrgUnitTypeFilterOption[] = [\n ALL_ORG_UNIT_TYPE_FILTER,\n ...ORG_UNIT_TYPES,\n];\n\nconst SCOPE_TYPES: readonly ScopeTypeOption[] = [\n { id: 'MEMBER', name: '指定會員' },\n { id: 'ORG_UNIT', name: '指定組織' },\n { id: 'POSITION', name: '指定職位' },\n];\nconst ALL_SCOPE_TYPE_FILTER: ScopeTypeFilterOption = {\n id: 'ALL',\n name: '全部範圍',\n};\nconst SCOPE_TYPE_FILTER_OPTIONS: readonly ScopeTypeFilterOption[] = [\n ALL_SCOPE_TYPE_FILTER,\n ...SCOPE_TYPES,\n];\nconst ALL_ACTIVE_FILTER: ActiveFilterOption = {\n activeOnly: false,\n id: 'ALL',\n name: '全部狀態',\n};\nconst ACTIVE_FILTER_OPTIONS: readonly ActiveFilterOption[] = [\n ALL_ACTIVE_FILTER,\n { activeOnly: true, id: 'ACTIVE', name: '目前有效' },\n];\n\nconst PRIMARY_OPTIONS: readonly PrimaryOption[] = [\n { id: 'true', name: '主要歸屬', value: true },\n { id: 'false', name: '一般歸屬', value: false },\n];\nconst ORGANIZATION_TABLE_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst ORG_UNIT_TABLE_MIN_WIDTH = 1368;\nconst POSITION_TABLE_MIN_WIDTH = 908;\nconst MEMBERSHIP_TABLE_MIN_WIDTH = 1292;\nconst MANAGER_TABLE_MIN_WIDTH = 1124;\n\n\nexport function AdminOrgsView(): ReactElement {\n const [activeTab, setActiveTab] = useState<AdminOrgTab>('ORG_UNITS');\n const [deleteConfirmation, setDeleteConfirmation] =\n useState<DeleteConfirmationState | null>(null);\n const [lastDeleteConfirmation, setLastDeleteConfirmation] =\n useState<DeleteConfirmationState | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [managerModal, setManagerModal] = useState<ManagerModalState | null>(\n null,\n );\n const [managerActiveFilter, setManagerActiveFilter] =\n useState<ActiveFilterOption>(ALL_ACTIVE_FILTER);\n const [managerPage, setManagerPage] = useState(1);\n const [managerPageSize, setManagerPageSize] = useState(10);\n const [managerScopeTypeFilter, setManagerScopeTypeFilter] =\n useState<ScopeTypeFilterOption>(ALL_SCOPE_TYPE_FILTER);\n const [managerTotalCount, setManagerTotalCount] = useState(0);\n const [memberProfiles, setMemberProfiles] = useState<\n readonly MemberProfileRecord[]\n >([]);\n const [membershipActiveFilter, setMembershipActiveFilter] =\n useState<ActiveFilterOption | null>(null);\n const [membershipModal, setMembershipModal] =\n useState<MembershipModalState | null>(null);\n const [membershipOrgUnitFilter, setMembershipOrgUnitFilter] =\n useState<OrgUnitOption | null>(null);\n const [membershipPage, setMembershipPage] = useState(1);\n const [membershipPageSize, setMembershipPageSize] = useState(10);\n const [membershipPositionFilter, setMembershipPositionFilter] =\n useState<PositionOption | null>(null);\n const [membershipTotalCount, setMembershipTotalCount] = useState(0);\n const [orgModal, setOrgModal] = useState<OrgModalState | null>(null);\n const [orgUnitPage, setOrgUnitPage] = useState(1);\n const [orgUnitPageSize, setOrgUnitPageSize] = useState(10);\n const [orgUnitSearchText, setOrgUnitSearchText] = useState('');\n const [orgUnitTotalCount, setOrgUnitTotalCount] = useState(0);\n const [orgUnitTypeFilter, setOrgUnitTypeFilter] =\n useState<OrgUnitTypeFilterOption>(ALL_ORG_UNIT_TYPE_FILTER);\n const [orgUnitViewMode, setOrgUnitViewMode] =\n useState<OrgUnitViewMode>('TABLE');\n const [orgUnits, setOrgUnits] = useState<readonly OrgUnitRecord[]>([]);\n const [visibleOrgUnits, setVisibleOrgUnits] = useState<\n readonly OrgUnitRecord[]\n >([]);\n const [visiblePositions, setVisiblePositions] = useState<\n readonly PositionRecord[]\n >([]);\n const [positionModal, setPositionModal] = useState<PositionModalState | null>(\n null,\n );\n const [positionPage, setPositionPage] = useState(1);\n const [positionPageSize, setPositionPageSize] = useState(10);\n const [positionSearchText, setPositionSearchText] = useState('');\n const [positionTotalCount, setPositionTotalCount] = useState(0);\n const [positions, setPositions] = useState<readonly PositionRecord[]>([]);\n const [visibleManagerResolutions, setVisibleManagerResolutions] = useState<\n readonly ManagerResolutionRecord[]\n >([]);\n const [visibleMemberships, setVisibleMemberships] = useState<\n readonly MembershipRecord[]\n >([]);\n const [saving, setSaving] = useState(false);\n\n useEffect((): void => {\n if (deleteConfirmation) {\n setLastDeleteConfirmation(deleteConfirmation);\n }\n }, [deleteConfirmation]);\n\n const visibleDeleteConfirmation =\n deleteConfirmation ?? lastDeleteConfirmation;\n\n const refreshOrganization = useCallback(async (): Promise<void> => {\n setLoading(true);\n setError(null);\n\n try {\n const dashboard = await readOrganizationDashboard({\n managerActiveOnly: managerActiveFilter.activeOnly,\n managerPage,\n managerPageSize,\n managerScopeType:\n managerScopeTypeFilter.id === 'ALL'\n ? null\n : managerScopeTypeFilter.id,\n membershipActiveOnly: membershipActiveFilter?.activeOnly ?? false,\n membershipOrgUnitId: membershipOrgUnitFilter?.id ?? null,\n membershipPage,\n membershipPageSize,\n membershipPositionId: membershipPositionFilter?.id ?? null,\n orgUnitPage,\n orgUnitPageSize,\n orgUnitSearchText,\n orgUnitType:\n orgUnitTypeFilter.id === 'ALL' ? null : orgUnitTypeFilter.id,\n positionPage,\n positionPageSize,\n positionSearchText,\n });\n const memberIds = readReferencedMemberIds(\n dashboard.memberships,\n dashboard.managerResolutions,\n );\n const profiles = await resolveMembers(memberIds);\n\n setMemberProfiles(profiles);\n setOrgUnits(dashboard.orgUnits);\n setOrgUnitTotalCount(dashboard.orgUnitCount);\n setVisibleOrgUnits(dashboard.filteredOrgUnits);\n setPositions(dashboard.positions);\n setPositionTotalCount(dashboard.positionCount);\n setVisiblePositions(dashboard.filteredPositions);\n setMembershipTotalCount(dashboard.membershipCount);\n setVisibleMemberships(dashboard.filteredMemberships);\n setManagerTotalCount(dashboard.managerResolutionCount);\n setVisibleManagerResolutions(dashboard.filteredManagerResolutions);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [\n managerActiveFilter,\n managerPage,\n managerPageSize,\n managerScopeTypeFilter,\n membershipActiveFilter,\n membershipOrgUnitFilter,\n membershipPage,\n membershipPageSize,\n membershipPositionFilter,\n orgUnitPage,\n orgUnitPageSize,\n orgUnitSearchText,\n orgUnitTypeFilter,\n positionPage,\n positionPageSize,\n positionSearchText,\n ]);\n\n useEffect((): void => {\n void refreshOrganization();\n }, [refreshOrganization]);\n\n const orgUnitsById = useMemo(\n (): ReadonlyMap<string, OrgUnitRecord> =>\n new Map(orgUnits.map((orgUnit) => [orgUnit.id, orgUnit])),\n [orgUnits],\n );\n const positionsById = useMemo(\n (): ReadonlyMap<string, PositionRecord> =>\n new Map(positions.map((position) => [position.id, position])),\n [positions],\n );\n const membersById = useMemo(\n (): ReadonlyMap<string, MemberProfileRecord> =>\n new Map(memberProfiles.map((member) => [member.memberId, member])),\n [memberProfiles],\n );\n\n const orgRows = useMemo(\n (): OrgUnitRow[] =>\n visibleOrgUnits.map((orgUnit) => ({\n ...orgUnit,\n key: orgUnit.id,\n parentName: orgUnit.parentId\n ? readOrgUnitLabel(orgUnitsById.get(orgUnit.parentId))\n : '根節點',\n typeLabel: readOrgUnitTypeLabel(orgUnit.type),\n })),\n [visibleOrgUnits, orgUnitsById],\n );\n const positionRows = useMemo(\n (): PositionRow[] =>\n visiblePositions.map((position) => ({\n ...position,\n key: position.id,\n })),\n [visiblePositions],\n );\n const membershipRows = useMemo(\n (): MembershipRow[] =>\n visibleMemberships.map((membership) => ({\n ...membership,\n key: membership.id,\n memberName: readMemberLabel(membersById.get(membership.memberId)),\n orgUnitName: readOrgUnitLabel(orgUnitsById.get(membership.orgUnitId)),\n positionName: membership.positionId\n ? readPositionLabel(positionsById.get(membership.positionId))\n : '未指定',\n })),\n [membersById, visibleMemberships, orgUnitsById, positionsById],\n );\n const managerRows = useMemo(\n (): ManagerResolutionRow[] =>\n visibleManagerResolutions.map((resolution) => ({\n ...resolution,\n key: resolution.id,\n managerName: readMemberLabel(\n membersById.get(resolution.managerMemberId),\n ),\n scopeLabel: readScopeLabel(resolution, {\n membersById,\n orgUnitsById,\n positionsById,\n }),\n })),\n [visibleManagerResolutions, membersById, orgUnitsById, positionsById],\n );\n\n const orgActions = useMemo(\n (): TableActions<OrgUnitRow> => ({\n render: (record): ReturnType<TableActions<OrgUnitRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setOrgModal({ record, type: 'EDIT' }),\n },\n {\n name: '停用',\n onClick: (): void =>\n setDeleteConfirmation({\n confirmText: '停用組織',\n description: `停用「${record.name}」後,這個組織節點將不再出現在可用組織清單中。`,\n id: record.id,\n title: '停用組織節點',\n type: 'ORG_UNIT',\n }),\n variant: 'destructive-secondary',\n },\n ],\n variant: 'base-secondary',\n width: 128,\n }),\n [],\n );\n const positionActions = useMemo(\n (): TableActions<PositionRow> => ({\n render: (record): ReturnType<TableActions<PositionRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setPositionModal({ record, type: 'EDIT' }),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [],\n );\n const membershipActions = useMemo(\n (): TableActions<MembershipRow> => ({\n render: (record): ReturnType<TableActions<MembershipRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setMembershipModal({ record, type: 'EDIT' }),\n },\n {\n name: '刪除',\n onClick: (): void =>\n setDeleteConfirmation({\n confirmText: '刪除歸屬',\n description: `刪除「${record.memberName}」在「${record.orgUnitName}」的會員歸屬。`,\n id: record.id,\n title: '刪除會員歸屬',\n type: 'MEMBERSHIP',\n }),\n variant: 'destructive-secondary',\n },\n ],\n variant: 'base-secondary',\n width: 128,\n }),\n [],\n );\n const managerActions = useMemo(\n (): TableActions<ManagerResolutionRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ManagerResolutionRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setManagerModal({ record, type: 'EDIT' }),\n },\n {\n name: '刪除',\n onClick: (): void =>\n setDeleteConfirmation({\n confirmText: '刪除主管規則',\n description: `刪除「${record.scopeLabel}」指派給「${record.managerName}」的主管解析規則。`,\n id: record.id,\n title: '刪除主管解析規則',\n type: 'MANAGER_RESOLUTION',\n }),\n variant: 'destructive-secondary',\n },\n ],\n variant: 'base-secondary',\n width: 128,\n }),\n [],\n );\n\n function updateOrgUnitSearchText(value: string): void {\n setOrgUnitPage(1);\n setOrgUnitSearchText(value);\n }\n\n function updateOrgUnitTypeFilter(value: OrgUnitTypeFilterOption): void {\n setOrgUnitPage(1);\n setOrgUnitTypeFilter(value);\n }\n\n function updatePositionSearchText(value: string): void {\n setPositionPage(1);\n setPositionSearchText(value);\n }\n\n function updateMembershipActiveFilter(value: ActiveFilterOption | null): void {\n setMembershipPage(1);\n setMembershipActiveFilter(value);\n }\n\n function updateMembershipOrgUnitFilter(value: OrgUnitOption | null): void {\n setMembershipPage(1);\n setMembershipOrgUnitFilter(value);\n }\n\n function updateMembershipPositionFilter(value: PositionOption | null): void {\n setMembershipPage(1);\n setMembershipPositionFilter(value);\n }\n\n function updateManagerActiveFilter(value: ActiveFilterOption): void {\n setManagerPage(1);\n setManagerActiveFilter(value);\n }\n\n function updateManagerScopeTypeFilter(value: ScopeTypeFilterOption): void {\n setManagerPage(1);\n setManagerScopeTypeFilter(value);\n }\n\n function closeDeleteConfirmation(): void {\n if (saving) {\n return;\n }\n\n setDeleteConfirmation(null);\n }\n\n async function handleConfirmDelete(): Promise<void> {\n if (!deleteConfirmation) {\n return;\n }\n\n await runMutation(async (): Promise<void> => {\n if (deleteConfirmation.type === 'ORG_UNIT') {\n await deleteOrgUnit(deleteConfirmation.id);\n }\n\n if (deleteConfirmation.type === 'MEMBERSHIP') {\n await deleteMembership(deleteConfirmation.id);\n }\n\n if (deleteConfirmation.type === 'MANAGER_RESOLUTION') {\n await deleteManagerResolution(deleteConfirmation.id);\n }\n\n setDeleteConfirmation(null);\n });\n }\n\n async function saveOrgUnitTreeDraft(\n changes: readonly OrgUnitHierarchyDraftChange[],\n ): Promise<void> {\n setSaving(true);\n setError(null);\n\n try {\n await commitOrgUnitTreeDraft({\n moves: changes.map((change) => {\n const orgUnit = orgUnitsById.get(change.orgUnitId);\n\n return {\n baseUpdatedAt: orgUnit?.updatedAt ?? '',\n id: change.orgUnitId,\n parentId: change.parentId,\n };\n }),\n });\n await refreshOrganization();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n throw requestError;\n } finally {\n setSaving(false);\n }\n }\n\n async function runMutation(mutation: () => Promise<void>): Promise<void> {\n setSaving(true);\n setError(null);\n\n try {\n await mutation();\n await refreshOrganization();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"維護組織樹、職位、會員歸屬與簽核主管解析規則。\"\n title=\"組織管理\"\n />\n </PageHeader>\n\n <SectionGroup>\n <Section\n tab={\n <Tab\n activeKey={activeTab}\n onChange={(key): void => setActiveTab(readAdminOrgTab(key))}\n >\n <TabItem key=\"ORG_UNITS\">組織樹</TabItem>\n <TabItem key=\"POSITIONS\">職位</TabItem>\n <TabItem key=\"MEMBERSHIPS\">會員歸屬</TabItem>\n <TabItem key=\"MANAGERS\">簽核主管</TabItem>\n </Tab>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {activeTab === 'ORG_UNITS' ? (\n <OrgUnitPanel\n actions={orgActions}\n loading={loading}\n onCreate={(): void =>\n setOrgModal({ parentId: null, record: null, type: 'CREATE' })\n }\n onCreateChild={(parentId): void =>\n setOrgModal({ parentId, record: null, type: 'CREATE' })\n }\n onEditOrgUnit={(record): void =>\n setOrgModal({ record, type: 'EDIT' })\n }\n onPageChange={setOrgUnitPage}\n onSaveDraft={saveOrgUnitTreeDraft}\n onPageSizeChange={(pageSize): void => {\n setOrgUnitPage(1);\n setOrgUnitPageSize(pageSize);\n }}\n onSearchTextChange={updateOrgUnitSearchText}\n onTypeFilterChange={updateOrgUnitTypeFilter}\n orgUnits={orgUnits}\n page={orgUnitPage}\n pageSize={orgUnitPageSize}\n rows={orgRows}\n searchText={orgUnitSearchText}\n saving={saving}\n total={orgUnitTotalCount}\n typeFilter={orgUnitTypeFilter}\n viewMode={orgUnitViewMode}\n onViewModeChange={setOrgUnitViewMode}\n />\n ) : null}\n {activeTab === 'POSITIONS' ? (\n <PositionPanel\n actions={positionActions}\n loading={loading}\n onCreate={(): void =>\n setPositionModal({ record: null, type: 'CREATE' })\n }\n onPageChange={setPositionPage}\n onPageSizeChange={(pageSize): void => {\n setPositionPage(1);\n setPositionPageSize(pageSize);\n }}\n onSearchTextChange={updatePositionSearchText}\n page={positionPage}\n pageSize={positionPageSize}\n rows={positionRows}\n searchText={positionSearchText}\n total={positionTotalCount}\n />\n ) : null}\n {activeTab === 'MEMBERSHIPS' ? (\n <MembershipPanel\n actions={membershipActions}\n loading={loading}\n onCreate={(): void =>\n setMembershipModal({ record: null, type: 'CREATE' })\n }\n onActiveFilterChange={updateMembershipActiveFilter}\n onOrgUnitFilterChange={updateMembershipOrgUnitFilter}\n onPageChange={setMembershipPage}\n onPageSizeChange={(pageSize): void => {\n setMembershipPage(1);\n setMembershipPageSize(pageSize);\n }}\n onPositionFilterChange={updateMembershipPositionFilter}\n orgUnitFilter={membershipOrgUnitFilter}\n orgUnits={orgUnits}\n page={membershipPage}\n pageSize={membershipPageSize}\n positionFilter={membershipPositionFilter}\n positions={positions}\n rows={membershipRows}\n statusFilter={membershipActiveFilter}\n total={membershipTotalCount}\n />\n ) : null}\n {activeTab === 'MANAGERS' ? (\n <ManagerPanel\n actions={managerActions}\n loading={loading}\n onCreate={(): void =>\n setManagerModal({ record: null, type: 'CREATE' })\n }\n onActiveFilterChange={updateManagerActiveFilter}\n onPageChange={setManagerPage}\n onPageSizeChange={(pageSize): void => {\n setManagerPage(1);\n setManagerPageSize(pageSize);\n }}\n onScopeTypeFilterChange={updateManagerScopeTypeFilter}\n page={managerPage}\n pageSize={managerPageSize}\n rows={managerRows}\n scopeTypeFilter={managerScopeTypeFilter}\n statusFilter={managerActiveFilter}\n total={managerTotalCount}\n />\n ) : null}\n </Section>\n </SectionGroup>\n\n <OrgUnitModal\n modal={orgModal}\n onClose={(): void => setOrgModal(null)}\n onSubmit={(input): Promise<void> =>\n runMutation(async (): Promise<void> => {\n if (orgModal?.type === 'EDIT' && orgModal.record) {\n await updateOrgUnit({\n ...input,\n id: orgModal.record.id,\n metadataJson: null,\n });\n } else {\n await createOrgUnit({\n code: input.code ?? '',\n metadataJson: '{}',\n name: input.name ?? '',\n parentId: input.parentId,\n type: input.type ?? 'DEPARTMENT',\n });\n }\n setOrgModal(null);\n })\n }\n orgUnits={orgUnits}\n saving={saving}\n />\n <PositionModal\n modal={positionModal}\n onClose={(): void => setPositionModal(null)}\n onSubmit={(input): Promise<void> =>\n runMutation(async (): Promise<void> => {\n if (positionModal?.type === 'EDIT' && positionModal.record) {\n await updatePosition({\n ...input,\n id: positionModal.record.id,\n metadataJson: null,\n });\n } else {\n await createPosition({\n code: input.code ?? '',\n level: input.level ?? 0,\n metadataJson: '{}',\n name: input.name ?? '',\n });\n }\n setPositionModal(null);\n })\n }\n saving={saving}\n />\n <MembershipModal\n membersById={membersById}\n modal={membershipModal}\n onClose={(): void => setMembershipModal(null)}\n onSubmit={(input): Promise<void> =>\n runMutation(async (): Promise<void> => {\n if (membershipModal?.type === 'EDIT' && membershipModal.record) {\n await updateMembership({\n ...input,\n id: membershipModal.record.id,\n });\n } else {\n await createMembership({\n effectiveFrom: input.effectiveFrom ?? today(),\n effectiveTo: input.effectiveTo,\n isPrimary: input.isPrimary ?? false,\n memberId: input.memberId ?? '',\n orgUnitId: input.orgUnitId ?? '',\n positionId: input.positionId,\n });\n }\n setMembershipModal(null);\n })\n }\n orgUnits={orgUnits}\n positions={positions}\n saving={saving}\n />\n <ManagerResolutionModal\n membersById={membersById}\n modal={managerModal}\n onClose={(): void => setManagerModal(null)}\n onSubmit={(input): Promise<void> =>\n runMutation(async (): Promise<void> => {\n if (managerModal?.type === 'EDIT' && managerModal.record) {\n await updateManagerResolution({\n ...input,\n id: managerModal.record.id,\n });\n } else {\n await createManagerResolution({\n effectiveFrom: input.effectiveFrom ?? today(),\n effectiveTo: input.effectiveTo,\n managerMemberId: input.managerMemberId ?? '',\n priority: input.priority ?? 0,\n scopeId: input.scopeId ?? '',\n scopeType: input.scopeType ?? 'MEMBER',\n });\n }\n setManagerModal(null);\n })\n }\n orgUnits={orgUnits}\n positions={positions}\n saving={saving}\n />\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ variant: 'destructive-primary' }}\n confirmText={visibleDeleteConfirmation?.confirmText ?? ''}\n loading={saving}\n modalStatusType=\"error\"\n modalType=\"standard\"\n onCancel={closeDeleteConfirmation}\n onClose={closeDeleteConfirmation}\n onConfirm={(): void => void handleConfirmDelete()}\n open={Boolean(deleteConfirmation)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n supportingText=\"此操作會立即套用,請確認後再繼續。\"\n title={visibleDeleteConfirmation?.title ?? ''}\n >\n <Typography color=\"text-neutral\" variant=\"body\">\n {visibleDeleteConfirmation?.description ?? ''}\n </Typography>\n </Modal>\n </>\n );\n}\n\nfunction OrgUnitPanel({\n actions,\n loading,\n onCreate,\n onCreateChild,\n onEditOrgUnit,\n onPageChange,\n onSaveDraft,\n onPageSizeChange,\n onSearchTextChange,\n onTypeFilterChange,\n onViewModeChange,\n orgUnits,\n page,\n pageSize,\n rows,\n searchText,\n saving,\n total,\n typeFilter,\n viewMode,\n}: {\n readonly actions: TableActions<OrgUnitRow>;\n readonly loading: boolean;\n readonly onCreate: () => void;\n readonly onCreateChild: (parentId: string) => void;\n readonly onEditOrgUnit: (record: OrgUnitRecord) => void;\n readonly onPageChange: (page: number) => void;\n readonly onSaveDraft: (\n changes: readonly OrgUnitHierarchyDraftChange[],\n ) => Promise<void>;\n readonly onPageSizeChange: (pageSize: number) => void;\n readonly onSearchTextChange: (value: string) => void;\n readonly onTypeFilterChange: (value: OrgUnitTypeFilterOption) => void;\n readonly onViewModeChange: (mode: OrgUnitViewMode) => void;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly page: number;\n readonly pageSize: number;\n readonly rows: readonly OrgUnitRow[];\n readonly searchText: string;\n readonly saving: boolean;\n readonly total: number;\n readonly typeFilter: OrgUnitTypeFilterOption;\n readonly viewMode: OrgUnitViewMode;\n}): ReactElement {\n const treeEditorRef = useRef<OrgUnitTreeDraftEditorHandle | null>(null);\n const [treeEditorState, setTreeEditorState] =\n useState<OrgUnitTreeDraftEditorState>(INITIAL_ORG_TREE_EDITOR_STATE);\n const nextViewMode: OrgUnitViewMode = viewMode === 'TABLE' ? 'FLOW' : 'TABLE';\n const viewModeToggleLabel = viewMode === 'TABLE' ? '切換樹狀圖' : '切換表格';\n const isTreeMode = viewMode === 'FLOW';\n const primaryActionLabel = readOrgUnitPrimaryActionLabel({\n isTreeMode,\n isTreeEditing: treeEditorState.isEditing,\n });\n const primaryActionIcon = readOrgUnitPrimaryActionIcon({\n isTreeMode,\n isTreeEditing: treeEditorState.isEditing,\n });\n const primaryActionDisabled = readOrgUnitPrimaryActionDisabled({\n hasDraftChanges: treeEditorState.hasDraftChanges,\n isTreeEditing: treeEditorState.isEditing,\n isTreeMode,\n loading,\n saving,\n });\n const columns = useMemo(\n (): TableColumn<OrgUnitRow>[] => [\n { dataIndex: 'code', key: 'code', title: '代碼', width: 180 },\n { dataIndex: 'name', key: 'name', title: '名稱', width: 240 },\n { dataIndex: 'typeLabel', key: 'typeLabel', title: '類型', width: 120 },\n { dataIndex: 'parentName', key: 'parentName', title: '上層', width: 280 },\n { dataIndex: 'path', key: 'path', title: 'Path', width: 420 },\n ],\n [],\n );\n\n useEffect((): void => {\n if (viewMode === 'TABLE') {\n setTreeEditorState(INITIAL_ORG_TREE_EDITOR_STATE);\n }\n }, [viewMode]);\n\n return (\n <>\n <PanelIntro\n actionDisabled={primaryActionDisabled}\n actionIcon={primaryActionIcon}\n actionLabel={primaryActionLabel}\n actions={\n <>\n <Button\n onClick={(): void => onViewModeChange(nextViewMode)}\n variant=\"base-secondary\"\n >\n {viewModeToggleLabel}\n </Button>\n {isTreeMode && treeEditorState.isEditing ? (\n <Button\n disabled={saving}\n icon={CloseIcon}\n iconType=\"leading\"\n onClick={(): void => treeEditorRef.current?.cancelEditing()}\n variant=\"base-secondary\"\n >\n 取消\n </Button>\n ) : null}\n </>\n }\n description=\"組織節點使用 ltree path 維護階層,搬移節點會同步更新子節點 path。\"\n onCreate={(): void => {\n if (!isTreeMode) {\n onCreate();\n return;\n }\n\n if (treeEditorState.isEditing) {\n void treeEditorRef.current?.saveDraft();\n return;\n }\n\n treeEditorRef.current?.startEditing();\n }}\n title=\"組織樹\"\n />\n {viewMode === 'TABLE' ? (\n <>\n <FilterArea className={styles.orgFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"orgUnitSearchText\"\n >\n <Input\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onSearchTextChange(event.target.value)\n }\n placeholder=\"搜尋組織名稱或代碼\"\n size=\"sub\"\n value={searchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"orgUnitTypeFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n onTypeFilterChange(readOrgUnitTypeFilterOption(option))\n }\n options={[...ORG_UNIT_TYPE_FILTER_OPTIONS]}\n placeholder=\"類型\"\n size=\"sub\"\n value={typeFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n <div className={styles.tableFrame}>\n <Table\n actions={actions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n })}\n style={{ minWidth: ORG_UNIT_TABLE_MIN_WIDTH }}\n />\n </div>\n </>\n ) : (\n <OrgUnitTreeDraftEditor\n ref={treeEditorRef}\n onCreateChild={onCreateChild}\n onCreateRoot={onCreate}\n onEditOrgUnit={onEditOrgUnit}\n onSaveDraft={onSaveDraft}\n onStateChange={setTreeEditorState}\n orgUnits={orgUnits}\n saving={saving}\n />\n )}\n </>\n );\n}\n\nfunction PositionPanel({\n actions,\n loading,\n onCreate,\n onPageChange,\n onPageSizeChange,\n onSearchTextChange,\n page,\n pageSize,\n rows,\n searchText,\n total,\n}: {\n readonly actions: TableActions<PositionRow>;\n readonly loading: boolean;\n readonly onCreate: () => void;\n readonly onPageChange: (page: number) => void;\n readonly onPageSizeChange: (pageSize: number) => void;\n readonly onSearchTextChange: (value: string) => void;\n readonly page: number;\n readonly pageSize: number;\n readonly rows: readonly PositionRow[];\n readonly searchText: string;\n readonly total: number;\n}): ReactElement {\n const columns = useMemo(\n (): TableColumn<PositionRow>[] => [\n { dataIndex: 'code', key: 'code', title: '代碼', width: 180 },\n { dataIndex: 'name', key: 'name', title: '名稱', width: 280 },\n { dataIndex: 'level', key: 'level', title: '職等', width: 96 },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n\n return (\n <>\n <PanelIntro\n actionLabel=\"新增職位\"\n description=\"職位提供會員歸屬與主管解析規則使用。\"\n onCreate={onCreate}\n title=\"職位\"\n />\n <FilterArea className={styles.orgFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"positionSearchText\"\n >\n <Input\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onSearchTextChange(event.target.value)\n }\n placeholder=\"搜尋職位名稱或代碼\"\n size=\"sub\"\n value={searchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n <div className={styles.tableFrame}>\n <Table\n actions={actions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n })}\n style={{ minWidth: POSITION_TABLE_MIN_WIDTH }}\n />\n </div>\n </>\n );\n}\n\nfunction MembershipPanel({\n actions,\n loading,\n onCreate,\n onActiveFilterChange,\n onOrgUnitFilterChange,\n onPageChange,\n onPageSizeChange,\n onPositionFilterChange,\n orgUnitFilter,\n orgUnits,\n page,\n pageSize,\n positionFilter,\n positions,\n rows,\n statusFilter,\n total,\n}: {\n readonly actions: TableActions<MembershipRow>;\n readonly loading: boolean;\n readonly onCreate: () => void;\n readonly onActiveFilterChange: (value: ActiveFilterOption | null) => void;\n readonly onOrgUnitFilterChange: (value: OrgUnitOption | null) => void;\n readonly onPageChange: (page: number) => void;\n readonly onPageSizeChange: (pageSize: number) => void;\n readonly onPositionFilterChange: (value: PositionOption | null) => void;\n readonly orgUnitFilter: OrgUnitOption | null;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly page: number;\n readonly pageSize: number;\n readonly positionFilter: PositionOption | null;\n readonly positions: readonly PositionRecord[];\n readonly rows: readonly MembershipRow[];\n readonly statusFilter: ActiveFilterOption | null;\n readonly total: number;\n}): ReactElement {\n const columns = useMemo(\n (): TableColumn<MembershipRow>[] => [\n { dataIndex: 'memberName', key: 'memberName', title: '會員', width: 280 },\n {\n dataIndex: 'orgUnitName',\n key: 'orgUnitName',\n title: '組織',\n width: 280,\n },\n {\n dataIndex: 'positionName',\n key: 'positionName',\n title: '職位',\n width: 220,\n },\n {\n key: 'isPrimary',\n render: (record: MembershipRow): string =>\n record.isPrimary ? '主要' : '一般',\n title: '類型',\n width: 104,\n },\n {\n dataIndex: 'effectiveFrom',\n key: 'effectiveFrom',\n title: '生效日',\n width: 140,\n },\n {\n dataIndex: 'effectiveTo',\n key: 'effectiveTo',\n title: '結束日',\n width: 140,\n },\n ],\n [],\n );\n const orgUnitOptions = useMemo(\n (): readonly OrgUnitOption[] => orgUnits.map(readOrgUnitOption),\n [orgUnits],\n );\n const positionOptions = useMemo(\n (): readonly PositionOption[] => positions.map(readPositionOption),\n [positions],\n );\n\n return (\n <>\n <PanelIntro\n actionLabel=\"新增歸屬\"\n description=\"會員歸屬是 BPM 內部組織權限、主管解析與條件判斷的來源。\"\n onCreate={onCreate}\n title=\"會員歸屬\"\n />\n <FilterArea\n className={[styles.orgFilterArea, styles.membershipFilterArea].join(\n ' ',\n )}\n size=\"sub\"\n >\n <FilterLine>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"membershipOrgUnitFilter\"\n >\n <AutoComplete\n disabledOptionsFilter\n emptyText=\"沒有符合的組織\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name: 'membershipOrgUnitFilter',\n spellCheck: false,\n }}\n mode=\"single\"\n name=\"membershipOrgUnitFilter\"\n onChange={(option): void =>\n onOrgUnitFilterChange(readOrgUnitOptionFromValue(option))\n }\n options={[...orgUnitOptions]}\n placeholder=\"全部組織\"\n size=\"sub\"\n value={orgUnitFilter}\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"membershipPositionFilter\"\n >\n <AutoComplete\n disabledOptionsFilter\n emptyText=\"沒有符合的職位\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name: 'membershipPositionFilter',\n spellCheck: false,\n }}\n mode=\"single\"\n name=\"membershipPositionFilter\"\n onChange={(option): void =>\n onPositionFilterChange(readPositionOptionFromValue(option))\n }\n options={[...positionOptions]}\n placeholder=\"全部職位\"\n size=\"sub\"\n value={positionFilter}\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"membershipStatusFilter\"\n >\n <AutoComplete\n disabledOptionsFilter\n emptyText=\"沒有符合的狀態\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name: 'membershipStatusFilter',\n spellCheck: false,\n }}\n mode=\"single\"\n name=\"membershipStatusFilter\"\n onChange={(option): void =>\n onActiveFilterChange(readNullableActiveFilterOption(option))\n }\n options={[...ACTIVE_FILTER_OPTIONS]}\n placeholder=\"全部狀態\"\n size=\"sub\"\n value={statusFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n <div className={styles.tableFrame}>\n <Table\n actions={actions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n })}\n style={{ minWidth: MEMBERSHIP_TABLE_MIN_WIDTH }}\n />\n </div>\n </>\n );\n}\n\nfunction ManagerPanel({\n actions,\n loading,\n onCreate,\n onActiveFilterChange,\n onPageChange,\n onPageSizeChange,\n onScopeTypeFilterChange,\n page,\n pageSize,\n rows,\n scopeTypeFilter,\n statusFilter,\n total,\n}: {\n readonly actions: TableActions<ManagerResolutionRow>;\n readonly loading: boolean;\n readonly onCreate: () => void;\n readonly onActiveFilterChange: (value: ActiveFilterOption) => void;\n readonly onPageChange: (page: number) => void;\n readonly onPageSizeChange: (pageSize: number) => void;\n readonly onScopeTypeFilterChange: (value: ScopeTypeFilterOption) => void;\n readonly page: number;\n readonly pageSize: number;\n readonly rows: readonly ManagerResolutionRow[];\n readonly scopeTypeFilter: ScopeTypeFilterOption;\n readonly statusFilter: ActiveFilterOption;\n readonly total: number;\n}): ReactElement {\n const columns = useMemo(\n (): TableColumn<ManagerResolutionRow>[] => [\n {\n dataIndex: 'scopeLabel',\n key: 'scopeLabel',\n title: '套用範圍',\n width: 320,\n },\n {\n dataIndex: 'managerName',\n key: 'managerName',\n title: '簽核主管',\n width: 300,\n },\n { dataIndex: 'priority', key: 'priority', title: '優先序', width: 96 },\n {\n dataIndex: 'effectiveFrom',\n key: 'effectiveFrom',\n title: '生效日',\n width: 140,\n },\n {\n dataIndex: 'effectiveTo',\n key: 'effectiveTo',\n title: '結束日',\n width: 140,\n },\n ],\n [],\n );\n\n return (\n <>\n <PanelIntro\n actionLabel=\"新增主管規則\"\n description=\"簽核主管規則獨立於組織樹 parent,解析優先序為會員、組織、職位。\"\n onCreate={onCreate}\n title=\"簽核主管\"\n />\n <FilterArea className={styles.orgFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"managerScopeTypeFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n onScopeTypeFilterChange(readScopeTypeFilterOption(option))\n }\n options={[...SCOPE_TYPE_FILTER_OPTIONS]}\n placeholder=\"套用範圍\"\n size=\"sub\"\n value={scopeTypeFilter}\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"managerStatusFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n onActiveFilterChange(readActiveFilterOption(option))\n }\n options={[...ACTIVE_FILTER_OPTIONS]}\n placeholder=\"狀態\"\n size=\"sub\"\n value={statusFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n <div className={styles.tableFrame}>\n <Table\n actions={actions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n })}\n style={{ minWidth: MANAGER_TABLE_MIN_WIDTH }}\n />\n </div>\n </>\n );\n}\n\nfunction createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n}: TablePaginationState): {\n current: number;\n onChange: (page: number) => void;\n onChangePageSize: (pageSize: number) => void;\n pageSize: number;\n pageSizeLabel: string;\n pageSizeOptions: number[];\n renderResultSummary: (from: number, to: number, total: number) => string;\n showPageSizeOptions: true;\n total: number;\n} {\n return {\n current: page,\n onChange: onPageChange,\n onChangePageSize: onPageSizeChange,\n pageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: [...ORGANIZATION_TABLE_PAGE_SIZE_OPTIONS],\n renderResultSummary: (from, to, resultTotal): string =>\n `顯示 ${from}-${to} 筆,共 ${resultTotal} 筆`,\n showPageSizeOptions: true,\n total,\n };\n}\n\nfunction readOrgUnitPrimaryActionLabel({\n isTreeEditing,\n isTreeMode,\n}: {\n readonly isTreeEditing: boolean;\n readonly isTreeMode: boolean;\n}): string {\n if (!isTreeMode) {\n return '新增組織';\n }\n\n return isTreeEditing ? '儲存' : '開始編輯';\n}\n\nfunction readOrgUnitPrimaryActionIcon({\n isTreeEditing,\n isTreeMode,\n}: {\n readonly isTreeEditing: boolean;\n readonly isTreeMode: boolean;\n}): IconDefinition {\n if (!isTreeMode) {\n return PlusIcon;\n }\n\n return isTreeEditing ? SaveIcon : EditIcon;\n}\n\nfunction readOrgUnitPrimaryActionDisabled({\n hasDraftChanges,\n isTreeEditing,\n isTreeMode,\n loading,\n saving,\n}: {\n readonly hasDraftChanges: boolean;\n readonly isTreeEditing: boolean;\n readonly isTreeMode: boolean;\n readonly loading: boolean;\n readonly saving: boolean;\n}): boolean {\n if (!isTreeMode) {\n return false;\n }\n\n if (!isTreeEditing) {\n return loading;\n }\n\n return !hasDraftChanges || saving;\n}\n\nfunction PanelIntro({\n actionDisabled = false,\n actionIcon = PlusIcon,\n actionLabel,\n actions,\n description,\n onCreate,\n title,\n}: {\n readonly actionDisabled?: boolean;\n readonly actionIcon?: IconDefinition;\n readonly actionLabel: string;\n readonly actions?: ReactElement;\n readonly description: string;\n readonly onCreate: () => void;\n readonly title: string;\n}): ReactElement {\n return (\n <div className={styles.tableIntro}>\n <div>\n <Typography component=\"h2\" variant=\"h3\">\n {title}\n </Typography>\n <Typography color=\"text-neutral\" variant=\"body\">\n {description}\n </Typography>\n </div>\n <div className={styles.tableIntroActions}>\n {actions}\n <Button\n disabled={actionDisabled}\n icon={actionIcon}\n iconType=\"leading\"\n onClick={onCreate}\n >\n {actionLabel}\n </Button>\n </div>\n </div>\n );\n}\n\nfunction OrgUnitModal({\n modal,\n onClose,\n onSubmit,\n orgUnits,\n saving,\n}: {\n readonly modal: OrgModalState | null;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly code: string | null;\n readonly name: string | null;\n readonly parentId: string | null;\n readonly type: OrgUnitType | null;\n }) => Promise<void>;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly saving: boolean;\n}): ReactElement {\n const [code, setCode] = useState('');\n const [name, setName] = useState('');\n const [parent, setParent] = useState<OrgUnitOption | null>(null);\n const [type, setType] = useState<OrgUnitTypeOption>(ORG_UNIT_TYPES[2]);\n\n useEffect((): void => {\n if (!modal) {\n return;\n }\n\n const record = modal.record;\n const parentId = record?.parentId ?? modal.parentId ?? null;\n const parentOrgUnit = parentId\n ? (orgUnits.find((orgUnit) => orgUnit.id === parentId) ?? null)\n : null;\n\n setCode(record?.code ?? '');\n setName(record?.name ?? '');\n setParent(parentOrgUnit ? readOrgUnitOption(parentOrgUnit) : null);\n setType(\n ORG_UNIT_TYPES.find((option) => option.id === record?.type) ??\n ORG_UNIT_TYPES[2],\n );\n }, [modal, orgUnits]);\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !code || !name }}\n confirmText={modal?.type === 'EDIT' ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void =>\n void onSubmit({\n code,\n name,\n parentId: parent?.id ?? null,\n type: type.id,\n })\n }\n open={Boolean(modal)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={modal?.type === 'EDIT' ? '編輯組織' : '新增組織'}\n >\n <div className={styles.modalFields}>\n <OrgModalTextField\n label=\"代碼\"\n name=\"orgCode\"\n onChange={setCode}\n placeholder=\"例如 FIN-TW\"\n value={code}\n />\n <OrgModalTextField\n label=\"名稱\"\n name=\"orgName\"\n onChange={setName}\n placeholder=\"例如 財務部\"\n value={name}\n />\n <BPMFormField label=\"類型\" name=\"orgType\">\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => setType(readOrgUnitTypeOption(option))}\n options={[...ORG_UNIT_TYPES]}\n placeholder=\"選擇組織類型\"\n value={type}\n />\n </BPMFormField>\n <BPMFormField label=\"上層組織\" name=\"parentId\">\n <OrgUnitPicker\n name=\"parentId\"\n onChange={setParent}\n orgUnits={orgUnits.filter(\n (orgUnit) => orgUnit.id !== modal?.record?.id,\n )}\n placeholder=\"選擇上層組織\"\n value={parent}\n />\n </BPMFormField>\n </div>\n </Modal>\n );\n}\n\nfunction PositionModal({\n modal,\n onClose,\n onSubmit,\n saving,\n}: {\n readonly modal: PositionModalState | null;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly code: string | null;\n readonly level: number | null;\n readonly name: string | null;\n }) => Promise<void>;\n readonly saving: boolean;\n}): ReactElement {\n const [code, setCode] = useState('');\n const [level, setLevel] = useState('0');\n const [name, setName] = useState('');\n\n useEffect((): void => {\n if (!modal) {\n return;\n }\n\n setCode(modal.record?.code ?? '');\n setLevel(String(modal.record?.level ?? 0));\n setName(modal.record?.name ?? '');\n }, [modal]);\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !code || !name }}\n confirmText={modal?.type === 'EDIT' ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void =>\n void onSubmit({\n code,\n level: Number(level),\n name,\n })\n }\n open={Boolean(modal)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={modal?.type === 'EDIT' ? '編輯職位' : '新增職位'}\n >\n <div className={styles.modalFields}>\n <OrgModalTextField\n label=\"代碼\"\n name=\"positionCode\"\n onChange={setCode}\n placeholder=\"例如 FIN-MGR\"\n value={code}\n />\n <OrgModalTextField\n label=\"名稱\"\n name=\"positionName\"\n onChange={setName}\n placeholder=\"例如 財務主管\"\n value={name}\n />\n <OrgModalTextField\n label=\"職等\"\n name=\"positionLevel\"\n onChange={setLevel}\n placeholder=\"例如 5\"\n value={level}\n />\n </div>\n </Modal>\n );\n}\n\nfunction MembershipModal({\n membersById,\n modal,\n onClose,\n onSubmit,\n orgUnits,\n positions,\n saving,\n}: {\n readonly membersById: ReadonlyMap<string, MemberProfileRecord>;\n readonly modal: MembershipModalState | null;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly effectiveFrom: string | null;\n readonly effectiveTo: string | null;\n readonly isPrimary: boolean | null;\n readonly memberId: string | null;\n readonly orgUnitId: string | null;\n readonly positionId: string | null;\n }) => Promise<void>;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly positions: readonly PositionRecord[];\n readonly saving: boolean;\n}): ReactElement {\n const [effectiveFrom, setEffectiveFrom] = useState(today());\n const [effectiveTo, setEffectiveTo] = useState('');\n const [isPrimary, setIsPrimary] = useState<PrimaryOption>(PRIMARY_OPTIONS[1]);\n const [member, setMember] = useState<MemberOption | null>(null);\n const [orgUnit, setOrgUnit] = useState<OrgUnitOption | null>(null);\n const [position, setPosition] = useState<PositionOption | null>(null);\n\n useEffect((): void => {\n if (!modal) {\n return;\n }\n\n const record = modal.record;\n const profile = record ? membersById.get(record.memberId) : null;\n\n setEffectiveFrom(record?.effectiveFrom ?? today());\n setEffectiveTo(record?.effectiveTo ?? '');\n setIsPrimary(\n PRIMARY_OPTIONS.find((option) => option.value === record?.isPrimary) ??\n PRIMARY_OPTIONS[1],\n );\n setMember(profile ? readMemberOption(profile) : null);\n setOrgUnit(\n readNullableOption(\n orgUnits.find((candidate) => candidate.id === record?.orgUnitId),\n readOrgUnitOption,\n ),\n );\n setPosition(\n readNullableOption(\n positions.find((candidate) => candidate.id === record?.positionId),\n readPositionOption,\n ),\n );\n }, [membersById, modal, orgUnits, positions]);\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !member || !orgUnit }}\n confirmText={modal?.type === 'EDIT' ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void =>\n void onSubmit({\n effectiveFrom,\n effectiveTo: effectiveTo || null,\n isPrimary: isPrimary.value,\n memberId: member?.id ?? null,\n orgUnitId: orgUnit?.id ?? null,\n positionId: position?.id ?? null,\n })\n }\n open={Boolean(modal)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={modal?.type === 'EDIT' ? '編輯會員歸屬' : '新增會員歸屬'}\n >\n <div className={styles.modalFields}>\n <BPMFormField label=\"會員\" name=\"memberId\">\n <MemberPicker\n name=\"memberId\"\n onChange={setMember}\n placeholder=\"搜尋會員姓名或信箱\"\n value={member}\n />\n </BPMFormField>\n <BPMFormField label=\"組織\" name=\"orgUnitId\">\n <OrgUnitPicker\n name=\"orgUnitId\"\n onChange={setOrgUnit}\n orgUnits={orgUnits}\n placeholder=\"選擇歸屬組織\"\n value={orgUnit}\n />\n </BPMFormField>\n <BPMFormField label=\"職位\" name=\"positionId\">\n <PositionPicker\n name=\"positionId\"\n onChange={setPosition}\n placeholder=\"選擇職位\"\n positions={positions}\n value={position}\n />\n </BPMFormField>\n <BPMFormField label=\"歸屬類型\" name=\"isPrimary\">\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => setIsPrimary(readPrimaryOption(option))}\n options={[...PRIMARY_OPTIONS]}\n placeholder=\"選擇歸屬類型\"\n value={isPrimary}\n />\n </BPMFormField>\n <DateField\n label=\"生效日\"\n name=\"membershipEffectiveFrom\"\n onChange={setEffectiveFrom}\n placeholder=\"YYYY-MM-DD\"\n value={effectiveFrom}\n />\n <DateField\n label=\"結束日\"\n name=\"membershipEffectiveTo\"\n onChange={setEffectiveTo}\n placeholder=\"YYYY-MM-DD,未設定代表無期限\"\n value={effectiveTo}\n />\n </div>\n </Modal>\n );\n}\n\nfunction ManagerResolutionModal({\n membersById,\n modal,\n onClose,\n onSubmit,\n orgUnits,\n positions,\n saving,\n}: {\n readonly membersById: ReadonlyMap<string, MemberProfileRecord>;\n readonly modal: ManagerModalState | null;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly effectiveFrom: string | null;\n readonly effectiveTo: string | null;\n readonly managerMemberId: string | null;\n readonly priority: number | null;\n readonly scopeId: string | null;\n readonly scopeType: ManagerResolutionScopeType | null;\n }) => Promise<void>;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly positions: readonly PositionRecord[];\n readonly saving: boolean;\n}): ReactElement {\n const [effectiveFrom, setEffectiveFrom] = useState(today());\n const [effectiveTo, setEffectiveTo] = useState('');\n const [manager, setManager] = useState<MemberOption | null>(null);\n const [priority, setPriority] = useState('0');\n const [scopeMember, setScopeMember] = useState<MemberOption | null>(null);\n const [scopeOrgUnit, setScopeOrgUnit] = useState<OrgUnitOption | null>(null);\n const [scopePosition, setScopePosition] = useState<PositionOption | null>(\n null,\n );\n const [scopeType, setScopeType] = useState<ScopeTypeOption>(SCOPE_TYPES[0]);\n\n useEffect((): void => {\n if (!modal) {\n return;\n }\n\n const record = modal.record;\n const nextScopeType =\n SCOPE_TYPES.find((option) => option.id === record?.scopeType) ??\n SCOPE_TYPES[0];\n\n setEffectiveFrom(record?.effectiveFrom ?? today());\n setEffectiveTo(record?.effectiveTo ?? '');\n setManager(\n readNullableOption(\n record ? membersById.get(record.managerMemberId) : null,\n readMemberOption,\n ),\n );\n setPriority(String(record?.priority ?? 0));\n setScopeMember(\n nextScopeType.id === 'MEMBER'\n ? readNullableOption(\n record ? membersById.get(record.scopeId) : null,\n readMemberOption,\n )\n : null,\n );\n setScopeOrgUnit(\n nextScopeType.id === 'ORG_UNIT'\n ? readNullableOption(\n orgUnits.find((candidate) => candidate.id === record?.scopeId),\n readOrgUnitOption,\n )\n : null,\n );\n setScopePosition(\n nextScopeType.id === 'POSITION'\n ? readNullableOption(\n positions.find((candidate) => candidate.id === record?.scopeId),\n readPositionOption,\n )\n : null,\n );\n setScopeType(nextScopeType);\n }, [membersById, modal, orgUnits, positions]);\n\n const scopeId =\n scopeType.id === 'MEMBER'\n ? scopeMember?.id\n : scopeType.id === 'ORG_UNIT'\n ? scopeOrgUnit?.id\n : scopePosition?.id;\n const isSelfManagerResolution = Boolean(\n scopeType.id === 'MEMBER' &&\n scopeMember?.id &&\n manager?.id &&\n scopeMember.id === manager.id,\n );\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{\n disabled: !manager || !scopeId || isSelfManagerResolution,\n }}\n confirmText={modal?.type === 'EDIT' ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void =>\n void onSubmit({\n effectiveFrom,\n effectiveTo: effectiveTo || null,\n managerMemberId: manager?.id ?? null,\n priority: Number(priority),\n scopeId: scopeId ?? null,\n scopeType: scopeType.id,\n })\n }\n open={Boolean(modal)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={modal?.type === 'EDIT' ? '編輯主管規則' : '新增主管規則'}\n >\n <div className={styles.modalFields}>\n <BPMFormField label=\"套用範圍\" name=\"scopeType\">\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n setScopeType(readScopeTypeOption(option))\n }\n options={[...SCOPE_TYPES]}\n placeholder=\"選擇套用範圍\"\n value={scopeType}\n />\n </BPMFormField>\n {scopeType.id === 'MEMBER' ? (\n <BPMFormField label=\"會員\" name=\"scopeMemberId\">\n <MemberPicker\n name=\"scopeMemberId\"\n onChange={setScopeMember}\n placeholder=\"搜尋套用會員\"\n value={scopeMember}\n />\n </BPMFormField>\n ) : null}\n {scopeType.id === 'ORG_UNIT' ? (\n <BPMFormField label=\"組織\" name=\"scopeOrgUnitId\">\n <OrgUnitPicker\n name=\"scopeOrgUnitId\"\n onChange={setScopeOrgUnit}\n orgUnits={orgUnits}\n placeholder=\"選擇套用組織\"\n value={scopeOrgUnit}\n />\n </BPMFormField>\n ) : null}\n {scopeType.id === 'POSITION' ? (\n <BPMFormField label=\"職位\" name=\"scopePositionId\">\n <PositionPicker\n name=\"scopePositionId\"\n onChange={setScopePosition}\n placeholder=\"選擇套用職位\"\n positions={positions}\n value={scopePosition}\n />\n </BPMFormField>\n ) : null}\n <BPMFormField label=\"簽核主管\" name=\"managerMemberId\">\n <MemberPicker\n name=\"managerMemberId\"\n onChange={setManager}\n placeholder=\"搜尋簽核主管\"\n value={manager}\n />\n </BPMFormField>\n {isSelfManagerResolution ? (\n <Typography color=\"text-error\" variant=\"caption\">\n 簽核主管不可設定為套用會員本人。\n </Typography>\n ) : null}\n <OrgModalTextField\n label=\"優先序\"\n name=\"managerPriority\"\n onChange={setPriority}\n placeholder=\"例如 10\"\n value={priority}\n />\n <DateField\n label=\"生效日\"\n name=\"managerEffectiveFrom\"\n onChange={setEffectiveFrom}\n placeholder=\"YYYY-MM-DD\"\n value={effectiveFrom}\n />\n <DateField\n label=\"結束日\"\n name=\"managerEffectiveTo\"\n onChange={setEffectiveTo}\n placeholder=\"YYYY-MM-DD,未設定代表無期限\"\n value={effectiveTo}\n />\n </div>\n </Modal>\n );\n}\n\nfunction OrgModalTextField({\n label,\n name,\n onChange,\n placeholder,\n value,\n}: {\n readonly label: string;\n readonly name: string;\n readonly onChange: (value: string) => void;\n readonly placeholder: string;\n readonly value: string;\n}): ReactElement {\n return (\n <BPMFormField label={label} name={name}>\n <Input\n fullWidth\n name={name}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onChange(event.target.value)\n }\n placeholder={placeholder}\n value={value}\n />\n </BPMFormField>\n );\n}\n\nfunction DateField({\n label,\n name,\n onChange,\n placeholder,\n value,\n}: {\n readonly label: string;\n readonly name: string;\n readonly onChange: (value: string) => void;\n readonly placeholder: string;\n readonly value: string;\n}): ReactElement {\n return (\n <BPMFormField label={label} name={name}>\n <DatePicker\n format=\"YYYY-MM-DD\"\n fullWidth\n inputProps={{ name }}\n onChange={(nextValue): void => onChange(formatDateOnly(nextValue))}\n placeholder={placeholder}\n value={value.trim() ? value : undefined}\n />\n </BPMFormField>\n );\n}\n\nfunction readReferencedMemberIds(\n memberships: readonly MembershipRecord[],\n managerResolutions: readonly ManagerResolutionRecord[],\n): readonly string[] {\n return [\n ...new Set([\n ...memberships.map((membership) => membership.memberId),\n ...managerResolutions.map((resolution) => resolution.managerMemberId),\n ...managerResolutions\n .filter((resolution) => resolution.scopeType === 'MEMBER')\n .map((resolution) => resolution.scopeId),\n ]),\n ];\n}\n\nfunction readScopeLabel(\n resolution: ManagerResolutionRecord,\n lookup: {\n readonly membersById: ReadonlyMap<string, MemberProfileRecord>;\n readonly orgUnitsById: ReadonlyMap<string, OrgUnitRecord>;\n readonly positionsById: ReadonlyMap<string, PositionRecord>;\n },\n): string {\n if (resolution.scopeType === 'MEMBER') {\n return `會員:${readMemberLabel(lookup.membersById.get(resolution.scopeId))}`;\n }\n\n if (resolution.scopeType === 'ORG_UNIT') {\n return `組織:${readOrgUnitLabel(lookup.orgUnitsById.get(resolution.scopeId))}`;\n }\n\n return `職位:${readPositionLabel(lookup.positionsById.get(resolution.scopeId))}`;\n}\n\nfunction readMemberLabel(member: MemberProfileRecord | undefined): string {\n return member ? `${member.name} · ${member.email}` : '未知會員';\n}\n\nfunction readOrgUnitLabel(orgUnit: OrgUnitRecord | undefined): string {\n return orgUnit ? `${orgUnit.name} · ${orgUnit.code}` : '未知組織';\n}\n\nfunction readOrgUnitTypeLabel(type: OrgUnitType): string {\n return (\n ORG_UNIT_TYPES.find(\n (option) => option.id.toLowerCase() === type.toLowerCase(),\n )?.name ?? '未知類型'\n );\n}\n\nfunction readPositionLabel(position: PositionRecord | undefined): string {\n return position ? `${position.name} · ${position.code}` : '未指定';\n}\n\nfunction readAdminOrgTab(value: unknown): AdminOrgTab {\n return value === 'MANAGERS' ||\n value === 'MEMBERSHIPS' ||\n value === 'POSITIONS'\n ? value\n : 'ORG_UNITS';\n}\n\nfunction readOrgUnitTypeOption(value: unknown): OrgUnitTypeOption {\n const record = isRecord(value) ? value : null;\n\n if (typeof record?.id === 'string') {\n const id = record.id;\n\n return (\n ORG_UNIT_TYPES.find(\n (option) => option.id.toLowerCase() === id.toLowerCase(),\n ) ?? ORG_UNIT_TYPES[2]\n );\n }\n\n return ORG_UNIT_TYPES[2];\n}\n\nfunction readOrgUnitTypeFilterOption(value: unknown): OrgUnitTypeFilterOption {\n const record = isRecord(value) ? value : null;\n\n if (typeof record?.id === 'string') {\n const id = record.id;\n\n return (\n ORG_UNIT_TYPE_FILTER_OPTIONS.find(\n (option) => option.id.toLowerCase() === id.toLowerCase(),\n ) ?? ALL_ORG_UNIT_TYPE_FILTER\n );\n }\n\n return ALL_ORG_UNIT_TYPE_FILTER;\n}\n\nfunction readScopeTypeOption(value: unknown): ScopeTypeOption {\n return readOption(value, SCOPE_TYPES, SCOPE_TYPES[0]);\n}\n\nfunction readScopeTypeFilterOption(value: unknown): ScopeTypeFilterOption {\n return readOption(value, SCOPE_TYPE_FILTER_OPTIONS, ALL_SCOPE_TYPE_FILTER);\n}\n\nfunction readActiveFilterOption(value: unknown): ActiveFilterOption {\n return readOption(value, ACTIVE_FILTER_OPTIONS, ALL_ACTIVE_FILTER);\n}\n\nfunction readNullableActiveFilterOption(\n value: unknown,\n): ActiveFilterOption | null {\n const record = isRecord(value) ? value : null;\n const id = typeof record?.id === 'string' ? record.id : null;\n\n return ACTIVE_FILTER_OPTIONS.find((option) => option.id === id) ?? null;\n}\n\nfunction readOrgUnitOptionFromValue(value: unknown): OrgUnitOption | null {\n const record = isRecord(value) ? value : null;\n const id = typeof record?.id === 'string' ? record.id : null;\n const name = typeof record?.name === 'string' ? record.name : null;\n\n return id && name ? { id, name } : null;\n}\n\nfunction readPositionOptionFromValue(value: unknown): PositionOption | null {\n const record = isRecord(value) ? value : null;\n const id = typeof record?.id === 'string' ? record.id : null;\n const name = typeof record?.name === 'string' ? record.name : null;\n\n return id && name ? { id, name } : null;\n}\n\nfunction readPrimaryOption(value: unknown): PrimaryOption {\n return readOption(value, PRIMARY_OPTIONS, PRIMARY_OPTIONS[1]);\n}\n\nfunction readOption<TOption extends { readonly id: string }>(\n value: unknown,\n options: readonly TOption[],\n fallback: TOption,\n): TOption {\n const record = isRecord(value) ? value : null;\n const id = typeof record?.id === 'string' ? record.id : null;\n\n return options.find((option) => option.id === id) ?? fallback;\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readNullableOption<TValue, TOption>(\n value: TValue | null | undefined,\n mapper: (value: TValue) => TOption,\n): TOption | null {\n return value ? mapper(value) : null;\n}\n\nfunction today(): string {\n return formatDateParts(new Date());\n}\n\nfunction formatDateOnly(value: string | undefined): string {\n const date = value ? new Date(value) : null;\n\n return date && !Number.isNaN(date.getTime()) ? formatDateParts(date) : '';\n}\n\nfunction formatDateParts(date: Date): string {\n return `${date.getFullYear()}-${padDatePart(date.getMonth() + 1)}-${padDatePart(\n date.getDate(),\n )}`;\n}\n\nfunction padDatePart(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '讀取組織資料失敗。';\n}\n"],"mappings":"qfAgBA,SAAgB,EACd,EACuB,CACvB,OAAO,IAAI,IACT,EAAS,IAAK,GAA8C,CAC1D,EAAQ,GACR,EAAQ,QACV,CAAC,CACH,CACF,CAEA,SAAgB,EAAyB,CACvC,YACA,cACA,YAKgC,CAChC,IAAM,EAAqB,IAAa,EAAY,EAAY,EAC1D,EAAoB,EAAmC,CAC3D,YACA,cACA,SAAU,CACZ,CAAC,EAED,GAAI,EACF,MAAO,CACL,QAAS,EACT,cACA,OAAQ,SACV,EAGF,IAAK,EAAY,IAAI,CAAS,GAAK,QAAU,EAC3C,MAAO,CACL,QAAS,YACT,cACA,OAAQ,WACV,EAGF,IAAM,EAAY,IAAI,IAAI,CAAW,EAGrC,OAFA,EAAU,IAAI,EAAW,CAAkB,EAEpC,CACL,QAAS,EAAqB,aAAe,WAC7C,YAAa,EACb,OAAQ,SACV,CACF,CAEA,SAAgB,EAAiC,CAC/C,WACA,eAIyC,CACzC,OAAO,EACJ,IAAK,GAAgD,CACpD,IAAM,EAAW,EAAY,IAAI,EAAQ,EAAE,GAAK,KAEhD,OAAO,IAAa,EAAQ,SACxB,KACA,CACE,UAAW,EAAQ,GACnB,WACA,iBAAkB,EAAQ,QAC5B,CACN,CAAC,EACA,OAAQ,GAAkD,EAAQ,CAAO,CAC9E,CAEA,SAAgB,EAAmC,CACjD,YACA,cACA,YAKgB,CAiBhB,OAhBK,EAAY,IAAI,CAAS,EAIzB,EAIA,EAAY,IAAI,CAAQ,EAIzB,IAAa,EACR,eAGF,EAA0B,CAAE,YAAW,cAAa,UAAS,CAAC,EACjE,gBACA,KATK,aAJA,KAJA,cAkBX,CAEA,SAAS,EAA0B,CACjC,YACA,cACA,YAKU,CACV,IAAM,EAAa,IAAI,IACnB,EAAiC,EAErC,KAAO,GAAiB,CACtB,GAAI,IAAoB,GAAa,EAAW,IAAI,CAAe,EACjE,MAAO,GAGT,EAAW,IAAI,CAAe,EAC9B,EAAkB,EAAY,IAAI,CAAe,GAAK,IACxD,CAEA,MAAO,EACT,2iBE5DM,EAAmB,oBACnB,EAAsB,IACtB,EAAuB,IACvB,EAAsB,IACtB,EAAuB,GACvB,EAAyB,IAKzB,EAAoB,IACpB,EAAyB,IAGzB,EAA0B,KAI1B,EAA8B,IAG9B,GAA6B,GAE7B,EAAyE,CAC7E,QAAS,KACT,WAAY,KACZ,SAAU,MACV,KAAM,IACR,EAEM,GAAkC,CACtC,QAAS,CACX,EAEa,GAAA,EAAA,EAAA,YAGX,SACA,CACE,gBACA,eACA,gBACA,cACA,gBACA,YAEF,EACc,CACd,GAAM,CAAC,EAAW,IAAA,EAAA,EAAA,UAAyB,EAAK,EAC1C,CAAC,EAAc,IAAA,EAAA,EAAA,UAA2C,IAAI,EAC9D,CAAC,EAAmB,IAAA,EAAA,EAAA,UACxB,IACF,EACM,CAAC,EAAa,IAAA,EAAA,EAAA,cAClB,EAA4B,CAAQ,CACtC,EACM,CAAC,EAAW,IAAA,EAAA,EAAA,UAAqD,CAAC,CAAC,EAEnE,GAAA,EAAA,EAAA,aAEF,IAAI,IAAI,EAAS,IAAK,GAAY,CAAC,EAAQ,GAAI,CAAO,CAAC,CAAC,EAC1D,CAAC,CAAQ,CACX,EACM,GAAA,EAAA,EAAA,aAEF,EAAiC,CAAE,WAAU,aAAY,CAAC,EAC5D,CAAC,EAAU,CAAW,CACxB,EACM,GAAA,EAAA,EAAA,aAMF,GAA8B,CAC5B,YACA,cAAgB,GAAmB,CAC7B,EACF,EAAc,CAAQ,EAEtB,EAAa,CAEjB,EACA,cAAgB,GAAoB,CAClC,IAAM,EAAU,EAAa,IAAI,CAAS,EAEtC,GACF,EAAc,CAAO,CAEzB,EACA,WACA,eACA,cACA,mBACF,CAAC,EACH,CACE,EACA,EACA,EACA,EACA,EACA,EACA,EACA,CACF,CACF,EACM,EAAkB,EAAa,OAAS,EACxC,IAAA,EAAA,EAAA,aAAgC,CACpC,IAAM,EAAc,KAAK,IACvB,EAAa,OAAO,MACpB,EAAa,OAAO,MACtB,EAMA,OAJI,GAAe,EACV,EAGF,KAAK,IACV,EACA,KAAK,IACH,EACA,EAA8B,CAChC,CACF,CACF,EAAG,CAAC,EAAa,OAAO,OAAQ,EAAa,OAAO,KAAK,CAAC,EACpD,EAAc,EAAS,QAAU,IAEvC,EAAA,EAAA,qBACE,OACqC,CACnC,iBACA,YACA,cACF,EACF,GAEA,EAAA,EAAA,eAAsB,CACpB,EAAc,CAAE,kBAAiB,WAAU,CAAC,CAC9C,EAAG,CAAC,EAAiB,EAAW,CAAa,CAAC,GAE9C,EAAA,EAAA,eAAsB,CACpB,EAAe,EAA4B,CAAQ,CAAC,EACpD,EAAqB,IAAI,EACzB,EAAgB,IAAI,EACpB,EAAa,EAAK,CACpB,EAAG,CAAC,CAAQ,CAAC,GAEb,EAAA,EAAA,eAAsB,CACpB,EAAa,EAAa,KAAK,CACjC,EAAG,CAAC,EAAa,KAAK,CAAC,EAEvB,IAAM,GAAA,EAAA,EAAA,cACH,EAAmB,IAAkC,CACpD,EAAgB,GAAiB,CAC/B,IAAM,EAAS,EAAyB,CACtC,YACA,YAAa,EACb,UACF,CAAC,EAID,OAFA,EAAgB,EAAO,OAAO,EAEvB,EAAO,WAChB,CAAC,CACH,EACA,CAAC,CACH,EAEM,GAAA,EAAA,EAAA,aACH,GAAiC,CAChC,GAAI,CAAC,GAAa,CAAC,EAAW,QAAU,CAAC,EAAW,OAClD,OAGF,IAAM,EACJ,EAAW,SAAW,EAAmB,KAAO,EAAW,OAE7D,GAAI,EAAW,SAAW,EAAkB,CAC1C,EAAgB,gBAAgB,EAChC,MACF,CAEA,EAAkB,EAAW,OAAQ,CAAY,CACnD,EACA,CAAC,EAAmB,CAAS,CAC/B,EAEM,GAAA,EAAA,EAAA,aACH,GAAkB,CACZ,GAIL,EAAc,IAAA,EAAA,EAAA,kBACK,EAAS,CAAC,GAAG,CAAY,CAAC,CAC7C,CACF,EACA,CAAC,CAAS,CACZ,EAEM,GAAA,EAAA,EAAA,cACH,EAAO,EAAM,IAAgB,CAC5B,GAAI,CAAC,GAAa,EAAK,KAAO,EAC5B,OAGF,IAAM,EACJ,EAAmC,EAAO,EAAK,EAAE,GACjD,GAAwB,EAAM,CAAK,EAErC,GAAI,IAAkB,IAAA,GAAW,CAC/B,EAAgB,yBAAyB,EACzC,MACF,CAEA,EACE,EAAK,GACL,IAAkB,EAAmB,KAAO,CAC9C,CACF,EACA,CAAC,EAAmB,CAAS,CAC/B,EAEA,SAAS,GAAqB,CAC5B,EAAa,EAAI,EACjB,EAAe,EAA4B,CAAQ,CAAC,EACpD,EAAgB,0BAA0B,CAC5C,CAEA,SAAS,IAAsB,CAC7B,EAAa,EAAK,EAClB,EAAe,EAA4B,CAAQ,CAAC,EACpD,EAAgB,UAAU,CAC5B,CAEA,eAAe,GAA2B,CACxC,GAAI,CAAC,EAAa,CAChB,EAAgB,yBAAyB,EACzC,MACF,CAEA,MAAM,EAAY,CAAY,EAC9B,EAAa,EAAK,EAClB,EAAgB,WAAW,CAC7B,CAEA,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAO,uBAAvB,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAO,wBAAvB,EACE,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,MAAM,eAAe,QAAQ,mBACtC,IACE,EACG,OAAO,EAAa,OAAO,aAC3B,YACI,CAAA,EACX,GACC,EAAA,EAAA,KAAC,KAAD,CAAI,UAAW,EAAO,2BACnB,EAAa,IAAK,IACjB,EAAA,EAAA,MAAC,KAAD,CAAA,SAAA,CACG,GAAgB,EAAO,UAAW,CAAY,EAC9C,IACA,GAAgB,EAAO,iBAAkB,CAAY,EACrD,OACA,GAAgB,EAAO,SAAU,CAAY,CAC5C,CAAA,EANK,EAAO,SAMZ,CACL,CACC,CAAA,EACF,IACD,KACL,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAO,wBACrB,EAAA,EAAA,MAAC,EAAA,UAAD,CACE,eAAgB,EAAA,eAAe,OAC/B,MAAO,CAAC,GAAG,EAAa,KAAK,EAC7B,QAAA,GACA,eAAgB,CAAE,WAAS,QAAS,GAAK,EACzC,kBAAoB,GAClB,GACE,CAAE,OAAQ,EAAW,OAAQ,OAAQ,EAAW,MAAO,EACvD,CACF,EAEF,QAAS,EACA,WACT,UAAW,GACX,MAAO,CAAC,GAAG,CAAS,EACpB,iBAAkB,EAClB,eAAgB,EAChB,UAAW,EACX,aAAc,EAAG,IAAe,CAC9B,EAAqB,EAAK,KAAO,EAAmB,KAAO,EAAK,EAAE,CACpE,EACA,mBAAoB,EAAG,IAAe,CACpC,GAAI,EAAK,KAAO,EAAkB,CAChC,IAAM,EAAU,EAAa,IAAI,EAAK,EAAE,EAEpC,GACF,EAAc,CAAO,CAEzB,CACF,EACA,eAAgB,EAChB,cAAe,EACf,gBAAyB,EAAqB,IAAI,EAClD,UAAA,GACA,WAAY,CAAE,gBAAiB,EAAK,WAlCtC,EAoCE,EAAA,EAAA,KAAC,EAAA,WAAD,CAAa,CAAA,GACb,EAAA,EAAA,KAAC,EAAA,SAAD,CAAW,CAAA,EACV,GAAc,EAAA,EAAA,KAAC,EAAA,QAAD,CAAS,SAAA,GAAS,SAAA,EAAU,CAAA,EAAI,IACtC,GACR,CAAA,CACF,GAET,CAAC,EAED,SAAS,EAAoB,CAC3B,OACA,YAC2C,CAC3C,OACE,EAAA,EAAA,MAAC,MAAD,CACE,UAAW,CACT,EAAO,YACP,EAAK,gBAAkB,EAAO,gBAAkB,GAChD,EAAK,QAAU,EAAO,mBAAqB,GAC3C,EAAK,QAAU,EAAO,mBAAqB,GAC3C,EAAW,EAAO,oBAAsB,EAC1C,EACG,OAAO,OAAO,EACd,KAAK,GAAG,WATb,CAWG,EAAK,gBAAkB,MACtB,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,GAAG,SACH,cAAe,EAAK,UACpB,SAAU,EAAA,SAAS,IACnB,KAAK,QACN,CAAA,GAEH,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,GAAG,SACH,cAAe,EAAK,UACpB,SAAU,EAAA,SAAS,OACnB,KAAK,QACN,CAAA,GACD,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAO,2BAAvB,EACE,EAAA,EAAA,KAAC,EAAA,WAAD,CACE,UAAU,OACV,SAAA,GACA,MAAO,EAAK,KACZ,QAAQ,yBAEP,EAAK,IACI,CAAA,EACX,EAAK,SACJ,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAO,0BAAkB,IAAQ,CAAA,EAChD,IACD,KACL,EAAA,EAAA,KAAC,EAAA,WAAD,CACE,MAAM,eACN,UAAU,OACV,SAAA,GACA,MAAO,EAAK,KACZ,QAAQ,mBAEP,EAAK,gBACF,QACA,GAAG,EAAK,UAAU,KAAK,EAAK,MACtB,CAAA,EACX,EAAK,gBAAkB,MACtB,EAAA,EAAA,MAAC,EAAA,WAAD,CACE,MAAM,eACN,UAAU,OACV,SAAA,GACA,MAAO,EAAK,YACZ,QAAQ,mBALV,CAMC,MACK,EAAK,WACC,KAEd,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAO,4BACpB,EAAK,iBACJ,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,KAAM,EAAA,SACN,SAAS,UACT,YAAqB,EAAK,cAAc,IAAI,EAC5C,KAAK,MACL,QAAQ,0BACT,OAEO,CAAA,GAER,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,KAAM,EAAA,SACN,SAAS,UACT,YAAqB,CACf,EAAK,WACP,EAAK,OAAO,EAAK,SAAS,CAE9B,EACA,KAAK,MACL,QAAQ,0BACT,IAEO,CAAA,GACR,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,KAAM,EAAA,SACN,SAAS,UACT,YAAqB,EAAK,cAAc,EAAK,SAAS,EACtD,KAAK,MACL,QAAQ,0BACT,OAEO,CAAA,CACR,CAAA,CAAA,CAED,CAAA,CACF,GAET,CAEA,SAAS,GAA8B,CACrC,YACA,gBACA,gBACA,WACA,eACA,cACA,qBAaC,CACD,IAAM,EAAQ,IAAI,EAAM,SAAS,MACjC,EAAM,yBAA2B,CAAC,EAAE,EACpC,EAAM,SAAS,CAAE,QAAS,GAAI,QAAS,GAAI,QAAS,GAAI,QAAS,IAAK,CAAC,EACvE,EAAM,QAAQ,EAAkB,CAC9B,OAAQ,EACR,MAAO,CACT,CAAC,EACD,EAAS,QAAS,GAAkB,CAClC,EAAM,QAAQ,EAAQ,GAAI,CACxB,OAAQ,EACR,MAAO,CACT,CAAC,CACH,CAAC,EACD,EAAS,QAAS,GAAkB,CAClC,IAAM,EAAW,EAAY,IAAI,EAAQ,EAAE,GAAK,KAChD,EAAM,QAAQ,GAAY,EAAkB,EAAQ,EAAE,CACxD,CAAC,EACD,EAAM,OAAO,CAAK,EAElB,IAAM,EAAa,EAAM,MAAM,EACzB,EAAS,CACb,OAAQ,EAAW,QAAU,EAC7B,MAAO,EAAW,OAAS,CAC7B,EAEM,EAAW,EAAsB,CACrC,KAAM,CACJ,QAAS,GACT,KAAM,EACN,QAAS,GACT,YACA,gBAAiB,GACjB,KAAM,QACN,gBACA,OAAQ,EACR,UAAW,KACX,YAAa,GACb,KAAM,GACN,UAAW,EACb,EACA,QACA,OAAQ,EACR,GAAI,EACJ,SAAU,IAAsB,KAChC,MAAO,CACT,CAAC,EACK,EAAW,EAAS,IAAK,GAA6B,CAC1D,IAAM,EAAW,EAAY,IAAI,EAAQ,EAAE,GAAK,KAC1C,EAAc,GAAgB,EAAU,CAAY,EAE1D,OAAO,EAAsB,CAC3B,KAAM,CACJ,QAAS,IAAa,EAAQ,SAC9B,KAAM,EAAQ,KACd,QAAS,EAAQ,EAAQ,UACzB,YACA,gBAAiB,GACjB,KAAM,EAAQ,KACd,gBACA,OAAQ,EACR,UAAW,EAAQ,GACnB,cACA,KAAM,EAAQ,KACd,UAAW,EAAqB,EAAQ,IAAI,CAC9C,EACA,QACA,OAAQ,EACR,GAAI,EAAQ,GACZ,SAAU,IAAsB,EAAQ,GACxC,MAAO,CACT,CAAC,CACH,CAAC,EAoBD,MAAO,CACL,SACA,MArBY,EAAS,IAAK,GAA6B,CACvD,IAAM,EAAW,EAAY,IAAI,EAAQ,EAAE,GAAK,KAC1C,EAAU,IAAa,EAAQ,SAErC,MAAO,CACL,SAAU,GAAa,EACvB,KAAM,CAAC,EACP,GAAI,iBAAiB,GAAY,OAAO,GAAG,EAAQ,KACnD,OAAQ,GAAY,EACpB,aAAc,SACd,MAAO,EACH,CAAE,OAAQ,oCAAqC,YAAa,CAAE,EAC9D,IAAA,GACJ,OAAQ,EAAQ,GAChB,aAAc,SACd,KAAM,YACR,CACF,CAIE,EACA,MAAO,CAAC,EAAU,GAAG,CAAQ,CAC/B,CACF,CAEA,SAAS,EAAsB,CAC7B,OACA,QACA,SACA,KACA,WACA,SAQkB,CAClB,IAAM,EAAiB,EAAM,KAAK,CAAE,EAIpC,MAAO,CACL,OACA,SACA,KACA,cAAe,EACf,aAAc,EACd,SAAU,EACN,CACE,EAAG,EAAe,EAAI,EAAQ,EAC9B,EAAG,EAAe,EAAI,EAAS,CACjC,EACA,CAAE,EAAG,EAAG,EAAG,CAAE,EACjB,WACA,eAAgB,EAAA,SAAS,OACzB,eAAgB,EAAA,SAAS,IACzB,KAAM,UACN,OACF,CACF,CAEA,SAAS,GACP,EACA,EACoB,CACpB,IAAM,EAAgB,EAAe,CAAW,EAYhD,OAXmB,EAChB,OAAQ,GAAS,EAAK,KAAO,EAAY,EAAE,EAC3C,IACE,IAAsD,CACrD,SAAU,EAAa,EAAe,EAAe,CAAI,CAAC,EAC1D,GAAI,EAAK,EACX,EACF,EACC,OAAQ,GAAc,EAAU,UAAY,CAAsB,EAClE,MAAM,EAAM,IAAU,EAAK,SAAW,EAAM,QAExC,EAAW,IAAI,EACxB,CAEA,SAAS,EACP,EACA,EACoB,CACpB,IAAM,EAAQ,EAAiB,CAAK,EAE/B,KAkCL,OA9BmB,MAAM,KACvB,SAAS,iBAA8B,4BAA4B,CACrE,EACG,IAAK,GAA+D,CACnE,IAAM,EAAK,EAAQ,QAAQ,GAE3B,GAAI,CAAC,GAAM,IAAO,EAChB,OAAO,KAGT,IAAM,EAAO,EAAQ,sBAAsB,EAM3C,MAAO,CACL,SAAU,EAAa,EAAO,CAL9B,EAAG,EAAK,KAAO,EAAK,MAAQ,EAC5B,EAAG,EAAK,IAAM,EAAK,OAAS,CAIE,CAAM,EACpC,IACF,CACF,CAAC,EACA,OAEG,GAEA,EAAQ,CACZ,EACC,OAAQ,GAAc,EAAU,UAAY,CAAsB,EAClE,MAAM,EAAM,IAAU,EAAK,SAAW,EAAM,QAExC,EAAW,IAAI,EACxB,CAEA,SAAS,EACP,EAC2C,CAK3C,OAJK,GAAmB,CAAK,EAItB,CAAE,EAAG,EAAM,QAAS,EAAG,EAAM,OAAQ,EAHnC,IAIX,CAEA,SAAS,GACP,EACyD,CACzD,OACE,OAAO,GAAU,YACjB,GACA,YAAa,GACb,YAAa,GACb,OAAO,EAAM,SAAY,UACzB,OAAO,EAAM,SAAY,QAE7B,CAEA,SAAS,EACP,EACoC,CACpC,MAAO,CACL,EAAG,EAAK,SAAS,GAAK,EAAK,OAAS,GAAuB,EAC3D,EAAG,EAAK,SAAS,GAAK,EAAK,QAAU,GAAwB,CAC/D,CACF,CAEA,SAAS,EACP,EACA,EACQ,CACR,OAAO,KAAK,MAAM,EAAO,EAAI,EAAO,EAAG,EAAO,EAAI,EAAO,CAAC,CAC5D,CAEA,SAAS,GACP,EACA,EACS,CAST,MARI,CAAC,EAAW,QAAU,CAAC,EAAW,QAIlC,EAAW,SAAW,EACjB,GAIP,EAAmC,CACjC,UAAW,EAAW,OACtB,cACA,SACE,EAAW,SAAW,EAAmB,KAAO,EAAW,MAC/D,CAAC,IAAM,IAEX,CAEA,SAAS,GACP,EACA,EACQ,CACR,GAAI,CAAC,EACH,MAAO,MAGT,IAAM,EAAU,EAAa,IAAI,CAAS,EAE1C,OAAO,EAAU,GAAG,EAAQ,KAAK,KAAK,EAAQ,OAAS,MACzD,CAEA,SAAS,EAAqB,EAA2B,CAGvD,OAAO,EAFgB,EAAK,YAEA,IAAmB,MACjD,iSE9sBM,EAA6D,CACjE,gBAAiB,GACjB,UAAW,EACb,EA0GM,EAA+C,CACnD,CAAE,GAAI,UAAW,KAAM,IAAK,EAC5B,CAAE,GAAI,WAAY,KAAM,KAAM,EAC9B,CAAE,GAAI,aAAc,KAAM,IAAK,EAC/B,CAAE,GAAI,OAAQ,KAAM,IAAK,CAC3B,EACM,GAAoD,CACxD,GAAI,MACJ,KAAM,MACR,EACM,EAAmE,CACvE,GACA,GAAG,CACL,EAEM,EAA0C,CAC9C,CAAE,GAAI,SAAU,KAAM,MAAO,EAC7B,CAAE,GAAI,WAAY,KAAM,MAAO,EAC/B,CAAE,GAAI,WAAY,KAAM,MAAO,CACjC,EACM,GAA+C,CACnD,GAAI,MACJ,KAAM,MACR,EACM,GAA8D,CAClE,GACA,GAAG,CACL,EACM,GAAwC,CAC5C,WAAY,GACZ,GAAI,MACJ,KAAM,MACR,EACM,GAAuD,CAC3D,GACA,CAAE,WAAY,GAAM,GAAI,SAAU,KAAM,MAAO,CACjD,EAEM,EAA4C,CAChD,CAAE,GAAI,OAAQ,KAAM,OAAQ,MAAO,EAAK,EACxC,CAAE,GAAI,QAAS,KAAM,OAAQ,MAAO,EAAM,CAC5C,EACM,GAAuC,CAAC,GAAI,GAAI,EAAE,EAClD,GAA2B,KAC3B,GAA2B,IAC3B,GAA6B,KAC7B,GAA0B,KAGhC,SAAgB,GAA8B,CAC5C,GAAM,CAAC,EAAW,IAAA,EAAA,EAAA,UAAsC,WAAW,EAC7D,CAAC,EAAoB,IAAA,EAAA,EAAA,UACgB,IAAI,EACzC,CAAC,EAAwB,IAAA,EAAA,EAAA,UACY,IAAI,EACzC,CAAC,EAAO,IAAA,EAAA,EAAA,UAAoC,IAAI,EAChD,CAAC,EAAS,IAAA,EAAA,EAAA,UAAuB,EAAI,EACrC,CAAC,EAAc,IAAA,EAAA,EAAA,UACnB,IACF,EACM,CAAC,EAAqB,IAAA,EAAA,EAAA,UACG,EAAiB,EAC1C,CAAC,EAAa,IAAA,EAAA,EAAA,UAA2B,CAAC,EAC1C,CAAC,EAAiB,IAAA,EAAA,EAAA,UAA+B,EAAE,EACnD,CAAC,EAAwB,IAAA,EAAA,EAAA,UACG,EAAqB,EACjD,CAAC,EAAmB,IAAA,EAAA,EAAA,UAAiC,CAAC,EACtD,CAAC,EAAgB,KAAA,EAAA,EAAA,UAErB,CAAC,CAAC,EACE,CAAC,EAAwB,KAAA,EAAA,EAAA,UACO,IAAI,EACpC,CAAC,EAAiB,IAAA,EAAA,EAAA,UACgB,IAAI,EACtC,CAAC,GAAyB,IAAA,EAAA,EAAA,UACC,IAAI,EAC/B,CAAC,GAAgB,IAAA,EAAA,EAAA,UAA8B,CAAC,EAChD,CAAC,EAAoB,KAAA,EAAA,EAAA,UAAkC,EAAE,EACzD,CAAC,EAA0B,IAAA,EAAA,EAAA,UACC,IAAI,EAChC,CAAC,GAAsB,KAAA,EAAA,EAAA,UAAoC,CAAC,EAC5D,CAAC,EAAU,IAAA,EAAA,EAAA,UAA8C,IAAI,EAC7D,CAAC,EAAa,IAAA,EAAA,EAAA,UAA2B,CAAC,EAC1C,CAAC,EAAiB,IAAA,EAAA,EAAA,UAA+B,EAAE,EACnD,CAAC,GAAmB,KAAA,EAAA,EAAA,UAAiC,EAAE,EACvD,CAAC,EAAmB,KAAA,EAAA,EAAA,UAAiC,CAAC,EACtD,CAAC,GAAmB,KAAA,EAAA,EAAA,UACU,EAAwB,EACtD,CAAC,GAAiB,KAAA,EAAA,EAAA,UACI,OAAO,EAC7B,CAAC,EAAU,KAAA,EAAA,EAAA,UAAkD,CAAC,CAAC,EAC/D,CAAC,GAAiB,KAAA,EAAA,EAAA,UAEtB,CAAC,CAAC,EACE,CAAC,GAAkB,KAAA,EAAA,EAAA,UAEvB,CAAC,CAAC,EACE,CAAC,EAAe,IAAA,EAAA,EAAA,UACpB,IACF,EACM,CAAC,GAAc,KAAA,EAAA,EAAA,UAA4B,CAAC,EAC5C,CAAC,GAAkB,KAAA,EAAA,EAAA,UAAgC,EAAE,EACrD,CAAC,GAAoB,KAAA,EAAA,EAAA,UAAkC,EAAE,EACzD,CAAC,GAAoB,KAAA,EAAA,EAAA,UAAkC,CAAC,EACxD,CAAC,EAAW,KAAA,EAAA,EAAA,UAAoD,CAAC,CAAC,EAClE,CAAC,EAA2B,IAAA,EAAA,EAAA,UAEhC,CAAC,CAAC,EACE,CAAC,GAAoB,KAAA,EAAA,EAAA,UAEzB,CAAC,CAAC,EACE,CAAC,EAAQ,KAAA,EAAA,EAAA,UAAsB,EAAK,GAE1C,EAAA,EAAA,eAAsB,CAChB,GACF,EAA0B,CAAkB,CAEhD,EAAG,CAAC,CAAkB,CAAC,EAEvB,IAAM,GACJ,GAAsB,EAElB,IAAA,EAAA,EAAA,aAAkC,SAA2B,CACjE,EAAW,EAAI,EACf,EAAS,IAAI,EAEb,GAAI,CACF,IAAM,EAAY,MAAA,EAAA,EAAA,2BAAgC,CAChD,kBAAmB,EAAoB,WACvC,cACA,kBACA,iBACE,EAAuB,KAAO,MAC1B,KACA,EAAuB,GAC7B,qBAAsB,GAAwB,YAAc,GAC5D,oBAAqB,IAAyB,IAAM,KACpD,kBACA,qBACA,qBAAsB,GAA0B,IAAM,KACtD,cACA,kBACA,qBACA,YACE,GAAkB,KAAO,MAAQ,KAAO,GAAkB,GAC5D,gBACA,oBACA,qBACF,CAAC,EAOD,GAAkB,MAAA,EAAA,EAAA,gBANA,GAChB,EAAU,YACV,EAAU,kBAE0B,CAAS,CAErB,EAC1B,GAAY,EAAU,QAAQ,EAC9B,GAAqB,EAAU,YAAY,EAC3C,GAAmB,EAAU,gBAAgB,EAC7C,GAAa,EAAU,SAAS,EAChC,GAAsB,EAAU,aAAa,EAC7C,GAAoB,EAAU,iBAAiB,EAC/C,GAAwB,EAAU,eAAe,EACjD,GAAsB,EAAU,mBAAmB,EACnD,EAAqB,EAAU,sBAAsB,EACrD,EAA6B,EAAU,0BAA0B,CACnE,OAAS,EAAuB,CAC9B,EAAS,GAAiB,CAAY,CAAC,CACzC,QAAU,CACR,EAAW,EAAK,CAClB,CACF,EAAG,CACD,EACA,EACA,EACA,EACA,EACA,GACA,GACA,EACA,EACA,EACA,EACA,GACA,GACA,GACA,GACA,EACF,CAAC,GAED,EAAA,EAAA,eAAsB,CACpB,GAAyB,CAC3B,EAAG,CAAC,EAAmB,CAAC,EAExB,IAAM,GAAA,EAAA,EAAA,aAEF,IAAI,IAAI,EAAS,IAAK,GAAY,CAAC,EAAQ,GAAI,CAAO,CAAC,CAAC,EAC1D,CAAC,CAAQ,CACX,EACM,IAAA,EAAA,EAAA,aAEF,IAAI,IAAI,EAAU,IAAK,GAAa,CAAC,EAAS,GAAI,CAAQ,CAAC,CAAC,EAC9D,CAAC,CAAS,CACZ,EACM,GAAA,EAAA,EAAA,aAEF,IAAI,IAAI,EAAe,IAAK,GAAW,CAAC,EAAO,SAAU,CAAM,CAAC,CAAC,EACnE,CAAC,CAAc,CACjB,EAEM,IAAA,EAAA,EAAA,aAEF,GAAgB,IAAK,IAAa,CAChC,GAAG,EACH,IAAK,EAAQ,GACb,WAAY,EAAQ,SAChB,GAAiB,EAAa,IAAI,EAAQ,QAAQ,CAAC,EACnD,MACJ,UAAW,GAAqB,EAAQ,IAAI,CAC9C,EAAE,EACJ,CAAC,GAAiB,CAAY,CAChC,EACM,IAAA,EAAA,EAAA,aAEF,GAAiB,IAAK,IAAc,CAClC,GAAG,EACH,IAAK,EAAS,EAChB,EAAE,EACJ,CAAC,EAAgB,CACnB,EACM,IAAA,EAAA,EAAA,aAEF,GAAmB,IAAK,IAAgB,CACtC,GAAG,EACH,IAAK,EAAW,GAChB,WAAY,GAAgB,EAAY,IAAI,EAAW,QAAQ,CAAC,EAChE,YAAa,GAAiB,EAAa,IAAI,EAAW,SAAS,CAAC,EACpE,aAAc,EAAW,WACrB,GAAkB,GAAc,IAAI,EAAW,UAAU,CAAC,EAC1D,KACN,EAAE,EACJ,CAAC,EAAa,GAAoB,EAAc,EAAa,CAC/D,EACM,IAAA,EAAA,EAAA,aAEF,EAA0B,IAAK,IAAgB,CAC7C,GAAG,EACH,IAAK,EAAW,GAChB,YAAa,GACX,EAAY,IAAI,EAAW,eAAe,CAC5C,EACA,WAAY,GAAe,EAAY,CACrC,cACA,eACA,gBACF,CAAC,CACH,EAAE,EACJ,CAAC,EAA2B,EAAa,EAAc,EAAa,CACtE,EAEM,IAAA,EAAA,EAAA,cAC6B,CAC/B,OAAS,GAA2D,CAClE,CACE,KAAM,KACN,YAAqB,EAAY,CAAE,SAAQ,KAAM,MAAO,CAAC,CAC3D,EACA,CACE,KAAM,KACN,YACE,EAAsB,CACpB,YAAa,OACb,YAAa,MAAM,EAAO,KAAK,yBAC/B,GAAI,EAAO,GACX,MAAO,SACP,KAAM,UACR,CAAC,EACH,QAAS,uBACX,CACF,EACA,QAAS,iBACT,MAAO,GACT,GACA,CAAC,CACH,EACM,IAAA,EAAA,EAAA,cAC8B,CAChC,OAAS,GAA4D,CACnE,CACE,KAAM,KACN,YAAqB,EAAiB,CAAE,SAAQ,KAAM,MAAO,CAAC,CAChE,CACF,EACA,QAAS,iBACT,MAAO,EACT,GACA,CAAC,CACH,EACM,IAAA,EAAA,EAAA,cACgC,CAClC,OAAS,GAA8D,CACrE,CACE,KAAM,KACN,YAAqB,EAAmB,CAAE,SAAQ,KAAM,MAAO,CAAC,CAClE,EACA,CACE,KAAM,KACN,YACE,EAAsB,CACpB,YAAa,OACb,YAAa,MAAM,EAAO,WAAW,KAAK,EAAO,YAAY,SAC7D,GAAI,EAAO,GACX,MAAO,SACP,KAAM,YACR,CAAC,EACH,QAAS,uBACX,CACF,EACA,QAAS,iBACT,MAAO,GACT,GACA,CAAC,CACH,EACM,IAAA,EAAA,EAAA,cACuC,CACzC,OACE,GAC6D,CAC7D,CACE,KAAM,KACN,YAAqB,EAAgB,CAAE,SAAQ,KAAM,MAAO,CAAC,CAC/D,EACA,CACE,KAAM,KACN,YACE,EAAsB,CACpB,YAAa,SACb,YAAa,MAAM,EAAO,WAAW,OAAO,EAAO,YAAY,WAC/D,GAAI,EAAO,GACX,MAAO,WACP,KAAM,oBACR,CAAC,EACH,QAAS,uBACX,CACF,EACA,QAAS,iBACT,MAAO,GACT,GACA,CAAC,CACH,EAEA,SAAS,GAAwB,EAAqB,CACpD,EAAe,CAAC,EAChB,GAAqB,CAAK,CAC5B,CAEA,SAAS,GAAwB,EAAsC,CACrE,EAAe,CAAC,EAChB,GAAqB,CAAK,CAC5B,CAEA,SAAS,GAAyB,EAAqB,CACrD,GAAgB,CAAC,EACjB,GAAsB,CAAK,CAC7B,CAEA,SAAS,GAA6B,EAAwC,CAC5E,EAAkB,CAAC,EACnB,GAA0B,CAAK,CACjC,CAEA,SAAS,GAA8B,EAAmC,CACxE,EAAkB,CAAC,EACnB,EAA2B,CAAK,CAClC,CAEA,SAAS,GAA+B,EAAoC,CAC1E,EAAkB,CAAC,EACnB,EAA4B,CAAK,CACnC,CAEA,SAAS,GAA0B,EAAiC,CAClE,EAAe,CAAC,EAChB,EAAuB,CAAK,CAC9B,CAEA,SAAS,GAA6B,EAAoC,CACxE,EAAe,CAAC,EAChB,EAA0B,CAAK,CACjC,CAEA,SAAS,IAAgC,CACnC,GAIJ,EAAsB,IAAI,CAC5B,CAEA,eAAe,IAAqC,CAC7C,GAIL,MAAM,GAAY,SAA2B,CACvC,EAAmB,OAAS,YAC9B,MAAA,EAAA,EAAA,eAAoB,EAAmB,EAAE,EAGvC,EAAmB,OAAS,cAC9B,MAAA,EAAA,EAAA,kBAAuB,EAAmB,EAAE,EAG1C,EAAmB,OAAS,sBAC9B,MAAA,EAAA,EAAA,yBAA8B,EAAmB,EAAE,EAGrD,EAAsB,IAAI,CAC5B,CAAC,CACH,CAEA,eAAe,GACb,EACe,CACf,GAAU,EAAI,EACd,EAAS,IAAI,EAEb,GAAI,CACF,MAAA,EAAA,EAAA,wBAA6B,CAC3B,MAAO,EAAQ,IAAK,IAGX,CACL,cAHc,EAAa,IAAI,EAAO,SAGvB,GAAS,WAAa,GACrC,GAAI,EAAO,UACX,SAAU,EAAO,QACnB,EACD,CACH,CAAC,EACD,MAAM,GAAoB,CAC5B,OAAS,EAAuB,CAE9B,MADA,EAAS,GAAiB,CAAY,CAAC,EACjC,CACR,QAAU,CACR,GAAU,EAAK,CACjB,CACF,CAEA,eAAe,GAAY,EAA8C,CACvE,GAAU,EAAI,EACd,EAAS,IAAI,EAEb,GAAI,CACF,MAAM,EAAS,EACf,MAAM,GAAoB,CAC5B,OAAS,EAAuB,CAC9B,EAAS,GAAiB,CAAY,CAAC,CACzC,QAAU,CACR,GAAU,EAAK,CACjB,CACF,CAEA,OACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACI,EAAA,EAAA,KAAC,EAAA,WAAD,CAAA,UACE,EAAA,EAAA,KAAC,EAAA,QAAD,CACE,YAAY,0BACZ,MAAM,MACP,CAAA,CACS,CAAA,GAEZ,EAAA,EAAA,KAAC,EAAA,aAAD,CAAA,UACE,EAAA,EAAA,MAAC,EAAA,QAAD,CACE,KACE,EAAA,EAAA,MAAC,EAAA,IAAD,CACE,UAAW,EACX,SAAW,GAAc,EAAa,GAAgB,CAAG,CAAC,WAF5D,EAIE,EAAA,EAAA,KAAC,EAAA,QAAD,CAAA,SAAyB,KAAY,EAAxB,WAAwB,GACrC,EAAA,EAAA,KAAC,EAAA,QAAD,CAAA,SAAyB,IAAW,EAAvB,WAAuB,GACpC,EAAA,EAAA,KAAC,EAAA,QAAD,CAAA,SAA2B,MAAa,EAA3B,aAA2B,GACxC,EAAA,EAAA,KAAC,EAAA,QAAD,CAAA,SAAwB,MAAa,EAAxB,UAAwB,CAClC,aAVT,CAaG,GACC,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,MAAM,aAAa,QAAQ,gBACpC,CACS,CAAA,EACV,KACH,IAAc,aACb,EAAA,EAAA,KAAC,GAAD,CACE,QAAS,GACA,UACT,aACE,EAAY,CAAE,SAAU,KAAM,OAAQ,KAAM,KAAM,QAAS,CAAC,EAE9D,cAAgB,GACd,EAAY,CAAE,WAAU,OAAQ,KAAM,KAAM,QAAS,CAAC,EAExD,cAAgB,GACd,EAAY,CAAE,SAAQ,KAAM,MAAO,CAAC,EAEtC,aAAc,EACd,YAAa,GACb,iBAAmB,GAAmB,CACpC,EAAe,CAAC,EAChB,EAAmB,CAAQ,CAC7B,EACA,mBAAoB,GACpB,mBAAoB,GACV,WACV,KAAM,EACN,SAAU,EACV,KAAM,GACN,WAAY,GACJ,SACR,MAAO,EACP,WAAY,GACZ,SAAU,GACV,iBAAkB,EACnB,CAAA,EACC,KACH,IAAc,aACb,EAAA,EAAA,KAAC,GAAD,CACE,QAAS,GACA,UACT,aACE,EAAiB,CAAE,OAAQ,KAAM,KAAM,QAAS,CAAC,EAEnD,aAAc,GACd,iBAAmB,GAAmB,CACpC,GAAgB,CAAC,EACjB,GAAoB,CAAQ,CAC9B,EACA,mBAAoB,GACpB,KAAM,GACN,SAAU,GACV,KAAM,GACN,WAAY,GACZ,MAAO,EACR,CAAA,EACC,KACH,IAAc,eACb,EAAA,EAAA,KAAC,GAAD,CACE,QAAS,GACA,UACT,aACE,EAAmB,CAAE,OAAQ,KAAM,KAAM,QAAS,CAAC,EAErD,qBAAsB,GACtB,sBAAuB,GACvB,aAAc,EACd,iBAAmB,GAAmB,CACpC,EAAkB,CAAC,EACnB,GAAsB,CAAQ,CAChC,EACA,uBAAwB,GACxB,cAAe,GACL,WACV,KAAM,GACN,SAAU,EACV,eAAgB,EACL,YACX,KAAM,GACN,aAAc,EACd,MAAO,EACR,CAAA,EACC,KACH,IAAc,YACb,EAAA,EAAA,KAAC,GAAD,CACE,QAAS,GACA,UACT,aACE,EAAgB,CAAE,OAAQ,KAAM,KAAM,QAAS,CAAC,EAElD,qBAAsB,GACtB,aAAc,EACd,iBAAmB,GAAmB,CACpC,EAAe,CAAC,EAChB,EAAmB,CAAQ,CAC7B,EACA,wBAAyB,GACzB,KAAM,EACN,SAAU,EACV,KAAM,GACN,gBAAiB,EACjB,aAAc,EACd,MAAO,CACR,CAAA,EACC,IACG,GACG,CAAA,GAEd,EAAA,EAAA,KAAC,GAAD,CACE,MAAO,EACP,YAAqB,EAAY,IAAI,EACrC,SAAW,GACT,GAAY,SAA2B,CACjC,GAAU,OAAS,QAAU,EAAS,OACxC,MAAA,EAAA,EAAA,eAAoB,CAClB,GAAG,EACH,GAAI,EAAS,OAAO,GACpB,aAAc,IAChB,CAAC,EAED,MAAA,EAAA,EAAA,eAAoB,CAClB,KAAM,EAAM,MAAQ,GACpB,aAAc,KACd,KAAM,EAAM,MAAQ,GACpB,SAAU,EAAM,SAChB,KAAM,EAAM,MAAQ,YACtB,CAAC,EAEH,EAAY,IAAI,CAClB,CAAC,EAEO,WACF,QACT,CAAA,GACD,EAAA,EAAA,KAAC,GAAD,CACE,MAAO,EACP,YAAqB,EAAiB,IAAI,EAC1C,SAAW,GACT,GAAY,SAA2B,CACjC,GAAe,OAAS,QAAU,EAAc,OAClD,MAAA,EAAA,EAAA,gBAAqB,CACnB,GAAG,EACH,GAAI,EAAc,OAAO,GACzB,aAAc,IAChB,CAAC,EAED,MAAA,EAAA,EAAA,gBAAqB,CACnB,KAAM,EAAM,MAAQ,GACpB,MAAO,EAAM,OAAS,EACtB,aAAc,KACd,KAAM,EAAM,MAAQ,EACtB,CAAC,EAEH,EAAiB,IAAI,CACvB,CAAC,EAEK,QACT,CAAA,GACD,EAAA,EAAA,KAAC,GAAD,CACe,cACb,MAAO,EACP,YAAqB,EAAmB,IAAI,EAC5C,SAAW,GACT,GAAY,SAA2B,CACjC,GAAiB,OAAS,QAAU,EAAgB,OACtD,MAAA,EAAA,EAAA,kBAAuB,CACrB,GAAG,EACH,GAAI,EAAgB,OAAO,EAC7B,CAAC,EAED,MAAA,EAAA,EAAA,kBAAuB,CACrB,cAAe,EAAM,eAAiB,EAAM,EAC5C,YAAa,EAAM,YACnB,UAAW,EAAM,WAAa,GAC9B,SAAU,EAAM,UAAY,GAC5B,UAAW,EAAM,WAAa,GAC9B,WAAY,EAAM,UACpB,CAAC,EAEH,EAAmB,IAAI,CACzB,CAAC,EAEO,WACC,YACH,QACT,CAAA,GACD,EAAA,EAAA,KAAC,GAAD,CACe,cACb,MAAO,EACP,YAAqB,EAAgB,IAAI,EACzC,SAAW,GACT,GAAY,SAA2B,CACjC,GAAc,OAAS,QAAU,EAAa,OAChD,MAAA,EAAA,EAAA,yBAA8B,CAC5B,GAAG,EACH,GAAI,EAAa,OAAO,EAC1B,CAAC,EAED,MAAA,EAAA,EAAA,yBAA8B,CAC5B,cAAe,EAAM,eAAiB,EAAM,EAC5C,YAAa,EAAM,YACnB,gBAAiB,EAAM,iBAAmB,GAC1C,SAAU,EAAM,UAAY,EAC5B,QAAS,EAAM,SAAW,GAC1B,UAAW,EAAM,WAAa,QAChC,CAAC,EAEH,EAAgB,IAAI,CACtB,CAAC,EAEO,WACC,YACH,QACT,CAAA,GACD,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,WAAW,KACX,mBAAoB,CAAE,QAAS,qBAAsB,EACrD,YAAa,IAA2B,aAAe,GACvD,QAAS,EACT,gBAAgB,QAChB,UAAU,WACV,SAAU,GACV,QAAS,GACT,cAAuB,KAAK,GAAoB,EAChD,KAAM,EAAQ,EACd,gBAAA,GACA,gBAAA,GACA,KAAK,UACL,eAAe,oBACf,MAAO,IAA2B,OAAS,aAE3C,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,MAAM,eAAe,QAAQ,gBACtC,IAA2B,aAAe,EACjC,CAAA,CACP,CAAA,CACP,CAAA,CAAA,CAER,CAEA,SAAS,GAAa,CACpB,UACA,UACA,WACA,gBACA,gBACA,eACA,cACA,mBACA,qBACA,qBACA,mBACA,WACA,OACA,WACA,OACA,aACA,SACA,QACA,aACA,YAwBe,CACf,IAAM,GAAA,EAAA,EAAA,QAA4D,IAAI,EAChE,CAAC,EAAiB,IAAA,EAAA,EAAA,UACgB,CAA6B,EAC/D,EAAgC,IAAa,QAAU,OAAS,QAChE,GAAsB,IAAa,QAAU,QAAU,OACvD,EAAa,IAAa,OAC1B,GAAqB,GAA8B,CACvD,aACA,cAAe,EAAgB,SACjC,CAAC,EACK,EAAoB,GAA6B,CACrD,aACA,cAAe,EAAgB,SACjC,CAAC,EACK,GAAwB,GAAiC,CAC7D,gBAAiB,EAAgB,gBACjC,cAAe,EAAgB,UAC/B,aACA,UACA,QACF,CAAC,EACK,GAAA,EAAA,EAAA,aAC6B,CAC/B,CAAE,UAAW,OAAQ,IAAK,OAAQ,MAAO,KAAM,MAAO,GAAI,EAC1D,CAAE,UAAW,OAAQ,IAAK,OAAQ,MAAO,KAAM,MAAO,GAAI,EAC1D,CAAE,UAAW,YAAa,IAAK,YAAa,MAAO,KAAM,MAAO,GAAI,EACpE,CAAE,UAAW,aAAc,IAAK,aAAc,MAAO,KAAM,MAAO,GAAI,EACtE,CAAE,UAAW,OAAQ,IAAK,OAAQ,MAAO,OAAQ,MAAO,GAAI,CAC9D,EACA,CAAC,CACH,EAQA,OANA,EAAA,EAAA,eAAsB,CAChB,IAAa,SACf,EAAmB,CAA6B,CAEpD,EAAG,CAAC,CAAQ,CAAC,GAGX,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,GAAD,CACE,eAAgB,GAChB,WAAY,EACZ,YAAa,GACb,SACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,YAAqB,EAAiB,CAAY,EAClD,QAAQ,0BAEP,EACK,CAAA,EACP,GAAc,EAAgB,WAC7B,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,SAAU,EACV,KAAM,EAAA,UACN,SAAS,UACT,YAAqB,EAAc,SAAS,cAAc,EAC1D,QAAQ,0BACT,IAEO,CAAA,EACN,IACJ,CAAA,CAAA,EAEJ,YAAY,4CACZ,aAAsB,CACpB,GAAI,CAAC,EAAY,CACf,EAAS,EACT,MACF,CAEA,GAAI,EAAgB,UAAW,CAC7B,EAAmB,SAAS,UAAU,EACtC,MACF,CAEA,EAAc,SAAS,aAAa,CACtC,EACA,MAAM,KACP,CAAA,EACA,IAAa,SACZ,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,UAAW,EAAO,cAAe,KAAK,gBAChD,EAAA,EAAA,MAAC,EAAA,WAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAA,OAAD,CAAQ,KAAM,YACZ,EAAA,EAAA,KAAC,EAAA,UAAD,CACE,UAAA,GACA,OAAQ,EAAA,gBAAgB,SACxB,KAAK,8BAEL,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,UAAA,GACA,SAAW,GACT,EAAmB,EAAM,OAAO,KAAK,EAEvC,YAAY,YACZ,KAAK,MACL,MAAO,EACP,QAAQ,MACT,CAAA,CACQ,CAAA,CACL,CAAA,GACR,EAAA,EAAA,KAAC,EAAA,OAAD,CAAQ,KAAM,YACZ,EAAA,EAAA,KAAC,EAAA,UAAD,CACE,UAAA,GACA,OAAQ,EAAA,gBAAgB,SACxB,KAAK,8BAEL,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,UAAW,GACX,UAAA,GACA,SAAW,GACT,EAAmB,GAA4B,CAAM,CAAC,EAExD,QAAS,CAAC,GAAG,CAA4B,EACzC,YAAY,KACZ,KAAK,MACL,MAAO,CACR,CAAA,CACQ,CAAA,CACL,CAAA,CACE,CAAA,CAAA,CACF,CAAA,GACZ,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAO,qBACrB,EAAA,EAAA,KAAC,EAAA,MAAD,CACW,UACA,UACT,WAAY,CAAC,GAAG,CAAI,EACpB,UAAA,GACS,UACT,WAAY,GAAsB,CAChC,eACA,mBACA,OACA,WACA,OACF,CAAC,EACD,MAAO,CAAE,SAAU,EAAyB,CAC7C,CAAA,CACE,CAAA,CACL,CAAA,CAAA,GAEF,EAAA,EAAA,KAAC,EAAD,CACE,IAAK,EACU,gBACf,aAAc,EACC,gBACF,cACb,cAAe,EACL,WACF,QACT,CAAA,CAEH,CAAA,CAAA,CAEN,CAEA,SAAS,GAAc,CACrB,UACA,UACA,WACA,eACA,mBACA,qBACA,OACA,WACA,OACA,aACA,SAae,CACf,IAAM,GAAA,EAAA,EAAA,aAC8B,CAChC,CAAE,UAAW,OAAQ,IAAK,OAAQ,MAAO,KAAM,MAAO,GAAI,EAC1D,CAAE,UAAW,OAAQ,IAAK,OAAQ,MAAO,KAAM,MAAO,GAAI,EAC1D,CAAE,UAAW,QAAS,IAAK,QAAS,MAAO,KAAM,MAAO,EAAG,EAC3D,CACE,UAAW,YACX,IAAK,YACL,MAAO,OACP,MAAO,GACT,CACF,EACA,CAAC,CACH,EAEA,OACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,GAAD,CACE,YAAY,OACZ,YAAY,qBACF,WACV,MAAM,IACP,CAAA,GACD,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,UAAW,EAAO,cAAe,KAAK,gBAChD,EAAA,EAAA,KAAC,EAAA,WAAD,CAAA,UACE,EAAA,EAAA,KAAC,EAAA,OAAD,CAAQ,KAAM,YACZ,EAAA,EAAA,KAAC,EAAA,UAAD,CACE,UAAA,GACA,OAAQ,EAAA,gBAAgB,SACxB,KAAK,+BAEL,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,UAAA,GACA,SAAW,GACT,EAAmB,EAAM,OAAO,KAAK,EAEvC,YAAY,YACZ,KAAK,MACL,MAAO,EACP,QAAQ,MACT,CAAA,CACQ,CAAA,CACL,CAAA,CACE,CAAA,CACF,CAAA,GACZ,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAO,qBACrB,EAAA,EAAA,KAAC,EAAA,MAAD,CACW,UACA,UACT,WAAY,CAAC,GAAG,CAAI,EACpB,UAAA,GACS,UACT,WAAY,GAAsB,CAChC,eACA,mBACA,OACA,WACA,OACF,CAAC,EACD,MAAO,CAAE,SAAU,EAAyB,CAC7C,CAAA,CACE,CAAA,CACL,CAAA,CAAA,CAEN,CAEA,SAAS,GAAgB,CACvB,UACA,UACA,WACA,uBACA,wBACA,eACA,mBACA,yBACA,gBACA,WACA,OACA,WACA,iBACA,YACA,OACA,eACA,SAmBe,CACf,IAAM,GAAA,EAAA,EAAA,aACgC,CAClC,CAAE,UAAW,aAAc,IAAK,aAAc,MAAO,KAAM,MAAO,GAAI,EACtE,CACE,UAAW,cACX,IAAK,cACL,MAAO,KACP,MAAO,GACT,EACA,CACE,UAAW,eACX,IAAK,eACL,MAAO,KACP,MAAO,GACT,EACA,CACE,IAAK,YACL,OAAS,GACP,EAAO,UAAY,KAAO,KAC5B,MAAO,KACP,MAAO,GACT,EACA,CACE,UAAW,gBACX,IAAK,gBACL,MAAO,MACP,MAAO,GACT,EACA,CACE,UAAW,cACX,IAAK,cACL,MAAO,MACP,MAAO,GACT,CACF,EACA,CAAC,CACH,EACM,GAAA,EAAA,EAAA,aAC4B,EAAS,IAAI,EAAA,CAAiB,EAC9D,CAAC,CAAQ,CACX,EACM,GAAA,EAAA,EAAA,aAC6B,EAAU,IAAI,EAAA,CAAkB,EACjE,CAAC,CAAS,CACZ,EAEA,OACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,GAAD,CACE,YAAY,OACZ,YAAY,iCACF,WACV,MAAM,MACP,CAAA,GACD,EAAA,EAAA,KAAC,EAAA,WAAD,CACE,UAAW,CAAC,EAAO,cAAe,EAAO,oBAAoB,EAAE,KAC7D,GACF,EACA,KAAK,gBAEL,EAAA,EAAA,MAAC,EAAA,WAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAA,OAAD,CAAQ,KAAM,YACZ,EAAA,EAAA,KAAC,EAAA,UAAD,CACE,UAAA,GACA,OAAQ,EAAA,gBAAgB,SACxB,KAAK,oCAEL,EAAA,EAAA,KAAC,EAAA,aAAD,CACE,sBAAA,GACA,UAAU,UACV,WAAY,CACV,eAAgB,OAChB,YAAa,MACb,KAAM,0BACN,WAAY,EACd,EACA,KAAK,SACL,KAAK,0BACL,SAAW,GACT,EAAsB,GAA2B,CAAM,CAAC,EAE1D,QAAS,CAAC,GAAG,CAAc,EAC3B,YAAY,OACZ,KAAK,MACL,MAAO,CACR,CAAA,CACQ,CAAA,CACL,CAAA,GACR,EAAA,EAAA,KAAC,EAAA,OAAD,CAAQ,KAAM,YACZ,EAAA,EAAA,KAAC,EAAA,UAAD,CACE,UAAA,GACA,OAAQ,EAAA,gBAAgB,SACxB,KAAK,qCAEL,EAAA,EAAA,KAAC,EAAA,aAAD,CACE,sBAAA,GACA,UAAU,UACV,WAAY,CACV,eAAgB,OAChB,YAAa,MACb,KAAM,2BACN,WAAY,EACd,EACA,KAAK,SACL,KAAK,2BACL,SAAW,GACT,EAAuB,GAA4B,CAAM,CAAC,EAE5D,QAAS,CAAC,GAAG,CAAe,EAC5B,YAAY,OACZ,KAAK,MACL,MAAO,CACR,CAAA,CACQ,CAAA,CACL,CAAA,GACR,EAAA,EAAA,KAAC,EAAA,OAAD,CAAQ,KAAM,YACZ,EAAA,EAAA,KAAC,EAAA,UAAD,CACE,UAAA,GACA,OAAQ,EAAA,gBAAgB,SACxB,KAAK,mCAEL,EAAA,EAAA,KAAC,EAAA,aAAD,CACE,sBAAA,GACA,UAAU,UACV,WAAY,CACV,eAAgB,OAChB,YAAa,MACb,KAAM,yBACN,WAAY,EACd,EACA,KAAK,SACL,KAAK,yBACL,SAAW,GACT,EAAqB,GAA+B,CAAM,CAAC,EAE7D,QAAS,CAAC,GAAG,EAAqB,EAClC,YAAY,OACZ,KAAK,MACL,MAAO,CACR,CAAA,CACQ,CAAA,CACL,CAAA,CACE,CAAA,CAAA,CACF,CAAA,GACZ,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAO,qBACrB,EAAA,EAAA,KAAC,EAAA,MAAD,CACW,UACA,UACT,WAAY,CAAC,GAAG,CAAI,EACpB,UAAA,GACS,UACT,WAAY,GAAsB,CAChC,eACA,mBACA,OACA,WACA,OACF,CAAC,EACD,MAAO,CAAE,SAAU,EAA2B,CAC/C,CAAA,CACE,CAAA,CACL,CAAA,CAAA,CAEN,CAEA,SAAS,GAAa,CACpB,UACA,UACA,WACA,uBACA,eACA,mBACA,0BACA,OACA,WACA,OACA,kBACA,eACA,SAee,CACf,IAAM,GAAA,EAAA,EAAA,aACuC,CACzC,CACE,UAAW,aACX,IAAK,aACL,MAAO,OACP,MAAO,GACT,EACA,CACE,UAAW,cACX,IAAK,cACL,MAAO,OACP,MAAO,GACT,EACA,CAAE,UAAW,WAAY,IAAK,WAAY,MAAO,MAAO,MAAO,EAAG,EAClE,CACE,UAAW,gBACX,IAAK,gBACL,MAAO,MACP,MAAO,GACT,EACA,CACE,UAAW,cACX,IAAK,cACL,MAAO,MACP,MAAO,GACT,CACF,EACA,CAAC,CACH,EAEA,OACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,GAAD,CACE,YAAY,SACZ,YAAY,sCACF,WACV,MAAM,MACP,CAAA,GACD,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,UAAW,EAAO,cAAe,KAAK,gBAChD,EAAA,EAAA,MAAC,EAAA,WAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAA,OAAD,CAAQ,KAAM,YACZ,EAAA,EAAA,KAAC,EAAA,UAAD,CACE,UAAA,GACA,OAAQ,EAAA,gBAAgB,SACxB,KAAK,mCAEL,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,UAAW,GACX,UAAA,GACA,SAAW,GACT,EAAwB,GAA0B,CAAM,CAAC,EAE3D,QAAS,CAAC,GAAG,EAAyB,EACtC,YAAY,OACZ,KAAK,MACL,MAAO,CACR,CAAA,CACQ,CAAA,CACL,CAAA,GACR,EAAA,EAAA,KAAC,EAAA,OAAD,CAAQ,KAAM,YACZ,EAAA,EAAA,KAAC,EAAA,UAAD,CACE,UAAA,GACA,OAAQ,EAAA,gBAAgB,SACxB,KAAK,gCAEL,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,UAAW,GACX,UAAA,GACA,SAAW,GACT,EAAqB,GAAuB,CAAM,CAAC,EAErD,QAAS,CAAC,GAAG,EAAqB,EAClC,YAAY,KACZ,KAAK,MACL,MAAO,CACR,CAAA,CACQ,CAAA,CACL,CAAA,CACE,CAAA,CAAA,CACF,CAAA,GACZ,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAO,qBACrB,EAAA,EAAA,KAAC,EAAA,MAAD,CACW,UACA,UACT,WAAY,CAAC,GAAG,CAAI,EACpB,UAAA,GACS,UACT,WAAY,GAAsB,CAChC,eACA,mBACA,OACA,WACA,OACF,CAAC,EACD,MAAO,CAAE,SAAU,EAAwB,CAC5C,CAAA,CACE,CAAA,CACL,CAAA,CAAA,CAEN,CAEA,SAAS,GAAsB,CAC7B,eACA,mBACA,OACA,WACA,SAWA,CACA,MAAO,CACL,QAAS,EACT,SAAU,EACV,iBAAkB,EAClB,WACA,cAAe,OACf,gBAAiB,CAAC,GAAG,EAAoC,EACzD,qBAAsB,EAAM,EAAI,IAC9B,MAAM,EAAK,GAAG,EAAG,OAAO,EAAY,IACtC,oBAAqB,GACrB,OACF,CACF,CAEA,SAAS,GAA8B,CACrC,gBACA,cAIS,CAKT,OAJK,EAIE,EAAgB,KAAO,OAHrB,MAIX,CAEA,SAAS,GAA6B,CACpC,gBACA,cAIiB,CAKjB,OAJK,EAIE,EAAgB,EAAA,SAAW,EAAA,SAHzB,EAAA,QAIX,CAEA,SAAS,GAAiC,CACxC,kBACA,gBACA,aACA,UACA,UAOU,CASV,OARK,EAIA,EAIE,CAAC,GAAmB,EAHlB,EAJA,EAQX,CAEA,SAAS,GAAW,CAClB,iBAAiB,GACjB,aAAa,EAAA,SACb,cACA,UACA,cACA,WACA,SASe,CACf,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAO,oBAAvB,EACE,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,UAAU,KAAK,QAAQ,cAChC,CACS,CAAA,GACZ,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,MAAM,eAAe,QAAQ,gBACtC,CACS,CAAA,CACT,CAAA,CAAA,GACL,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAO,2BAAvB,CACG,GACD,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,SAAU,EACV,KAAM,EACN,SAAS,UACT,QAAS,WAER,CACK,CAAA,CACL,GACF,GAET,CAEA,SAAS,GAAa,CACpB,QACA,UACA,WACA,WACA,UAYe,CACf,GAAM,CAAC,EAAM,IAAA,EAAA,EAAA,UAAoB,EAAE,EAC7B,CAAC,EAAM,IAAA,EAAA,EAAA,UAAoB,EAAE,EAC7B,CAAC,EAAQ,IAAA,EAAA,EAAA,UAA4C,IAAI,EACzD,CAAC,EAAM,IAAA,EAAA,EAAA,UAAuC,EAAe,EAAE,EAsBrE,OApBA,EAAA,EAAA,eAAsB,CACpB,GAAI,CAAC,EACH,OAGF,IAAM,EAAS,EAAM,OACf,EAAW,GAAQ,UAAY,EAAM,UAAY,KACjD,EAAgB,EACjB,EAAS,KAAM,GAAY,EAAQ,KAAO,CAAQ,GAAK,KACxD,KAEJ,EAAQ,GAAQ,MAAQ,EAAE,EAC1B,EAAQ,GAAQ,MAAQ,EAAE,EAC1B,EAAU,EAAgB,EAAA,EAAkB,CAAa,EAAI,IAAI,EACjE,EACE,EAAe,KAAM,GAAW,EAAO,KAAO,GAAQ,IAAI,GACxD,EAAe,EACnB,CACF,EAAG,CAAC,EAAO,CAAQ,CAAC,GAGlB,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,WAAW,KACX,mBAAoB,CAAE,SAAU,CAAC,GAAQ,CAAC,CAAK,EAC/C,YAAa,GAAO,OAAS,OAAS,KAAO,KAC7C,QAAS,EACT,UAAU,WACV,SAAU,EACD,UACT,cACE,KAAK,EAAS,CACZ,OACA,OACA,SAAU,GAAQ,IAAM,KACxB,KAAM,EAAK,EACb,CAAC,EAEH,KAAM,EAAQ,EACd,gBAAA,GACA,gBAAA,GACA,KAAK,UACL,MAAO,GAAO,OAAS,OAAS,OAAS,iBAEzC,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAO,qBAAvB,EACE,EAAA,EAAA,KAAC,EAAD,CACE,MAAM,KACN,KAAK,UACL,SAAU,EACV,YAAY,YACZ,MAAO,CACR,CAAA,GACD,EAAA,EAAA,KAAC,EAAD,CACE,MAAM,KACN,KAAK,UACL,SAAU,EACV,YAAY,SACZ,MAAO,CACR,CAAA,GACD,EAAA,EAAA,KAAC,EAAA,EAAD,CAAc,MAAM,KAAK,KAAK,oBAC5B,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,UAAW,GACX,UAAA,GACA,SAAW,GAAiB,EAAQ,GAAsB,CAAM,CAAC,EACjE,QAAS,CAAC,GAAG,CAAc,EAC3B,YAAY,SACZ,MAAO,CACR,CAAA,CACW,CAAA,GACd,EAAA,EAAA,KAAC,EAAA,EAAD,CAAc,MAAM,OAAO,KAAK,qBAC9B,EAAA,EAAA,KAAC,EAAA,EAAD,CACE,KAAK,WACL,SAAU,EACV,SAAU,EAAS,OAChB,GAAY,EAAQ,KAAO,GAAO,QAAQ,EAC7C,EACA,YAAY,SACZ,MAAO,CACR,CAAA,CACW,CAAA,CACX,GACA,CAAA,CAEX,CAEA,SAAS,GAAc,CACrB,QACA,UACA,WACA,UAUe,CACf,GAAM,CAAC,EAAM,IAAA,EAAA,EAAA,UAAoB,EAAE,EAC7B,CAAC,EAAO,IAAA,EAAA,EAAA,UAAqB,GAAG,EAChC,CAAC,EAAM,IAAA,EAAA,EAAA,UAAoB,EAAE,EAYnC,OAVA,EAAA,EAAA,eAAsB,CACf,IAIL,EAAQ,EAAM,QAAQ,MAAQ,EAAE,EAChC,EAAS,OAAO,EAAM,QAAQ,OAAS,CAAC,CAAC,EACzC,EAAQ,EAAM,QAAQ,MAAQ,EAAE,EAClC,EAAG,CAAC,CAAK,CAAC,GAGR,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,WAAW,KACX,mBAAoB,CAAE,SAAU,CAAC,GAAQ,CAAC,CAAK,EAC/C,YAAa,GAAO,OAAS,OAAS,KAAO,KAC7C,QAAS,EACT,UAAU,WACV,SAAU,EACD,UACT,cACE,KAAK,EAAS,CACZ,OACA,MAAO,OAAO,CAAK,EACnB,MACF,CAAC,EAEH,KAAM,EAAQ,EACd,gBAAA,GACA,gBAAA,GACA,KAAK,UACL,MAAO,GAAO,OAAS,OAAS,OAAS,iBAEzC,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAO,qBAAvB,EACE,EAAA,EAAA,KAAC,EAAD,CACE,MAAM,KACN,KAAK,eACL,SAAU,EACV,YAAY,aACZ,MAAO,CACR,CAAA,GACD,EAAA,EAAA,KAAC,EAAD,CACE,MAAM,KACN,KAAK,eACL,SAAU,EACV,YAAY,UACZ,MAAO,CACR,CAAA,GACD,EAAA,EAAA,KAAC,EAAD,CACE,MAAM,KACN,KAAK,gBACL,SAAU,EACV,YAAY,OACZ,MAAO,CACR,CAAA,CACE,GACA,CAAA,CAEX,CAEA,SAAS,GAAgB,CACvB,cACA,QACA,UACA,WACA,WACA,YACA,UAgBe,CACf,GAAM,CAAC,EAAe,IAAA,EAAA,EAAA,UAA6B,EAAM,CAAC,EACpD,CAAC,EAAa,IAAA,EAAA,EAAA,UAA2B,EAAE,EAC3C,CAAC,EAAW,IAAA,EAAA,EAAA,UAAwC,EAAgB,EAAE,EACtE,CAAC,EAAQ,IAAA,EAAA,EAAA,UAA2C,IAAI,EACxD,CAAC,EAAS,IAAA,EAAA,EAAA,UAA6C,IAAI,EAC3D,CAAC,EAAU,IAAA,EAAA,EAAA,UAA+C,IAAI,EA+BpE,OA7BA,EAAA,EAAA,eAAsB,CACpB,GAAI,CAAC,EACH,OAGF,IAAM,EAAS,EAAM,OACf,EAAU,EAAS,EAAY,IAAI,EAAO,QAAQ,EAAI,KAE5D,EAAiB,GAAQ,eAAiB,EAAM,CAAC,EACjD,EAAe,GAAQ,aAAe,EAAE,EACxC,EACE,EAAgB,KAAM,GAAW,EAAO,QAAU,GAAQ,SAAS,GACjE,EAAgB,EACpB,EACA,EAAU,EAAU,EAAA,EAAiB,CAAO,EAAI,IAAI,EACpD,EACE,EACE,EAAS,KAAM,GAAc,EAAU,KAAO,GAAQ,SAAS,EAC/D,EAAA,CACF,CACF,EACA,EACE,EACE,EAAU,KAAM,GAAc,EAAU,KAAO,GAAQ,UAAU,EACjE,EAAA,CACF,CACF,CACF,EAAG,CAAC,EAAa,EAAO,EAAU,CAAS,CAAC,GAG1C,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,WAAW,KACX,mBAAoB,CAAE,SAAU,CAAC,GAAU,CAAC,CAAQ,EACpD,YAAa,GAAO,OAAS,OAAS,KAAO,KAC7C,QAAS,EACT,UAAU,WACV,SAAU,EACD,UACT,cACE,KAAK,EAAS,CACZ,gBACA,YAAa,GAAe,KAC5B,UAAW,EAAU,MACrB,SAAU,GAAQ,IAAM,KACxB,UAAW,GAAS,IAAM,KAC1B,WAAY,GAAU,IAAM,IAC9B,CAAC,EAEH,KAAM,EAAQ,EACd,gBAAA,GACA,gBAAA,GACA,KAAK,UACL,MAAO,GAAO,OAAS,OAAS,SAAW,mBAE3C,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAO,qBAAvB,EACE,EAAA,EAAA,KAAC,EAAA,EAAD,CAAc,MAAM,KAAK,KAAK,qBAC5B,EAAA,EAAA,KAAC,EAAA,EAAD,CACE,KAAK,WACL,SAAU,EACV,YAAY,YACZ,MAAO,CACR,CAAA,CACW,CAAA,GACd,EAAA,EAAA,KAAC,EAAA,EAAD,CAAc,MAAM,KAAK,KAAK,sBAC5B,EAAA,EAAA,KAAC,EAAA,EAAD,CACE,KAAK,YACL,SAAU,EACA,WACV,YAAY,SACZ,MAAO,CACR,CAAA,CACW,CAAA,GACd,EAAA,EAAA,KAAC,EAAA,EAAD,CAAc,MAAM,KAAK,KAAK,uBAC5B,EAAA,EAAA,KAAC,EAAA,EAAD,CACE,KAAK,aACL,SAAU,EACV,YAAY,OACD,YACX,MAAO,CACR,CAAA,CACW,CAAA,GACd,EAAA,EAAA,KAAC,EAAA,EAAD,CAAc,MAAM,OAAO,KAAK,sBAC9B,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,UAAW,GACX,UAAA,GACA,SAAW,GAAiB,EAAa,EAAkB,CAAM,CAAC,EAClE,QAAS,CAAC,GAAG,CAAe,EAC5B,YAAY,SACZ,MAAO,CACR,CAAA,CACW,CAAA,GACd,EAAA,EAAA,KAAC,EAAD,CACE,MAAM,MACN,KAAK,0BACL,SAAU,EACV,YAAY,aACZ,MAAO,CACR,CAAA,GACD,EAAA,EAAA,KAAC,EAAD,CACE,MAAM,MACN,KAAK,wBACL,SAAU,EACV,YAAY,sBACZ,MAAO,CACR,CAAA,CACE,GACA,CAAA,CAEX,CAEA,SAAS,GAAuB,CAC9B,cACA,QACA,UACA,WACA,WACA,YACA,UAgBe,CACf,GAAM,CAAC,EAAe,IAAA,EAAA,EAAA,UAA6B,EAAM,CAAC,EACpD,CAAC,EAAa,IAAA,EAAA,EAAA,UAA2B,EAAE,EAC3C,CAAC,EAAS,IAAA,EAAA,EAAA,UAA4C,IAAI,EAC1D,CAAC,EAAU,IAAA,EAAA,EAAA,UAAwB,GAAG,EACtC,CAAC,EAAa,IAAA,EAAA,EAAA,UAAgD,IAAI,EAClE,CAAC,EAAc,IAAA,EAAA,EAAA,UAAkD,IAAI,EACrE,CAAC,EAAe,IAAA,EAAA,EAAA,UACpB,IACF,EACM,CAAC,EAAW,IAAA,EAAA,EAAA,UAA0C,EAAY,EAAE,GAE1E,EAAA,EAAA,eAAsB,CACpB,GAAI,CAAC,EACH,OAGF,IAAM,EAAS,EAAM,OACf,EACJ,EAAY,KAAM,GAAW,EAAO,KAAO,GAAQ,SAAS,GAC5D,EAAY,GAEd,EAAiB,GAAQ,eAAiB,EAAM,CAAC,EACjD,EAAe,GAAQ,aAAe,EAAE,EACxC,EACE,EACE,EAAS,EAAY,IAAI,EAAO,eAAe,EAAI,KACnD,EAAA,CACF,CACF,EACA,EAAY,OAAO,GAAQ,UAAY,CAAC,CAAC,EACzC,EACE,EAAc,KAAO,SACjB,EACE,EAAS,EAAY,IAAI,EAAO,OAAO,EAAI,KAC3C,EAAA,CACF,EACA,IACN,EACA,EACE,EAAc,KAAO,WACjB,EACE,EAAS,KAAM,GAAc,EAAU,KAAO,GAAQ,OAAO,EAC7D,EAAA,CACF,EACA,IACN,EACA,EACE,EAAc,KAAO,WACjB,EACE,EAAU,KAAM,GAAc,EAAU,KAAO,GAAQ,OAAO,EAC9D,EAAA,CACF,EACA,IACN,EACA,EAAa,CAAa,CAC5B,EAAG,CAAC,EAAa,EAAO,EAAU,CAAS,CAAC,EAE5C,IAAM,EACJ,EAAU,KAAO,SACb,GAAa,GACb,EAAU,KAAO,WACf,GAAc,GACd,GAAe,GACjB,GAA0B,GAC9B,EAAU,KAAO,UACjB,GAAa,IACb,GAAS,IACT,EAAY,KAAO,EAAQ,IAG7B,OACE,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,WAAW,KACX,mBAAoB,CAClB,SAAU,CAAC,GAAW,CAAC,GAAW,EACpC,EACA,YAAa,GAAO,OAAS,OAAS,KAAO,KAC7C,QAAS,EACT,UAAU,WACV,SAAU,EACD,UACT,cACE,KAAK,EAAS,CACZ,gBACA,YAAa,GAAe,KAC5B,gBAAiB,GAAS,IAAM,KAChC,SAAU,OAAO,CAAQ,EACzB,QAAS,GAAW,KACpB,UAAW,EAAU,EACvB,CAAC,EAEH,KAAM,EAAQ,EACd,gBAAA,GACA,gBAAA,GACA,KAAK,UACL,MAAO,GAAO,OAAS,OAAS,SAAW,mBAE3C,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAO,qBAAvB,EACE,EAAA,EAAA,KAAC,EAAA,EAAD,CAAc,MAAM,OAAO,KAAK,sBAC9B,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,UAAW,GACX,UAAA,GACA,SAAW,GACT,EAAa,GAAoB,CAAM,CAAC,EAE1C,QAAS,CAAC,GAAG,CAAW,EACxB,YAAY,SACZ,MAAO,CACR,CAAA,CACW,CAAA,EACb,EAAU,KAAO,UAChB,EAAA,EAAA,KAAC,EAAA,EAAD,CAAc,MAAM,KAAK,KAAK,0BAC5B,EAAA,EAAA,KAAC,EAAA,EAAD,CACE,KAAK,gBACL,SAAU,EACV,YAAY,SACZ,MAAO,CACR,CAAA,CACW,CAAA,EACZ,KACH,EAAU,KAAO,YAChB,EAAA,EAAA,KAAC,EAAA,EAAD,CAAc,MAAM,KAAK,KAAK,2BAC5B,EAAA,EAAA,KAAC,EAAA,EAAD,CACE,KAAK,iBACL,SAAU,EACA,WACV,YAAY,SACZ,MAAO,CACR,CAAA,CACW,CAAA,EACZ,KACH,EAAU,KAAO,YAChB,EAAA,EAAA,KAAC,EAAA,EAAD,CAAc,MAAM,KAAK,KAAK,4BAC5B,EAAA,EAAA,KAAC,EAAA,EAAD,CACE,KAAK,kBACL,SAAU,EACV,YAAY,SACD,YACX,MAAO,CACR,CAAA,CACW,CAAA,EACZ,MACJ,EAAA,EAAA,KAAC,EAAA,EAAD,CAAc,MAAM,OAAO,KAAK,4BAC9B,EAAA,EAAA,KAAC,EAAA,EAAD,CACE,KAAK,kBACL,SAAU,EACV,YAAY,SACZ,MAAO,CACR,CAAA,CACW,CAAA,EACb,IACC,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,MAAM,aAAa,QAAQ,mBAAU,kBAErC,CAAA,EACV,MACJ,EAAA,EAAA,KAAC,EAAD,CACE,MAAM,MACN,KAAK,kBACL,SAAU,EACV,YAAY,QACZ,MAAO,CACR,CAAA,GACD,EAAA,EAAA,KAAC,EAAD,CACE,MAAM,MACN,KAAK,uBACL,SAAU,EACV,YAAY,aACZ,MAAO,CACR,CAAA,GACD,EAAA,EAAA,KAAC,EAAD,CACE,MAAM,MACN,KAAK,qBACL,SAAU,EACV,YAAY,sBACZ,MAAO,CACR,CAAA,CACE,GACA,CAAA,CAEX,CAEA,SAAS,EAAkB,CACzB,QACA,OACA,WACA,cACA,SAOe,CACf,OACE,EAAA,EAAA,KAAC,EAAA,EAAD,CAAqB,QAAa,iBAChC,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,UAAA,GACM,OACN,SAAW,GACT,EAAS,EAAM,OAAO,KAAK,EAEhB,cACN,OACR,CAAA,CACW,CAAA,CAElB,CAEA,SAAS,EAAU,CACjB,QACA,OACA,WACA,cACA,SAOe,CACf,OACE,EAAA,EAAA,KAAC,EAAA,EAAD,CAAqB,QAAa,iBAChC,EAAA,EAAA,KAAC,EAAA,WAAD,CACE,OAAO,aACP,UAAA,GACA,WAAY,CAAE,MAAK,EACnB,SAAW,GAAoB,EAAS,GAAe,CAAS,CAAC,EACpD,cACb,MAAO,EAAM,KAAK,EAAI,EAAQ,IAAA,EAC/B,CAAA,CACW,CAAA,CAElB,CAEA,SAAS,GACP,EACA,EACmB,CACnB,MAAO,CACL,GAAG,IAAI,IAAI,CACT,GAAG,EAAY,IAAK,GAAe,EAAW,QAAQ,EACtD,GAAG,EAAmB,IAAK,GAAe,EAAW,eAAe,EACpE,GAAG,EACA,OAAQ,GAAe,EAAW,YAAc,QAAQ,EACxD,IAAK,GAAe,EAAW,OAAO,CAC3C,CAAC,CACH,CACF,CAEA,SAAS,GACP,EACA,EAKQ,CASR,OARI,EAAW,YAAc,SACpB,MAAM,GAAgB,EAAO,YAAY,IAAI,EAAW,OAAO,CAAC,IAGrE,EAAW,YAAc,WACpB,MAAM,GAAiB,EAAO,aAAa,IAAI,EAAW,OAAO,CAAC,IAGpE,MAAM,GAAkB,EAAO,cAAc,IAAI,EAAW,OAAO,CAAC,GAC7E,CAEA,SAAS,GAAgB,EAAiD,CACxE,OAAO,EAAS,GAAG,EAAO,KAAK,KAAK,EAAO,QAAU,MACvD,CAEA,SAAS,GAAiB,EAA4C,CACpE,OAAO,EAAU,GAAG,EAAQ,KAAK,KAAK,EAAQ,OAAS,MACzD,CAEA,SAAS,GAAqB,EAA2B,CACvD,OACE,EAAe,KACZ,GAAW,EAAO,GAAG,YAAY,IAAM,EAAK,YAAY,CAC3D,GAAG,MAAQ,MAEf,CAEA,SAAS,GAAkB,EAA8C,CACvE,OAAO,EAAW,GAAG,EAAS,KAAK,KAAK,EAAS,OAAS,KAC5D,CAEA,SAAS,GAAgB,EAA6B,CACpD,OAAO,IAAU,YACf,IAAU,eACV,IAAU,YACR,EACA,WACN,CAEA,SAAS,GAAsB,EAAmC,CAChE,IAAM,EAAS,EAAS,CAAK,EAAI,EAAQ,KAEzC,GAAI,OAAO,GAAQ,IAAO,SAAU,CAClC,IAAM,EAAK,EAAO,GAElB,OACE,EAAe,KACZ,GAAW,EAAO,GAAG,YAAY,IAAM,EAAG,YAAY,CACzD,GAAK,EAAe,EAExB,CAEA,OAAO,EAAe,EACxB,CAEA,SAAS,GAA4B,EAAyC,CAC5E,IAAM,EAAS,EAAS,CAAK,EAAI,EAAQ,KAEzC,GAAI,OAAO,GAAQ,IAAO,SAAU,CAClC,IAAM,EAAK,EAAO,GAElB,OACE,EAA6B,KAC1B,GAAW,EAAO,GAAG,YAAY,IAAM,EAAG,YAAY,CACzD,GAAK,EAET,CAEA,OAAO,EACT,CAEA,SAAS,GAAoB,EAAiC,CAC5D,OAAO,GAAW,EAAO,EAAa,EAAY,EAAE,CACtD,CAEA,SAAS,GAA0B,EAAuC,CACxE,OAAO,GAAW,EAAO,GAA2B,EAAqB,CAC3E,CAEA,SAAS,GAAuB,EAAoC,CAClE,OAAO,GAAW,EAAO,GAAuB,EAAiB,CACnE,CAEA,SAAS,GACP,EAC2B,CAC3B,IAAM,EAAS,EAAS,CAAK,EAAI,EAAQ,KACnC,EAAK,OAAO,GAAQ,IAAO,SAAW,EAAO,GAAK,KAExD,OAAO,GAAsB,KAAM,GAAW,EAAO,KAAO,CAAE,GAAK,IACrE,CAEA,SAAS,GAA2B,EAAsC,CACxE,IAAM,EAAS,EAAS,CAAK,EAAI,EAAQ,KACnC,EAAK,OAAO,GAAQ,IAAO,SAAW,EAAO,GAAK,KAClD,EAAO,OAAO,GAAQ,MAAS,SAAW,EAAO,KAAO,KAE9D,OAAO,GAAM,EAAO,CAAE,KAAI,MAAK,EAAI,IACrC,CAEA,SAAS,GAA4B,EAAuC,CAC1E,IAAM,EAAS,EAAS,CAAK,EAAI,EAAQ,KACnC,EAAK,OAAO,GAAQ,IAAO,SAAW,EAAO,GAAK,KAClD,EAAO,OAAO,GAAQ,MAAS,SAAW,EAAO,KAAO,KAE9D,OAAO,GAAM,EAAO,CAAE,KAAI,MAAK,EAAI,IACrC,CAEA,SAAS,EAAkB,EAA+B,CACxD,OAAO,GAAW,EAAO,EAAiB,EAAgB,EAAE,CAC9D,CAEA,SAAS,GACP,EACA,EACA,EACS,CACT,IAAM,EAAS,EAAS,CAAK,EAAI,EAAQ,KACnC,EAAK,OAAO,GAAQ,IAAO,SAAW,EAAO,GAAK,KAExD,OAAO,EAAQ,KAAM,GAAW,EAAO,KAAO,CAAE,GAAK,CACvD,CAEA,SAAS,EAAS,EAA4D,CAC5E,OAAO,OAAO,GAAU,YAAY,GAAkB,CAAC,MAAM,QAAQ,CAAK,CAC5E,CAEA,SAAS,EACP,EACA,EACgB,CAChB,OAAO,EAAQ,EAAO,CAAK,EAAI,IACjC,CAEA,SAAS,GAAgB,CACvB,OAAO,GAAgB,IAAI,IAAM,CACnC,CAEA,SAAS,GAAe,EAAmC,CACzD,IAAM,EAAO,EAAQ,IAAI,KAAK,CAAK,EAAI,KAEvC,OAAO,GAAQ,CAAC,OAAO,MAAM,EAAK,QAAQ,CAAC,EAAI,GAAgB,CAAI,EAAI,EACzE,CAEA,SAAS,GAAgB,EAAoB,CAC3C,MAAO,GAAG,EAAK,YAAY,EAAE,GAAG,EAAY,EAAK,SAAS,EAAI,CAAC,EAAE,GAAG,EAClE,EAAK,QAAQ,CACf,GACF,CAEA,SAAS,EAAY,EAAuB,CAC1C,OAAO,OAAO,CAAK,EAAE,SAAS,EAAG,GAAG,CACtC,CAEA,SAAS,GAAiB,EAAwB,CAChD,OAAO,aAAiB,MAAQ,EAAM,QAAU,WAClD"}
|