gigaboard 1.5.1 → 1.5.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/coordinates.tsx","../src/hooks/use-board-subscription.ts","../src/components/piece-layer.tsx","../src/lib/geometry.ts","../src/board-editor.tsx","../src/components/arrows-layer.tsx","../src/components/square.tsx","../src/components/board-grid.tsx","../src/components/check-layer.tsx","../src/components/drag-layer.tsx","../src/components/illegal-flash-layer.tsx","../src/components/live-region.tsx","../src/components/premove-layer.tsx","../src/components/promotion-overlay.tsx","../src/components/static-piece-layer.tsx","../src/hooks/use-animation.ts","../src/hooks/use-arrow-gesture.ts","../src/hooks/use-click-to-move.ts","../src/hooks/use-cursor-controller.ts","../src/hooks/use-drag.ts","../src/hooks/use-hover-square.ts","../src/hooks/use-keyboard-nav.ts","../src/hooks/use-last-move-controller.ts","../src/lib/haptics.ts","../src/lib/move-feedback.ts","../src/hooks/use-move-haptics.ts","../src/hooks/use-move-sound.ts","../src/hooks/use-selection-controller.ts","../src/chessboard.tsx","../src/hooks/use-chess-game.ts","../src/index.ts"],"names":["jsx","PieceLayer","algebraicOf","useCallback","jsxs","tip","scale","dockX","halfH","path","memo","ArrowsLayer","useRef","useMemo","useEffect","BoardGrid","forwardRef","DragLayer","useImperativeHandle","positionOf","useLayoutEffect","pieceName","useState","srOnlyStyle","prefersReducedMotion","played","STYLE_ID","triggerMoveHaptic"],"mappings":"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","file":"index.js","sourcesContent":["\"use client\";\n\n/**\n * Algebraic coordinate labels on the board edges.\n *\n * Static overlay — no subscriptions. Files (a–h) render along the bottom\n * edge; ranks (1–8) along the left edge. Orientation flips the order.\n * Label colours come from `--gb-coord-light` / `--gb-coord-dark` so the\n * label contrasts against whichever square it sits on.\n */\n\nimport { CSS_VARS } from \"../default-theme.js\";\nimport type { Orientation, RanksPosition } from \"../types.js\";\n\nconst FILE_LETTERS = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\"] as const;\n\n/** Props for {@link Coordinates}. */\nexport interface CoordinatesProps {\n readonly orientation: Orientation;\n /** Which side of the board the rank labels sit on. Default `\"left\"`. */\n readonly ranksPosition?: RanksPosition;\n}\n\n/**\n * Overlay of file and rank labels. `pointer-events: none` so clicks fall\n * through to squares underneath.\n */\nexport function Coordinates({ orientation, ranksPosition = \"left\" }: CoordinatesProps) {\n const ranksOnRight = ranksPosition === \"right\";\n return (\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n pointerEvents: \"none\",\n fontSize: \"min(1.6vmin, 11px)\",\n fontWeight: 600,\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n }}\n >\n {FILE_LETTERS.map((letter, idx) => {\n const col = orientation === \"white\" ? idx : 7 - idx;\n // Bottom rank label colour depends on the bottom-row square colour at `col`.\n // Bottom rank index is 0 (white-bottom) or 7 (black-bottom). File `col`\n // on rank 0: (col + 0) % 2 === 1 → light. We want label to contrast.\n const bottomRank = orientation === \"white\" ? 0 : 7;\n const isLightSquare = (col + bottomRank) % 2 === 1;\n return (\n <span\n key={`file-${letter}`}\n style={{\n position: \"absolute\",\n left: `${col * 12.5 + 10}%`,\n bottom: \"1%\",\n color: `var(${isLightSquare ? CSS_VARS.COORDINATE_LIGHT : CSS_VARS.COORDINATE_DARK})`,\n }}\n >\n {letter}\n </span>\n );\n })}\n {FILE_LETTERS.map((_, idx) => {\n // Re-use letter loop for ranks; the index maps directly to 1..8.\n const rank = idx; // 0..7 corresponds to ranks 1..8\n const row = orientation === \"white\" ? 7 - rank : rank;\n // `edgeFile` is the file the rank label sits on — 0 (left column)\n // for `ranksPosition=\"left\"`, 7 (right column) for `\"right\"`.\n // In black orientation the visual edges stay put but the file\n // indices flip.\n const edgeFile = ranksOnRight\n ? orientation === \"white\"\n ? 7\n : 0\n : orientation === \"white\"\n ? 0\n : 7;\n const isLightSquare = (edgeFile + rank) % 2 === 1;\n const sideStyle = ranksOnRight ? { right: \"1%\" } : { left: \"1%\" };\n return (\n <span\n key={`rank-${rank}`}\n style={{\n position: \"absolute\",\n top: `${row * 12.5 + 1}%`,\n ...sideStyle,\n color: `var(${isLightSquare ? CSS_VARS.COORDINATE_LIGHT : CSS_VARS.COORDINATE_DARK})`,\n }}\n >\n {rank + 1}\n </span>\n );\n })}\n </div>\n );\n}\n","\"use client\";\n\n/**\n * Thin `useSyncExternalStore` wrappers for the `BoardModel` subscribe store.\n *\n * Rationale: components should read the slice they actually care about and\n * nothing more. Reading the whole snapshot triggers a re-render on every\n * commit (arrow add, premove queue, selection change — anything). Reading a\n * single field leverages React's `Object.is` bailout and limits re-renders\n * to commits that actually moved that field.\n *\n * The per-byte square hook uses the store's `subscribeSquare` path, so a\n * component that reads `board[12]` only wakes up on commits that changed\n * that byte.\n */\n\nimport { useCallback, useSyncExternalStore } from \"react\";\nimport type { BoardModel, BoardSnapshot, SquareIndex } from \"../core/index.js\";\n\n/** Subscribe to the entire board snapshot. Wakes up on every commit. */\nexport function useBoardSnapshot(model: BoardModel): BoardSnapshot {\n return useSyncExternalStore(model.subscribe, model.getSnapshot, model.getSnapshot);\n}\n\n/**\n * Subscribe to a slice derived from the snapshot. Re-renders only when the\n * selector's return value changes by `Object.is`.\n *\n * The selector is called on every `getSnapshot` tick, so it should be cheap\n * (a field access) and must return a stable reference when the underlying\n * data didn't change. Our snapshot store guarantees stability for primitive\n * fields and for the `legalTargets` / `arrows` / `premoves` collections.\n */\nexport function useBoardSlice<T>(model: BoardModel, selector: (snapshot: BoardSnapshot) => T): T {\n const getSnapshot = useCallback((): T => selector(model.getSnapshot()), [model, selector]);\n return useSyncExternalStore(model.subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Subscribe to a single board byte via `subscribeSquare`. The component\n * receives the byte's current value (0 for empty, 1–12 for a piece) and\n * wakes up only when that byte changes.\n *\n * @remarks\n * The returned value is a primitive number, so React's default `Object.is`\n * bailout handles equality. The `useCallback` pins the subscribe function\n * to `(model, index)` — a Square that re-renders for unrelated reasons\n * doesn't force a re-subscription.\n */\nexport function useSquareCell(model: BoardModel | null | undefined, index: SquareIndex): number {\n const subscribe = useCallback(\n (listener: () => void) => (model ? model.subscribeSquare(index, listener) : () => {}),\n [model, index],\n );\n const getSnapshot = useCallback((): number => {\n if (!model) return 0;\n const snap = model.getSnapshot();\n return snap.board[index] ?? 0;\n }, [model, index]);\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n","\"use client\";\n\n/**\n * Piece overlay: 64 `PieceSlot` children, one per square. Each slot\n * subscribes to a single byte of the board snapshot — so a move that\n * touches 2–4 bytes wakes 2–4 slots, not all 64.\n *\n * Layout is an 8×8 CSS grid. A slot's position is expressed with\n * `gridColumnStart` / `gridRowStart` — two integer CSS properties —\n * instead of the `left: \"${x}%\"; top: \"${y}%\"` percentage math we used\n * to do. That removes per-render string interpolation and lets the\n * browser's grid layout path short-circuit: only slots whose integer\n * coordinates changed get a layout update. Paint cost drops too —\n * composited grid cells are cheaper than absolute-positioned ones\n * because the layout root stays the grid container, not each sibling.\n *\n * The layer itself (`pointer-events: none`) never intercepts clicks; the\n * board grid beneath owns pointer events.\n */\n\nimport { memo } from \"react\";\nimport type { BoardCell, BoardModel, SquareIndex } from \"../core/index.js\";\nimport { CSS_VARS } from \"../default-theme.js\";\nimport { useSquareCell } from \"../hooks/use-board-subscription.js\";\nimport type { Orientation, PieceRenderer } from \"../types.js\";\n\n/**\n * Compute the 1-based CSS grid column + row for a square. The grid has\n * 8 columns and 8 rows; white orientation puts rank 1 at row 8 (the\n * bottom) and rank 8 at row 1 (the top).\n *\n * Exported so the subscription-free `<StaticPieceLayer/>` can share the\n * same geometry and produce DOM identical to what this layer emits —\n * keeps the \"null game → fallback FEN\" transition free of layout shift.\n */\nexport function gridCoord(\n index: SquareIndex,\n orientation: Orientation,\n): { col: number; row: number } {\n const file = index & 7;\n const rank = index >> 3;\n const col = orientation === \"white\" ? file + 1 : 8 - file;\n const row = orientation === \"white\" ? 8 - rank : rank + 1;\n return { col, row };\n}\n\n/** Props for each individual piece slot. */\ninterface PieceSlotProps {\n readonly index: SquareIndex;\n readonly model: BoardModel;\n readonly orientation: Orientation;\n readonly pieces: PieceRenderer;\n}\n\n/** Algebraic name for a square index — used as a debug/test attribute. */\nexport function algebraicOf(index: SquareIndex): string {\n const file = index & 7;\n const rank = index >> 3;\n return `${String.fromCharCode(0x61 + file)}${rank + 1}`;\n}\n\n/**\n * Shared base style object for every slot. Pre-frozen so React's\n * shallow prop-diff short-circuits; the per-square placement is added\n * on top of this as an `inline-style` spread. Exported for\n * `<StaticPieceLayer/>` so both layers emit bit-identical DOM.\n */\nexport const SLOT_BASE_STYLE = Object.freeze({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"none\",\n containerType: \"size\" as const,\n});\n\nfunction PieceSlotImpl({ index, model, orientation, pieces }: PieceSlotProps) {\n const cell = useSquareCell(model, index);\n if (cell === 0) return null;\n const { col, row } = gridCoord(index, orientation);\n // Return-null on empty squares keeps the mutation count at 1 childList\n // per square per move. An earlier attempt to keep all 64 slots\n // persistently mounted (swap only the inner <img>) pushed per-move\n // mutations UP — childList on the slot *plus* a data-piece-cell\n // attribute write per slot = 2 mutations where the mount/unmount was\n // 1. See `bench/playwright/mutation-audit.spec.ts` — the assertion\n // guards this.\n return (\n <div\n data-piece-square={algebraicOf(index)}\n data-piece-cell={cell}\n style={{\n ...SLOT_BASE_STYLE,\n gridColumnStart: col,\n gridRowStart: row,\n filter: `var(${cell <= 6 ? CSS_VARS.PIECE_FILTER_WHITE : CSS_VARS.PIECE_FILTER_BLACK}, none)`,\n }}\n >\n {pieces({ cell: cell as BoardCell, square: index })}\n </div>\n );\n}\nconst PieceSlot = memo(PieceSlotImpl);\nPieceSlot.displayName = \"PieceSlot\";\n\n/** Props for {@link PieceLayer}. */\nexport interface PieceLayerProps {\n readonly model: BoardModel;\n readonly orientation: Orientation;\n readonly pieces: PieceRenderer;\n}\n\n/**\n * CSS-grid container style. 8×8, stretches to fill the board; each\n * occupied slot drops in at its `gridColumnStart` / `gridRowStart`.\n * Frozen so the outer `<div>`'s prop identity is stable across\n * renders. Exported so `<StaticPieceLayer/>` can reuse it.\n */\nexport const CONTAINER_STYLE = Object.freeze({\n position: \"absolute\" as const,\n inset: 0,\n display: \"grid\" as const,\n gridTemplateColumns: \"repeat(8, 1fr)\",\n gridTemplateRows: \"repeat(8, 1fr)\",\n pointerEvents: \"none\" as const,\n});\n\n/**\n * Render 64 `PieceSlot` children. React keys by square index so each slot\n * has a stable identity across rerenders — necessary for M3's WAAPI\n * animation to find and animate the right DOM node.\n */\nexport const PieceLayer = memo(function PieceLayer({\n model,\n orientation,\n pieces,\n}: PieceLayerProps) {\n const slots: React.ReactNode[] = [];\n for (let i = 0; i < 64; i++) {\n slots.push(\n <PieceSlot\n key={i}\n index={i as SquareIndex}\n model={model}\n orientation={orientation}\n pieces={pieces}\n />,\n );\n }\n return (\n <div aria-hidden=\"true\" style={CONTAINER_STYLE}>\n {slots}\n </div>\n );\n});\n","/**\n * Board geometry helpers.\n *\n * Pure, framework-agnostic utilities for mapping between viewport pixel\n * coordinates and `SquareIndex` (LERF 0..63). Single source of truth\n * consumed by {@link useDrag}, {@link useArrowGesture}, the spare-piece\n * drag hook, and any consumer who wants to hit-test the board from\n * custom React code (analysis overlays, piece tooltips, screenshots).\n *\n * No DOM mutation; no side effects. Each call reads\n * `container.getBoundingClientRect()` once — cheap but not free, so\n * hot-path callers should batch calls per pointer event.\n */\nimport type { SquareIndex } from \"../core/index.js\";\nimport type { Orientation } from \"../types.js\";\n\n/**\n * Resolve a viewport point to the `SquareIndex` it lies inside, or\n * `null` when the point is outside the board rect.\n *\n * The hit-test assumes the container has 1:1 geometry with the 8×8 grid\n * — i.e. the outer `<div>` of `<Chessboard/>`. Coordinates/edge padding\n * layers do **not** sit inside a smaller sub-rect; they're overlays on\n * the same box.\n *\n * @param container The board container element.\n * @param clientX `MouseEvent.clientX` / `PointerEvent.clientX`.\n * @param clientY `MouseEvent.clientY` / `PointerEvent.clientY`.\n * @param orientation Board orientation (flips file/rank derivation).\n * @returns The square under the point, or `null` if out of bounds.\n */\nexport function getSquareAtPoint(\n container: HTMLElement,\n clientX: number,\n clientY: number,\n orientation: Orientation,\n): SquareIndex | null {\n const rect = container.getBoundingClientRect();\n const relX = clientX - rect.left;\n const relY = clientY - rect.top;\n if (relX < 0 || relY < 0 || relX >= rect.width || relY >= rect.height) return null;\n const col = Math.floor((relX / rect.width) * 8);\n const row = Math.floor((relY / rect.height) * 8);\n const file = orientation === \"white\" ? col : 7 - col;\n const rank = orientation === \"white\" ? 7 - row : row;\n return (rank * 8 + file) as SquareIndex;\n}\n\n/**\n * Inverse of {@link getSquareAtPoint}: the viewport point at the centre\n * of a given square, expressed in client (viewport) coordinates.\n *\n * Useful for drawing tooltips, floating annotations, or anchoring DOM\n * nodes against a specific square without sampling the actual DOM child.\n *\n * @param container The board container element.\n * @param square Square index in LERF order.\n * @param orientation Board orientation.\n * @returns `{ x, y }` in viewport pixel coordinates.\n */\nexport function getPointAtSquareCentre(\n container: HTMLElement,\n square: SquareIndex,\n orientation: Orientation,\n): { readonly x: number; readonly y: number } {\n const rect = container.getBoundingClientRect();\n const sqW = rect.width / 8;\n const sqH = rect.height / 8;\n const file = square & 7;\n const rank = square >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n return {\n x: rect.left + sqW * col + sqW / 2,\n y: rect.top + sqH * row + sqH / 2,\n };\n}\n\n/** Algebraic name (`\"a1\"`, `\"h8\"`, …) for a square index. */\nexport function algebraicOf(square: SquareIndex): string {\n const file = square & 7;\n const rank = square >> 3;\n return `${String.fromCharCode(0x61 + file)}${rank + 1}`;\n}\n\n/** Square index for an algebraic name (`\"a1\"`, `\"h8\"`, …), or `null` if invalid. */\nexport function squareOf(algebraic: string): SquareIndex | null {\n if (algebraic.length !== 2) return null;\n const file = algebraic.charCodeAt(0) - 0x61;\n const rank = algebraic.charCodeAt(1) - 0x31;\n if (file < 0 || file > 7 || rank < 0 || rank > 7) return null;\n return ((rank << 3) | file) as SquareIndex;\n}\n","\"use client\";\n\n/**\n * `BoardEditor` — First-class accessible chess workstation board editor.\n *\n * Implements a unified, high-performance editor with `role=\"application\"`\n * so screen readers (JAWS, NVDA, VoiceOver) bypass virtual PC cursor browse\n * mode on single-key shortcuts:\n *\n * - Single-key piece placement:\n * - `p` / `P` (pawn: lowercase = Black, uppercase = White)\n * - `n` / `N` (knight)\n * - `b` / `B` (bishop)\n * - `r` / `R` (rook)\n * - `q` / `Q` (queen)\n * - `k` / `K` (king)\n * - Deletion: `Backspace`, `Delete`, `x`, `X` (clears focused cell)\n * - Walk cell-by-cell: `ArrowUp`, `ArrowDown`, `ArrowLeft`, `ArrowRight` (orientation-aware)\n * - Row edges: `Home`, `End`\n * - Board corners: `Ctrl+Home`, `Ctrl+End`\n * - Clear board: `c` / `C`\n * - Reset starting position: `s` / `S`\n * - Toggle side to move: `t` / `T`\n * - Palette placement: `Enter` / `Space`\n * - Free drag-and-drop between squares + drag off board to delete\n */\n\nimport React, {\n type CSSProperties,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Coordinates } from \"./components/coordinates.js\";\nimport { gridCoord, SLOT_BASE_STYLE } from \"./components/piece-layer.js\";\nimport {\n BOARD_CELL_BB,\n BOARD_CELL_BK,\n BOARD_CELL_BN,\n BOARD_CELL_BP,\n BOARD_CELL_BQ,\n BOARD_CELL_BR,\n BOARD_CELL_WB,\n BOARD_CELL_WK,\n BOARD_CELL_WN,\n BOARD_CELL_WP,\n BOARD_CELL_WQ,\n BOARD_CELL_WR,\n type BoardCell,\n type SquareIndex,\n} from \"./core/index.js\";\nimport { CSS_VARS, defaultTheme } from \"./default-theme.js\";\nimport { parseFenPlacement, STARTING_FEN } from \"./fen.js\";\nimport { algebraicOf, getSquareAtPoint } from \"./lib/geometry.js\";\nimport { defaultPieces } from \"./pieces/default-pieces.js\";\nimport type { Orientation, PieceRenderer, Theme } from \"./types.js\";\n\nconst PIECE_CHARS = [\"\", \"P\", \"N\", \"B\", \"R\", \"Q\", \"K\", \"p\", \"n\", \"b\", \"r\", \"q\", \"k\"] as const;\n\nexport function formatFenPlacement(board: Uint8Array): string {\n const rows: string[] = [];\n for (let r = 7; r >= 0; r--) {\n let empty = 0;\n let row = \"\";\n for (let f = 0; f < 8; f++) {\n const cell = board[r * 8 + f] ?? 0;\n if (cell === 0) {\n empty++;\n } else {\n if (empty > 0) {\n row += String(empty);\n empty = 0;\n }\n row += PIECE_CHARS[cell] ?? \"\";\n }\n }\n if (empty > 0) {\n row += String(empty);\n }\n rows.push(row);\n }\n return rows.join(\"/\");\n}\n\nfunction updateFenPlacement(originalFen: string, newPlacement: string): string {\n const tokens = originalFen.trim().split(/\\s+/);\n if (tokens.length <= 1) {\n return newPlacement;\n }\n tokens[0] = newPlacement;\n return tokens.join(\" \");\n}\n\nfunction pieceNameFromCell(cell: BoardCell): string {\n if (cell === 0) return \"empty\";\n const color = cell > 6 ? \"black\" : \"white\";\n const type = (cell - 1) % 6;\n const names = [\"pawn\", \"knight\", \"bishop\", \"rook\", \"queen\", \"king\"];\n return `${color} ${names[type] ?? \"piece\"}`;\n}\n\nfunction defaultSquareLabel(square: SquareIndex, cell: BoardCell): string {\n const sq = algebraicOf(square);\n if (cell === 0) {\n return `${sq}, empty`;\n }\n return `${sq}, ${pieceNameFromCell(cell)}`;\n}\n\nfunction cellFromKey(key: string): BoardCell {\n switch (key) {\n case \"P\":\n return BOARD_CELL_WP;\n case \"N\":\n return BOARD_CELL_WN;\n case \"B\":\n return BOARD_CELL_WB;\n case \"R\":\n return BOARD_CELL_WR;\n case \"Q\":\n return BOARD_CELL_WQ;\n case \"K\":\n return BOARD_CELL_WK;\n case \"p\":\n return BOARD_CELL_BP;\n case \"n\":\n return BOARD_CELL_BN;\n case \"b\":\n return BOARD_CELL_BB;\n case \"r\":\n return BOARD_CELL_BR;\n case \"q\":\n return BOARD_CELL_BQ;\n case \"k\":\n return BOARD_CELL_BK;\n default:\n return 0 as BoardCell;\n }\n}\n\nfunction cellFromPieceString(piece: string | null | undefined): BoardCell {\n if (!piece || piece === \"erase\") return 0 as BoardCell;\n if (piece.length === 2) {\n const c0 = piece[0];\n const c1 = piece[1];\n if (c0 && c1) {\n const color = c0.toLowerCase();\n const type = c1.toUpperCase();\n if (color === \"w\") return cellFromKey(type);\n if (color === \"b\") return cellFromKey(type.toLowerCase());\n }\n }\n return cellFromKey(piece);\n}\n\nfunction getOppositePieceString(piece: string | null | undefined): string | null {\n if (!piece || piece === \"erase\") return null;\n if (piece.length === 2) {\n const c0 = piece[0];\n const c1 = piece[1];\n if (c0 && c1) {\n const color = c0 === \"w\" ? \"b\" : \"w\";\n return `${color}${c1}`;\n }\n }\n return piece === piece.toUpperCase() ? piece.toLowerCase() : piece.toUpperCase();\n}\n\nfunction moveSquare(\n current: SquareIndex,\n direction: \"up\" | \"down\" | \"left\" | \"right\",\n orientation: Orientation,\n): SquareIndex {\n const file = current & 7;\n const rank = current >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n\n let newCol = col;\n let newRow = row;\n switch (direction) {\n case \"up\":\n newRow = Math.max(0, row - 1);\n break;\n case \"down\":\n newRow = Math.min(7, row + 1);\n break;\n case \"left\":\n newCol = Math.max(0, col - 1);\n break;\n case \"right\":\n newCol = Math.min(7, col + 1);\n break;\n }\n\n const newFile = orientation === \"white\" ? newCol : 7 - newCol;\n const newRank = orientation === \"white\" ? 7 - newRow : newRow;\n return ((newRank * 8 + newFile) & 0x3f) as SquareIndex;\n}\n\nfunction rankEndSquare(\n current: SquareIndex,\n which: \"home\" | \"end\",\n orientation: Orientation,\n): SquareIndex {\n const rank = current >> 3;\n if (orientation === \"white\") {\n return ((rank << 3) | (which === \"home\" ? 0 : 7)) as SquareIndex;\n }\n return ((rank << 3) | (which === \"home\" ? 7 : 0)) as SquareIndex;\n}\n\nexport interface BoardEditorProps {\n /** Current FEN or placement string. */\n fen?: string;\n /** Called whenever the board placement changes. */\n onChange?: (fen: string) => void;\n /** Called when a specific square piece changes. */\n onPieceChange?: (square: SquareIndex, cell: BoardCell, algebraic: string) => void;\n /** Currently selected piece for placement (e.g. \"wP\", \"bP\", \"wK\", or null for eraser). */\n selectedPiece?: string | null;\n /** Callback when shortcut piece is chosen. */\n onSelectPiece?: (piece: string | null) => void;\n /** Board orientation (default \"white\"). */\n orientation?: Orientation;\n /** Board visual theme. */\n theme?: Theme;\n /** Piece renderer. */\n pieces?: PieceRenderer;\n /** Whether algebraic coordinates are shown. */\n showCoordinates?: boolean;\n /** Container style overrides. */\n style?: CSSProperties;\n /** Container class name. */\n className?: string;\n /** Accessible label. */\n ariaLabel?: string;\n /** Announce feedback callback (e.g. forward to useAriaLive). */\n onAnnounce?: (message: string) => void;\n /** Custom generator for square speech labels. */\n getSquareAriaLabel?: (square: SquareIndex, cell: BoardCell, algebraic: string) => string;\n /** Current focused square (controlled). */\n focusedSquare?: SquareIndex;\n /** Square focus callback. */\n onSquareFocus?: (square: SquareIndex, cell: BoardCell, algebraic: string) => void;\n /** Optional container element id. */\n id?: string;\n /** Clear board callback. */\n onClear?: () => void;\n /** Set starting position callback. */\n onSetStartingPosition?: () => void;\n /** Toggle side to move callback. */\n onToggleSideToMove?: () => void;\n /** Callback when editor receives container focus. */\n onFocus?: (e: React.FocusEvent<HTMLDivElement>) => void;\n /** Callback when editor loses container focus. */\n onBlur?: (e: React.FocusEvent<HTMLDivElement>) => void;\n}\n\nexport function BoardEditor({\n fen = \"8/8/8/8/8/8/8/8 w - - 0 1\",\n onChange,\n onPieceChange,\n selectedPiece,\n onSelectPiece,\n orientation = \"white\",\n theme = defaultTheme,\n pieces = defaultPieces,\n showCoordinates = false,\n style,\n className,\n ariaLabel = \"Board editor\",\n onAnnounce,\n getSquareAriaLabel,\n focusedSquare: propFocusedSquare,\n onSquareFocus,\n id,\n onClear,\n onSetStartingPosition,\n onToggleSideToMove,\n onFocus,\n onBlur,\n}: BoardEditorProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const liveRegionRef = useRef<HTMLDivElement>(null);\n const liveCounter = useRef(0);\n const [board, setBoard] = useState<Uint8Array>(() => {\n try {\n return parseFenPlacement(fen);\n } catch {\n return new Uint8Array(64);\n }\n });\n\n const [internalFocusedSquare, setInternalFocusedSquare] = useState<SquareIndex>(\n () => (orientation === \"white\" ? 28 : 36) as SquareIndex, // e4 or e5\n );\n const focusedSquare = propFocusedSquare ?? internalFocusedSquare;\n const setFocusedSquare = setInternalFocusedSquare;\n const [hasKeyboardFocus, setHasKeyboardFocus] = useState(false);\n\n // Active dragging state\n const [dragging, setDragging] = useState<{\n origin: SquareIndex;\n cell: BoardCell;\n x: number;\n y: number;\n } | null>(null);\n\n useEffect(() => {\n try {\n const nextBoard = parseFenPlacement(fen);\n setBoard(nextBoard);\n } catch {\n // Keep current board on parse failure\n }\n }, [fen]);\n\n const announce = useCallback(\n (message: string) => {\n onAnnounce?.(message);\n const region = liveRegionRef.current;\n if (region) {\n liveCounter.current++;\n region.setAttribute(\"data-live-id\", String(liveCounter.current));\n region.textContent = \"\";\n void region.offsetHeight;\n region.textContent = message;\n }\n },\n [onAnnounce],\n );\n\n const getSquareDescription = useCallback(\n (square: SquareIndex, cell: BoardCell) => {\n const sq = algebraicOf(square);\n if (getSquareAriaLabel) {\n return getSquareAriaLabel(square, cell, sq);\n }\n return defaultSquareLabel(square, cell);\n },\n [getSquareAriaLabel],\n );\n\n const announceSquare = useCallback(\n (square: SquareIndex) => {\n const cell = (board[square] ?? 0) as BoardCell;\n const desc = getSquareDescription(square, cell);\n announce(desc);\n onSquareFocus?.(square, cell, algebraicOf(square));\n },\n [announce, board, getSquareDescription, onSquareFocus],\n );\n\n const commitBoard = useCallback(\n (nextBoard: Uint8Array) => {\n setBoard(nextBoard);\n const newPlacement = formatFenPlacement(nextBoard);\n const updatedFen = updateFenPlacement(fen, newPlacement);\n onChange?.(updatedFen);\n },\n [fen, onChange],\n );\n\n const placePieceAt = useCallback(\n (square: SquareIndex, cellOrCode: BoardCell | string) => {\n const targetCell =\n typeof cellOrCode === \"string\" ? cellFromPieceString(cellOrCode) : cellOrCode;\n const currentCell = (board[square] ?? 0) as BoardCell;\n const nextBoard = new Uint8Array(board);\n\n if (targetCell !== 0 && currentCell === targetCell) {\n // Toggle off\n nextBoard[square] = 0;\n commitBoard(nextBoard);\n onPieceChange?.(square, 0 as BoardCell, algebraicOf(square));\n announce(`Piece removed from ${algebraicOf(square)}`);\n } else if (targetCell !== 0) {\n nextBoard[square] = targetCell;\n commitBoard(nextBoard);\n onPieceChange?.(square, targetCell, algebraicOf(square));\n const name = pieceNameFromCell(targetCell);\n announce(`${name} placed on ${algebraicOf(square)}`);\n const char = PIECE_CHARS[targetCell] ?? \"\";\n const code = targetCell <= 6 ? `w${char}` : `b${char.toUpperCase()}`;\n onSelectPiece?.(code);\n } else {\n nextBoard[square] = 0;\n commitBoard(nextBoard);\n onPieceChange?.(square, 0 as BoardCell, algebraicOf(square));\n announce(`Piece removed from ${algebraicOf(square)}`);\n }\n },\n [announce, board, commitBoard, onPieceChange, onSelectPiece],\n );\n\n const removePieceAt = useCallback(\n (square: SquareIndex) => {\n const current = board[square] ?? 0;\n if (current === 0) {\n announce(`${algebraicOf(square)} is empty`);\n return;\n }\n const nextBoard = new Uint8Array(board);\n nextBoard[square] = 0;\n commitBoard(nextBoard);\n onPieceChange?.(square, 0 as BoardCell, algebraicOf(square));\n announce(`Piece removed from ${algebraicOf(square)}`);\n },\n [announce, board, commitBoard, onPieceChange],\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.altKey || e.ctrlKey || e.metaKey) return;\n\n // 1. Arrow navigation\n if (e.key.startsWith(\"Arrow\")) {\n if (e.shiftKey) return;\n e.preventDefault();\n const dir =\n e.key === \"ArrowUp\"\n ? \"up\"\n : e.key === \"ArrowDown\"\n ? \"down\"\n : e.key === \"ArrowLeft\"\n ? \"left\"\n : \"right\";\n const next = moveSquare(focusedSquare, dir, orientation);\n setFocusedSquare(next);\n announceSquare(next);\n return;\n }\n\n // 2. Home / End\n if (e.key === \"Home\" || e.key === \"End\") {\n e.preventDefault();\n const next = rankEndSquare(focusedSquare, e.key === \"Home\" ? \"home\" : \"end\", orientation);\n setFocusedSquare(next);\n announceSquare(next);\n return;\n }\n\n // 3. Delete / Backspace\n if (e.key === \"Backspace\" || e.key === \"Delete\" || e.key === \"x\" || e.key === \"X\") {\n e.preventDefault();\n removePieceAt(focusedSquare);\n return;\n }\n\n // 4. Clear board / Set start / Toggle side\n if (e.key === \"c\" || e.key === \"C\") {\n e.preventDefault();\n if (onClear) {\n onClear();\n } else {\n commitBoard(new Uint8Array(64));\n announce(\"Board cleared\");\n }\n return;\n }\n\n if (e.key === \"s\" || e.key === \"S\") {\n e.preventDefault();\n if (onSetStartingPosition) {\n onSetStartingPosition();\n } else {\n commitBoard(parseFenPlacement(STARTING_FEN));\n announce(\"Starting position\");\n }\n return;\n }\n\n if (e.key === \"t\" || e.key === \"T\") {\n e.preventDefault();\n onToggleSideToMove?.();\n return;\n }\n\n // 5. Enter / Space: place selected piece\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (selectedPiece) {\n const piece = e.shiftKey ? getOppositePieceString(selectedPiece) : selectedPiece;\n if (piece) placePieceAt(focusedSquare, piece);\n }\n return;\n }\n\n // 6. Quick piece shortcuts (FEN letters: p, P, n, N, b, B, r, R, q, Q, k, K)\n const pieceCell = cellFromKey(e.key);\n if (pieceCell !== 0) {\n e.preventDefault();\n placePieceAt(focusedSquare, pieceCell);\n }\n },\n [\n announce,\n announceSquare,\n commitBoard,\n focusedSquare,\n onClear,\n onSetStartingPosition,\n onToggleSideToMove,\n orientation,\n placePieceAt,\n removePieceAt,\n selectedPiece,\n ],\n );\n\n // Pointer drag and drop\n const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n if (e.button !== 0) return; // left click only\n const container = containerRef.current;\n if (!container) return;\n\n const sq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (sq === null) return;\n\n container.focus();\n setFocusedSquare(sq);\n onSquareFocus?.(sq, (board[sq] ?? 0) as BoardCell, algebraicOf(sq));\n const cell = (board[sq] ?? 0) as BoardCell;\n\n if (cell === 0) {\n // Empty square clicked: place selected piece\n if (selectedPiece) {\n placePieceAt(sq, selectedPiece);\n }\n return;\n }\n\n // Occupied square: start drag\n e.currentTarget.setPointerCapture(e.pointerId);\n setDragging({\n origin: sq,\n cell,\n x: e.clientX,\n y: e.clientY,\n });\n };\n\n const handlePointerMove = (e: React.PointerEvent<HTMLDivElement>) => {\n if (!dragging) return;\n setDragging((prev) => (prev ? { ...prev, x: e.clientX, y: e.clientY } : null));\n };\n\n const handlePointerUp = (e: React.PointerEvent<HTMLDivElement>) => {\n if (!dragging) return;\n const container = containerRef.current;\n const originSq = dragging.origin;\n const movedCell = dragging.cell;\n setDragging(null);\n\n if (!container) return;\n const targetSq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n\n if (targetSq === null) {\n // Dropped off the board: delete piece\n removePieceAt(originSq);\n return;\n }\n\n if (targetSq === originSq) {\n // Click without drag: place selected piece if palette has one\n if (selectedPiece) {\n placePieceAt(originSq, selectedPiece);\n }\n return;\n }\n\n // Move piece from origin to target\n const nextBoard = new Uint8Array(board);\n nextBoard[originSq] = 0;\n nextBoard[targetSq] = movedCell;\n commitBoard(nextBoard);\n announce(`${pieceNameFromCell(movedCell)} moved to ${algebraicOf(targetSq)}`);\n setFocusedSquare(targetSq);\n };\n\n const handleContextMenu = (e: React.MouseEvent<HTMLDivElement>) => {\n e.preventDefault();\n const container = containerRef.current;\n if (!container) return;\n const sq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (sq === null) return;\n\n setFocusedSquare(sq);\n if (selectedPiece) {\n const opp = getOppositePieceString(selectedPiece);\n if (opp) placePieceAt(sq, opp);\n }\n };\n\n // Build 64 squares visually\n const squareOrder = useMemo(() => {\n const squares: SquareIndex[] = [];\n if (orientation === \"white\") {\n for (let rank = 7; rank >= 0; rank--) {\n for (let file = 0; file < 8; file++) {\n squares.push((rank * 8 + file) as SquareIndex);\n }\n }\n } else {\n for (let rank = 0; rank < 8; rank++) {\n for (let file = 7; file >= 0; file--) {\n squares.push((rank * 8 + file) as SquareIndex);\n }\n }\n }\n return squares;\n }, [orientation]);\n\n const containerStyle: CSSProperties = {\n position: \"relative\",\n aspectRatio: \"1 / 1\",\n width: \"100%\",\n touchAction: \"none\",\n outline: hasKeyboardFocus ? \"3px solid var(--gb-editor-focus, #d97706)\" : \"none\",\n outlineOffset: \"2px\",\n borderRadius: \"8px\",\n ...(theme as CSSProperties),\n ...style,\n };\n\n return (\n <div\n ref={containerRef}\n id={id}\n role=\"application\"\n // biome-ignore lint/a11y/noNoninteractiveTabindex: role=\"application\" container owns keyboard focus\n tabIndex={0}\n aria-label={ariaLabel}\n aria-keyshortcuts=\"ArrowUp ArrowDown ArrowLeft ArrowRight Enter Space Backspace Delete p P n N b B r R q Q k K c C s S t T\"\n onKeyDown={handleKeyDown}\n onFocus={(e) => {\n if (e.target === e.currentTarget) {\n setHasKeyboardFocus(true);\n announceSquare(focusedSquare);\n }\n onFocus?.(e);\n }}\n onBlur={(e) => {\n if (e.target === e.currentTarget) {\n setHasKeyboardFocus(false);\n }\n onBlur?.(e);\n }}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={() => setDragging(null)}\n onContextMenu={handleContextMenu}\n className={className}\n style={containerStyle}\n data-gb-editor=\"true\"\n data-gb-orientation={orientation}\n >\n {/* 8x8 Board Grid */}\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"grid\",\n gridTemplateColumns: \"repeat(8, 1fr)\",\n gridTemplateRows: \"repeat(8, 1fr)\",\n pointerEvents: \"none\",\n }}\n >\n {squareOrder.map((sq) => {\n const file = sq & 7;\n const rank = sq >> 3;\n const isLight = ((file + rank) & 1) !== 0;\n const isFocused = hasKeyboardFocus && focusedSquare === sq;\n\n return (\n <div\n key={sq}\n data-square={algebraicOf(sq)}\n style={{\n position: \"relative\",\n backgroundColor: `var(${isLight ? CSS_VARS.SQ_LIGHT : CSS_VARS.SQ_DARK})`,\n backgroundImage: `var(${isLight ? CSS_VARS.SQ_LIGHT_IMAGE : CSS_VARS.SQ_DARK_IMAGE},none)`,\n backgroundSize: `var(${CSS_VARS.SQ_IMAGE_SIZE},cover)`,\n boxShadow: isFocused ? \"inset 0 0 0 3px rgba(255, 206, 76, 0.95)\" : undefined,\n userSelect: \"none\",\n }}\n />\n );\n })}\n </div>\n\n {/* Piece Layer */}\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"grid\",\n gridTemplateColumns: \"repeat(8, 1fr)\",\n gridTemplateRows: \"repeat(8, 1fr)\",\n pointerEvents: \"none\",\n }}\n >\n {squareOrder.map((sq) => {\n const cell = (board[sq] ?? 0) as BoardCell;\n if (cell === 0) return null;\n const isOrigin = dragging?.origin === sq;\n const { col, row } = gridCoord(sq, orientation);\n\n return (\n <div\n key={sq}\n data-piece-square={algebraicOf(sq)}\n style={{\n ...SLOT_BASE_STYLE,\n gridColumnStart: col,\n gridRowStart: row,\n opacity: isOrigin ? 0.25 : 1,\n filter: `var(${cell <= 6 ? CSS_VARS.PIECE_FILTER_WHITE : CSS_VARS.PIECE_FILTER_BLACK}, none)`,\n pointerEvents: \"none\",\n }}\n >\n {pieces({ cell, square: sq })}\n </div>\n );\n })}\n </div>\n\n {/* Visual square focus indicator for keyboard/active navigation (sighted users) */}\n {hasKeyboardFocus && (\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"grid\",\n gridTemplateColumns: \"repeat(8, 1fr)\",\n gridTemplateRows: \"repeat(8, 1fr)\",\n pointerEvents: \"none\",\n zIndex: 10,\n }}\n >\n {(() => {\n const { col, row } = gridCoord(focusedSquare, orientation);\n return (\n <div\n data-gb-editor-focus-square={algebraicOf(focusedSquare)}\n style={{\n gridColumnStart: col,\n gridRowStart: row,\n outline: \"3px solid var(--gb-editor-sq-focus, #f59e0b)\",\n outlineOffset: \"-3px\",\n boxShadow:\n \"inset 0 0 0 1.5px rgba(0, 0, 0, 0.75), 0 0 8px rgba(245, 158, 11, 0.7)\",\n borderRadius: \"2px\",\n pointerEvents: \"none\",\n }}\n />\n );\n })()}\n </div>\n )}\n\n {/* Dragging Piece Floating Overlay */}\n {dragging && containerRef.current ? (\n <div\n aria-hidden=\"true\"\n style={{\n position: \"fixed\",\n left: dragging.x - 30,\n top: dragging.y - 30,\n width: 60,\n height: 60,\n pointerEvents: \"none\",\n zIndex: 100,\n filter: `var(${dragging.cell <= 6 ? CSS_VARS.PIECE_FILTER_WHITE : CSS_VARS.PIECE_FILTER_BLACK}, none)`,\n }}\n >\n {pieces({ cell: dragging.cell, square: dragging.origin })}\n </div>\n ) : null}\n\n {/* Coordinates */}\n {showCoordinates ? <Coordinates orientation={orientation} /> : null}\n\n {/* Accessible Live Region */}\n <div\n ref={liveRegionRef}\n role=\"status\"\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n style={{\n position: \"absolute\",\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\",\n border: 0,\n }}\n />\n </div>\n );\n}\n","\"use client\";\n\n/**\n * Canvas-2D arrow overlay with optional SVG decorations.\n *\n * Renders every committed arrow from `snapshot.arrows` (optionally\n * filtered by the `below` flag) plus an in-flight preview arrow the\n * user is currently dragging. The preview is owned by\n * `useArrowGesture` via a ref; this component only exposes redraw\n * hooks and lets the gesture hook invalidate the canvas imperatively.\n *\n * ### Two-layer instantiation\n *\n * The board mounts `<ArrowsLayer below/>` before the piece layer and\n * `<ArrowsLayer/>` (above, default) after. Each instance filters its\n * arrows by the `below` flag; the `above` instance also renders the\n * active preview. No z-index juggling: pieces paint between them by\n * DOM order.\n *\n * ### Why Canvas instead of SVG\n *\n * SVG forces a React reconcile per arrow-set change (one React element\n * per arrow). During a right-click drag the preview arrow moves with\n * the pointer — an SVG approach would re-render on every pointermove.\n * A single `<canvas>` with an imperative redraw costs one React commit\n * per arrow-set mutation and zero React renders per drag frame.\n *\n * ### SVG child overlay for labels and customSvg\n *\n * `label` and `customSvg` require DOM, not a 2D context. When the\n * current arrow set contains at least one of either, the component\n * renders a sibling `<svg>` on top of the canvas. When the set has\n * none, the `<svg>` is not rendered at all — zero cost for plain\n * arrow boards.\n *\n * ### HiDPI handling\n *\n * `canvas.width`/`height` are set to `CSS pixels * devicePixelRatio`\n * so strokes stay crisp on retina displays. A `ResizeObserver`\n * re-provisions the backing store whenever the board resizes.\n *\n * ### Arrow drawing\n *\n * A normal move uses a straight shaft from the source-square centre to\n * the target square. A knight move uses a bent, Russian Г-shaped shaft:\n * first along the two-square axis, then along the one-square axis. In\n * both cases the shaft stops at the arrowhead base so translucent\n * arrows do not darken where the shaft and head meet. `from === to` is\n * a special case: rendered as a stroked circle at the centre of the\n * square — the convention the right-click gesture uses for \"mark this\n * square\".\n */\n\nimport {\n forwardRef,\n memo,\n type ReactElement,\n type RefObject,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport type { Arrow, ArrowHeadStyle, BoardModel } from \"../core/index.js\";\nimport { useBoardSlice } from \"../hooks/use-board-subscription.js\";\nimport type { Orientation, ResolvedArrowPalette } from \"../types.js\";\n\n/** Shape rendered mid-gesture, before the user releases the button. */\nexport interface PreviewArrow {\n readonly from: number;\n readonly to: number;\n readonly color: string;\n}\n\n/** Imperative API exposed by `<ArrowsLayer/>` to `useArrowGesture`. */\nexport interface ArrowsLayerHandle {\n /** Update the preview arrow (null to clear) and redraw. */\n setPreview(preview: PreviewArrow | null): void;\n}\n\n/** Props for {@link ArrowsLayer}. */\nexport interface ArrowsLayerProps {\n readonly model: BoardModel;\n readonly orientation: Orientation;\n /**\n * Optional palette resolving arrow `brush` keys to CSS colours. When\n * an arrow carries both `color` and `brush`, the brush wins if the\n * key is present in the palette; otherwise `color` is used as-is.\n */\n readonly palette?: ResolvedArrowPalette;\n /**\n * When `true`, only arrows with `below: true` are rendered and the\n * preview is suppressed — this is the \"beneath pieces\" layer.\n * Default `false` (the top layer).\n */\n readonly below?: boolean;\n}\n\n/* ============================================================ geometry */\n\n/** Square-index → (centreX%, centreY%) in board-local coordinates. */\nfunction squareCentrePct(index: number, orientation: Orientation): { cx: number; cy: number } {\n const file = index & 7;\n const rank = index >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n return { cx: col * 12.5 + 6.25, cy: row * 12.5 + 6.25 };\n}\n\n/** A point in board-local CSS-pixel coordinates. */\ninterface Point {\n readonly x: number;\n readonly y: number;\n}\n\n/** Geometry needed to paint a shaft and head without translucent self-overlap. */\ninterface ArrowPath {\n readonly start: Point;\n readonly corner: Point | null;\n readonly shaftEnd: Point;\n readonly tip: Point;\n readonly finalUnit: Point;\n}\n\n/** Does the square pair describe a knight's L-shaped move? */\nfunction isKnightMove(fromIndex: number, toIndex: number): boolean {\n const fileDelta = Math.abs((toIndex & 7) - (fromIndex & 7));\n const rankDelta = Math.abs((toIndex >> 3) - (fromIndex >> 3));\n return (fileDelta === 1 && rankDelta === 2) || (fileDelta === 2 && rankDelta === 1);\n}\n\nfunction unitVector(from: Point, to: Point): Point | null {\n const dx = to.x - from.x;\n const dy = to.y - from.y;\n const len = Math.hypot(dx, dy);\n if (len === 0) return null;\n return { x: dx / len, y: dy / len };\n}\n\nfunction arrowPath(\n fromIndex: number,\n toIndex: number,\n start: Point,\n end: Point,\n startOffset: number,\n tipOffset: number,\n headLength: number,\n): ArrowPath | null {\n if (!isKnightMove(fromIndex, toIndex)) {\n const unit = unitVector(start, end);\n if (unit === null) return null;\n const tip = { x: end.x - unit.x * tipOffset, y: end.y - unit.y * tipOffset };\n return {\n start: { x: start.x + unit.x * startOffset, y: start.y + unit.y * startOffset },\n corner: null,\n shaftEnd: { x: tip.x - unit.x * headLength, y: tip.y - unit.y * headLength },\n tip,\n finalUnit: unit,\n };\n }\n\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const corner = Math.abs(dx) > Math.abs(dy) ? { x: end.x, y: start.y } : { x: start.x, y: end.y };\n const firstUnit = unitVector(start, corner);\n const finalUnit = unitVector(corner, end);\n if (firstUnit === null || finalUnit === null) return null;\n\n const tip = { x: end.x - finalUnit.x * tipOffset, y: end.y - finalUnit.y * tipOffset };\n return {\n start: { x: start.x + firstUnit.x * startOffset, y: start.y + firstUnit.y * startOffset },\n corner,\n shaftEnd: { x: tip.x - finalUnit.x * headLength, y: tip.y - finalUnit.y * headLength },\n tip,\n finalUnit,\n };\n}\n\n/* ======================================================= draw primitives */\n\n/** Resolve the final colour for an arrow given an optional palette. */\nfunction resolveColor(arrow: Arrow, palette: ResolvedArrowPalette | undefined): string {\n if (arrow.brush !== undefined && palette !== undefined) {\n const brushed = palette[arrow.brush];\n if (brushed !== undefined) return brushed;\n }\n return arrow.color;\n}\n\n/** Draw a standard arrow (or same-square circle) onto the canvas. */\nfunction drawArrow(\n ctx: CanvasRenderingContext2D,\n fromIndex: number,\n toIndex: number,\n color: string,\n sqSize: number,\n orientation: Orientation,\n preview: boolean,\n): void {\n const a = squareCentrePct(fromIndex, orientation);\n const b = squareCentrePct(toIndex, orientation);\n const boardSize = sqSize * 8;\n const start = { x: (a.cx / 100) * boardSize, y: (a.cy / 100) * boardSize };\n const end = { x: (b.cx / 100) * boardSize, y: (b.cy / 100) * boardSize };\n\n if (fromIndex === toIndex) {\n ctx.strokeStyle = color;\n ctx.lineWidth = sqSize * 0.08;\n ctx.globalAlpha = preview ? 0.65 : 1;\n ctx.beginPath();\n ctx.arc(start.x, start.y, sqSize * 0.44, 0, Math.PI * 2);\n ctx.stroke();\n ctx.globalAlpha = 1;\n return;\n }\n\n const startOffset = sqSize * 0.28;\n const tipOffset = sqSize * 0.08;\n const headLength = sqSize * 0.36;\n const headHalfWidth = sqSize * 0.28;\n const shaftWidth = sqSize * 0.18;\n const path = arrowPath(fromIndex, toIndex, start, end, startOffset, tipOffset, headLength);\n if (path === null) return;\n\n ctx.globalAlpha = preview ? 0.65 : 1;\n ctx.strokeStyle = color;\n ctx.lineWidth = shaftWidth;\n ctx.lineCap = \"butt\";\n ctx.lineJoin = \"round\";\n ctx.beginPath();\n ctx.moveTo(path.start.x, path.start.y);\n if (path.corner !== null) ctx.lineTo(path.corner.x, path.corner.y);\n ctx.lineTo(path.shaftEnd.x, path.shaftEnd.y);\n ctx.stroke();\n\n const perpX = -path.finalUnit.y;\n const perpY = path.finalUnit.x;\n ctx.fillStyle = color;\n ctx.beginPath();\n ctx.moveTo(path.tip.x, path.tip.y);\n ctx.lineTo(path.shaftEnd.x + perpX * headHalfWidth, path.shaftEnd.y + perpY * headHalfWidth);\n ctx.lineTo(path.shaftEnd.x - perpX * headHalfWidth, path.shaftEnd.y - perpY * headHalfWidth);\n ctx.closePath();\n ctx.fill();\n ctx.globalAlpha = 1;\n}\n\n/** Redraw the full arrow set + preview onto the canvas. */\nfunction redraw(\n canvas: HTMLCanvasElement,\n arrows: readonly Arrow[],\n preview: PreviewArrow | null,\n orientation: Orientation,\n palette: ResolvedArrowPalette | undefined,\n): void {\n const ctx = canvas.getContext(\"2d\");\n if (ctx === null) return;\n const dpr = typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1;\n const rect = canvas.getBoundingClientRect();\n const cssWidth = rect.width;\n const cssHeight = rect.height;\n if (cssWidth <= 0 || cssHeight <= 0) return;\n\n const backingWidth = Math.round(cssWidth * dpr);\n const backingHeight = Math.round(cssHeight * dpr);\n if (canvas.width !== backingWidth) canvas.width = backingWidth;\n if (canvas.height !== backingHeight) canvas.height = backingHeight;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.clearRect(0, 0, cssWidth, cssHeight);\n\n const sqSize = cssWidth / 8;\n for (const arrow of arrows) {\n if (arrow.label?.background !== undefined) continue;\n drawArrow(ctx, arrow.from, arrow.to, resolveColor(arrow, palette), sqSize, orientation, false);\n }\n if (preview !== null) {\n drawArrow(ctx, preview.from, preview.to, preview.color, sqSize, orientation, true);\n }\n}\n\n/* ====================================================== decorations */\n\n/** ViewBox span (0..100) for the SVG decoration overlay. */\n/**\n * Anchor-point for label/customSvg rendering, returned in viewport\n * percent (0..100) so the SVG overlay can position nodes without a\n * second `getBoundingClientRect` call.\n */\nfunction anchorPct(\n from: number,\n to: number,\n orientation: Orientation,\n center: \"orig\" | \"dest\" | \"label\",\n): { cx: number; cy: number } {\n const a = squareCentrePct(from, orientation);\n const b = squareCentrePct(to, orientation);\n if (center === \"orig\") return a;\n if (center === \"dest\") return b;\n return { cx: (a.cx + b.cx) / 2, cy: (a.cy + b.cy) / 2 };\n}\n\n/** Geometry needed to paint an aerodynamic pointing head with integrated text. */\nexport interface AeroHeadGeometry {\n readonly path: string;\n readonly tipLen: number;\n readonly dockLen: number;\n readonly frontLen: number;\n readonly cabinW: number;\n}\n\n/**\n * Compute aerodynamic arrowhead geometry with dynamic rectangular auto-centering:\n * - The evaluation text is mathematically 100% centered at (0, 0).\n * - The rectangular cabin extends dynamically from -cabinW to +cabinW based on text length.\n * - The forward nose taper begins strictly AFTER +cabinW, so outer digits like `+32.3` or `#18`\n * never clip or cramp into the beveled nose cone!\n */\nexport function computeDynamicAeroGeometry(\n text: string | undefined,\n style: ArrowHeadStyle | undefined,\n fontSize: number,\n isTerminal = true,\n): AeroHeadGeometry {\n const resolvedStyle = style ?? \"aero_chisel\";\n const hasText = Boolean(text && text.trim().length > 0);\n\n if (!hasText) {\n // Sculpted Aero-Sharp pointer: compact, athletic chisel arrowhead\n // for non-evaluation moves, idle engine states, and user-drawn arrows.\n // Total length: 4.6u at 2.45u baseline, scaling with fontSize when provided.\n const scale = Math.max(1, fontSize / 2.45);\n const tipX = 2.8 * scale;\n const shoulderX = 0.2 * scale;\n const rearX = -1.2 * scale;\n const dockX = -1.8 * scale;\n const halfH = 2.2 * scale;\n const path = `M ${rearX},${-halfH} L ${shoulderX},${-halfH} L ${tipX},0 L ${shoulderX},${halfH} L ${rearX},${halfH} C ${dockX},${halfH} ${dockX},${-halfH} ${rearX},${-halfH} Z`;\n return {\n path,\n tipLen: tipX,\n dockLen: -dockX,\n frontLen: tipX,\n cabinW: 0,\n };\n }\n\n const charWidth = fontSize * 0.6;\n const textWidth = text!.length * charWidth;\n const halfTextW = textWidth / 2;\n\n const scale = Math.max(1, fontSize / 2.45);\n // Equal padding around the text (0.75 at baseline, scaling with fontSize)\n const padX = 0.75 * scale;\n const cabinW = Math.max(3.2 * scale, halfTextW + padX);\n const halfH = Math.max(2.3, fontSize * 0.9);\n\n // Scaled rear dock socket\n const rearInset = 0.65 * scale;\n const dockX = -cabinW - rearInset;\n\n let frontLen = 0;\n let path = \"\";\n\n if (resolvedStyle === \"aero_chisel\") {\n if (isTerminal) {\n // Modern 60° beveled chisel nose closing forward (1.25 at baseline, scaling with fontSize)\n const noseLead = 1.25 * scale;\n const tipX = cabinW + noseLead;\n frontLen = tipX;\n path = `M ${-cabinW},${-halfH} L ${cabinW},${-halfH} L ${tipX},0 L ${cabinW},${halfH} L ${-cabinW},${halfH} C ${dockX},${halfH} ${dockX},${-halfH} ${-cabinW},${-halfH} Z`;\n } else {\n frontLen = cabinW + rearInset;\n path = `M ${-cabinW},${-halfH} L ${cabinW},${-halfH} C ${frontLen},${-halfH} ${frontLen},${halfH} ${cabinW},${halfH} L ${-cabinW},${halfH} C ${dockX},${halfH} ${dockX},${-halfH} ${-cabinW},${-halfH} Z`;\n }\n } else if (resolvedStyle === \"chamfer_arrow\") {\n if (isTerminal) {\n const tipX = cabinW + 1.4;\n frontLen = tipX;\n path = `M ${-cabinW},-1.2 L ${-cabinW + 1.2},${-halfH} L ${cabinW},${-halfH} L ${tipX},0 L ${cabinW},${halfH} L ${-cabinW + 1.2},${halfH} L ${-cabinW},1.2 Z`;\n } else {\n frontLen = cabinW + 0.8;\n path = `M ${-cabinW},-1.2 L ${-cabinW + 1.2},${-halfH} L ${cabinW - 1.2},${-halfH} L ${cabinW},-1.2 L ${cabinW},1.2 L ${cabinW - 1.2},${halfH} L ${-cabinW + 1.2},${halfH} L ${-cabinW},1.2 Z`;\n }\n } else if (resolvedStyle === \"blunt_wedge\") {\n if (isTerminal) {\n const tipX = cabinW + 1.1;\n frontLen = tipX;\n path = `M ${-cabinW},${-halfH} L ${cabinW},${-halfH} L ${tipX},${-halfH * 0.35} L ${tipX},${halfH * 0.35} L ${cabinW},${halfH} L ${-cabinW},${halfH} C ${dockX},${halfH} ${dockX},${-halfH} ${-cabinW},${-halfH} Z`;\n } else {\n frontLen = cabinW + rearInset;\n path = `M ${-cabinW},${-halfH} L ${cabinW},${-halfH} C ${frontLen},${-halfH} ${frontLen},${halfH} ${cabinW},${halfH} L ${-cabinW},${halfH} C ${dockX},${halfH} ${dockX},${-halfH} ${-cabinW},${-halfH} Z`;\n }\n } else if (resolvedStyle === \"stealth\") {\n const wingBack = cabinW + 2.3;\n const wingY = halfH + 0.35;\n const shoulderX = cabinW * 0.35;\n const tipX = cabinW + 3.6;\n frontLen = tipX;\n path = `M ${dockX.toFixed(2)},0 L ${(-wingBack).toFixed(2)},${(-wingY).toFixed(2)} L ${(-cabinW).toFixed(2)},${(-halfH).toFixed(2)} L ${shoulderX.toFixed(2)},${(-halfH).toFixed(2)} L ${tipX.toFixed(2)},0 L ${shoulderX.toFixed(2)},${halfH.toFixed(2)} L ${(-cabinW).toFixed(2)},${halfH.toFixed(2)} L ${(-wingBack).toFixed(2)},${wingY.toFixed(2)} Z`;\n } else {\n const noseLead = 1.25;\n const tipX = cabinW + noseLead;\n frontLen = tipX;\n path = `M ${-cabinW},${-halfH} L ${cabinW},${-halfH} L ${tipX},0 L ${cabinW},${halfH} L ${-cabinW},${halfH} C ${dockX},${halfH} ${dockX},${-halfH} ${-cabinW},${-halfH} Z`;\n }\n\n return {\n path,\n tipLen: frontLen,\n dockLen: -dockX,\n frontLen,\n cabinW,\n };\n}\n\n/**\n * Select the optimal Russian Г-shape corner for knight moves to avoid collisions\n * with friendly pawns and co-linear arrows along the file/rank.\n */\nfunction chooseKnightCorner(\n fromIndex: number,\n toIndex: number,\n allArrows: readonly Arrow[],\n orientation: Orientation,\n): Point {\n const a = squareCentrePct(fromIndex, orientation);\n const b = squareCentrePct(toIndex, orientation);\n\n const dx = b.cx - a.cx;\n const dy = b.cy - a.cy;\n\n // Candidate 1: step along rank to toIndex's file, then along file to toIndex (b.cx, a.cy)\n const corner1 = { x: b.cx, y: a.cy };\n\n // Candidate 2: step along file to toIndex's rank, then along rank to toIndex (a.cx, b.cy)\n const corner2 = { x: a.cx, y: b.cy };\n\n // If another arrow shares the origin file (e.g. pawn on g7 moving while knight on g8 moves),\n // step off the file immediately (corner1) so the knight path does not collide with the pawn ray!\n const fromFile = fromIndex & 7;\n const hasColinearArrowOnFile = allArrows.some(\n (other) => other.from !== fromIndex && (other.from & 7) === fromFile,\n );\n\n if (hasColinearArrowOnFile) {\n return corner1;\n }\n\n return Math.abs(dx) > Math.abs(dy) ? corner1 : corner2;\n}\n\n/** Compute flight vectors, pointing clearance, and cabin geometry for integrated eval arrows. */\nfunction computeIntegratedArrowVectors(\n arrow: Arrow,\n orientation: Orientation,\n allArrows: readonly Arrow[],\n) {\n const label = arrow.label;\n if (!label || label.background === undefined) return null;\n\n const a = squareCentrePct(arrow.from, orientation);\n const b = squareCentrePct(arrow.to, orientation);\n if (arrow.from === arrow.to) return null;\n\n const isKnight = isKnightMove(arrow.from, arrow.to);\n const fontSize = label.fontSize ?? 2.45;\n const geom = computeDynamicAeroGeometry(label.text, label.headStyle, fontSize, true);\n\n let startUnit: Point | null;\n let finalUnit: Point | null;\n let corner: Point | null = null;\n\n if (!isKnight) {\n const u = unitVector({ x: a.cx, y: a.cy }, { x: b.cx, y: b.cy });\n if (u === null) return null;\n startUnit = u;\n finalUnit = u;\n } else {\n corner = chooseKnightCorner(arrow.from, arrow.to, allArrows, orientation);\n startUnit = unitVector({ x: a.cx, y: a.cy }, corner);\n finalUnit = unitVector(corner, { x: b.cx, y: b.cy });\n if (startUnit === null || finalUnit === null) return null;\n }\n\n // Pointing clearance: leaves >= 1/3 of destination square (4.17%) open after the arrow tip\n // In 100x100 coordinates with 12.5% squares, center + 2.08% stops 4.17% before far edge\n const tip = {\n x: b.cx + finalUnit.x * 2.08,\n y: b.cy + finalUnit.y * 2.08,\n };\n\n const headCenter = {\n x: tip.x - finalUnit.x * geom.frontLen,\n y: tip.y - finalUnit.y * geom.frontLen,\n };\n\n const shaftEnd = {\n x: headCenter.x - finalUnit.x * geom.dockLen,\n y: headCenter.y - finalUnit.y * geom.dockLen,\n };\n\n const dist = Math.hypot(b.cx - a.cx, b.cy - a.cy);\n const startOffset = dist < 18 ? 0.5 : 2.4;\n const shaftStart = {\n x: a.cx + startUnit.x * startOffset,\n y: a.cy + startUnit.y * startOffset,\n };\n\n const angleRad = Math.atan2(finalUnit.y, finalUnit.x);\n const angleDeg = (angleRad * 180) / Math.PI;\n\n let textRot = 0;\n const rotMode = label.textRotation ?? \"auto\";\n if (rotMode === \"flat\") {\n textRot = -angleDeg;\n } else if (rotMode === \"auto\") {\n const norm = ((angleDeg % 360) + 360) % 360;\n if (norm > 90 && norm < 270) {\n textRot = 180;\n }\n }\n\n const shaftD =\n corner !== null\n ? `M ${shaftStart.x} ${shaftStart.y} L ${corner.x} ${corner.y} L ${shaftEnd.x} ${shaftEnd.y}`\n : `M ${shaftStart.x} ${shaftStart.y} L ${shaftEnd.x} ${shaftEnd.y}`;\n\n const shaftLen =\n (shaftEnd.x - shaftStart.x) * startUnit.x + (shaftEnd.y - shaftStart.y) * startUnit.y;\n const showShaft = isKnight || shaftLen > 0.2;\n\n return {\n label,\n fontSize,\n geom,\n headCenter,\n shaftD,\n showShaft,\n angleDeg,\n textRot,\n };\n}\n\n/** Render the shaft of an integrated arrow (with trench casing and contact shadow). */\nfunction renderIntegratedShaft(\n arrow: Arrow,\n color: string,\n orientation: Orientation,\n key: string,\n allArrows: readonly Arrow[],\n): ReactElement | null {\n const v = computeIntegratedArrowVectors(arrow, orientation, allArrows);\n if (v === null || !v.showShaft) return null;\n\n const is3d = v.label.style3d !== false;\n const filterId = is3d ? \"url(#gb-apple-elevation)\" : \"url(#gb-arrow-shadow)\";\n\n return (\n <g key={`${key}-shaft`} filter={filterId}>\n {/* Trench casing under-stroke */}\n <path\n d={v.shaftD}\n fill=\"none\"\n stroke={is3d ? \"rgba(44, 27, 20, 0.75)\" : color}\n strokeWidth={is3d ? \"3.2\" : \"2.2\"}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n {/* Core stroke */}\n <path\n d={v.shaftD}\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2.1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n {/* 3D highlight micro-spine */}\n {is3d && (\n <path\n d={v.shaftD}\n fill=\"none\"\n stroke=\"rgba(255, 255, 255, 0.3)\"\n strokeWidth=\"0.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n )}\n </g>\n );\n}\n\n/** Render the Aero-Chisel arrowhead pod with dynamic centered numerical evaluation. */\nfunction renderIntegratedHead(\n arrow: Arrow,\n _color: string,\n orientation: Orientation,\n key: string,\n allArrows: readonly Arrow[],\n): ReactElement | null {\n const v = computeIntegratedArrowVectors(arrow, orientation, allArrows);\n if (v === null) return null;\n\n const is3d = v.label.style3d !== false;\n const filterId = is3d ? \"url(#gb-apple-elevation)\" : \"url(#gb-arrow-shadow)\";\n const headFill =\n v.label.background === \"#F59E0B\" && is3d ? \"url(#gb-apple-amber-grad)\" : v.label.background;\n const headStroke = v.label.borderColor ?? \"#78350F\";\n\n return (\n <g key={`${key}-head`} filter={filterId}>\n <g transform={`translate(${v.headCenter.x}, ${v.headCenter.y}) rotate(${v.angleDeg})`}>\n <path\n d={v.geom.path}\n fill={headFill}\n stroke={headStroke}\n strokeWidth=\"0.7\"\n strokeLinejoin=\"round\"\n />\n {Boolean(v.label.text && v.label.text.trim().length > 0) && (\n <text\n x={0}\n y={0}\n transform={v.textRot !== 0 ? `rotate(${v.textRot})` : undefined}\n fill={v.label.fill ?? \"#000000\"}\n fontSize={v.fontSize}\n fontWeight=\"800\"\n fontFamily=\"'JetBrains Mono', ui-monospace, monospace\"\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n style={{ userSelect: \"none\" }}\n >\n {v.label.text}\n </text>\n )}\n </g>\n </g>\n );\n}\n\n/* ====================================================== component */\n\nexport const ArrowsLayer = memo(\n forwardRef<ArrowsLayerHandle, ArrowsLayerProps>(function ArrowsLayer(\n { model, orientation, palette, below = false },\n handle,\n ) {\n const canvasRef = useRef<HTMLCanvasElement | null>(null);\n const previewRef = useRef<PreviewArrow | null>(null);\n const allArrows = useBoardSlice(model, (s) => s.arrows);\n\n // Filter by the `below` flag. A fresh reference is produced only\n // when the subset changes — preserves `useLayoutEffect` dep\n // stability across renders that don't affect this layer.\n const arrows = useMemo(\n () => allArrows.filter((a) => (a.below === true) === below),\n [allArrows, below],\n );\n\n // Does any arrow in this subset carry a label/customSvg? If not,\n // the SVG overlay isn't rendered at all — zero cost for the common\n // \"plain arrows only\" case.\n const hasDecorations = useMemo(\n () => arrows.some((a) => a.label !== undefined || a.customSvg !== undefined),\n [arrows],\n );\n\n // Preview is owned by the top layer only; the below layer ignores\n // gesture previews (drawings always land on top during creation).\n useImperativeHandle(\n handle,\n () => ({\n setPreview(preview: PreviewArrow | null): void {\n if (below) return;\n previewRef.current = preview;\n const canvas = canvasRef.current;\n if (canvas !== null) redraw(canvas, arrows, preview, orientation, palette);\n },\n }),\n [arrows, orientation, palette, below],\n );\n\n useLayoutEffect(() => {\n const canvas = canvasRef.current;\n if (canvas === null) return;\n redraw(canvas, arrows, previewRef.current, orientation, palette);\n }, [arrows, orientation, palette]);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (canvas === null) return;\n const parent = canvas.parentElement;\n if (parent === null || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(() => {\n redraw(canvas, arrows, previewRef.current, orientation, palette);\n });\n observer.observe(parent);\n return () => observer.disconnect();\n }, [arrows, orientation, palette]);\n\n const layerZIndex = below ? undefined : 15;\n\n return (\n <>\n <canvas\n ref={canvasRef}\n data-layer={below ? \"arrows-below\" : \"arrows\"}\n style={{\n position: \"absolute\",\n inset: 0,\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n ...(layerZIndex !== undefined ? { zIndex: layerZIndex } : {}),\n }}\n />\n {hasDecorations ? (\n <svg\n data-layer={below ? \"arrows-below-decor\" : \"arrows-decor\"}\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n // Decorations share the z-plane of the canvas they annotate.\n ...(layerZIndex !== undefined ? { zIndex: layerZIndex } : {}),\n }}\n >\n <defs>\n <filter\n id=\"gb-arrow-shadow\"\n filterUnits=\"userSpaceOnUse\"\n x=\"-20\"\n y=\"-20\"\n width=\"140\"\n height=\"140\"\n >\n <feDropShadow\n dx=\"0\"\n dy=\"1.2\"\n stdDeviation=\"1.2\"\n floodColor=\"#000000\"\n floodOpacity=\"0.55\"\n />\n </filter>\n <filter\n id=\"gb-apple-elevation\"\n filterUnits=\"userSpaceOnUse\"\n x=\"-20\"\n y=\"-20\"\n width=\"140\"\n height=\"140\"\n >\n <feDropShadow\n dx=\"0\"\n dy=\"2.8\"\n stdDeviation=\"2.2\"\n floodColor=\"#000000\"\n floodOpacity=\"0.4\"\n />\n <feDropShadow\n dx=\"0\"\n dy=\"1.0\"\n stdDeviation=\"0.7\"\n floodColor=\"#000000\"\n floodOpacity=\"0.6\"\n />\n </filter>\n <linearGradient id=\"gb-apple-amber-grad\" x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#FBBF24\" stopOpacity=\"1\" />\n <stop offset=\"60%\" stopColor=\"#F59E0B\" stopOpacity=\"1\" />\n <stop offset=\"100%\" stopColor=\"#D97706\" stopOpacity=\"1\" />\n </linearGradient>\n </defs>\n {/* Pass 1: Integrated arrow shafts (rendered before heads for Dual Aero overlap) */}\n {arrows.map((arrow) => {\n if (arrow.label?.background === undefined) return null;\n const key = `${arrow.from}-${arrow.to}-${arrow.color}-${arrow.brush ?? \"\"}`;\n const color = resolveColor(arrow, palette);\n return renderIntegratedShaft(arrow, color, orientation, key, arrows);\n })}\n {/* Pass 2: Integrated arrow pointing heads */}\n {arrows.map((arrow) => {\n if (arrow.label?.background === undefined) return null;\n const key = `${arrow.from}-${arrow.to}-${arrow.color}-${arrow.brush ?? \"\"}`;\n const color = resolveColor(arrow, palette);\n return renderIntegratedHead(arrow, color, orientation, key, arrows);\n })}\n {/* Pass 3: Non-integrated labels and customSvg */}\n {arrows.map((arrow) => {\n if (arrow.label?.background !== undefined) return null;\n const key = `${arrow.from}-${arrow.to}-${arrow.color}-${arrow.brush ?? \"\"}`;\n const color = resolveColor(arrow, palette);\n const nodes: ReactElement[] = [];\n if (arrow.label !== undefined) {\n const { cx, cy } = anchorPct(arrow.from, arrow.to, orientation, \"label\");\n nodes.push(\n <text\n key={`${key}-label`}\n x={cx}\n y={cy}\n fill={arrow.label.fill ?? color}\n fontSize=\"4\"\n fontWeight=\"700\"\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n style={{ userSelect: \"none\" }}\n >\n {arrow.label.text}\n </text>,\n );\n }\n if (arrow.customSvg !== undefined) {\n const { cx, cy } = anchorPct(\n arrow.from,\n arrow.to,\n orientation,\n arrow.customSvg.center ?? \"dest\",\n );\n nodes.push(\n <g\n key={`${key}-svg`}\n transform={`translate(${cx}, ${cy})`}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted consumer-supplied SVG\n dangerouslySetInnerHTML={{ __html: arrow.customSvg.html }}\n />,\n );\n }\n return nodes.length === 0 ? null : <g key={key}>{nodes}</g>;\n })}\n </svg>\n ) : null}\n </>\n );\n }),\n);\n\n/** Utility for external hooks: the singleton reference shape. */\nexport type ArrowsLayerRef = RefObject<ArrowsLayerHandle | null>;\n","\"use client\";\n\n/**\n * A single static board square.\n *\n * Static in content — dynamic highlights and pieces live on sibling\n * overlays (piece layer, arrows canvas, drag ghost), so a square\n * renders exactly once per mount except when its `isFocused` prop\n * flips. This preserves the \"0 re-renders per hover\" budget in\n * PERFORMANCE.md.\n *\n * ### ARIA grid pattern\n *\n * - `role=\"gridcell\"` with algebraic `aria-label` so screen readers\n * announce \"square e4\".\n * - `aria-rowindex` / `aria-colindex` let assistive tech describe the\n * cell's grid position without relying on row groups in the DOM.\n * - Roving tabindex: the one focused cell has `tabindex=0`, every other\n * cell has `tabindex=-1`. Tab steps into the board once, then out.\n * - When the `isFocused` prop flips to `true` **and the board already\n * owns DOM focus** (arrow-key nav), the cell programmatically focuses\n * itself. The initial \"seed\" of `focusedSquare` on mount does **not**\n * move DOM focus, so the board stays dormant until the user engages.\n *\n * ### Focus ring is painted via `:focus-visible`, not inline\n *\n * The amber focus ring used to ship as an always-on inline `boxShadow`\n * keyed off the `isFocused` prop, which meant the square that held the\n * roving `tabindex=0` showed the ring on page load — even when the user\n * had never touched the board. The ring now ships as a CSS rule that\n * only matches `:focus-visible`, so browser heuristics keep it hidden\n * for mouse / pointer interaction and surface it only when the user is\n * actually navigating with the keyboard.\n *\n * ### Selection + legal-target highlights are NOT rendered here\n *\n * Chessground-style: a `useSelectionController` hook sets the\n * `data-gb-selection` attribute on this `<div>` imperatively, and the\n * CSS shipped by `injectSelectionStyles()` paints a `::before`\n * pseudo-element overlay. That bypasses React reconciliation entirely\n * on selection changes — critical for the drag-start peak frame.\n *\n * To support that, the square uses `backgroundColor` (the `color` part\n * of the CSS `background` shorthand) rather than the full `background`\n * shorthand — which would otherwise reset `background-image` to `none`\n * and wipe out any CSS-set gradient overlay.\n */\n\nimport { memo, type ReactNode, useCallback, useEffect, useRef } from \"react\";\nimport type { BoardCell, BoardModel, SquareIndex } from \"../core/index.js\";\nimport { CSS_VARS } from \"../default-theme.js\";\nimport { useSquareCell } from \"../hooks/use-board-subscription.js\";\nimport type { SquareContext } from \"../types.js\";\n\n/** Singleton id used to dedupe the injected focus-ring style element. */\nconst FOCUS_STYLE_ID = \"gb-focus-ring-styles\";\n\n/**\n * Inject the keyboard-focus ring CSS once per document. SSR-safe\n * (early-returns when there's no `document`). The rule uses\n * `:focus-visible` so the ring only appears for genuine keyboard\n * navigation — page-load hydration, programmatic focus without prior\n * keyboard activity, and pointer clicks all keep it hidden.\n */\nfunction injectFocusRingStyles(): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(FOCUS_STYLE_ID) !== null) return;\n const style = document.createElement(\"style\");\n style.id = FOCUS_STYLE_ID;\n style.textContent = `\n[data-gb-square]:focus-visible {\n box-shadow: inset 0 0 0 3px rgba(255, 206, 76, 0.95);\n}\n`;\n document.head.appendChild(style);\n}\n\n/** Algebraic name (`\"a1\"`, `\"h8\"`, …) for a square index. */\nfunction algebraicOf(index: SquareIndex): string {\n const file = index & 7;\n const rank = index >> 3;\n return `${String.fromCharCode(0x61 + file)}${rank + 1}`;\n}\n\n/** Props for {@link Square}. */\nexport interface SquareProps {\n readonly index: SquareIndex;\n readonly onClick: (index: SquareIndex) => void;\n readonly renderSquare?: ((ctx: SquareContext) => ReactNode) | undefined;\n /**\n * `true` for the single square that currently owns the roving tabindex.\n * When this flips to `true`, the cell focuses itself programmatically.\n */\n readonly isFocused: boolean;\n /**\n * Stable setter called with `(index, element | null)` whenever the\n * square's DOM node mounts or unmounts. Consumers (the selection\n * controller) use this to build a 64-entry refs array so they can\n * write `data-gb-selection` imperatively on the right square.\n */\n readonly setSquareRef?: ((index: SquareIndex, el: HTMLElement | null) => void) | undefined;\n readonly model?: BoardModel | null | undefined;\n readonly getSquareAriaLabel?: ((square: SquareIndex, cell: BoardCell) => string) | undefined;\n readonly onFocus?: ((square: SquareIndex, cell: BoardCell) => void) | undefined;\n}\n\nfunction SquareImpl({\n index,\n onClick,\n renderSquare,\n isFocused,\n setSquareRef,\n model,\n getSquareAriaLabel,\n onFocus,\n}: SquareProps) {\n const file = index & 7;\n const rank = index >> 3;\n const isLight = (file + rank) % 2 === 1;\n const cell = useSquareCell(model, index) as BoardCell;\n const label = getSquareAriaLabel ? getSquareAriaLabel(index, cell) : algebraicOf(index);\n\n const internalRef = useRef<HTMLDivElement | null>(null);\n const lastReportedFocusRef = useRef<boolean>(false);\n\n // Stable ref-setter: React only calls it when the DOM node\n // mounts/unmounts, not per render, so `memo`'s prop-diff stays valid.\n const setRef = useCallback(\n (el: HTMLDivElement | null) => {\n internalRef.current = el;\n setSquareRef?.(index, el);\n },\n [index, setSquareRef],\n );\n\n // One-time CSS injection for the `:focus-visible` ring. Idempotent\n // across remounts via a singleton `<style>` id.\n useEffect(() => {\n injectFocusRingStyles();\n }, []);\n\n // When focus state flips to `true`, move DOM focus to this cell — but\n // ONLY if the board already contains focus. That gate prevents the\n // initial roving-tabindex seed (which happens after mount) from\n // stealing page focus on load. Once the user has actually entered the\n // board via Tab or click, this effect takes over for arrow-key nav.\n useEffect(() => {\n if (!isFocused) {\n lastReportedFocusRef.current = false;\n return;\n }\n const el = internalRef.current;\n if (el === null) return;\n const grid = el.closest('[role=\"grid\"]');\n if (grid === null) return;\n if (!grid.contains(document.activeElement)) return;\n // Only focus if we aren't already, to avoid thrashing.\n if (document.activeElement !== el) el.focus();\n if (!lastReportedFocusRef.current) {\n lastReportedFocusRef.current = true;\n onFocus?.(index, cell);\n }\n }, [isFocused, index, cell, onFocus]);\n\n const handleFocus = useCallback(() => {\n lastReportedFocusRef.current = true;\n onFocus?.(index, cell);\n }, [index, cell, onFocus]);\n\n const handleClick = (): void => onClick(index);\n\n return (\n <div\n ref={setRef}\n role=\"gridcell\"\n aria-label={label}\n aria-rowindex={rank + 1}\n aria-colindex={file + 1}\n tabIndex={isFocused ? 0 : -1}\n data-square={algebraicOf(index)}\n data-gb-square=\"\"\n data-light={isLight ? \"true\" : \"false\"}\n onClick={handleClick}\n onFocus={handleFocus}\n style={{\n position: \"relative\",\n // `backgroundColor` (not the `background` shorthand) so the\n // CSS `background-image` set by `useSelectionController` (or pseudo-elements)\n // can layer on top without clobbering this base colour.\n backgroundColor: `var(${isLight ? CSS_VARS.SQ_LIGHT : CSS_VARS.SQ_DARK})`,\n backgroundImage: `var(${isLight ? CSS_VARS.SQ_LIGHT_IMAGE : CSS_VARS.SQ_DARK_IMAGE},none)`,\n backgroundSize: `var(${CSS_VARS.SQ_IMAGE_SIZE},cover)`,\n backgroundBlendMode: `var(${CSS_VARS.SQ_BLEND_MODE},normal)`,\n // Cursor is managed by `useCursorController` via injected CSS so\n // it can flip between `pointer` / `grab` / `grabbing` without a\n // React re-render per hover.\n userSelect: \"none\",\n // Suppress the browser's default focus ring; the keyboard focus\n // indicator ships via `:focus-visible` (see `injectFocusRingStyles`).\n outline: \"none\",\n // Squares carry the container-query context so pieces inside can\n // size relative to this cell (85cqh glyph sizing).\n containerType: \"size\",\n }}\n >\n {renderSquare !== undefined ? renderSquare({ index, isLight, label }) : null}\n </div>\n );\n}\n\n/**\n * Memoised square. All props are primitives or stable callbacks — memo\n * skips re-render for every square whose `isFocused` flag didn't flip,\n * so arrow-key navigation re-renders exactly 2 squares (old + new).\n */\nexport const Square = memo(SquareImpl);\nSquare.displayName = \"Square\";\n","\"use client\";\n\n/**\n * The 8×8 grid of {@link Square} cells. Laid out with CSS Grid so browser\n * layout does all the work; we just emit the squares in the right order\n * based on orientation.\n *\n * The grid is static and never re-renders after mount. Dynamic content\n * (highlights, pieces, coordinates) lives on absolutely-positioned sibling\n * layers inside the board container.\n */\n\nimport { memo, type ReactNode, useMemo } from \"react\";\nimport type { BoardCell, BoardModel, SquareIndex } from \"../core/index.js\";\nimport type { Orientation, SquareContext } from \"../types.js\";\nimport { Square } from \"./square.js\";\n\n/** Build the order squares should appear in for a given orientation. */\nfunction buildSquareOrder(orientation: Orientation): SquareIndex[] {\n const squares: SquareIndex[] = [];\n if (orientation === \"white\") {\n // White at bottom: rank 7 (top) first, rank 0 (bottom) last.\n for (let rank = 7; rank >= 0; rank--) {\n for (let file = 0; file < 8; file++) {\n squares.push((rank * 8 + file) as SquareIndex);\n }\n }\n } else {\n // Black at bottom: rank 0 (top) first, rank 7 (bottom) last, files flipped.\n for (let rank = 0; rank < 8; rank++) {\n for (let file = 7; file >= 0; file--) {\n squares.push((rank * 8 + file) as SquareIndex);\n }\n }\n }\n return squares;\n}\n\n/** Props for {@link BoardGrid}. */\nexport interface BoardGridProps {\n readonly orientation: Orientation;\n readonly onSquareClick: (index: SquareIndex) => void;\n readonly renderSquare?: ((ctx: SquareContext) => ReactNode) | undefined;\n readonly ariaLabel?: string | undefined;\n /**\n * Index of the square that currently owns the roving `tabindex=0`.\n * `null` means no cell in the grid is focused — the user hasn't Tabbed\n * into the board yet.\n */\n readonly focusedSquare: SquareIndex | null;\n /**\n * Stable setter that receives each square's DOM node on mount /\n * unmount. The selection controller uses the resulting refs array to\n * paint highlights imperatively — no React state, no reconciliation.\n */\n readonly setSquareRef?: ((index: SquareIndex, el: HTMLElement | null) => void) | undefined;\n /**\n * Flip the grid into a declarative, non-interactive mode. Emits\n * `aria-readonly=\"true\"` for assistive tech and mirrors the shape of\n * the server-rendered `StaticChessboard` so a `viewOnly` client board\n * reads the same as an SSR'd one.\n */\n readonly readOnly?: boolean | undefined;\n readonly model?: BoardModel | null | undefined;\n readonly getSquareAriaLabel?: ((square: SquareIndex, cell: BoardCell) => string) | undefined;\n readonly onSquareFocus?: ((square: SquareIndex, cell: BoardCell) => void) | undefined;\n}\n\n/**\n * The static 8×8 grid. Re-renders only on orientation / focus changes.\n * When `focusedSquare` flips, only the two affected `Square` children\n * re-render (old + new) thanks to `React.memo` on `Square`.\n */\nexport const BoardGrid = memo(function BoardGrid({\n orientation,\n onSquareClick,\n renderSquare,\n ariaLabel,\n focusedSquare,\n setSquareRef,\n readOnly,\n model,\n getSquareAriaLabel,\n onSquareFocus,\n}: BoardGridProps) {\n const squares = useMemo(() => buildSquareOrder(orientation), [orientation]);\n\n return (\n <div\n role=\"grid\"\n aria-label={ariaLabel ?? \"Chess board\"}\n aria-rowcount={8}\n aria-colcount={8}\n {...(readOnly === true ? { \"aria-readonly\": true } : {})}\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"grid\",\n gridTemplateColumns: \"repeat(8, 1fr)\",\n gridTemplateRows: \"repeat(8, 1fr)\",\n }}\n >\n {squares.map((index) => (\n <Square\n key={index}\n index={index}\n onClick={onSquareClick}\n isFocused={focusedSquare === index}\n model={model}\n getSquareAriaLabel={getSquareAriaLabel}\n onFocus={onSquareFocus}\n {...(renderSquare !== undefined ? { renderSquare } : {})}\n {...(setSquareRef !== undefined ? { setSquareRef } : {})}\n />\n ))}\n </div>\n );\n});\n","\"use client\";\n\n/**\n * Red-glow highlight under the king when the side-to-move is in check.\n *\n * Subscribes to `inCheck`, `turn`, and `board` — when any of those change\n * (which is rare: only on moves that give or resolve check) we scan the\n * board for the side-to-move's king and position a radial-gradient tint\n * under its square. Pointer-events are `none` so the highlight never\n * intercepts clicks; the piece on top remains fully interactive.\n */\n\nimport type { BoardCell, BoardModel, SquareIndex } from \"../core/index.js\";\nimport { CSS_VARS } from \"../default-theme.js\";\nimport { useBoardSlice } from \"../hooks/use-board-subscription.js\";\nimport type { Orientation } from \"../types.js\";\n\n/** King cell value depending on colour. */\nconst WHITE_KING = 6 as BoardCell; // BOARD_CELL_WK\nconst BLACK_KING = 12 as BoardCell; // BOARD_CELL_BK\n\n/** Find the side-to-move's king index on the board, or `null` if missing. */\nfunction findKing(board: Readonly<Uint8Array>, turn: 0 | 1): SquareIndex | null {\n const code = turn === 0 ? WHITE_KING : BLACK_KING;\n for (let i = 0; i < 64; i++) {\n if (board[i] === code) return i as SquareIndex;\n }\n return null;\n}\n\n/** Pixel position of a square within the board, as `{ x%, y% }`. */\nfunction positionOf(\n index: SquareIndex,\n orientation: Orientation,\n): {\n x: number;\n y: number;\n} {\n const file = index & 7;\n const rank = index >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n return { x: col * 12.5, y: row * 12.5 };\n}\n\n/** Props for {@link CheckLayer}. */\nexport interface CheckLayerProps {\n readonly model: BoardModel;\n readonly orientation: Orientation;\n}\n\n/**\n * Renders nothing when the side-to-move is not in check. When it is, draws\n * a single absolute-positioned div with a radial-gradient background over\n * the king's square.\n *\n * Split into an outer shell that only subscribes to the cheap `inCheck`\n * primitive and an inner component that subscribes to `turn`/`board`. The\n * inner component only exists while the king IS in check, so the 64-byte\n * `board` slice is only observed during those commits — untouched during\n * the overwhelming majority of moves.\n */\nexport function CheckLayer({ model, orientation }: CheckLayerProps) {\n const inCheck = useBoardSlice(model, (s) => s.inCheck);\n if (!inCheck) return null;\n return <CheckLayerInner model={model} orientation={orientation} />;\n}\n\nfunction CheckLayerInner({ model, orientation }: CheckLayerProps) {\n const turn = useBoardSlice(model, (s) => s.turn) as 0 | 1;\n const board = useBoardSlice(model, (s) => s.board);\n const kingSquare = findKing(board, turn);\n if (kingSquare === null) return null;\n const { x, y } = positionOf(kingSquare, orientation);\n\n return (\n <div\n data-layer=\"check\"\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: `${x}%`,\n top: `${y}%`,\n width: \"12.5%\",\n height: \"12.5%\",\n background: `var(${CSS_VARS.CHECK})`,\n pointerEvents: \"none\",\n zIndex: 2,\n }}\n />\n );\n}\n","\"use client\";\n\n/**\n * Single floating-piece element that follows the pointer during a drag.\n *\n * ### Pre-mount, imperative show/hide\n *\n * Previously the layer conditionally rendered on a `dragActive` React\n * state flag — dragging started with a `flushSync(setState)`, which\n * synchronously re-rendered `<Chessboard/>` (and the entire layer\n * stack under it) during the first `pointermove` handler. Under CPU\n * throttle this showed up as a 25 ms peak frame at drag-start vs\n * chessground's 9 ms.\n *\n * The new model mounts all 12 possible drag ghosts **once** (hidden)\n * and exposes an imperative `DragLayerHandle`. `useDrag` calls\n * `handle.show(cell)` + `handle.setTransform(x, y)` from its pointer\n * handlers — no React state change, no reconciliation, compositor does\n * the work. `handle.hide()` on drag-end.\n */\n\nimport { forwardRef, useImperativeHandle, useMemo, useRef } from \"react\";\nimport type { BoardCell } from \"../core/index.js\";\nimport { CSS_VARS } from \"../default-theme.js\";\nimport type { PieceRenderer } from \"../types.js\";\n\n/**\n * Frozen style object for the wrapper. Always mounted, always visible\n * to the compositor — hidden via `opacity: 0` + `pointer-events: none`\n * rather than `display: none`. That keeps the GPU layer alive between\n * drags so the first pointer-move of a drag doesn't pay the cost of\n * allocating a fresh compositor layer (the previous design's 25 ms\n * peak frame in real Chromium was mostly that one-off).\n *\n * `transform: translate3d(0,0,0)` forces the browser to promote the\n * element to its own layer immediately at mount.\n */\nconst WRAPPER_STYLE = Object.freeze({\n position: \"absolute\" as const,\n top: 0,\n left: 0,\n width: \"12.5%\",\n height: \"12.5%\",\n pointerEvents: \"none\" as const,\n willChange: \"transform\",\n zIndex: 20,\n containerType: \"size\" as const,\n opacity: 0,\n transform: \"translate3d(0, 0, 0)\",\n});\n\n/**\n * Frozen style object shared across the 12 pre-materialised slot\n * wrappers. Kept always-laid-out (not `display: none`) so paint + layer\n * state is warm — opacity flips only on the selected one.\n */\nconst SLOT_STYLE = Object.freeze({\n position: \"absolute\" as const,\n inset: 0,\n opacity: 0,\n containerType: \"size\" as const,\n});\n\n/**\n * Imperative handle exposed by {@link DragLayer}. `useDrag` uses these\n * methods in its pointer handlers to show the ghost, move it, and hide\n * it — all without triggering a React render.\n */\nexport interface DragLayerHandle {\n /** Reveal the ghost for the given piece cell (1..12). */\n show(cell: BoardCell): void;\n /** Hide the ghost. Safe to call while already hidden. */\n hide(): void;\n /** Write the ghost's transform. Called every pointer-move during a drag. */\n setTransform(x: number, y: number): void;\n /** Raw wrapper element — kept for legacy callers that measure geometry. */\n element(): HTMLDivElement | null;\n}\n\n/** Props for {@link DragLayer}. */\nexport interface DragLayerProps {\n /**\n * The piece renderer to use — the same one `<PieceLayer/>` renders\n * with. The drag layer calls this once per piece code at mount and\n * stores the resulting elements in the DOM, so piece rendering never\n * happens on the hot path.\n */\n readonly pieces: PieceRenderer;\n}\n\n/**\n * Always-mounted, imperatively-controlled drag overlay. Always emits\n * the `data-layer=\"drag\"` attribute so existing CSS hooks keep working;\n * `data-active` toggles true during a drag so styling or tests can\n * key on that.\n */\nexport const DragLayer = forwardRef<DragLayerHandle, DragLayerProps>(function DragLayer(\n { pieces },\n ref,\n) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n // Refs to the 12 pre-materialised piece slots, keyed by cell code (1..12).\n // Index 0 is unused (empty cell has no drag ghost).\n const slotRefs = useRef<Array<HTMLDivElement | null>>(new Array(13).fill(null));\n\n // Pre-materialise the 13 (well, 12 — cell 0 is null) piece elements\n // once at mount. Rebuild only when the renderer identity changes.\n const slots = useMemo(() => {\n const nodes: Array<React.ReactNode> = [];\n for (let cell = 1; cell <= 12; cell++) {\n const child = pieces({ cell: cell as BoardCell, square: 0 as never });\n nodes.push(\n <div\n key={cell}\n ref={(el) => {\n slotRefs.current[cell] = el;\n }}\n data-drag-cell={cell}\n style={{\n ...SLOT_STYLE,\n filter: `var(${cell <= 6 ? CSS_VARS.PIECE_FILTER_WHITE : CSS_VARS.PIECE_FILTER_BLACK}, none)`,\n }}\n >\n {child}\n </div>,\n );\n }\n return nodes;\n }, [pieces]);\n\n useImperativeHandle(\n ref,\n () => ({\n show(cell): void {\n const wrapper = wrapperRef.current;\n if (wrapper === null) return;\n wrapper.style.opacity = \"1\";\n wrapper.dataset[\"active\"] = \"true\";\n // Show just the chosen piece slot; others stay at opacity 0.\n for (let c = 1; c <= 12; c++) {\n const el = slotRefs.current[c];\n if (el !== null && el !== undefined) {\n el.style.opacity = c === cell ? \"1\" : \"0\";\n }\n }\n },\n hide(): void {\n const wrapper = wrapperRef.current;\n if (wrapper === null) return;\n wrapper.style.opacity = \"0\";\n wrapper.dataset[\"active\"] = \"false\";\n },\n setTransform(x, y): void {\n const wrapper = wrapperRef.current;\n if (wrapper === null) return;\n wrapper.style.transform = `translate3d(${x}px, ${y}px, 0)`;\n },\n element(): HTMLDivElement | null {\n return wrapperRef.current;\n },\n }),\n [],\n );\n\n return (\n <div\n ref={wrapperRef}\n data-layer=\"drag\"\n data-active=\"false\"\n aria-hidden=\"true\"\n style={WRAPPER_STYLE}\n >\n {slots}\n </div>\n );\n});\n","\"use client\";\n\n/**\n * One-shot red flash on an origin square to announce a rejected move.\n *\n * Driven by a `flashAt` prop owned by `Chessboard`. When the prop changes\n * from `null` to a `SquareIndex`, a WAAPI animation fades a red tint in\n * and out once; the parent's timer nulls the prop afterwards.\n *\n * Honours `prefers-reduced-motion`: the flash renders briefly but the\n * opacity timeline collapses to zero so motion-sensitive users don't see\n * a pulse.\n */\n\nimport { useLayoutEffect, useRef } from \"react\";\nimport type { SquareIndex } from \"../core/index.js\";\nimport { DEFAULT_ILLEGAL_FLASH_TINT } from \"../default-theme.js\";\nimport type { Orientation } from \"../types.js\";\n\n/** CSS-percentage position of the square inside the board. */\nfunction positionOf(\n index: SquareIndex,\n orientation: Orientation,\n): {\n x: number;\n y: number;\n} {\n const file = index & 7;\n const rank = index >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n return { x: col * 12.5, y: row * 12.5 };\n}\n\nfunction prefersReducedMotion(): boolean {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return false;\n }\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\n/** Flash duration, in ms. Kept short so it doesn't interfere with UX. */\nconst FLASH_DURATION_MS = 280;\n\n/** Props for {@link IllegalFlashLayer}. */\nexport interface IllegalFlashLayerProps {\n readonly at: SquareIndex | null;\n readonly orientation: Orientation;\n}\n\n/**\n * Renders `null` when `at` is `null`. When `at` is a `SquareIndex`,\n * renders a tinted div and kicks off a one-shot opacity animation via\n * WAAPI. No setState / re-render during the fade.\n */\nexport function IllegalFlashLayer({ at, orientation }: IllegalFlashLayerProps) {\n const elRef = useRef<HTMLDivElement | null>(null);\n\n useLayoutEffect(() => {\n if (at === null) return;\n const el = elRef.current;\n if (el === null || typeof el.animate !== \"function\") return;\n const duration = prefersReducedMotion() ? 0 : FLASH_DURATION_MS;\n el.animate(\n [\n { opacity: 0, offset: 0 },\n { opacity: 1, offset: 0.15 },\n { opacity: 0, offset: 1 },\n ],\n { duration, easing: \"ease-out\", fill: \"forwards\" },\n );\n }, [at]);\n\n if (at === null) return null;\n const { x, y } = positionOf(at, orientation);\n return (\n <div\n ref={elRef}\n data-layer=\"illegal-flash\"\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: `${x}%`,\n top: `${y}%`,\n width: \"12.5%\",\n height: \"12.5%\",\n background: DEFAULT_ILLEGAL_FLASH_TINT,\n opacity: 0,\n pointerEvents: \"none\",\n zIndex: 5,\n }}\n />\n );\n}\n","\"use client\";\n\n/**\n * Visually-hidden screen-reader announcer.\n *\n * Subscribes to `snapshot.lastMove` and emits a concise, descriptive\n * announcement each time a move lands. Uses `aria-live=\"polite\"` so the\n * announcement is queued after any critical output the user is already\n * reading, not interrupted mid-word.\n *\n * ### Why descriptive text instead of SAN?\n *\n * SAN (\"Nf3\", \"exd5\", \"O-O\") is concise but not pronounceable by screen\n * readers in a way players recognise. \"Knight to f3\" reads out as\n * \"Knight to eff three\", which is what a chess commentator would say.\n * We compose the announcement from the packed move + the post-move board\n * snapshot so no extra engine call is required.\n */\n\nimport { useMemo } from \"react\";\nimport { type BoardModel, decodePackedMove, type PackedMove } from \"../core/index.js\";\nimport { useBoardSlice } from \"../hooks/use-board-subscription.js\";\n\n/** 0-indexed square → algebraic (`\"e4\"`). */\nfunction algebraicOf(index: number): string {\n const file = index & 7;\n const rank = index >> 3;\n return `${String.fromCharCode(0x61 + file)}${rank + 1}`;\n}\n\n/** Readable piece name for a board cell. Empty cell returns `\"piece\"`. */\nfunction pieceName(cell: number): string {\n if (cell === 0) return \"piece\";\n const color = cell > 6 ? \"black\" : \"white\";\n const type = (cell - 1) % 6;\n switch (type) {\n case 0:\n return `${color} pawn`;\n case 1:\n return `${color} knight`;\n case 2:\n return `${color} bishop`;\n case 3:\n return `${color} rook`;\n case 4:\n return `${color} queen`;\n case 5:\n return `${color} king`;\n default:\n return `${color} piece`;\n }\n}\n\n/** Build the announcement string from the last packed move + board state. */\nfunction announcementFor(\n lastMove: PackedMove,\n board: Readonly<Uint8Array>,\n wasCapture: boolean,\n): string {\n const { from, to, kind, promotion } = decodePackedMove(lastMove);\n\n // A pass moves no piece and has no from/to — announce the pass rather\n // than reading the sentinel as an h8→h8 move.\n if (kind === \"pass\") return \"Passes.\";\n\n if (kind === \"castle\") {\n const isKingside = (to & 7) > (from & 7);\n return isKingside ? \"Castles kingside.\" : \"Castles queenside.\";\n }\n\n // Post-move board[to] holds the piece that just moved (or promoted to).\n const landed = board[to] ?? 0;\n const name = pieceName(landed);\n const fromSq = algebraicOf(from);\n const toSq = algebraicOf(to);\n\n if (kind === \"promotion\" && promotion !== null) {\n const promoted =\n promotion === 1 ? \"knight\" : promotion === 2 ? \"bishop\" : promotion === 3 ? \"rook\" : \"queen\";\n const action = wasCapture ? \"captures and promotes\" : \"promotes\";\n return `Pawn ${fromSq} ${action} to ${promoted} on ${toSq}.`;\n }\n\n if (kind === \"en-passant\") {\n return `${capitalise(name)} ${fromSq} captures en passant on ${toSq}.`;\n }\n\n if (wasCapture) {\n return `${capitalise(name)} ${fromSq} captures on ${toSq}.`;\n }\n\n return `${capitalise(name)} ${fromSq} to ${toSq}.`;\n}\n\nfunction capitalise(s: string): string {\n return s.length === 0 ? s : s.charAt(0).toUpperCase() + s.slice(1);\n}\n\n/** Visually-hidden style block (the `sr-only` pattern). */\nconst srOnlyStyle = {\n position: \"absolute\" as const,\n width: \"1px\",\n height: \"1px\",\n padding: 0,\n margin: \"-1px\",\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\" as const,\n border: 0,\n};\n\n/** Props for {@link LiveRegion}. */\nexport interface LiveRegionProps {\n readonly model: BoardModel;\n}\n\n/**\n * Subscribes to `lastMove` + `board` + `lastAnimations` and renders a\n * visually-hidden `aria-live=\"polite\"` region with a human-readable\n * description of the most recent move.\n */\nexport function LiveRegion({ model }: LiveRegionProps) {\n // Subscribe to `lastMove` only. The board bytes relevant to the\n // announcement (the `to` square) are read lazily inside the memo via\n // `getSnapshot()`, so we never wake on unrelated commits (arrow draw,\n // selection change, etc.) and never subscribe to a Uint8Array whose\n // identity is kept across commits — both of those were quiet no-ops\n // before and are gone now, one less thing for React to schedule.\n const lastMove = useBoardSlice(model, (s) => s.lastMove);\n\n const message = useMemo(() => {\n if (lastMove === null) return \"\";\n // Capture detection: inspect the just-emitted animation descriptors.\n // `lastAnimations` isn't part of the snapshot object but is stable\n // across the same commit, so reading it here is safe.\n const wasCapture = model.lastAnimations.some(\n (d) => d.kind === \"capture\" || d.kind === \"en-passant\",\n );\n return announcementFor(lastMove, model.getSnapshot().board, wasCapture);\n }, [lastMove, model]);\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n data-layer=\"live-region\"\n style={srOnlyStyle}\n >\n {message}\n </div>\n );\n}\n","\"use client\";\n\n/**\n * Ghost-piece overlay for pending premoves.\n *\n * Subscribes to `snapshot.premoves`. If a premove is queued we render a\n * blue tint on its target square plus a translucent ghost of the moving\n * piece at that target. The ghost uses the caller's `pieces` renderer so\n * theme consistency is automatic.\n *\n * For M4 we only render the **first** queued premove. Chained premoves\n * would need to project the board state forward through every pending\n * move — tractable, but out of scope here. The engine still processes\n * every queued premove in order once the opponent plays; this is strictly\n * a visual simplification.\n */\n\nimport type { BoardCell, BoardModel, SquareIndex } from \"../core/index.js\";\nimport { DEFAULT_PREMOVE_TINT } from \"../default-theme.js\";\nimport { useBoardSlice, useSquareCell } from \"../hooks/use-board-subscription.js\";\nimport type { Orientation, PieceRenderer } from \"../types.js\";\n\n/** CSS-percentage position of the square inside the board. */\nfunction positionOf(\n index: SquareIndex,\n orientation: Orientation,\n): {\n x: number;\n y: number;\n} {\n const file = index & 7;\n const rank = index >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n return { x: col * 12.5, y: row * 12.5 };\n}\n\n/** Props for {@link PremoveLayer}. */\nexport interface PremoveLayerProps {\n readonly model: BoardModel;\n readonly orientation: Orientation;\n readonly pieces: PieceRenderer;\n}\n\n/**\n * Renders `null` when the premove queue is empty.\n *\n * Two-tier structure: the outer shell only subscribes to the `premoves`\n * slice (changes rarely). The inner component, which subscribes to the\n * specific from-square byte, is mounted only while a premove is queued —\n * so no `board` subscription is paid for during the bulk of the game.\n */\nexport function PremoveLayer({ model, orientation, pieces }: PremoveLayerProps) {\n const premoves = useBoardSlice(model, (s) => s.premoves);\n if (premoves.length === 0) return null;\n const head = premoves[0];\n if (head === undefined) return null;\n return (\n <PremoveLayerInner\n model={model}\n orientation={orientation}\n pieces={pieces}\n from={head.from}\n to={head.to}\n />\n );\n}\n\ninterface PremoveLayerInnerProps {\n readonly model: BoardModel;\n readonly orientation: Orientation;\n readonly pieces: PieceRenderer;\n readonly from: SquareIndex;\n readonly to: SquareIndex;\n}\n\nfunction PremoveLayerInner({ model, orientation, pieces, from, to }: PremoveLayerInnerProps) {\n const cell = useSquareCell(model, from) as BoardCell;\n if (cell === 0) return null;\n const origin = positionOf(from, orientation);\n const target = positionOf(to, orientation);\n\n return (\n <div\n data-layer=\"premove\"\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n pointerEvents: \"none\",\n zIndex: 4,\n }}\n >\n {/* Origin tint (faint, so the piece still reads through). */}\n <div\n style={{\n position: \"absolute\",\n left: `${origin.x}%`,\n top: `${origin.y}%`,\n width: \"12.5%\",\n height: \"12.5%\",\n background: DEFAULT_PREMOVE_TINT,\n opacity: 0.5,\n }}\n />\n {/* Target tint + ghost piece. */}\n <div\n style={{\n position: \"absolute\",\n left: `${target.x}%`,\n top: `${target.y}%`,\n width: \"12.5%\",\n height: \"12.5%\",\n background: DEFAULT_PREMOVE_TINT,\n }}\n />\n <div\n data-premove-ghost=\"true\"\n style={{\n position: \"absolute\",\n left: `${target.x}%`,\n top: `${target.y}%`,\n width: \"12.5%\",\n height: \"12.5%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: 0.55,\n containerType: \"size\",\n }}\n >\n {pieces({ cell, square: to })}\n </div>\n </div>\n );\n}\n","\"use client\";\n\n/**\n * Built-in promotion dialog.\n *\n * Rendered only while a promotion is pending. Shows the four promotion\n * options (Queen, Rook, Bishop, Knight) stacked on the target square,\n * with the queen on the promoting side.\n *\n * ### UX contract\n *\n * - Primary pointer click on a choice resolves the promotion.\n * - <kbd>Q</kbd>, <kbd>R</kbd>, <kbd>B</kbd>, <kbd>N</kbd> keyboard\n * shortcuts resolve without moving focus.\n * - <kbd>Escape</kbd> or a click outside the dialog cancels the move.\n * - `role=\"dialog\"` with `aria-modal=\"true\"` + labelled title, so screen\n * readers announce the choice prompt.\n *\n * Rendered inside the Chessboard container so theme CSS variables (for\n * piece glyphs) are in scope.\n */\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n type BoardCell,\n type Color,\n encodeBoardCell,\n PieceType,\n type SquareIndex,\n} from \"../core/index.js\";\nimport { CSS_VARS } from \"../default-theme.js\";\nimport type { Orientation, PieceRenderer } from \"../types.js\";\n\n/** Props for {@link PromotionOverlay}. */\nexport interface PromotionOverlayProps {\n readonly from: SquareIndex;\n readonly to: SquareIndex;\n readonly color: 0 | 1;\n readonly orientation: Orientation;\n readonly pieces: PieceRenderer;\n readonly onSelect: (piece: PieceType) => void;\n readonly onCancel: () => void;\n readonly getPromotionPieceAriaLabel?: ((piece: PieceType, color: Color) => string) | undefined;\n}\n\n/** Pixel position of a square within the board, as `{ x%, y% }`. */\nfunction positionOf(\n index: SquareIndex,\n orientation: Orientation,\n): {\n x: number;\n y: number;\n} {\n const file = index & 7;\n const rank = index >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n return { x: col * 12.5, y: row * 12.5 };\n}\n\n/** Order pieces offer (Chess.com order: Queen, Knight, Rook, Bishop). */\nconst CHOICE_ORDER: readonly PieceType[] = [\n PieceType.Queen,\n PieceType.Knight,\n PieceType.Rook,\n PieceType.Bishop,\n];\n\n/** Map from keyboard shortcut to piece type. */\nconst SHORTCUTS: Readonly<Record<string, PieceType>> = {\n q: PieceType.Queen,\n r: PieceType.Rook,\n b: PieceType.Bishop,\n n: PieceType.Knight,\n Q: PieceType.Queen,\n R: PieceType.Rook,\n B: PieceType.Bishop,\n N: PieceType.Knight,\n};\n\nexport function PromotionOverlay({\n from: _from,\n to,\n color,\n orientation,\n pieces,\n onSelect,\n onCancel,\n getPromotionPieceAriaLabel,\n}: PromotionOverlayProps) {\n const buttonRefs = useRef<(HTMLButtonElement | null)[]>([]);\n\n const getLabel = useCallback(\n (piece: PieceType): string =>\n getPromotionPieceAriaLabel\n ? getPromotionPieceAriaLabel(piece, color as Color)\n : pieceName(piece),\n [getPromotionPieceAriaLabel, color],\n );\n\n const [activeAnnouncement, setActiveAnnouncement] = useState<string>(() =>\n getLabel(CHOICE_ORDER[0] ?? PieceType.Queen),\n );\n\n // Auto-focus the primary promotion option on open\n useEffect(() => {\n buttonRefs.current[0]?.focus();\n }, []);\n\n // Keyboard navigation, shortcuts, Escape, and focus trapping\n useEffect(() => {\n const onKey = (e: KeyboardEvent): void => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onCancel();\n return;\n }\n\n if (e.key === \"Tab\") {\n e.preventDefault();\n const activeEl = document.activeElement as HTMLButtonElement | null;\n const currentIdx = buttonRefs.current.indexOf(activeEl);\n let nextIdx: number;\n if (e.shiftKey) {\n nextIdx = currentIdx <= 0 ? buttonRefs.current.length - 1 : currentIdx - 1;\n } else {\n nextIdx = currentIdx >= buttonRefs.current.length - 1 ? 0 : currentIdx + 1;\n }\n buttonRefs.current[nextIdx]?.focus();\n return;\n }\n\n if (e.key === \"ArrowDown\" || e.key === \"ArrowRight\") {\n e.preventDefault();\n const activeEl = document.activeElement as HTMLButtonElement | null;\n const currentIdx = buttonRefs.current.indexOf(activeEl);\n const nextIdx = currentIdx < 0 ? 0 : (currentIdx + 1) % CHOICE_ORDER.length;\n buttonRefs.current[nextIdx]?.focus();\n return;\n }\n\n if (e.key === \"ArrowUp\" || e.key === \"ArrowLeft\") {\n e.preventDefault();\n const activeEl = document.activeElement as HTMLButtonElement | null;\n const currentIdx = buttonRefs.current.indexOf(activeEl);\n const prevIdx = currentIdx <= 0 ? CHOICE_ORDER.length - 1 : currentIdx - 1;\n buttonRefs.current[prevIdx]?.focus();\n return;\n }\n\n if (e.key === \"Home\") {\n e.preventDefault();\n buttonRefs.current[0]?.focus();\n return;\n }\n\n if (e.key === \"End\") {\n e.preventDefault();\n buttonRefs.current[CHOICE_ORDER.length - 1]?.focus();\n return;\n }\n\n const choice = SHORTCUTS[e.key];\n if (choice !== undefined) {\n e.preventDefault();\n onSelect(choice);\n }\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [onSelect, onCancel]);\n\n const targetPos = positionOf(to, orientation);\n // Black-side promotion stacks upward; white-side stacks downward.\n // For a black pawn promoting on rank 0 in white orientation, the target\n // square visually sits at the bottom (row 7) — the dialog grows upward so\n // rook/bishop/knight don't fall off-board.\n const promotingColorIsBlack = color === 1;\n const stackUpward = orientation === \"white\" ? promotingColorIsBlack : !promotingColorIsBlack;\n\n return (\n <div\n role=\"presentation\"\n data-layer=\"promotion-overlay\"\n onClick={onCancel}\n style={{\n position: \"absolute\",\n inset: 0,\n background: \"rgba(0, 0, 0, 0.35)\",\n zIndex: 30,\n cursor: \"pointer\",\n }}\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={`Choose promotion piece at ${algebraicOf(to)}`}\n onClick={(e) => e.stopPropagation()}\n style={{\n position: \"absolute\",\n left: `${targetPos.x}%`,\n top: `${stackUpward ? targetPos.y - 12.5 * 3 : targetPos.y}%`,\n width: \"12.5%\",\n height: `${12.5 * 4}%`,\n display: \"flex\",\n flexDirection: stackUpward ? \"column-reverse\" : \"column\",\n background: \"#ffffff\",\n boxShadow: \"0 4px 16px rgba(0, 0, 0, 0.28)\",\n borderRadius: \"4px\",\n overflow: \"hidden\",\n }}\n >\n {CHOICE_ORDER.map((piece, index) => {\n const cell = encodeBoardCell(color as Color, piece) as BoardCell;\n const label = getLabel(piece);\n return (\n <button\n key={piece}\n ref={(el) => {\n buttonRefs.current[index] = el;\n }}\n type=\"button\"\n onClick={() => onSelect(piece)}\n onFocus={() => setActiveAnnouncement(label)}\n aria-label={label}\n style={{\n flex: 1,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n border: \"none\",\n background: \"transparent\",\n cursor: \"pointer\",\n padding: 0,\n margin: 0,\n font: \"inherit\",\n containerType: \"size\",\n }}\n data-promotion-piece={pieceName(piece)}\n >\n {pieces({ cell, square: to })}\n </button>\n );\n })}\n </div>\n <span className=\"sr-only\" aria-live=\"polite\" aria-atomic=\"true\" style={srOnlyStyle}>\n {activeAnnouncement}\n </span>\n <span className=\"sr-only\" style={srOnlyStyle}>\n Choose a promotion piece with Q, N, R, or B, or arrow keys. Press Escape to cancel.\n </span>\n </div>\n );\n}\n\n/** Ultra-minimal visually-hidden style for the sr-only announcement. */\nconst srOnlyStyle = {\n position: \"absolute\" as const,\n width: \"1px\",\n height: \"1px\",\n padding: 0,\n margin: \"-1px\",\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\" as const,\n border: 0,\n};\n\nfunction pieceName(t: PieceType): string {\n switch (t) {\n case PieceType.Queen:\n return \"Queen\";\n case PieceType.Rook:\n return \"Rook\";\n case PieceType.Bishop:\n return \"Bishop\";\n case PieceType.Knight:\n return \"Knight\";\n default:\n return \"Piece\";\n }\n}\n\nfunction algebraicOf(index: SquareIndex): string {\n const file = index & 7;\n const rank = index >> 3;\n return `${String.fromCharCode(0x61 + file)}${rank + 1}`;\n}\n\n// Prevent an unused-import warning when CSS_VARS is only referenced in docs.\nvoid CSS_VARS;\n","\"use client\";\n\n/**\n * FEN-only piece overlay — a pure, subscription-free twin of\n * `<PieceLayer/>` used before the engine has loaded.\n *\n * `<Chessboard/>` renders this layer when its `game` prop is `null`\n * **and** a `fallbackFen` has been supplied. The DOM it produces is\n * intentionally identical to `<PieceLayer/>`'s — same container tree,\n * same CSS-grid placement, same `data-piece-*` attributes — so when\n * the engine resolves and the interactive layer takes over, the\n * browser doesn't reflow or shift the pieces visibly.\n *\n * Because this component has no state and no effects it runs on the\n * very first commit, with no wait for `useEffect` to fire. Pieces are\n * painted inside the first frame the board DOM lays out — typically\n * under ~60 ms from navigation start on a cold mount, which is the\n * whole point of `fallbackFen`.\n *\n * Geometry helpers, slot style, and container style are imported\n * from `piece-layer.tsx` so the two layers really do produce the\n * same DOM and the shared constants dedupe in the minified bundle.\n */\n\nimport type { BoardCell, SquareIndex } from \"../core/index.js\";\nimport { CSS_VARS } from \"../default-theme.js\";\nimport type { Orientation, PieceRenderer } from \"../types.js\";\nimport { algebraicOf, CONTAINER_STYLE, gridCoord, SLOT_BASE_STYLE } from \"./piece-layer.js\";\n\n/** Props for {@link StaticPieceLayer}. */\nexport interface StaticPieceLayerProps {\n /** Parsed FEN placement, 64 bytes, LERF indexed. */\n readonly board: Uint8Array;\n readonly orientation: Orientation;\n readonly pieces: PieceRenderer;\n}\n\n/**\n * Render one slot per occupied square — empty squares are elided so\n * the commit doesn't allocate nodes it would just have to drop. Keys\n * match the square index (matching the interactive layer) so React's\n * diff is minimal if either side of the transition re-enters.\n */\nexport function StaticPieceLayer({ board, orientation, pieces }: StaticPieceLayerProps) {\n const slots: React.ReactNode[] = [];\n for (let i = 0; i < 64; i++) {\n const cell = board[i] ?? 0;\n if (cell === 0) continue;\n const index = i as SquareIndex;\n const { col, row } = gridCoord(index, orientation);\n slots.push(\n <div\n key={i}\n data-piece-square={algebraicOf(index)}\n data-piece-cell={cell}\n style={{\n ...SLOT_BASE_STYLE,\n gridColumnStart: col,\n gridRowStart: row,\n filter: `var(${cell <= 6 ? CSS_VARS.PIECE_FILTER_WHITE : CSS_VARS.PIECE_FILTER_BLACK}, none)`,\n }}\n >\n {pieces({ cell: cell as BoardCell, square: index })}\n </div>,\n );\n }\n return (\n <div aria-hidden=\"true\" style={CONTAINER_STYLE}>\n {slots}\n </div>\n );\n}\n","\"use client\";\n\n/**\n * WAAPI-driven FLIP animations for piece glides.\n *\n * ### Strategy\n *\n * After every model commit we know, via `model.lastAnimations`, what\n * visually changed: a set of {@link AnimDescriptor}s describing `move`,\n * `capture`, `en-passant`, `castle`, `promotion`, `appear`, or `disappear`.\n *\n * For each descriptor that has a source and a destination, we:\n *\n * 1. Compute the pixel displacement between the `from` and `to` squares.\n * 2. Locate the destination `PieceSlot` DOM node (by `data-piece-square`).\n * 3. Cancel any in-flight animation on that node.\n * 4. Kick off a WAAPI animation whose first keyframe translates it back\n * to the source and whose last keyframe returns to identity.\n *\n * The animation runs entirely on the compositor — React never re-renders\n * during the glide.\n *\n * ### FLIP invariants\n *\n * - Run inside `useLayoutEffect` so the transform is applied **before**\n * the browser paints, preventing a one-frame flash at the destination.\n * - Skip animation when `prefers-reduced-motion: reduce` is set, or when\n * the caller's duration is zero.\n * - Fall back silently if the destination DOM node is missing (e.g. the\n * piece-layer was reparented mid-animation) — never throw.\n */\n\nimport { type ReactNode, type RefObject, useLayoutEffect, useRef } from \"react\";\nimport type { AnimDescriptor, BoardModel, SquareIndex } from \"../core/index.js\";\nimport type { AnimationOptions, Orientation } from \"../types.js\";\nimport { useBoardSlice } from \"./use-board-subscription.js\";\n\nconst DEFAULT_DURATION_MS = 60;\nconst DEFAULT_EASING = \"cubic-bezier(0.22, 0.61, 0.36, 1)\";\n\n/** Algebraic name `\"e2\"` from a square index. */\nfunction algebraicOf(index: SquareIndex): string {\n const file = index & 7;\n const rank = index >> 3;\n return `${String.fromCharCode(0x61 + file)}${rank + 1}`;\n}\n\n/**\n * Compute the pixel delta from `to` back to `from` in board coordinates.\n * In an orientation-flipped board, the sign of both axes flips together so\n * the helper just needs to know the square size and the two raw indices.\n */\nfunction deltaFromTo(\n from: SquareIndex,\n to: SquareIndex,\n squareSize: number,\n orientation: Orientation,\n): { dx: number; dy: number } {\n const fromFile = from & 7;\n const fromRank = from >> 3;\n const toFile = to & 7;\n const toRank = to >> 3;\n const fromCol = orientation === \"white\" ? fromFile : 7 - fromFile;\n const fromRow = orientation === \"white\" ? 7 - fromRank : fromRank;\n const toCol = orientation === \"white\" ? toFile : 7 - toFile;\n const toRow = orientation === \"white\" ? 7 - toRank : toRank;\n return {\n dx: (fromCol - toCol) * squareSize,\n dy: (fromRow - toRow) * squareSize,\n };\n}\n\n/** Cancel any running WAAPI animation on `element`. */\nfunction cancelAnimations(element: Element): void {\n // `getAnimations` is standard but may be absent in reduced test envs.\n if (typeof element.getAnimations !== \"function\") return;\n for (const anim of element.getAnimations()) anim.cancel();\n}\n\n/**\n * Read `prefers-reduced-motion: reduce`. Returns `false` in non-browser\n * environments (e.g. during SSR).\n */\nfunction prefersReducedMotion(): boolean {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return false;\n }\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\n/**\n * Animate one piece glide from the source square back to identity at the\n * destination. `element` is the destination `PieceSlot` wrapper — the same\n * one the `PieceLayer` renders.\n */\nfunction animateGlide(\n element: HTMLElement,\n dx: number,\n dy: number,\n duration: number,\n easing: string,\n): void {\n cancelAnimations(element);\n if (duration <= 0 || typeof element.animate !== \"function\") return;\n element.animate(\n [{ transform: `translate(${dx}px, ${dy}px)` }, { transform: \"translate(0, 0)\" }],\n { duration, easing, fill: \"none\" },\n );\n}\n\n/** Runtime hooks exposed to {@link useAnimation}'s caller. */\nexport interface UseAnimationRuntime {\n /**\n * Ref to a boolean flag. If `true` at commit time the next animation is\n * skipped and the flag is reset to `false` automatically. Used by the\n * drag handler to suppress the FLIP glide — for a drag-initiated move,\n * the user has already placed the piece at the target, so animating\n * from source → target reverses their action and looks jarring.\n */\n readonly skipNextRef?: RefObject<boolean>;\n}\n\n/**\n * Subscribe to the model's commit stream and play a WAAPI animation for\n * every descriptor in `model.lastAnimations`.\n *\n * @param model The board model (or `null` during async init).\n * @param containerRef Ref to the outer board container — used for pixel\n * geometry.\n * @param orientation Current board orientation.\n * @param options Duration / easing overrides.\n * @param runtime Optional runtime hooks (e.g. a `skipNextRef` to bypass\n * the animation on the next commit).\n */\n/**\n * Drive FLIP animations off a cheap scalar slice subscription.\n *\n * Previously this hook ran a `setState` inside `<Chessboard/>` on every\n * model commit to make its `useLayoutEffect` re-fire. That worked, but it\n * forced `<Chessboard/>` (and the entire layer tree below it) to re-run\n * its function body every single move — the per-byte subscriptions saved\n * `<Square/>` / `<PieceSlot/>` from re-rendering, but the 11 layer\n * wrappers above them paid full price. See the M7 render-budget diagnosis\n * in BENCH.md's \"What's not measured yet\" section.\n *\n * The fix: expose `<AnimationRunner/>` as a sibling component that\n * subscribes to `historyPly` via `useBoardSlice`. When a move lands,\n * only `<AnimationRunner/>` re-renders (it produces `null`), its layout\n * effect fires, and it reads `model.lastAnimations` to run the WAAPI\n * glides. `<Chessboard/>` never re-renders on a move.\n */\nfunction runAnimations(\n descriptors: readonly AnimDescriptor[],\n container: HTMLElement,\n orientation: Orientation,\n duration: number,\n easing: string,\n): void {\n const rect = container.getBoundingClientRect();\n const sqSize = rect.width / 8;\n if (sqSize <= 0) return;\n\n for (const d of descriptors) {\n switch (d.kind) {\n case \"move\":\n case \"capture\":\n case \"en-passant\":\n case \"promotion\": {\n const toEl = container.querySelector<HTMLElement>(\n `[data-piece-square=\"${algebraicOf(d.to)}\"]`,\n );\n if (toEl === null) break;\n const { dx, dy } = deltaFromTo(d.from, d.to, sqSize, orientation);\n animateGlide(toEl, dx, dy, duration, easing);\n break;\n }\n case \"castle\": {\n const kingEl = container.querySelector<HTMLElement>(\n `[data-piece-square=\"${algebraicOf(d.kingTo)}\"]`,\n );\n const rookEl = container.querySelector<HTMLElement>(\n `[data-piece-square=\"${algebraicOf(d.rookTo)}\"]`,\n );\n if (kingEl !== null) {\n const { dx, dy } = deltaFromTo(d.kingFrom, d.kingTo, sqSize, orientation);\n animateGlide(kingEl, dx, dy, duration, easing);\n }\n if (rookEl !== null) {\n const { dx, dy } = deltaFromTo(d.rookFrom, d.rookTo, sqSize, orientation);\n animateGlide(rookEl, dx, dy, duration, easing);\n }\n break;\n }\n // `appear` / `disappear` deliberately not animated — they cover\n // edge cases like `load(fen)` where no \"glide\" is meaningful.\n case \"appear\":\n case \"disappear\":\n break;\n }\n }\n}\n\n/** Props for {@link AnimationRunner}. */\nexport interface AnimationRunnerProps {\n readonly model: BoardModel;\n readonly containerRef: RefObject<HTMLElement | null>;\n readonly orientation: Orientation;\n readonly options?: AnimationOptions;\n readonly runtime?: UseAnimationRuntime;\n}\n\n/**\n * Sibling component that owns the animation subscription. Renders `null`;\n * its only job is to translate a scalar slice change (`historyPly`) into\n * a `useLayoutEffect` firing with the descriptors from the just-committed\n * move. Because the subscription lives here — not in `<Chessboard/>` —\n * the root board component no longer re-renders once per move.\n */\nexport function AnimationRunner({\n model,\n containerRef,\n orientation,\n options,\n runtime,\n}: AnimationRunnerProps): ReactNode {\n const duration = options?.durationMs ?? DEFAULT_DURATION_MS;\n const easing = options?.easing ?? DEFAULT_EASING;\n const skipNextRef = runtime?.skipNextRef;\n\n // `historyPly` advances exactly once per committed move (including\n // undo / redo / goto). Subscribing to this single number — via React's\n // default `Object.is` bailout — wakes us exactly when we need to run\n // the post-commit glide. We include `historyPly` in the layout-effect\n // deps below so the effect re-fires on every move; without it, the\n // effect would run once on mount and sit there forever.\n const historyPly = useBoardSlice(model, (s) => s.historyPly);\n const lastAnimatedPlyRef = useRef<number | null>(null);\n\n useLayoutEffect(() => {\n if (lastAnimatedPlyRef.current === historyPly) return;\n lastAnimatedPlyRef.current = historyPly;\n const container = containerRef.current;\n if (container === null) return;\n const descriptors = model.lastAnimations;\n if (descriptors.length === 0) return;\n\n // Drag-initiated commits: consume the skip flag and bail out. The\n // user has already placed the piece at the target; replaying a glide\n // from the source looks like the move is being undone and redone.\n if (skipNextRef?.current) {\n skipNextRef.current = false;\n return;\n }\n\n const effectiveDuration = prefersReducedMotion() ? 0 : duration;\n if (effectiveDuration <= 0) return;\n\n runAnimations(descriptors, container, orientation, effectiveDuration, easing);\n }, [historyPly, model, containerRef, orientation, duration, easing, skipNextRef]);\n\n return null;\n}\n","\"use client\";\n\n/**\n * Right-click drawing gesture.\n *\n * Mirrors the left-click drag hook but listens only for the secondary\n * button. On `pointerdown` we record the origin square. Each `pointermove`\n * updates an in-flight preview arrow via `arrowsLayerRef.setPreview` —\n * **zero React re-renders** per frame, the canvas repaints imperatively.\n * On `pointerup` we commit the arrow through the board model's\n * `toggleArrow` (identical start/end toggles the same-square mark).\n *\n * Also intercepts the browser context menu so right-click doesn't pop the\n * OS menu.\n */\n\nimport { type RefObject, useEffect } from \"react\";\nimport type { ArrowsLayerHandle } from \"../components/arrows-layer.js\";\nimport type { BoardModel, SquareIndex } from \"../core/index.js\";\nimport { getSquareAtPoint } from \"../lib/geometry.js\";\nimport type { Orientation, ResolvedArrowPalette } from \"../types.js\";\n\n/** Resolve modifier keys to a colour channel. */\nfunction colorForModifiers(e: PointerEvent, palette: ResolvedArrowPalette): string {\n if (e.shiftKey) return palette.shift;\n if (e.altKey) return palette.alt;\n if (e.ctrlKey || e.metaKey) return palette.ctrl;\n return palette.default;\n}\n\nexport interface UseArrowGestureOptions {\n readonly game: BoardModel | null;\n readonly orientation: Orientation;\n readonly containerRef: RefObject<HTMLElement | null>;\n readonly arrowsLayerRef: RefObject<ArrowsLayerHandle | null>;\n readonly enabled: boolean;\n /** Fully-resolved colour palette (caller merges prop with defaults). */\n readonly palette: ResolvedArrowPalette;\n /**\n * When `true`, an arrow endpoint that lies on a legal move target\n * from the origin snaps to that target. Typical usage: analysis\n * boards where the user wants to draw future-move hints that align\n * with the rules. Default `false`.\n */\n readonly snapToValidMove?: boolean;\n}\n\n/**\n * Install right-click pointer listeners. Returns nothing — the side effect\n * is the listener registration. Gesture state lives entirely inside the\n * effect's closure and is torn down on unmount / dep change.\n */\nexport function useArrowGesture(options: UseArrowGestureOptions): void {\n const { game, orientation, containerRef, arrowsLayerRef, enabled, palette, snapToValidMove } =\n options;\n\n useEffect(() => {\n if (!enabled) return;\n const container = containerRef.current;\n if (container === null || game === null) return;\n\n let origin: SquareIndex | null = null;\n let activePointerId: number | null = null;\n\n const clearPreview = (): void => {\n arrowsLayerRef.current?.setPreview(null);\n };\n\n /**\n * Constrain a candidate endpoint to a legal target from `origin`\n * when `snapToValidMove` is enabled. Same-square (circle / mark)\n * is always preserved. When the caller hovers a non-legal square,\n * the arrow snaps to the nearest legal target — euclidean on square\n * indices (cheap; no allocations in the hot path because\n * `legalFrom` is already cached by position hash in the model).\n */\n const snap = (candidate: SquareIndex): SquareIndex => {\n if (!snapToValidMove) return candidate;\n if (origin === null) return candidate;\n if (candidate === origin) return candidate;\n const legals = game.legalFrom(origin);\n if (legals.size === 0 || legals.has(candidate)) return candidate;\n // File/rank diff to the candidate; square-index euclidean is a\n // fine proxy since we're comparing targets on an 8×8 grid.\n const cf = candidate & 7;\n const cr = candidate >> 3;\n let best = candidate;\n let bestDist = Infinity;\n for (const t of legals) {\n const df = (t & 7) - cf;\n const dr = (t >> 3) - cr;\n const d = df * df + dr * dr;\n if (d < bestDist) {\n bestDist = d;\n best = t;\n }\n }\n return best;\n };\n\n const setPreview = (to: SquareIndex, color: string): void => {\n if (origin === null) return;\n arrowsLayerRef.current?.setPreview({ from: origin, to: snap(to), color });\n };\n\n const onContextMenu = (e: MouseEvent): void => {\n // Suppress the browser menu whenever arrow drawing is armed — otherwise\n // the OS context menu steals the pointerup and leaves the preview ghost\n // on the board.\n e.preventDefault();\n };\n\n const onPointerDown = (e: PointerEvent): void => {\n if (e.button !== 2) return;\n const sq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (sq === null) return;\n origin = sq;\n activePointerId = e.pointerId;\n // Initial preview: a same-square \"mark\" at the origin.\n setPreview(sq, colorForModifiers(e, palette));\n try {\n container.setPointerCapture(e.pointerId);\n } catch {\n /* pointer capture not supported in this environment */\n }\n };\n\n const onPointerMove = (e: PointerEvent): void => {\n if (origin === null) return;\n if (activePointerId !== null && e.pointerId !== activePointerId) return;\n const sq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (sq === null) {\n // Pointer left the board — show the preview as a mark at origin.\n setPreview(origin, colorForModifiers(e, palette));\n return;\n }\n setPreview(sq, colorForModifiers(e, palette));\n };\n\n const onPointerUp = (e: PointerEvent): void => {\n if (origin === null) return;\n if (activePointerId !== null && e.pointerId !== activePointerId) return;\n const raw = getSquareAtPoint(container, e.clientX, e.clientY, orientation) ?? origin;\n const target = snap(raw);\n const color = colorForModifiers(e, palette);\n game.toggleArrow({ from: origin, to: target, color });\n origin = null;\n activePointerId = null;\n clearPreview();\n };\n\n const onPointerCancel = (e: PointerEvent): void => {\n if (origin === null) return;\n if (activePointerId !== null && e.pointerId !== activePointerId) return;\n origin = null;\n activePointerId = null;\n clearPreview();\n };\n\n container.addEventListener(\"contextmenu\", onContextMenu);\n container.addEventListener(\"pointerdown\", onPointerDown);\n container.addEventListener(\"pointermove\", onPointerMove, { passive: true });\n container.addEventListener(\"pointerup\", onPointerUp);\n container.addEventListener(\"pointercancel\", onPointerCancel);\n\n return (): void => {\n container.removeEventListener(\"contextmenu\", onContextMenu);\n container.removeEventListener(\"pointerdown\", onPointerDown);\n container.removeEventListener(\"pointermove\", onPointerMove);\n container.removeEventListener(\"pointerup\", onPointerUp);\n container.removeEventListener(\"pointercancel\", onPointerCancel);\n clearPreview();\n };\n }, [game, orientation, containerRef, arrowsLayerRef, enabled, palette, snapToValidMove]);\n}\n","\"use client\";\n\n/**\n * Click-to-move handler.\n *\n * Given a `BoardModel`, returns a stable `(index) => void` that implements\n * the standard chess-UI click semantics:\n *\n * | Prior state | Clicked square | Result |\n * |------------------|-------------------|-----------------------------------|\n * | nothing selected | own piece | select it |\n * | nothing selected | empty / opponent | no-op |\n * | piece selected | same square | deselect |\n * | piece selected | legal target | play (or defer to onPromotion) |\n * | piece selected | own piece | switch selection |\n * | piece selected | illegal square | deselect |\n *\n * The handler reads `model.getSnapshot()` at click time and does not\n * subscribe — the component wrapping this hook never re-renders because of\n * it.\n *\n * When a promotion is required:\n *\n * - If `onPromotionNeeded` is supplied, it's invoked with `(from, to)` and\n * `tryMove` is NOT called — the caller is responsible for resolving the\n * promotion and invoking `model.tryMove(from, to, chosenPiece)`.\n * - Otherwise we auto-promote to queen. This keeps the zero-config default\n * behaviour intact.\n */\n\nimport { useCallback } from \"react\";\nimport {\n type BoardModel,\n Color,\n type PackedMove,\n PieceType,\n type SquareIndex,\n} from \"../core/index.js\";\n\n/** Pawn = piece-type 0; rank 7 / rank 0 is the last rank for white / black. */\nfunction wouldPromote(fromCell: number, toIndex: SquareIndex): boolean {\n if (fromCell === 0) return false;\n const pieceType = (fromCell - 1) % 6;\n if (pieceType !== PieceType.Pawn) return false;\n const toRank = toIndex >> 3;\n return toRank === 0 || toRank === 7;\n}\n\n/**\n * @param model The board model, or `null` while the engine is loading.\n * @param onMove Optional callback fired on every successful move.\n * @param onPromotionNeeded Optional deferred-promotion handler. When\n * provided, `tryMove` is not called — the caller resolves the promotion\n * piece and invokes `model.tryMove` itself.\n * @param enabled Gate click-to-move. When `false` the returned callback\n * is a no-op — used by `viewOnly` boards and anywhere the caller needs\n * a stable identity while suppressing input. Defaults to `true`.\n */\nexport function useClickToMove(\n model: BoardModel | null,\n onMove?: (m: PackedMove) => void,\n onPromotionNeeded?: (from: SquareIndex, to: SquareIndex) => void,\n enabled = true,\n): (index: SquareIndex) => void {\n return useCallback(\n (index: SquareIndex) => {\n if (!enabled) return;\n if (model === null) return;\n const snap = model.getSnapshot();\n const cell = snap.board[index] ?? 0;\n const pieceColour = cell === 0 ? -1 : cell > 6 ? Color.Black : Color.White;\n\n if (snap.selected === null) {\n if (pieceColour === snap.turn) model.selectSquare(index);\n return;\n }\n\n if (snap.selected === index) {\n model.selectSquare(null);\n return;\n }\n\n if (snap.legalTargets.has(index)) {\n const fromCell = snap.board[snap.selected] ?? 0;\n if (wouldPromote(fromCell, index)) {\n if (onPromotionNeeded !== undefined) {\n onPromotionNeeded(snap.selected, index);\n return;\n }\n const played = model.tryMove(snap.selected, index, PieceType.Queen);\n if (played !== null && onMove !== undefined) onMove(played);\n return;\n }\n const played = model.tryMove(snap.selected, index);\n if (played !== null && onMove !== undefined) onMove(played);\n return;\n }\n\n if (pieceColour === snap.turn) {\n model.selectSquare(index);\n return;\n }\n\n model.selectSquare(null);\n },\n [model, onMove, onPromotionNeeded, enabled],\n );\n}\n","\"use client\";\n\n/**\n * `useCursorController` — cursor paint for grabbable pieces via a\n * single container-level attribute plus CSS matching.\n *\n * ### Why this exists\n *\n * The board's pointer cursor is a signal: hover a piece you can pick up,\n * see `grab`; drag it, see `grabbing`; hover an empty square or a piece\n * that isn't yours to move, see the normal `pointer`. That's how every\n * native chess UI (lichess / chess.com / chessground) behaves.\n *\n * ### Design — why not per-square data-attributes\n *\n * An earlier version of this controller imperatively wrote\n * `data-gb-grabbable=\"true\"` on every square that currently held a\n * pickup-eligible piece. The diff logic was correct, but every turn\n * flip changes grabbable status for 16 white + 16 black piece squares,\n * so a single move dispatched **32 DOM attribute mutations**. For a\n * 40-ply game that's 1 280 attribute writes — the library's largest\n * source of DOM churn per move, visible in the mutation-audit bench.\n *\n * The new design writes **one** container-level attribute per turn\n * flip and lets CSS express which pieces are grabbable based on data\n * already present on each piece slot:\n *\n * - `data-gb-turn=\"white\" | \"black\"` on the board container\n * — one attribute write per commit in which `turn` changes.\n * - `data-gb-premove=\"true\"` on the container when `allowPremove`\n * is on — one attribute write when premove availability changes.\n * - `[data-piece-cell]` is already set on every `PieceSlot`\n * (1..6 white, 7..12 black); see `piece-layer.tsx`.\n *\n * The injected CSS rules target piece slots directly, flipping\n * `pointer-events: auto` + `cursor: grab` on them. Because piece slots\n * render inside an overlay that normally has `pointer-events: none`,\n * this has the side-benefit of making ONLY grabbable pieces intercept\n * pointer events — click-to-move / drag initiation still fire via the\n * board's bubbling listener.\n *\n * Net effect:\n * Before: 32 attribute writes per turn flip (per-square)\n * After: 0-1 attribute write per turn flip (per-container)\n * ≈ 98 % reduction in cursor-system DOM mutations per move.\n */\n\nimport { type RefObject, useEffect } from \"react\";\nimport type { BoardModel } from \"../core/index.js\";\n\n/** Singleton id used to dedupe the injected `<style>` element. */\nconst STYLE_ID = \"gb-cursor-styles\";\n\n/**\n * Inject the cursor CSS once per document. SSR-safe (early-returns).\n *\n * Rule precedence (later rules win on ties):\n * 1. Every square defaults to `pointer`.\n * 2. Piece slots whose cell code belongs to the side-to-move get\n * `cursor: grab` and `pointer-events: auto` so the cursor on the\n * piece reads correctly and the piece intercepts the pointerdown.\n * 3. Same for `data-gb-premove=\"true\"` + opposite-colour pieces.\n * 4. While any descendant square is under an active drag (the board\n * container carries `data-gb-dragging=\"true\"`), every square\n * reads `grabbing`.\n */\nfunction injectCursorStyles(): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(STYLE_ID) !== null) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = `\n[data-gb-square] {\n cursor: pointer;\n}\n[data-gb-turn=\"white\"] [data-piece-cell=\"1\"],\n[data-gb-turn=\"white\"] [data-piece-cell=\"2\"],\n[data-gb-turn=\"white\"] [data-piece-cell=\"3\"],\n[data-gb-turn=\"white\"] [data-piece-cell=\"4\"],\n[data-gb-turn=\"white\"] [data-piece-cell=\"5\"],\n[data-gb-turn=\"white\"] [data-piece-cell=\"6\"],\n[data-gb-turn=\"black\"] [data-piece-cell=\"7\"],\n[data-gb-turn=\"black\"] [data-piece-cell=\"8\"],\n[data-gb-turn=\"black\"] [data-piece-cell=\"9\"],\n[data-gb-turn=\"black\"] [data-piece-cell=\"10\"],\n[data-gb-turn=\"black\"] [data-piece-cell=\"11\"],\n[data-gb-turn=\"black\"] [data-piece-cell=\"12\"] {\n pointer-events: auto;\n cursor: grab;\n}\n[data-gb-premove=\"true\"][data-gb-turn=\"white\"] [data-piece-cell=\"7\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"white\"] [data-piece-cell=\"8\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"white\"] [data-piece-cell=\"9\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"white\"] [data-piece-cell=\"10\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"white\"] [data-piece-cell=\"11\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"white\"] [data-piece-cell=\"12\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"black\"] [data-piece-cell=\"1\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"black\"] [data-piece-cell=\"2\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"black\"] [data-piece-cell=\"3\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"black\"] [data-piece-cell=\"4\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"black\"] [data-piece-cell=\"5\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"black\"] [data-piece-cell=\"6\"] {\n pointer-events: auto;\n cursor: grab;\n}\n[data-gb-dragging=\"true\"] [data-gb-square],\n[data-gb-dragging=\"true\"] [data-piece-cell] {\n cursor: grabbing;\n}\n`;\n document.head.appendChild(style);\n}\n\n/**\n * Paint `data-gb-turn` (and, when applicable, `data-gb-premove`) on\n * the board container. One attribute write per turn flip, independent\n * of how many pieces are on the board.\n *\n * @param model The board model, or `null` while the engine is loading.\n * @param containerRef Ref to the board container — the root of the\n * ARIA grid and the element that carries every container-level\n * interaction attribute (dragging, turn, premove).\n * @param allowDrag When `false`, no piece is grabbable — the container\n * drops the `data-gb-turn` attribute entirely so the CSS rules no\n * longer match.\n * @param allowPremove When `true`, pieces of the colour that's **not**\n * to move are also grabbable (premove queueing).\n */\nexport function useCursorController(\n model: BoardModel | null,\n containerRef: RefObject<HTMLElement | null>,\n allowDrag: boolean,\n allowPremove: boolean,\n): void {\n useEffect(() => {\n injectCursorStyles();\n }, []);\n\n useEffect(() => {\n if (model === null) return;\n\n // Track the last value we wrote so we only touch the DOM on change.\n // DOMStringMap deletion on an already-absent key is a no-op, but the\n // browser still serialises the call — this guard keeps the observer\n // clean in test environments.\n let lastTurn: \"white\" | \"black\" | null = null;\n let lastPremove: boolean | null = null;\n\n const write = (): void => {\n const el = containerRef.current;\n if (el === null) return;\n if (!allowDrag) {\n // Drag is off — CSS rules won't match anything without the\n // attribute, so pull it cleanly if it was set.\n if (lastTurn !== null) {\n delete el.dataset[\"gbTurn\"];\n lastTurn = null;\n }\n if (lastPremove !== null) {\n delete el.dataset[\"gbPremove\"];\n lastPremove = null;\n }\n return;\n }\n const turn = model.getSnapshot().turn === 0 ? \"white\" : \"black\";\n if (turn !== lastTurn) {\n el.dataset[\"gbTurn\"] = turn;\n lastTurn = turn;\n }\n if (allowPremove !== lastPremove) {\n if (allowPremove) {\n el.dataset[\"gbPremove\"] = \"true\";\n } else {\n delete el.dataset[\"gbPremove\"];\n }\n lastPremove = allowPremove;\n }\n };\n\n write();\n const unsubscribe = model.subscribe(write);\n return () => {\n unsubscribe();\n const el = containerRef.current;\n if (el !== null) {\n delete el.dataset[\"gbTurn\"];\n delete el.dataset[\"gbPremove\"];\n }\n };\n }, [model, containerRef, allowDrag, allowPremove]);\n}\n","\"use client\";\n\n/**\n * Pointer-driven drag orchestration.\n *\n * The hook attaches `pointerdown`/`pointermove`/`pointerup`/`pointercancel`\n * listeners to a container ref and threads them through the drag state\n * machine from `gigaboard/core`.\n *\n * ### Why event listeners on the container (not per square)\n *\n * We need a single source of truth for every pointer sample during a drag:\n * the pointer naturally crosses square boundaries many times in a single\n * drag. Attaching per-square `onPointerMove` handlers would register 64\n * React listeners and re-subscribe every render. A single container\n * listener is one registration that never re-subscribes.\n *\n * ### Zero React renders per frame during drag\n *\n * During the `dragging` state we never call `setState`. Instead the hook\n * writes to `dragLayerRef.current.style.transform` in the pointer-move\n * handler. React sees nothing change until drag-end, at which point one\n * commit finishes the interaction (and the model's own commit renders the\n * new position).\n *\n * ### Contract with the caller\n *\n * - Provide a `containerRef` to the outermost board container (has 1:1\n * geometry with the 8×8 grid).\n * - Provide a `dragLayerRef` to the single absolutely-positioned element\n * that represents the floating piece; the hook writes its `transform`.\n * - `onDragStart(from, cell)` is called once when the drag crosses the\n * activation threshold. The caller should render the piece into the\n * drag layer (via React state) and imperatively hide the origin.\n * - `onDrop(from, to)` is called when a drop lands on a different square.\n * Illegal moves are the caller's problem — the hook merely reports the\n * user's intent.\n * - `onDragEnd()` is called on every terminal transition (drop, cancel,\n * same-square drop). The caller restores DOM opacity and clears the\n * drag-layer render state.\n */\n\nimport { type RefObject, useEffect, useRef } from \"react\";\nimport type { DragLayerHandle } from \"../components/drag-layer.js\";\nimport {\n type BoardCell,\n type BoardModel,\n createDragController,\n type SquareIndex,\n} from \"../core/index.js\";\nimport { CSS_VARS } from \"../default-theme.js\";\nimport { algebraicOf, getSquareAtPoint } from \"../lib/geometry.js\";\nimport type { Orientation } from \"../types.js\";\n\n/** CSS variable the theme uses to control drag-origin opacity. */\nconst GHOST_OPACITY_VAR = CSS_VARS.DRAG_GHOST_OPACITY;\n\n/** Options passed to {@link useDrag}. */\nexport interface UseDragOptions {\n readonly game: BoardModel | null;\n readonly orientation: Orientation;\n readonly containerRef: RefObject<HTMLElement | null>;\n /**\n * Imperative handle to the always-mounted drag overlay. `useDrag`\n * calls `show`, `setTransform`, and `hide` here from its pointer\n * handlers — zero React state changes during the drag loop (and\n * crucially, none at drag-start either).\n */\n readonly dragLayerRef: RefObject<DragLayerHandle | null>;\n readonly enabled: boolean;\n /** The activation distance (pixels) for `pending → dragging`. */\n readonly activationDistance?: number;\n /** Callbacks — see hook docs above. */\n readonly onDragStart: (from: SquareIndex, cell: BoardCell) => void;\n readonly onDragEnd: () => void;\n readonly onDrop: (from: SquareIndex, to: SquareIndex) => void;\n /**\n * Optional per-piece gate. If provided and it returns `false` for the\n * would-be drag source, pointer-down is silently ignored and no drag\n * initiates. Called once per attempt, never during a drag.\n */\n readonly canDragPiece?: (ctx: {\n readonly square: SquareIndex;\n readonly cell: BoardCell;\n }) => boolean;\n}\n\n/**\n * Install pointer listeners for drag-and-drop. Listeners stay registered for\n * the lifetime of the containing component.\n */\nexport function useDrag(options: UseDragOptions): void {\n const {\n game,\n orientation,\n containerRef,\n dragLayerRef,\n enabled,\n activationDistance,\n onDragStart,\n onDragEnd,\n onDrop,\n canDragPiece,\n } = options;\n\n // Latest-ref so the caller can pass a fresh predicate every render\n // without tearing down the pointer listeners. Absorbed here — not at\n // the call site — so consumers don't have to wrap every time.\n const canDragPieceRef = useRef(canDragPiece);\n useEffect(() => {\n canDragPieceRef.current = canDragPiece;\n });\n\n useEffect(() => {\n if (!enabled) return;\n const container = containerRef.current;\n if (container === null || game === null) return;\n\n const controller = createDragController(\n activationDistance === undefined ? {} : { activationDistance },\n );\n\n // Imperative drag internals. Mutating these does NOT re-render.\n let originEl: HTMLElement | null = null;\n let active = false;\n let activePointerId: number | null = null;\n\n const writeTransform = (clientX: number, clientY: number): void => {\n const layer = dragLayerRef.current;\n if (layer === null) return;\n const rect = container.getBoundingClientRect();\n const sqSize = rect.width / 8;\n // Centre the piece on the pointer.\n const x = clientX - rect.left - sqSize / 2;\n const y = clientY - rect.top - sqSize / 2;\n layer.setTransform(x, y);\n };\n\n const restoreOrigin = (): void => {\n if (originEl !== null) {\n originEl.style.opacity = \"\";\n originEl = null;\n }\n };\n\n const cleanup = (): void => {\n restoreOrigin();\n // Hide the ghost imperatively; no React state change.\n dragLayerRef.current?.hide();\n active = false;\n activePointerId = null;\n onDragEnd();\n };\n\n const onPointerDown = (e: PointerEvent): void => {\n // Primary button only. Right-clicks are reserved for arrows (M4).\n // Multi-touch is defended by drag-controller's pointerId tracking.\n if (e.button !== 0) return;\n const sq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (sq === null) return;\n const cell = game.getSnapshot().board[sq] ?? 0;\n if (cell === 0) return;\n // Caller-supplied gate. Fires on the cold activation path — never\n // during a drag — so the ref deref is free on the hot loop.\n const canDrag = canDragPieceRef.current;\n if (canDrag !== undefined && !canDrag({ square: sq, cell: cell as BoardCell })) {\n return;\n }\n const consumed = controller.pointerDown(sq, e.pointerId, e.clientX, e.clientY);\n if (consumed) activePointerId = e.pointerId;\n };\n\n const onPointerMove = (e: PointerEvent): void => {\n const evt = controller.pointerMove(e.pointerId, e.clientX, e.clientY);\n if (evt === null) return;\n\n if (evt.kind === \"drag-start\") {\n const cell = (game.getSnapshot().board[evt.from] ?? 0) as BoardCell;\n if (cell === 0) {\n // Piece disappeared between down and move — treat as cancel.\n controller.cancel();\n return;\n }\n // Fade the origin piece imperatively (no re-render). The target\n // opacity is sourced from `--gb-drag-ghost-opacity` on the board\n // container so themes control the look — `0` for chess.com's\n // vanish-on-drag, `0.35` for lichess-style translucent ghost.\n // Reading via `var(...)` inside the inline style keeps the value\n // live: users can toggle the CSS var and the next drag reflects\n // it without a remount.\n const originLabel = algebraicOf(evt.from);\n originEl = container.querySelector<HTMLElement>(`[data-piece-square=\"${originLabel}\"]`);\n if (originEl !== null) {\n // Fallback `0.35` matches the lichess convention and keeps the\n // behaviour correct when the caller swaps in a theme that\n // doesn't define the variable (theme records replace — not\n // merge with — the default theme).\n originEl.style.opacity = `var(${GHOST_OPACITY_VAR}, 0.35)`;\n }\n\n active = true;\n try {\n container.setPointerCapture(e.pointerId);\n } catch {\n // Some test environments don't support pointer capture; ignore.\n }\n\n // Show the ghost imperatively — no React state change, no\n // `flushSync`, no synchronous re-render of `<Chessboard/>`.\n // This is the fix that closes the 25 ms drag-peak gap with\n // chessground in real Chromium.\n dragLayerRef.current?.show(cell);\n writeTransform(e.clientX, e.clientY);\n\n // `onDragStart` still fires for callers that need to react\n // (clear arrows, set `selectSquare` to show legal targets,\n // analytics, haptic feedback, etc.) — but it no longer drives\n // the drag-layer visibility.\n onDragStart(evt.from, cell);\n return;\n }\n\n // drag-move: imperative only, no React involvement.\n writeTransform(e.clientX, e.clientY);\n };\n\n const onPointerUp = (e: PointerEvent): void => {\n const evt = controller.pointerUp(e.pointerId, e.clientX, e.clientY);\n if (evt === null) return;\n\n if (evt.kind === \"drop\") {\n const target = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (target !== null && target !== evt.from) {\n onDrop(evt.from, target);\n }\n }\n // \"click\" kind is ignored — Square.onClick handles simple clicks; the\n // browser only fires click if the pointer didn't move past threshold.\n\n if (active) cleanup();\n activePointerId = null;\n };\n\n const onPointerCancel = (e: PointerEvent): void => {\n if (activePointerId !== null && e.pointerId !== activePointerId) return;\n controller.cancel();\n if (active) cleanup();\n activePointerId = null;\n };\n\n // Passive listeners where possible; pointer-move gets `passive: true`\n // since we never call preventDefault inside.\n container.addEventListener(\"pointerdown\", onPointerDown);\n container.addEventListener(\"pointermove\", onPointerMove, { passive: true });\n container.addEventListener(\"pointerup\", onPointerUp);\n container.addEventListener(\"pointercancel\", onPointerCancel);\n\n return (): void => {\n container.removeEventListener(\"pointerdown\", onPointerDown);\n container.removeEventListener(\"pointermove\", onPointerMove);\n container.removeEventListener(\"pointerup\", onPointerUp);\n container.removeEventListener(\"pointercancel\", onPointerCancel);\n if (active) cleanup();\n };\n }, [\n game,\n orientation,\n containerRef,\n dragLayerRef,\n enabled,\n activationDistance,\n onDragStart,\n onDragEnd,\n onDrop,\n ]);\n}\n","\"use client\";\n\n/**\n * Per-square pointer-hover tracker.\n *\n * One `pointermove` + `pointerleave` listener on the container diffs the\n * current square against the previous, firing `onEnter`/`onLeave` once\n * per transition. Attaching handlers per-square would cost 64 React\n * listeners and break the \"0 re-renders per hover\" budget\n * (STANDARDS.md §4.2).\n *\n * Callbacks read through latest-refs so a fresh arrow function each\n * render doesn't re-install the effect.\n */\n\nimport { type RefObject, useEffect, useRef } from \"react\";\nimport type { BoardCell, BoardModel, SquareIndex } from \"../core/index.js\";\nimport { getSquareAtPoint } from \"../lib/geometry.js\";\nimport type { Orientation } from \"../types.js\";\n\n/** Context passed to hover callbacks. */\nexport interface HoverSquareContext {\n readonly square: SquareIndex;\n readonly cell: BoardCell;\n}\n\n/** Options for {@link useHoverSquare}. */\nexport interface UseHoverSquareOptions {\n readonly game: BoardModel | null;\n readonly orientation: Orientation;\n readonly containerRef: RefObject<HTMLElement | null>;\n readonly enabled: boolean;\n readonly onEnter?: (ctx: HoverSquareContext) => void;\n readonly onLeave?: (ctx: HoverSquareContext) => void;\n}\n\nexport function useHoverSquare(options: UseHoverSquareOptions): void {\n const { game, orientation, containerRef, enabled, onEnter, onLeave } = options;\n\n const onEnterRef = useRef(onEnter);\n const onLeaveRef = useRef(onLeave);\n useEffect(() => {\n onEnterRef.current = onEnter;\n onLeaveRef.current = onLeave;\n });\n\n useEffect(() => {\n if (!enabled) return;\n const container = containerRef.current;\n if (container === null) return;\n\n let current: SquareIndex | null = null;\n\n const cellAt = (sq: SquareIndex): BoardCell =>\n game === null ? (0 as BoardCell) : ((game.getSnapshot().board[sq] ?? 0) as BoardCell);\n\n const onPointerMove = (e: PointerEvent): void => {\n const sq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (sq === current) return;\n if (current !== null) onLeaveRef.current?.({ square: current, cell: cellAt(current) });\n if (sq !== null) onEnterRef.current?.({ square: sq, cell: cellAt(sq) });\n current = sq;\n };\n\n const onPointerLeave = (): void => {\n if (current === null) return;\n onLeaveRef.current?.({ square: current, cell: cellAt(current) });\n current = null;\n };\n\n container.addEventListener(\"pointermove\", onPointerMove, { passive: true });\n container.addEventListener(\"pointerleave\", onPointerLeave);\n\n return () => {\n container.removeEventListener(\"pointermove\", onPointerMove);\n container.removeEventListener(\"pointerleave\", onPointerLeave);\n if (current !== null) {\n onLeaveRef.current?.({ square: current, cell: cellAt(current) });\n current = null;\n }\n };\n }, [game, orientation, containerRef, enabled]);\n}\n","\"use client\";\n\n/**\n * Keyboard navigation for the 8×8 grid.\n *\n * Implements the WAI-ARIA \"Grid\" authoring pattern:\n *\n * - Tab brings focus to the board via a roving tabindex — only the\n * currently-focused square has `tabindex=0`; every other cell has\n * `tabindex=-1`, so Tab moves straight out of the grid once the user\n * is done.\n * - Arrow keys move the focus between squares (visual up/down/left/right,\n * orientation-aware).\n * - Enter / Space activate the focused square (same path as a mouse click).\n * - Escape clears the selection + any drawn arrows.\n * - Home / End jump to the first / last square in the focused rank.\n * - Ctrl+Home / Ctrl+End jump to the first / last square on the board.\n *\n * The hook is controlled: the caller owns `focusedSquare` state. This\n * lets {@link Chessboard} integrate the keyboard focus with other\n * board-level state (selection, drag, promotion dialog).\n */\n\nimport { type RefObject, useEffect } from \"react\";\nimport type { SquareIndex } from \"../core/index.js\";\nimport type { Orientation } from \"../types.js\";\n\n/**\n * Translate a visual direction into a new square index, honouring\n * orientation so arrow keys always move focus the way the user sees it.\n */\nfunction moveFocus(\n current: SquareIndex,\n direction: \"up\" | \"down\" | \"left\" | \"right\",\n orientation: Orientation,\n): SquareIndex {\n const file = current & 7;\n const rank = current >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n\n let newCol = col;\n let newRow = row;\n switch (direction) {\n case \"up\":\n newRow = Math.max(0, row - 1);\n break;\n case \"down\":\n newRow = Math.min(7, row + 1);\n break;\n case \"left\":\n newCol = Math.max(0, col - 1);\n break;\n case \"right\":\n newCol = Math.min(7, col + 1);\n break;\n }\n\n const newFile = orientation === \"white\" ? newCol : 7 - newCol;\n const newRank = orientation === \"white\" ? 7 - newRow : newRow;\n return (newRank * 8 + newFile) as SquareIndex;\n}\n\n/** Jump to the first / last file in the same rank as `current`, orientation-aware. */\nfunction rankEnd(\n current: SquareIndex,\n which: \"home\" | \"end\",\n orientation: Orientation,\n): SquareIndex {\n const rank = current >> 3;\n if (orientation === \"white\") {\n return ((rank << 3) | (which === \"home\" ? 0 : 7)) as SquareIndex;\n }\n return ((rank << 3) | (which === \"home\" ? 7 : 0)) as SquareIndex;\n}\n\n/** Jump to a board corner. */\nfunction boardCorner(which: \"home\" | \"end\", orientation: Orientation): SquareIndex {\n // \"home\" = visual top-left, \"end\" = visual bottom-right.\n if (orientation === \"white\") {\n return (which === \"home\" ? 56 : 7) as SquareIndex;\n }\n return (which === \"home\" ? 7 : 56) as SquareIndex;\n}\n\n/** Options accepted by {@link useKeyboardNav}. */\nexport interface UseKeyboardNavOptions {\n readonly containerRef: RefObject<HTMLElement | null>;\n readonly orientation: Orientation;\n readonly focusedSquare: SquareIndex | null;\n readonly setFocusedSquare: (square: SquareIndex) => void;\n readonly onActivate: (square: SquareIndex) => void;\n readonly onEscape: () => void;\n readonly enabled: boolean;\n}\n\n/**\n * Attach keyboard navigation listeners to the board container. All motion\n * is expressed via `setFocusedSquare` — the render layer is responsible\n * for applying `tabindex` and programmatic focus based on that state.\n */\nexport function useKeyboardNav(options: UseKeyboardNavOptions): void {\n const {\n containerRef,\n orientation,\n focusedSquare,\n setFocusedSquare,\n onActivate,\n onEscape,\n enabled,\n } = options;\n\n useEffect(() => {\n if (!enabled) return;\n const container = containerRef.current;\n if (container === null) return;\n\n const onKeyDown = (e: KeyboardEvent): void => {\n // Only consume keys if focus is somewhere inside our container —\n // otherwise a user typing in an unrelated input would have Tab or\n // Arrow keys hijacked.\n if (!container.contains(e.target as Node)) return;\n const current = focusedSquare;\n if (current === null) return;\n\n switch (e.key) {\n case \"ArrowUp\":\n e.preventDefault();\n setFocusedSquare(moveFocus(current, \"up\", orientation));\n return;\n case \"ArrowDown\":\n e.preventDefault();\n setFocusedSquare(moveFocus(current, \"down\", orientation));\n return;\n case \"ArrowLeft\":\n e.preventDefault();\n setFocusedSquare(moveFocus(current, \"left\", orientation));\n return;\n case \"ArrowRight\":\n e.preventDefault();\n setFocusedSquare(moveFocus(current, \"right\", orientation));\n return;\n case \"Home\":\n e.preventDefault();\n setFocusedSquare(\n e.ctrlKey || e.metaKey\n ? boardCorner(\"home\", orientation)\n : rankEnd(current, \"home\", orientation),\n );\n return;\n case \"End\":\n e.preventDefault();\n setFocusedSquare(\n e.ctrlKey || e.metaKey\n ? boardCorner(\"end\", orientation)\n : rankEnd(current, \"end\", orientation),\n );\n return;\n case \"Enter\":\n case \" \":\n e.preventDefault();\n onActivate(current);\n return;\n case \"Escape\":\n e.preventDefault();\n onEscape();\n return;\n default:\n return;\n }\n };\n\n container.addEventListener(\"keydown\", onKeyDown);\n return () => container.removeEventListener(\"keydown\", onKeyDown);\n }, [containerRef, orientation, focusedSquare, setFocusedSquare, onActivate, onEscape, enabled]);\n}\n","\"use client\";\n\n/**\n * `useLastMoveController` — imperative last-move tint paint.\n *\n * Mirror of `useSelectionController` for the from/to last-move\n * highlight. Previously rendered as `<LastMoveLayer/>`, a React\n * component that emitted two fresh `<div>` tints on every move\n * commit. Those two divs were real DOM + layout + paint work\n * inside the same commit as the move itself — which in Chromium\n * showed up as part of the \"drop frame\" peak during drag storms.\n *\n * The new controller:\n *\n * 1. Subscribes to the model via `model.subscribe` inside a\n * `useEffect`. Never calls `setState`, never triggers React.\n * 2. On each commit, derives `(from, to)` from `s.lastMove` and\n * diffs against the previously-painted pair.\n * 3. Writes `el.dataset.gbLastMove = \"from\" | \"to\"` on only the\n * changed squares — removing the attribute for squares that\n * are no longer either endpoint of the last move.\n * 4. CSS (injected once per document by `injectLastMoveStyles`)\n * paints a `::after` pseudo-element with the `--gb-last-move`\n * theme variable.\n *\n * Uses `::after` rather than `::before` because the selection\n * controller already owns `::before`. Paint order ends up\n * `background → selection tint (::before) → last-move tint\n * (::after)` — for the rare overlap where a square is both\n * selected AND one end of the last move, last-move paints on top.\n * That's a reversal of the old Chessboard JSX order, but the\n * visual difference between \"selection on top of last-move\" and\n * \"last-move on top of selection\" is imperceptible when both use\n * semi-transparent rgba tints.\n */\n\nimport { type RefObject, useEffect } from \"react\";\nimport { type BoardModel, isNullMove, type SquareIndex } from \"../core/index.js\";\n\n/** Values written to `data-gb-last-move`. */\ntype LastMoveState = \"from\" | \"to\";\n\n/** Singleton id used to dedupe the injected `<style>` element. */\nconst STYLE_ID = \"gb-last-move-styles\";\n\n/**\n * Inject the last-move CSS once per document. SSR-safe (early-returns).\n *\n * The `::after` pseudo-element is declared on EVERY square (with a\n * transparent background) rather than only when the attribute matches.\n * That pre-materialises 64 rendering nodes during mount — the same\n * trick used by the selection controller — so the user's first move\n * doesn't pay for first-match pseudo-element creation + first-paint of\n * the tint as an INP outlier. The `data-gb-last-move` attribute then\n * only changes `background`, which repaints an already-live node.\n */\nfunction injectLastMoveStyles(): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(STYLE_ID) !== null) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = `\n[data-gb-square]::after {\n content: \"\";\n position: absolute;\n inset: 0;\n background: transparent;\n pointer-events: none;\n}\n[data-gb-square][data-gb-last-move]::after {\n background: var(--gb-last-move);\n}\n`;\n document.head.appendChild(style);\n}\n\n/**\n * Imperatively paint the from/to tints of the most recent move.\n *\n * @param model The board model, or `null` while the engine is loading.\n * @param squareRefs 64-slot refs array from `<BoardGrid/>`. Each slot\n * is the DOM node of the square at that LERF index, or `null` if\n * unmounted.\n * @param enabled When `false`, the controller clears any existing\n * last-move tint and does nothing further. Matches the contract of\n * the old `highlightLastMove={false}` prop exactly.\n */\nexport function useLastMoveController(\n model: BoardModel | null,\n squareRefs: RefObject<Array<HTMLElement | null>>,\n enabled: boolean,\n): void {\n useEffect(() => {\n injectLastMoveStyles();\n }, []);\n\n useEffect(() => {\n if (model === null) return;\n\n // Track what we painted last so we diff-write only changes.\n let prevFrom: SquareIndex | null = null;\n let prevTo: SquareIndex | null = null;\n\n const write = (i: SquareIndex, val: LastMoveState | null): void => {\n const el = squareRefs.current?.[i];\n if (el === null || el === undefined) return;\n if (val === null) {\n delete el.dataset[\"gbLastMove\"];\n } else {\n el.dataset[\"gbLastMove\"] = val;\n }\n };\n\n const clearAll = (): void => {\n if (prevFrom !== null) write(prevFrom, null);\n if (prevTo !== null) write(prevTo, null);\n prevFrom = null;\n prevTo = null;\n };\n\n if (!enabled) {\n // Nothing to subscribe to — just make sure no stale tint remains.\n return clearAll;\n }\n\n const update = (): void => {\n const snap = model.getSnapshot();\n const lastMove = snap.lastMove;\n\n let from: SquareIndex | null = null;\n let to: SquareIndex | null = null;\n // A pass moves no piece, so it has no from/to to tint. Its sentinel\n // word would otherwise decode to h8→h8 and paint a highlight on a\n // square that never changed.\n if (lastMove !== null && !isNullMove(lastMove)) {\n from = (lastMove & 0x3f) as SquareIndex;\n to = ((lastMove >> 6) & 0x3f) as SquareIndex;\n }\n\n // Early exit when nothing changed.\n if (from === prevFrom && to === prevTo) return;\n\n // Clear any previous endpoint that isn't also one of the new\n // endpoints. (Castling / promotion can keep one endpoint and\n // change the other, so we can't wipe unconditionally.)\n if (prevFrom !== null && prevFrom !== from && prevFrom !== to) {\n write(prevFrom, null);\n }\n if (prevTo !== null && prevTo !== from && prevTo !== to) {\n write(prevTo, null);\n }\n\n // Paint current. If one square is both `from` and `to` (shouldn't\n // happen in normal play, but defensive), `to` wins — it's the\n // landing square.\n if (from !== null && from !== to) write(from, \"from\");\n if (to !== null) write(to, \"to\");\n\n prevFrom = from;\n prevTo = to;\n };\n\n update();\n const unsubscribe = model.subscribe(update);\n return () => {\n unsubscribe();\n clearAll();\n };\n }, [model, squareRefs, enabled]);\n}\n","\"use client\";\n\nimport type { HapticInput, TriggerOptions, WebHaptics } from \"web-haptics\";\n\nexport type { HapticInput, TriggerOptions };\n\nconst COARSE_POINTER_QUERY = \"(hover: none), (pointer: coarse)\";\n\nlet cached: WebHaptics | null | undefined;\nlet pending: Promise<WebHaptics | null> | null = null;\n\nfunction isCoarsePointer(): boolean {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return false;\n }\n return window.matchMedia(COARSE_POINTER_QUERY).matches;\n}\n\nfunction shouldRunHaptics(options: {\n readonly enabled?: boolean;\n readonly mobileOnly?: boolean;\n}): boolean {\n if (options.enabled === false) return false;\n if (options.mobileOnly === false) return true;\n return isCoarsePointer();\n}\n\nasync function getInstance(): Promise<WebHaptics | null> {\n if (cached !== undefined) {\n return cached;\n }\n if (pending !== null) {\n return pending;\n }\n if (typeof window === \"undefined\") {\n cached = null;\n return cached;\n }\n\n pending = import(\"web-haptics\")\n .then(({ WebHaptics }) => {\n try {\n cached = new WebHaptics();\n } catch {\n cached = null;\n }\n return cached;\n })\n .catch(() => {\n cached = null;\n return cached;\n })\n .finally(() => {\n pending = null;\n });\n\n return pending;\n}\n\nexport interface HapticFeedbackOptions extends TriggerOptions {\n /** Master switch. Default `true`. */\n readonly enabled?: boolean;\n /** Restrict haptics to coarse-pointer/mobile-like devices. Default `true`. */\n readonly mobileOnly?: boolean;\n}\n\nexport function triggerHaptic(input?: HapticInput, options: HapticFeedbackOptions = {}): void {\n if (!shouldRunHaptics(options)) {\n return;\n }\n const { enabled: _enabled, mobileOnly: _mobileOnly, ...triggerOptions } = options;\n void getInstance().then((instance) => {\n void instance?.trigger(input, triggerOptions);\n });\n}\n\nexport function warmupHaptics(options: HapticFeedbackOptions = {}): void {\n if (!shouldRunHaptics(options)) {\n return;\n }\n void getInstance();\n}\n","\"use client\";\n\nimport type { HapticInput } from \"web-haptics\";\n\n/** The shared move-feedback cue categories. */\nexport type MoveFeedbackKey =\n | \"moveSelf\"\n | \"moveOpponent\"\n | \"capture\"\n | \"castle\"\n | \"moveCheck\"\n | \"promote\"\n | \"gameEnd\";\n\n/** Default haptic pattern per move-feedback cue. */\nexport const DEFAULT_MOVE_HAPTIC_PATTERNS: Readonly<Record<MoveFeedbackKey, HapticInput>> =\n Object.freeze({\n moveSelf: \"selection\",\n moveOpponent: \"selection\",\n capture: \"medium\",\n castle: \"medium\",\n moveCheck: \"success\",\n promote: \"success\",\n gameEnd: \"success\",\n });\n\n/**\n * Classify the feedback cue that should fire for the given committed move.\n *\n * Priority (highest wins):\n * 1. `gameEnd` if the engine reports `isGameOver`.\n * 2. `promote` / `castle` because structural moves get their own cue.\n * 3. `moveCheck` if the side-to-move is now in check.\n * 4. `capture` if any descriptor is a capture.\n * 5. `moveSelf` / `moveOpponent` otherwise.\n */\nexport function classifyMoveFeedback(\n animations: ReadonlyArray<{ readonly kind: string }>,\n snapshot: { readonly isGameOver: boolean; readonly inCheck: boolean; readonly turn: 0 | 1 },\n perspective: 0 | 1 | undefined,\n): MoveFeedbackKey {\n if (snapshot.isGameOver) return \"gameEnd\";\n\n let sawPromotion = false;\n let sawCastle = false;\n let sawCapture = false;\n for (const d of animations) {\n if (d.kind === \"promotion\") sawPromotion = true;\n else if (d.kind === \"castle\") sawCastle = true;\n else if (d.kind === \"capture\" || d.kind === \"en-passant\") sawCapture = true;\n }\n\n if (sawPromotion) return \"promote\";\n if (sawCastle) return \"castle\";\n if (snapshot.inCheck) return \"moveCheck\";\n if (sawCapture) return \"capture\";\n\n // The side that just moved is the opposite of the new side-to-move.\n if (perspective !== undefined) {\n const moverWasMe = snapshot.turn !== perspective;\n return moverWasMe ? \"moveSelf\" : \"moveOpponent\";\n }\n return \"moveSelf\";\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef } from \"react\";\nimport type { BoardModel } from \"../core/index.js\";\nimport {\n type HapticFeedbackOptions,\n type HapticInput,\n triggerHaptic,\n warmupHaptics,\n} from \"../lib/haptics.js\";\nimport {\n classifyMoveFeedback,\n DEFAULT_MOVE_HAPTIC_PATTERNS,\n type MoveFeedbackKey,\n} from \"../lib/move-feedback.js\";\n\nexport type MoveHapticKey = MoveFeedbackKey;\nexport type MoveHapticPatterns = Partial<Readonly<Record<MoveHapticKey, HapticInput>>>;\nexport type TriggerMoveHaptic = (key: MoveHapticKey) => void;\n\nexport interface MoveHapticOptions {\n /** Master switch. Default `true`. */\n readonly enabled?: boolean;\n /** Per-key haptic overrides. Missing keys fall back to the built-in pattern map. */\n readonly patterns?: MoveHapticPatterns;\n /**\n * Viewer perspective. When set, moves played by this colour use `moveSelf`\n * and moves played by the opponent use `moveOpponent`.\n */\n readonly perspective?: 0 | 1;\n /** Restrict haptics to coarse-pointer/mobile-like devices. Default `true`. */\n readonly mobileOnly?: boolean;\n /** Minimum gap between emitted haptic events. Default `14ms`. */\n readonly minIntervalMs?: number;\n /** Warm the haptic backend on the first user gesture. Default `true`. */\n readonly warmupOnFirstInteraction?: boolean;\n /** Forwarded to `web-haptics` trigger intensity. */\n readonly intensity?: HapticFeedbackOptions[\"intensity\"];\n}\n\nconst DEFAULT_MIN_INTERVAL_MS = 14;\n\nexport function triggerMoveHaptic(\n key: MoveHapticKey,\n {\n enabled = true,\n patterns,\n mobileOnly = true,\n intensity,\n }: Pick<MoveHapticOptions, \"enabled\" | \"patterns\" | \"mobileOnly\" | \"intensity\"> = {},\n): void {\n if (!enabled) {\n return;\n }\n const input = patterns?.[key] ?? DEFAULT_MOVE_HAPTIC_PATTERNS[key];\n triggerHaptic(input, {\n enabled,\n mobileOnly,\n ...(intensity !== undefined ? { intensity } : {}),\n });\n}\n\nexport function useMoveHaptics(\n model: BoardModel | null,\n options: MoveHapticOptions = {},\n): TriggerMoveHaptic {\n const {\n enabled = true,\n patterns,\n perspective,\n mobileOnly = true,\n minIntervalMs = DEFAULT_MIN_INTERVAL_MS,\n warmupOnFirstInteraction = true,\n intensity,\n } = options;\n\n const patternsRef = useRef(patterns);\n useEffect(() => {\n patternsRef.current = patterns;\n });\n\n const perspectiveRef = useRef(perspective);\n useEffect(() => {\n perspectiveRef.current = perspective;\n });\n\n const mobileOnlyRef = useRef(mobileOnly);\n useEffect(() => {\n mobileOnlyRef.current = mobileOnly;\n });\n\n const intensityRef = useRef(intensity);\n useEffect(() => {\n intensityRef.current = intensity;\n });\n\n const lastTriggerAtRef = useRef(0);\n\n const trigger = useCallback<TriggerMoveHaptic>(\n (key) => {\n triggerMoveHaptic(key, {\n enabled,\n ...(patternsRef.current !== undefined ? { patterns: patternsRef.current } : {}),\n mobileOnly: mobileOnlyRef.current,\n ...(intensityRef.current !== undefined ? { intensity: intensityRef.current } : {}),\n });\n },\n [enabled],\n );\n\n useEffect(() => {\n if (!enabled || !warmupOnFirstInteraction) {\n return;\n }\n\n let warmed = false;\n const warmup = () => {\n if (warmed) {\n return;\n }\n warmed = true;\n warmupHaptics({ mobileOnly: mobileOnlyRef.current });\n window.removeEventListener(\"pointerdown\", warmup, true);\n window.removeEventListener(\"touchstart\", warmup, true);\n window.removeEventListener(\"keydown\", warmup, true);\n };\n\n window.addEventListener(\"pointerdown\", warmup, { capture: true, passive: true });\n window.addEventListener(\"touchstart\", warmup, { capture: true, passive: true });\n window.addEventListener(\"keydown\", warmup, { capture: true });\n\n return () => {\n window.removeEventListener(\"pointerdown\", warmup, true);\n window.removeEventListener(\"touchstart\", warmup, true);\n window.removeEventListener(\"keydown\", warmup, true);\n };\n }, [enabled, warmupOnFirstInteraction]);\n\n useEffect(() => {\n if (!enabled || model === null) return;\n\n let prevPly = model.getSnapshot().historyPly;\n\n return model.subscribe(() => {\n const snap = model.getSnapshot();\n if (snap.historyPly <= prevPly) {\n prevPly = snap.historyPly;\n return;\n }\n prevPly = snap.historyPly;\n\n const nowMs = performance.now();\n if (nowMs - lastTriggerAtRef.current < minIntervalMs) {\n return;\n }\n lastTriggerAtRef.current = nowMs;\n\n const key = classifyMoveFeedback(model.lastAnimations, snap, perspectiveRef.current);\n trigger(key);\n });\n }, [enabled, minIntervalMs, model, trigger]);\n\n return trigger;\n}\n","\"use client\";\n\n/**\n * `useMoveSound` — drop-in chess.com-style move-sound effects.\n *\n * Plays one short audio cue on every committed move. The sound is picked\n * from the just-emitted `lastAnimations` descriptors and the post-move\n * snapshot, not from SAN — so the same hook works for drag, click,\n * keyboard, and `tryMove` invocations without any integration boilerplate.\n *\n * ### Design choices\n *\n * 1. **Local assets by default.** The seven chess.com MP3s ship in-package\n * (see `src/sounds/`). Users may override any URL via the `sources`\n * option — set one, set all, or set none. No runtime CDN dependency.\n * 2. **One pool per sound.** Each sound gets a {@link POOL_SIZE}-element\n * pool of `HTMLAudioElement` so rapid-fire clicks don't cut each other\n * off (the browser serializes `.play()` on a single element).\n * 3. **One cue per committed move.** We only fire when `historyPly`\n * advances. Undo / redo-to-same-state is silent (matches chess.com).\n * 4. **SSR-safe.** `new Audio()` is guarded behind a `typeof window`\n * check; the hook does nothing on the server.\n * 5. **`enabled={false}` zeroes all work.** No pool, no subscription, no\n * allocation — pass `false` and the hook returns without side effects.\n *\n * The hook is self-contained: it does not call into the engine adapter,\n * it does not need `san()`, and it will not re-render the component.\n */\n\nimport { useCallback, useEffect, useRef } from \"react\";\nimport type { BoardModel } from \"../core/index.js\";\nimport { classifyMoveFeedback, type MoveFeedbackKey } from \"../lib/move-feedback.js\";\n\n/** The seven categories of move cue, mirroring chess.com's default set. */\nexport type MoveSoundKey = MoveFeedbackKey;\n\n/** Sparse URL map — any key omitted falls back to the built-in local asset. */\nexport type MoveSoundSources = Partial<Readonly<Record<MoveSoundKey, string>>>;\nexport type TriggerMoveSound = (key: MoveSoundKey) => void;\n\n/**\n * Default URL map. Points at the MP3 files shipped with this package; the\n * package build copies them next to the emitted JS under `dist/sounds/`.\n * Keeping these as static `new URL(..., import.meta.url)` expressions lets\n * consumer bundlers such as Vite and Next.js rebase/copy the files correctly.\n *\n * The `typeof import.meta.url` guard keeps the CommonJS build importable in\n * Node; browser ESM consumers get the fully resolved asset URLs.\n */\nexport const DEFAULT_MOVE_SOUND_SOURCES: Readonly<Record<MoveSoundKey, string>> = Object.freeze({\n moveSelf:\n typeof import.meta.url === \"string\"\n ? new URL(\"./sounds/move-self.mp3\", import.meta.url).href\n : \"./sounds/move-self.mp3\",\n moveOpponent:\n typeof import.meta.url === \"string\"\n ? new URL(\"./sounds/move-opponent.mp3\", import.meta.url).href\n : \"./sounds/move-opponent.mp3\",\n capture:\n typeof import.meta.url === \"string\"\n ? new URL(\"./sounds/capture.mp3\", import.meta.url).href\n : \"./sounds/capture.mp3\",\n castle:\n typeof import.meta.url === \"string\"\n ? new URL(\"./sounds/castle.mp3\", import.meta.url).href\n : \"./sounds/castle.mp3\",\n moveCheck:\n typeof import.meta.url === \"string\"\n ? new URL(\"./sounds/move-check.mp3\", import.meta.url).href\n : \"./sounds/move-check.mp3\",\n promote:\n typeof import.meta.url === \"string\"\n ? new URL(\"./sounds/promote.mp3\", import.meta.url).href\n : \"./sounds/promote.mp3\",\n gameEnd:\n typeof import.meta.url === \"string\"\n ? new URL(\"./sounds/game-end.mp3\", import.meta.url).href\n : \"./sounds/game-end.mp3\",\n});\n\n/** Public configuration for the hook (and the `<Chessboard sound/>` prop). */\nexport interface MoveSoundOptions {\n /** Master switch. Default `true`. */\n readonly enabled?: boolean;\n /** Output volume, `0`–`1`. Default `1`. */\n readonly volume?: number;\n /** Audio preload mode used when the lazy pool is first created. Default `\"none\"`. */\n readonly preload?: \"none\" | \"metadata\" | \"auto\";\n /** Per-key URL overrides. Missing keys fall back to {@link DEFAULT_MOVE_SOUND_SOURCES}. */\n readonly sources?: MoveSoundSources;\n /**\n * Viewer perspective. When set, moves played *by* this colour use the\n * `moveSelf` cue and moves played by the opponent use `moveOpponent`. When\n * omitted (the default), every non-special move uses `moveSelf`.\n */\n readonly perspective?: 0 | 1;\n}\n\n/** How many audio elements per category. Four is enough for spam-clicking. */\nconst POOL_SIZE = 4;\n\n/** Internal per-category pool record. */\ntype Pool = {\n readonly elements: HTMLAudioElement[];\n cursor: number;\n};\n\nfunction createPools(\n sources: Readonly<Record<MoveSoundKey, string>>,\n preload: MoveSoundOptions[\"preload\"],\n): Record<MoveSoundKey, Pool> {\n const pools = {} as Record<MoveSoundKey, Pool>;\n for (const key of Object.keys(sources) as MoveSoundKey[]) {\n const url = sources[key];\n const elements: HTMLAudioElement[] = [];\n for (let i = 0; i < POOL_SIZE; i++) {\n const audio = new Audio(url);\n audio.preload = preload ?? \"none\";\n elements.push(audio);\n }\n pools[key] = { elements, cursor: 0 };\n }\n return pools;\n}\n\n/**\n * Drop-in hook. Mount inside a React tree that has a `BoardModel`. Pass\n * `null` while the engine is still loading — the hook no-ops until the\n * model is available.\n *\n * @example\n * ```tsx\n * useMoveSound(game, { enabled: soundOn, volume: 0.6 });\n * ```\n */\nexport function useMoveSound(\n model: BoardModel | null,\n options: MoveSoundOptions = {},\n): TriggerMoveSound {\n const { enabled = true, volume = 1, preload = \"none\", sources, perspective } = options;\n\n const poolsRef = useRef<Record<MoveSoundKey, Pool> | null>(null);\n const sourcesRef = useRef<Readonly<Record<MoveSoundKey, string>>>(DEFAULT_MOVE_SOUND_SOURCES);\n const preloadRef = useRef(preload);\n\n // Keep a latest-value ref for volume so the pool doesn't tear down\n // every time the slider moves — we just update each element's volume\n // at play time.\n const volumeRef = useRef(volume);\n useEffect(() => {\n volumeRef.current = volume;\n });\n\n const perspectiveRef = useRef(perspective);\n useEffect(() => {\n perspectiveRef.current = perspective;\n });\n\n useEffect(() => {\n sourcesRef.current = {\n ...DEFAULT_MOVE_SOUND_SOURCES,\n ...(sources ?? {}),\n };\n poolsRef.current = null;\n }, [sources]);\n\n useEffect(() => {\n preloadRef.current = preload;\n poolsRef.current = null;\n }, [preload]);\n\n useEffect(() => {\n if (!enabled) {\n poolsRef.current = null;\n }\n }, [enabled]);\n\n const triggerMoveSound = useCallback<TriggerMoveSound>(\n (key) => {\n if (!enabled) return;\n if (typeof window === \"undefined\") return; // SSR guard.\n if (typeof Audio === \"undefined\") return; // happy-dom lacks Audio.\n\n const pools = poolsRef.current ?? createPools(sourcesRef.current, preloadRef.current);\n poolsRef.current = pools;\n\n const pool = pools[key];\n if (pool === undefined) return;\n\n pool.cursor = (pool.cursor + 1) % pool.elements.length;\n const el = pool.elements[pool.cursor];\n if (el === undefined) return;\n el.volume = Math.max(0, Math.min(1, volumeRef.current));\n el.currentTime = 0;\n // Some browsers reject autoplay before a user gesture. Swallow the\n // rejection — once the user interacts, subsequent plays succeed.\n void el.play().catch(() => {\n /* autoplay blocked — will resolve after the first user gesture. */\n });\n },\n [enabled],\n );\n\n // Subscribe to the model. Fire the chosen cue on every commit that\n // increments `historyPly` (forward moves only — undo is silent, matching\n // chess.com). The subscription is cheap: one `subscribe` per enabled\n // mount and zero re-renders.\n useEffect(() => {\n if (!enabled || model === null) return;\n\n let prevPly = model.getSnapshot().historyPly;\n\n return model.subscribe(() => {\n const snap = model.getSnapshot();\n if (snap.historyPly <= prevPly) {\n prevPly = snap.historyPly;\n return;\n }\n prevPly = snap.historyPly;\n\n const key = classifyMoveFeedback(model.lastAnimations, snap, perspectiveRef.current);\n triggerMoveSound(key);\n });\n }, [enabled, model, triggerMoveSound]);\n\n return triggerMoveSound;\n}\n","\"use client\";\n\n/**\n * `useSelectionController` — imperative selection + legal-target paint.\n *\n * ### Why this exists\n *\n * The prior `<SelectionLayer/>` React component rendered fresh DOM\n * nodes (one tint + N legal-target markers) every time `selected` or\n * `legalTargets` changed. That's cheap in isolation, but during the\n * drag-start frame — where the pointermove handler also calls\n * `game.selectSquare(from)` — it compounds with React reconciliation\n * and the browser's layout/paint for the new nodes. In real Chromium\n * under 4× CPU throttle, that frame was a 25 ms spike (vs chessground's\n * 9 ms).\n *\n * This controller replaces that entirely. It:\n *\n * 1. Subscribes to the model via `model.subscribe(...)` inside a\n * `useEffect` — never calls `setState`, never triggers React.\n * 2. On each commit, computes the diff between\n * `(prev.selected, prev.legalTargets)` and\n * `(next.selected, next.legalTargets)`.\n * 3. Writes `el.dataset.gbSelection = \"selected\" | \"legal-quiet\" |\n * \"legal-capture\" | \"none\"` on only the squares whose state\n * changed, using the 64-slot ref array from `<BoardGrid/>`.\n * 4. CSS (injected by `injectSelectionStyles` below) paints the\n * overlay on each square via a `::before` pseudo-element.\n *\n * Result: selection changes cost one or two data-attribute writes per\n * affected square — pure browser-level work, no React, no new DOM,\n * no layout. Matches chessground's class-toggle strategy.\n */\n\nimport { type RefObject, useEffect } from \"react\";\nimport type { BoardModel, SquareIndex } from \"../core/index.js\";\nimport type { LegalTargetStyle } from \"../types.js\";\n\n/**\n * Values written to `data-gb-selection`.\n *\n * - `selected` — the from-square of a pending move.\n * - `legal-quiet` — a legal target with no capture.\n * - `legal-capture` — a legal target on an occupied square.\n * - `none` — no highlight.\n */\ntype SelectionState = \"none\" | \"selected\" | \"legal-quiet\" | \"legal-capture\";\n\n/** Singleton id used to dedupe the injected `<style>` element. */\nconst STYLE_ID = \"gb-selection-styles\";\n\n/**\n * Inject the selection CSS once per document. SSR-safe (early-returns).\n *\n * ### First-click INP: why `::before` is declared on EVERY square\n *\n * The earlier design declared `::before` only on squares currently\n * carrying `data-gb-selection`. That saves 64 pseudo-element nodes\n * at mount but costs the browser a first-match materialisation pass\n * on the user's very first click: when the attribute appears on a\n * square for the first time, Chromium creates the ::before rendering\n * node AND does its first paint of the radial gradient. The cost\n * shows up as a 20-30 ms INP outlier — visible in the bench's p99\n * per-click number and a major share of Ultra's \"worst click\" INP\n * reading.\n *\n * We now declare a universal `::before` on every `[data-gb-square]`\n * with a transparent background; the selection attribute only\n * changes `background` / `background-image`. All 64 pseudo-element\n * rendering nodes are materialised during cold mount, where their\n * ~0.5 ms cost is invisible inside the larger first-paint work.\n * Subsequent clicks only repaint the already-materialised nodes —\n * eliminating the INP outlier without any per-move cost.\n */\nfunction injectSelectionStyles(): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(STYLE_ID) !== null) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = `\n[data-gb-square]::before {\n content: \"\";\n position: absolute;\n inset: 0;\n background: transparent;\n pointer-events: none;\n}\n[data-gb-square][data-gb-selection=\"selected\"]::before {\n background: var(--gb-selected);\n}\n[data-gb-square][data-gb-selection=\"legal-quiet\"]::before {\n background-image: radial-gradient(var(--gb-legal-target) 22%, transparent 24%);\n}\n[data-gb-square][data-gb-selection=\"legal-capture\"]::before {\n background-image: radial-gradient(transparent 0 75%, var(--gb-legal-target-capture) 77% 83%, transparent 85%);\n}\n[data-gb-target-style=\"dots\"] [data-gb-square][data-gb-selection=\"legal-quiet\"]::before {\n background-image: radial-gradient(var(--gb-legal-target) 14%, transparent 16%);\n}\n[data-gb-target-style=\"dots\"] [data-gb-square][data-gb-selection=\"legal-capture\"]::before {\n background-image: radial-gradient(var(--gb-legal-target-capture) 20%, transparent 22%);\n}\n`;\n document.head.appendChild(style);\n}\n\n/**\n * Imperatively paint selection + legal-target highlights.\n *\n * @param model The board model, or `null` while the engine is loading.\n * @param squareRefs 64-slot refs array. Each slot is the DOM node of\n * the square at that LERF index, or `null` if unmounted.\n * @param style Rendering style for legal targets. `false` suppresses\n * the overlay entirely; `\"rings\"` (default) and `\"dots\"` are picked\n * up by the board container's `data-gb-target-style` attribute.\n */\nexport function useSelectionController(\n model: BoardModel | null,\n squareRefs: RefObject<Array<HTMLElement | null>>,\n style: LegalTargetStyle,\n): void {\n useEffect(() => {\n injectSelectionStyles();\n }, []);\n\n useEffect(() => {\n if (model === null) return;\n\n // Track what we painted last so we can diff-write only changes.\n let prevSelected: SquareIndex | null = null;\n let prevTargets: ReadonlySet<SquareIndex> = new Set();\n\n const write = (i: SquareIndex, val: SelectionState): void => {\n const el = squareRefs.current?.[i];\n if (el === null || el === undefined) return;\n if (val === \"none\") {\n delete el.dataset[\"gbSelection\"];\n } else {\n el.dataset[\"gbSelection\"] = val;\n }\n };\n\n const clear = (): void => {\n if (prevSelected !== null) write(prevSelected, \"none\");\n for (const sq of prevTargets) write(sq, \"none\");\n prevSelected = null;\n prevTargets = new Set();\n };\n\n const update = (): void => {\n const snap = model.getSnapshot();\n const { selected, legalTargets, board } = snap;\n\n // When the caller disables target rendering, keep the selected\n // tint but hide legal targets — same contract the old component\n // had with `style === false`.\n if (style === false) {\n // Clear any old targets.\n for (const sq of prevTargets) {\n if (sq !== selected) write(sq, \"none\");\n }\n // Adjust selected highlight.\n if (prevSelected !== null && prevSelected !== selected) {\n write(prevSelected, \"none\");\n }\n if (selected !== null) write(selected, \"selected\");\n prevSelected = selected;\n prevTargets = new Set();\n return;\n }\n\n // Identity-compare: the store guarantees stable `selected` and\n // `legalTargets` refs when nothing changed, so most commits land\n // here and return instantly.\n if (selected === prevSelected && legalTargets === prevTargets) return;\n\n // Clear squares that were previously highlighted but no longer are.\n if (prevSelected !== null && prevSelected !== selected && !legalTargets.has(prevSelected)) {\n write(prevSelected, \"none\");\n }\n for (const sq of prevTargets) {\n if (sq !== selected && !legalTargets.has(sq)) write(sq, \"none\");\n }\n\n // Paint current highlights.\n if (selected !== null) write(selected, \"selected\");\n for (const sq of legalTargets) {\n if (sq === selected) continue;\n const targetCell = board[sq] ?? 0;\n write(sq, targetCell === 0 ? \"legal-quiet\" : \"legal-capture\");\n }\n\n prevSelected = selected;\n prevTargets = legalTargets;\n };\n\n update();\n const unsubscribe = model.subscribe(update);\n return () => {\n unsubscribe();\n clear();\n };\n }, [model, squareRefs, style]);\n}\n","\"use client\";\n\n/**\n * The top-level interactive board.\n *\n * Composes the static grid, piece layer, highlight layers, coordinate\n * overlay, drag layer, arrow overlay, and promotion overlay into a single\n * `position: relative; aspect-ratio: 1/1` container. Theme variables are\n * written inline on the container so they land at first paint without\n * needing an effect — SSR-safe and hydration-clean.\n *\n * The board is a client component. For a server-rendered static board\n * (zero client JS), import from `gigaboard/server` (M5).\n */\n\nimport {\n type CSSProperties,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { ArrowsLayer, type ArrowsLayerHandle } from \"./components/arrows-layer.js\";\nimport { BoardGrid } from \"./components/board-grid.js\";\nimport { CheckLayer } from \"./components/check-layer.js\";\nimport { Coordinates } from \"./components/coordinates.js\";\nimport { DragLayer, type DragLayerHandle } from \"./components/drag-layer.js\";\nimport { IllegalFlashLayer } from \"./components/illegal-flash-layer.js\";\nimport { LiveRegion } from \"./components/live-region.js\";\nimport { PieceLayer } from \"./components/piece-layer.js\";\nimport { PremoveLayer } from \"./components/premove-layer.js\";\nimport { PromotionOverlay } from \"./components/promotion-overlay.js\";\nimport { StaticPieceLayer } from \"./components/static-piece-layer.js\";\nimport {\n type BoardCell,\n colorOf,\n isEmptyCell,\n isNullMoveUci,\n type PieceType,\n pieceTypeOf,\n type SquareIndex,\n} from \"./core/index.js\";\nimport { defaultArrowColors, defaultTheme } from \"./default-theme.js\";\nimport { parseFenPlacement } from \"./fen.js\";\nimport { AnimationRunner } from \"./hooks/use-animation.js\";\nimport { useArrowGesture } from \"./hooks/use-arrow-gesture.js\";\nimport { useClickToMove } from \"./hooks/use-click-to-move.js\";\nimport { useCursorController } from \"./hooks/use-cursor-controller.js\";\nimport { useDrag } from \"./hooks/use-drag.js\";\nimport { useHoverSquare } from \"./hooks/use-hover-square.js\";\nimport { useKeyboardNav } from \"./hooks/use-keyboard-nav.js\";\nimport { useLastMoveController } from \"./hooks/use-last-move-controller.js\";\nimport { type MoveHapticOptions, useMoveHaptics } from \"./hooks/use-move-haptics.js\";\nimport { type MoveSoundOptions, useMoveSound } from \"./hooks/use-move-sound.js\";\nimport { useSelectionController } from \"./hooks/use-selection-controller.js\";\nimport { getSquareAtPoint } from \"./lib/geometry.js\";\nimport { classifyMoveFeedback } from \"./lib/move-feedback.js\";\nimport { defaultPieces } from \"./pieces/default-pieces.js\";\nimport type {\n AnimationOptions,\n ArrowColors,\n ChessboardProps,\n Orientation,\n PositionTransition,\n ResolvedArrowPalette,\n} from \"./types.js\";\n\n/** Internal record describing a pending promotion. */\ninterface PendingPromotion {\n readonly from: SquareIndex;\n readonly to: SquareIndex;\n readonly color: 0 | 1;\n readonly resolve: (piece: PieceType) => void;\n readonly cancel: () => void;\n}\n\n/** Interior colour-of from a cell code. Empty cell returns `0` defensively. */\nfunction colorOfCell(cell: number): 0 | 1 {\n return (cell > 6 ? 1 : 0) as 0 | 1;\n}\n\n/** Is `(from → to)` a pawn promotion given the current position? */\nfunction movePromotesPawn(fromCell: number, to: SquareIndex): boolean {\n if (fromCell === 0) return false;\n const pieceType = (fromCell - 1) % 6;\n if (pieceType !== 0 /* Pawn */) return false;\n const toRank = to >> 3;\n return toRank === 0 || toRank === 7;\n}\n\n/** Flash duration — must outlive the WAAPI animation in IllegalFlashLayer. */\nconst ILLEGAL_FLASH_HOLD_MS = 320;\n\nconst DEFAULT_POSITION_SYNC_DURATION_MS = 60;\nconst DEFAULT_POSITION_SYNC_EASING = \"cubic-bezier(0.22, 0.61, 0.36, 1)\";\nconst UCI_TRANSITION_RE = /^([a-h][1-8])([a-h][1-8])([nbrq])?$/i;\n\n/**\n * A pass is spelled `\"0000\"` in UCI. It never matches {@link UCI_TRANSITION_RE}\n * — there is no square to glide between — so the transition contributes no\n * square animations and no feedback descriptor. Recognised explicitly rather\n * than left to fall through on the regex miss, so the intent is pinned.\n */\nfunction isNullTransition(transition: PositionTransition): boolean {\n return isNullMoveUci(transition.uci);\n}\n\ninterface SquareTransition {\n readonly from: string;\n readonly to: string;\n}\n\ninterface ParsedTransitionMove {\n readonly from: SquareIndex;\n readonly to: SquareIndex;\n readonly promotion: string | null;\n}\n\ninterface FeedbackDescriptor {\n readonly kind: string;\n}\n\nfunction prefersReducedMotion(): boolean {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return false;\n }\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\nfunction cancelElementAnimations(element: HTMLElement): void {\n if (typeof element.getAnimations !== \"function\") return;\n for (const anim of element.getAnimations()) anim.cancel();\n}\n\nfunction queryPieceAt(container: HTMLElement, square: string): HTMLElement | null {\n return container.querySelector<HTMLElement>(`[data-piece-square=\"${square}\"]`);\n}\n\nfunction squareIndexOfName(square: string): SquareIndex {\n const file = square.charCodeAt(0) - 0x61;\n const rank = Number(square[1]) - 1;\n return ((rank << 3) | file) as SquareIndex;\n}\n\nfunction deltaFromSquareNames(\n from: string,\n to: string,\n squareSize: number,\n orientation: Orientation,\n): { dx: number; dy: number } {\n const fromIndex = squareIndexOfName(from);\n const toIndex = squareIndexOfName(to);\n const fromFile = fromIndex & 7;\n const fromRank = fromIndex >> 3;\n const toFile = toIndex & 7;\n const toRank = toIndex >> 3;\n const fromCol = orientation === \"white\" ? fromFile : 7 - fromFile;\n const fromRow = orientation === \"white\" ? 7 - fromRank : fromRank;\n const toCol = orientation === \"white\" ? toFile : 7 - toFile;\n const toRow = orientation === \"white\" ? 7 - toRank : toRank;\n return {\n dx: (fromCol - toCol) * squareSize,\n dy: (fromRow - toRow) * squareSize,\n };\n}\n\nfunction castleRookTransition(from: string, to: string): SquareTransition | null {\n const fromFile = from.charCodeAt(0);\n const toFile = to.charCodeAt(0);\n if (fromFile !== 0x65 /* e */ || Math.abs(toFile - fromFile) !== 2) return null;\n const rank = from[1];\n if (rank !== \"1\" && rank !== \"8\") return null;\n const kingSide = toFile > fromFile;\n return {\n from: `${kingSide ? \"h\" : \"a\"}${rank}`,\n to: `${kingSide ? \"f\" : \"d\"}${rank}`,\n };\n}\n\nfunction transitionSquares(transition: PositionTransition): SquareTransition[] {\n // A pass moves nothing: no square animations.\n if (isNullTransition(transition)) return [];\n const parsed = UCI_TRANSITION_RE.exec(transition.uci.trim().toLowerCase());\n if (parsed === null) return [];\n\n const moveFrom = parsed[1] ?? \"\";\n const moveTo = parsed[2] ?? \"\";\n const forward: SquareTransition[] = [{ from: moveFrom, to: moveTo }];\n const rook = castleRookTransition(moveFrom, moveTo);\n if (rook !== null) forward.push(rook);\n\n return transition.direction === \"forward\"\n ? forward\n : forward.map((item) => ({ from: item.to, to: item.from }));\n}\n\nfunction parseTransitionMove(transition: PositionTransition): ParsedTransitionMove | null {\n // A pass has no from/to; reporting `null` keeps it out of capture /\n // promotion / castle classification.\n if (isNullTransition(transition)) return null;\n const parsed = UCI_TRANSITION_RE.exec(transition.uci.trim().toLowerCase());\n if (parsed === null) return null;\n const from = parsed[1];\n const to = parsed[2];\n if (from === undefined || to === undefined) return null;\n return {\n from: squareIndexOfName(from),\n to: squareIndexOfName(to),\n promotion: parsed[3] ?? null,\n };\n}\n\nfunction isPawn(cell: BoardCell): boolean {\n return !isEmptyCell(cell) && pieceTypeOf(cell) === 0;\n}\n\nfunction controlledFeedbackDescriptors(\n transition: PositionTransition | null | undefined,\n previousBoard: Readonly<Uint8Array>,\n nextBoard: Readonly<Uint8Array>,\n): FeedbackDescriptor[] | null {\n if (transition === null || transition === undefined) return null;\n\n const parsed = parseTransitionMove(transition);\n if (parsed === null) return null;\n\n // Classify the original chess move even while replaying backward. The\n // post-sync snapshot is \"before\" the move in that case, so swap the board\n // pair back into original move order before inspecting capture/promotion.\n const before = transition.direction === \"forward\" ? previousBoard : nextBoard;\n const after = transition.direction === \"forward\" ? nextBoard : previousBoard;\n const movingPiece = (before[parsed.from] ?? 0) as BoardCell;\n if (isEmptyCell(movingPiece)) return null;\n\n const fromFile = parsed.from & 7;\n const toFile = parsed.to & 7;\n const targetBefore = (before[parsed.to] ?? 0) as BoardCell;\n const targetAfter = (after[parsed.to] ?? 0) as BoardCell;\n\n if (pieceTypeOf(movingPiece) === 5 && Math.abs(toFile - fromFile) === 2) {\n return [{ kind: \"castle\" }];\n }\n\n if (\n parsed.promotion !== null ||\n (isPawn(movingPiece) &&\n (parsed.to >> 3 === 0 || parsed.to >> 3 === 7) &&\n !isEmptyCell(targetAfter) &&\n pieceTypeOf(targetAfter) !== 0)\n ) {\n return [{ kind: \"promotion\" }];\n }\n\n if (!isEmptyCell(targetBefore) && colorOf(targetBefore) !== colorOf(movingPiece)) {\n return [{ kind: \"capture\" }];\n }\n\n if (isPawn(movingPiece) && fromFile !== toFile && isEmptyCell(targetBefore)) {\n const capturedSquare = ((parsed.from & ~7) | toFile) as SquareIndex;\n const capturedBefore = (before[capturedSquare] ?? 0) as BoardCell;\n const capturedAfter = (after[capturedSquare] ?? 0) as BoardCell;\n if (\n !isEmptyCell(capturedBefore) &&\n colorOf(capturedBefore) !== colorOf(movingPiece) &&\n isEmptyCell(capturedAfter)\n ) {\n return [{ kind: \"en-passant\" }];\n }\n }\n\n return [{ kind: \"move\" }];\n}\n\nfunction schedulePositionAnimation(\n container: HTMLElement,\n transitions: readonly SquareTransition[],\n options: Required<AnimationOptions>,\n orientation: Orientation,\n): void {\n const animate = (): void => {\n const rect = container.getBoundingClientRect();\n const squareSize = rect.width / 8;\n if (squareSize <= 0) return;\n\n for (const item of transitions) {\n const piece = queryPieceAt(container, item.to);\n if (piece === null || typeof piece.animate !== \"function\") continue;\n const { dx, dy } = deltaFromSquareNames(item.from, item.to, squareSize, orientation);\n if (Math.abs(dx) < 0.5 && Math.abs(dy) < 0.5) continue;\n\n cancelElementAnimations(piece);\n piece.animate(\n [{ transform: `translate(${dx}px, ${dy}px)` }, { transform: \"translate(0, 0)\" }],\n { duration: options.durationMs, easing: options.easing, fill: \"none\" },\n );\n }\n };\n\n if (typeof window.requestAnimationFrame === \"function\") {\n window.requestAnimationFrame(animate);\n } else {\n window.setTimeout(animate, 0);\n }\n}\n\nfunction syncPositionFen(\n game: NonNullable<ChessboardProps[\"game\"]>,\n targetFen: string,\n transition: PositionTransition | null | undefined,\n managedArrows: ChessboardProps[\"managedArrows\"],\n preserveUserArrows: boolean | undefined,\n container: HTMLElement | null,\n animation: AnimationOptions | undefined,\n orientation: Orientation,\n): boolean {\n const positionChanged = game.engine.fen() !== targetFen;\n const durationMs = animation?.durationMs ?? DEFAULT_POSITION_SYNC_DURATION_MS;\n const easing = animation?.easing ?? DEFAULT_POSITION_SYNC_EASING;\n const shouldAnimate =\n positionChanged &&\n transition !== null &&\n transition !== undefined &&\n container !== null &&\n durationMs > 0 &&\n !prefersReducedMotion();\n\n const transitions: SquareTransition[] = [];\n if (shouldAnimate) {\n for (const item of transitionSquares(transition)) {\n if (queryPieceAt(container, item.from) !== null) transitions.push(item);\n }\n }\n\n try {\n if (managedArrows === undefined) {\n if (!positionChanged) return false;\n game.load(targetFen);\n } else {\n game.syncPosition({\n fen: targetFen,\n managedArrows,\n preserveUserArrows: preserveUserArrows === true,\n });\n }\n } catch {\n return false;\n }\n\n if (transitions.length > 0 && container !== null) {\n schedulePositionAnimation(container, transitions, { durationMs, easing }, orientation);\n }\n return positionChanged;\n}\n\n/**\n * Interactive chess board.\n *\n * @example\n * ```tsx\n * \"use client\";\n * import { Chessboard, useChessGame } from \"gigaboard\";\n *\n * export default function Board() {\n * const game = useChessGame();\n * return <Chessboard game={game} />;\n * }\n * ```\n */\nexport function Chessboard(props: ChessboardProps) {\n const {\n game,\n fallbackFen,\n positionFen,\n positionTransition = null,\n managedArrows,\n preserveUserArrowsOnPositionSync,\n orientation = \"white\",\n theme = defaultTheme,\n pieces = defaultPieces,\n showCoordinates = true,\n ranksPosition = \"left\",\n showLegalTargets = \"rings\",\n highlightLastMove = true,\n onMove,\n onPromote,\n renderSquare,\n style,\n className,\n ariaLabel,\n animation,\n allowDrag = true,\n allowDrawingArrows = true,\n clearArrowsOnMove = true,\n clearArrowsOnClick = true,\n arrowColors,\n snapArrowsToValidMove = false,\n allowPremove = false,\n showCheckHighlight = true,\n showIllegalFlash = true,\n sound = true,\n haptics = false,\n viewOnly = false,\n canDragPiece,\n onSquareMouseEnter,\n onSquareMouseLeave,\n disableContextMenu = true,\n getSquareAriaLabel,\n onSquareFocus,\n getPromotionPieceAriaLabel,\n } = props;\n\n // Every interactive subsystem consults these resolved flags. Keeping\n // the resolution here — rather than inlining `!viewOnly && …` at each\n // call site — makes the blast radius of `viewOnly` explicit, keeps\n // dependency arrays stable, and means the branch is evaluated once\n // per render instead of once per consumer.\n const dragEnabled = allowDrag && !viewOnly;\n const arrowGestureEnabled = allowDrawingArrows && !viewOnly;\n const clickToMoveEnabled = !viewOnly;\n const keyboardNavEnabled = !viewOnly;\n\n // Parse the fallback FEN at most once per distinct string. The 64-byte\n // output is passed into `<StaticPieceLayer/>` only while `game` is null;\n // once a real model arrives the interactive `<PieceLayer/>` takes over.\n // Parsing costs a few µs so the memoisation is about render-identity,\n // not speed — `StaticPieceLayer` memos on the array reference.\n const fallbackBoard = useMemo<Uint8Array | null>(() => {\n if (fallbackFen === undefined || fallbackFen === \"\") return null;\n try {\n return parseFenPlacement(fallbackFen);\n } catch {\n // Malformed FEN → fall back to a pieceless board rather than\n // throwing out of a render. The console warning would be noisy\n // in tests; silent no-op is the least-surprising behaviour.\n return null;\n }\n }, [fallbackFen]);\n\n // Normalise `sound` (boolean | options) into a concrete options object.\n // Memoised so `useMoveSound` doesn't rebuild its audio pool on every\n // render when the caller passes a raw object literal.\n const soundOptions = useMemo<MoveSoundOptions>(() => {\n if (sound === true) return { enabled: true };\n if (sound === false || sound === undefined) return { enabled: false };\n return sound;\n }, [sound]);\n\n const hapticOptions = useMemo<MoveHapticOptions>(() => {\n if (haptics === true) return { enabled: true };\n if (haptics === false || haptics === undefined) return { enabled: false };\n return haptics;\n }, [haptics]);\n\n const containerRef = useRef<HTMLDivElement | null>(null);\n const dragLayerRef = useRef<DragLayerHandle | null>(null);\n const arrowsLayerRef = useRef<ArrowsLayerHandle | null>(null);\n const lastControlledFeedbackFenRef = useRef<string | null>(null);\n\n // 64-slot refs array populated by each `<Square/>` on mount. The\n // selection controller reads this to paint highlights imperatively.\n const squareRefs = useRef<Array<HTMLElement | null>>(new Array(64).fill(null));\n const setSquareRef = useCallback((index: SquareIndex, el: HTMLElement | null) => {\n squareRefs.current[index] = el;\n }, []);\n\n // Set to `true` whenever the next model commit is the result of a drag\n // (or a promotion dialog opened by a drag). `<AnimationRunner/>` reads\n // this flag on each commit and skips the FLIP animation, because the\n // piece has already been positioned by the user's pointer. Reset to\n // `false` anywhere the move is abandoned (illegal drop, dialog cancel)\n // so the flag never leaks into a subsequent non-drag move.\n const skipNextAnimationRef = useRef(false);\n\n // Latest-ref pattern for user callbacks — keeps `useCallback`/`useEffect`\n // deps stable while still reading the newest prop values at call time.\n const onMoveRef = useRef(onMove);\n const onPromoteRef = useRef(onPromote);\n useEffect(() => {\n onMoveRef.current = onMove;\n onPromoteRef.current = onPromote;\n });\n\n // Move feedback effects. The hooks subscribe to normal model moves and\n // also expose direct triggers for controlled `positionFen` syncs below.\n const triggerMoveSound = useMoveSound(game, soundOptions);\n const triggerMoveHaptic = useMoveHaptics(game, hapticOptions);\n\n useLayoutEffect(() => {\n if (game === null || positionFen === undefined || positionFen === \"\") return;\n const previousFeedbackFen = lastControlledFeedbackFenRef.current;\n const previousSnapshot = game.getSnapshot();\n if (game.engine.fen() === positionFen && managedArrows === undefined) {\n lastControlledFeedbackFenRef.current = positionFen;\n return;\n }\n const positionChanged = syncPositionFen(\n game,\n positionFen,\n positionTransition,\n managedArrows,\n preserveUserArrowsOnPositionSync,\n containerRef.current,\n animation,\n orientation,\n );\n lastControlledFeedbackFenRef.current = positionFen;\n\n if (!positionChanged || previousFeedbackFen === null || previousFeedbackFen === positionFen) {\n return;\n }\n\n const snapshot = game.getSnapshot();\n const feedbackDescriptors =\n controlledFeedbackDescriptors(positionTransition, previousSnapshot.board, snapshot.board) ??\n game.lastAnimations;\n const feedbackSnapshot =\n positionTransition?.direction === \"backward\" ? previousSnapshot : snapshot;\n triggerMoveSound(\n classifyMoveFeedback(feedbackDescriptors, feedbackSnapshot, soundOptions.perspective),\n );\n triggerMoveHaptic(\n classifyMoveFeedback(feedbackDescriptors, feedbackSnapshot, hapticOptions.perspective),\n );\n }, [\n animation,\n game,\n hapticOptions.perspective,\n positionFen,\n positionTransition,\n managedArrows,\n preserveUserArrowsOnPositionSync,\n orientation,\n soundOptions.perspective,\n triggerMoveHaptic,\n triggerMoveSound,\n ]);\n\n // Merge user-provided arrow colours with defaults. Memoised against\n // the whole `arrowColors` reference so consumers who pass a stable\n // object literal don't thrash the gesture hook's deps; callers who\n // recreate it each render pay one shallow-copy per commit — cheap.\n // Extra user-defined brush keys flow through alongside the four\n // modifier channels that always get defaults applied.\n const palette = useMemo<ResolvedArrowPalette>(() => {\n const merged: { [k: string]: string } = {\n default: defaultArrowColors.default,\n shift: defaultArrowColors.shift,\n alt: defaultArrowColors.alt,\n ctrl: defaultArrowColors.ctrl,\n };\n if (arrowColors !== undefined) {\n for (const k in arrowColors) {\n const v = (arrowColors as ArrowColors)[k];\n if (v !== undefined) merged[k] = v;\n }\n }\n return merged as ResolvedArrowPalette;\n }, [arrowColors]);\n\n // Drag state used to live here as `useState` + `flushSync` on\n // drag-start. It's gone now: the `<DragLayer/>` below is always\n // mounted (hidden) and exposes an imperative handle that `useDrag`\n // drives from its pointer handlers. This keeps the drag-start\n // pointer-move handler off React's critical path entirely, closing\n // the drag-peak-frame gap with chessground.\n\n // Promotion dialog state — null when no promotion is pending.\n const [pendingPromotion, setPendingPromotion] = useState<PendingPromotion | null>(null);\n\n // Keyboard-focus state for the roving tabindex. `null` means the board\n // hasn't been focused yet — Tabbing into it takes the user to the\n // square picked by `initialKeyboardFocusSquare` (below), or e2 for\n // a white-oriented board.\n const [focusedSquare, setFocusedSquare] = useState<SquareIndex | null>(null);\n // Visual bottom-left square given the current orientation: e2-ish for\n // white (a good default landing spot near the kingside piece the user\n // most often moves first), a7-ish for black.\n const defaultKeyboardFocus = useCallback(\n (): SquareIndex => (orientation === \"white\" ? 12 : 52) as SquareIndex,\n [orientation],\n );\n\n // Illegal-flash state: the square to pulse red, cleared after a short hold.\n const [flashSquare, setFlashSquare] = useState<SquareIndex | null>(null);\n const flashTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const triggerIllegalFlash = useCallback(\n (square: SquareIndex): void => {\n if (!showIllegalFlash) return;\n setFlashSquare(square);\n if (flashTimerRef.current !== null) clearTimeout(flashTimerRef.current);\n flashTimerRef.current = setTimeout(() => {\n setFlashSquare(null);\n flashTimerRef.current = null;\n }, ILLEGAL_FLASH_HOLD_MS);\n },\n [showIllegalFlash],\n );\n // Cancel any pending flash when the component unmounts.\n useEffect(\n () => () => {\n if (flashTimerRef.current !== null) clearTimeout(flashTimerRef.current);\n },\n [],\n );\n\n /**\n * Auto-clear arrows when the game advances. Subscribes to `historyPly`\n * and wipes the *user-drawn* arrows on every increment. Arrows marked\n * `managed: true` (engine hints, programmatic annotations) survive so\n * an analysis board can keep its best-move arrow current across the\n * move that replaces it. Toggled off by `clearArrowsOnMove={false}`.\n */\n useEffect(() => {\n if (game === null || !clearArrowsOnMove) return;\n let prevPly = game.getSnapshot().historyPly;\n return game.subscribe(() => {\n const snap = game.getSnapshot();\n if (snap.historyPly > prevPly && snap.arrows.length > 0) {\n game.clearUserArrows();\n }\n prevPly = snap.historyPly;\n });\n }, [game, clearArrowsOnMove]);\n\n /**\n * Kick off promotion resolution. Uses the caller-provided `onPromote`\n * prop when present, otherwise opens the built-in overlay.\n */\n const requestPromotion = useCallback(\n (from: SquareIndex, to: SquareIndex): void => {\n if (game === null) return;\n const fromCell = game.getSnapshot().board[from] ?? 0;\n const color = colorOfCell(fromCell);\n\n const completeMove = (piece: PieceType): void => {\n const played = game.tryMove(from, to, piece);\n const cb = onMoveRef.current;\n if (played !== null && cb !== undefined) cb(played);\n };\n\n const promoteHandler = onPromoteRef.current;\n if (promoteHandler !== undefined) {\n // Caller owns the UI. Resolve through their promise.\n Promise.resolve(promoteHandler({ from, to, color })).then(completeMove, () => {\n // Rejected → abandon the move. Board remains in its pre-move state.\n // A drag-initiated promotion that rejects must clear the skip\n // flag so the next non-drag move animates normally.\n skipNextAnimationRef.current = false;\n });\n return;\n }\n\n // Built-in overlay: rendered below via `pendingPromotion`.\n setPendingPromotion({\n from,\n to,\n color,\n resolve: (piece) => {\n setPendingPromotion(null);\n completeMove(piece);\n },\n cancel: () => {\n // A drag-initiated promotion that's cancelled must reset the\n // skip flag — otherwise the *next* legitimate move would be\n // silently de-animated.\n skipNextAnimationRef.current = false;\n setPendingPromotion(null);\n },\n });\n },\n [game],\n );\n\n const clickToMove = useClickToMove(game, onMove, requestPromotion, clickToMoveEnabled);\n\n /**\n * Clear any drawn arrows if `clearArrowsOnClick` is enabled. Called at\n * the start of every left-button interaction — click or drag-start —\n * and on Escape.\n */\n const maybeClearArrows = useCallback((): void => {\n if (!clearArrowsOnClick || game === null) return;\n // Managed arrows (engine hints) are deliberately preserved — the\n // user's left-click should dismiss their own annotations only, not\n // the app's.\n if (game.getSnapshot().arrows.length > 0) game.clearUserArrows();\n }, [clearArrowsOnClick, game]);\n\n /** Click-to-move with the arrow-clearing side effect woven in. */\n const handleSquareClick = useCallback(\n (index: SquareIndex): void => {\n // `viewOnly` keeps clicks from perturbing any board state — including\n // user-drawn or programmatic arrows. `clickToMove` is already a no-op\n // when disabled; guarding the arrow-clear here keeps the click path\n // purely declarative.\n if (viewOnly) return;\n maybeClearArrows();\n clickToMove(index);\n },\n [viewOnly, maybeClearArrows, clickToMove],\n );\n\n /** Escape clears arrows (and is a natural analogue for \"cancel\"). */\n useEffect(() => {\n if (!clearArrowsOnClick || game === null || viewOnly) return;\n const onKey = (e: KeyboardEvent): void => {\n if (e.key === \"Escape\") maybeClearArrows();\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [clearArrowsOnClick, game, maybeClearArrows, viewOnly]);\n\n // Piece slots carry `pointer-events: auto` (see `useCursorController`)\n // so the `grab` cursor renders correctly on pickable pieces. A native\n // click landing on a piece slot does NOT fire the underlying\n // `<Square/>`'s React `onClick`: the square is not an ancestor of the\n // slot in the React tree. Forward those clicks to click-to-move via\n // coordinate resolution — same geometry path `useDrag` / `useHoverSquare`\n // already use.\n useEffect(() => {\n if (viewOnly || clickToMoveEnabled === false || game === null) return;\n const container = containerRef.current;\n if (container === null) return;\n const onContainerClick = (e: MouseEvent): void => {\n if (e.button !== 0) return;\n const target = e.target as Element | null;\n if (target === null) return;\n // Only handle clicks that landed on the piece overlay — clicks\n // on squares already route through `Square.onClick`, and double\n // dispatch would fire click-to-move twice.\n if (target.closest(\"[data-piece-square]\") === null) return;\n const sq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (sq === null) return;\n handleSquareClick(sq);\n };\n container.addEventListener(\"click\", onContainerClick);\n return () => container.removeEventListener(\"click\", onContainerClick);\n }, [viewOnly, clickToMoveEnabled, game, orientation, handleSquareClick]);\n\n /**\n * Suppress the browser context menu on the board container. Works\n * independently of `allowDrawingArrows` so consumers can have the OS\n * menu blocked even in view-only / no-arrow configurations. When\n * arrows are enabled, `useArrowGesture` installs its own identical\n * listener too — both call `preventDefault` on the same event, which\n * is idempotent.\n */\n useEffect(() => {\n if (!disableContextMenu) return;\n const container = containerRef.current;\n if (container === null) return;\n const onContextMenu = (e: MouseEvent): void => {\n e.preventDefault();\n };\n container.addEventListener(\"contextmenu\", onContextMenu);\n return () => container.removeEventListener(\"contextmenu\", onContextMenu);\n }, [disableContextMenu]);\n\n // Drag callbacks — each is stable across renders so `useDrag` doesn't\n // re-install its pointer listeners on every commit. The drag-layer\n // visibility is managed imperatively by `useDrag` itself via the\n // `DragLayerHandle`; these callbacks only carry out the React-state\n // side effects (arrow clear, selection update) that a drag implies.\n const onDragStart = useCallback(\n (from: SquareIndex, _cell: BoardCell): void => {\n maybeClearArrows();\n // Flip the container into \"grabbing\" cursor mode. See\n // `useCursorController` for the CSS rule that consumes this.\n const container = containerRef.current;\n if (container !== null) container.dataset[\"gbDragging\"] = \"true\";\n // Calling `game.selectSquare(from)` propagates the drag-source\n // into the model so the selection controller shows legal targets\n // while the piece is in flight — the same visual affordance\n // click-to-move gets.\n game?.selectSquare(from);\n },\n [game, maybeClearArrows],\n );\n const onDragEnd = useCallback((): void => {\n // Reset the cursor. We clear unconditionally because React may have\n // skipped a render cycle between drop and the next pointer event.\n const container = containerRef.current;\n if (container !== null) delete container.dataset[\"gbDragging\"];\n // Note: Selection on the origin square is retained on drag release/abort\n // so the user can seamlessly execute click-to-move. On a successful move,\n // tryMove already cleared the selection.\n }, []);\n\n const onDrop = useCallback(\n (from: SquareIndex, to: SquareIndex): void => {\n if (game === null) return;\n const snap = game.getSnapshot();\n const fromCell = snap.board[from] ?? 0;\n const pieceColour = colorOfCell(fromCell);\n\n // Not our turn? Queue as a premove if allowed; otherwise reject with\n // the same red flash any other illegal move gets. Silently dropping\n // the attempt was the default-true M4 behaviour but left users\n // confused (\"a blue ghost appeared from nowhere\").\n if (fromCell !== 0 && pieceColour !== snap.turn) {\n if (!allowPremove) {\n triggerIllegalFlash(from);\n return;\n }\n // Premove promotion auto-queens (lichess convention) — the user\n // isn't given a dialog here because it's not their turn yet.\n const promotion = movePromotesPawn(fromCell, to) ? (4 as PieceType) /* Queen */ : undefined;\n game.queuePremove(promotion === undefined ? { from, to } : { from, to, promotion });\n return;\n }\n\n // Drag-initiated → skip the next FLIP animation. The promotion and\n // happy paths both consume this flag; on failure we reset it so it\n // doesn't leak into a later, unrelated move.\n skipNextAnimationRef.current = true;\n\n if (movePromotesPawn(fromCell, to) && game.isLegal(from, to, 4 /* Queen */)) {\n requestPromotion(from, to);\n return;\n }\n\n const played = game.tryMove(from, to);\n const cb = onMoveRef.current;\n if (played !== null) {\n if (cb !== undefined) cb(played);\n } else {\n skipNextAnimationRef.current = false;\n triggerIllegalFlash(from);\n game.selectSquare(from);\n }\n },\n [game, requestPromotion, allowPremove, triggerIllegalFlash],\n );\n\n useDrag({\n game,\n orientation,\n containerRef,\n dragLayerRef,\n enabled: dragEnabled && game !== null,\n onDragStart,\n onDragEnd,\n onDrop,\n ...(canDragPiece !== undefined ? { canDragPiece } : {}),\n });\n\n // Initialise keyboard focus once per orientation so Tab lands on a\n // sensible square. We deliberately do NOT auto-focus on mount — the\n // board stays dormant until the user Tabs into it. Suppressed in\n // `viewOnly` mode so the grid stays out of the tab order entirely.\n useEffect(() => {\n if (!keyboardNavEnabled) {\n setFocusedSquare(null);\n return;\n }\n setFocusedSquare((current) => current ?? defaultKeyboardFocus());\n }, [defaultKeyboardFocus, keyboardNavEnabled]);\n\n const onKeyboardActivate = useCallback(\n (index: SquareIndex): void => {\n maybeClearArrows();\n clickToMove(index);\n },\n [maybeClearArrows, clickToMove],\n );\n const onKeyboardEscape = useCallback((): void => {\n maybeClearArrows();\n game?.selectSquare(null);\n }, [maybeClearArrows, game]);\n\n useKeyboardNav({\n containerRef,\n orientation,\n focusedSquare,\n setFocusedSquare,\n onActivate: onKeyboardActivate,\n onEscape: onKeyboardEscape,\n enabled: game !== null && keyboardNavEnabled,\n });\n\n // Per-square hover notification — only armed when the caller supplies\n // at least one of the two callbacks, so no container listener is\n // installed on the default play path. Pointer events not mouse events,\n // so touch drags through a square pair the same as pointer drags.\n useHoverSquare({\n game,\n orientation,\n containerRef,\n enabled: onSquareMouseEnter !== undefined || onSquareMouseLeave !== undefined,\n ...(onSquareMouseEnter !== undefined ? { onEnter: onSquareMouseEnter } : {}),\n ...(onSquareMouseLeave !== undefined ? { onLeave: onSquareMouseLeave } : {}),\n });\n\n useArrowGesture({\n game,\n orientation,\n containerRef,\n arrowsLayerRef,\n enabled: arrowGestureEnabled && game !== null,\n palette,\n snapToValidMove: snapArrowsToValidMove,\n });\n\n // Imperative selection + legal-target highlighter. Writes\n // `data-gb-selection` on the 64 square refs above; no React state,\n // no per-commit reconciliation. This is what closes the drag-start\n // peak-frame gap with chessground — a selectSquare call no longer\n // triggers a React render at all.\n useSelectionController(game, squareRefs, showLegalTargets);\n\n // Imperative last-move tint. Same pattern as the selection\n // controller — paints `data-gb-last-move` on the two endpoint\n // squares via a CSS `::after` pseudo-element. Removes the\n // `<LastMoveLayer/>` React component from the drop-frame commit,\n // eliminating two DOM creates + layout + paint per move.\n useLastMoveController(game, squareRefs, highlightLastMove);\n\n // Container-level cursor paint. Writes `data-gb-turn` (and\n // optionally `data-gb-premove`) on the board container — a CSS rule\n // chain keyed to `[data-piece-cell]` values picks out grabbable\n // pieces without touching any square. That takes per-move cursor\n // DOM churn from 32 attribute writes down to 0-1; the grabbing\n // cursor (`grabbing`) is applied by the sibling `data-gb-dragging`\n // attribute toggled from `onDragStart` / `onDragEnd`.\n useCursorController(game, containerRef, dragEnabled, allowPremove);\n\n // Memoised runtime so `<AnimationRunner/>`'s effect-deps stay stable\n // across `<Chessboard/>` prop changes unrelated to animation.\n const animationRuntime = useMemo(() => ({ skipNextRef: skipNextAnimationRef }), []);\n\n // Inline theme variables → available at first paint.\n const containerStyle: CSSProperties = {\n position: \"relative\",\n aspectRatio: \"1 / 1\",\n width: \"100%\",\n touchAction: \"none\", // let the drag layer own pan gestures\n ...(theme as CSSProperties),\n ...style,\n };\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={containerStyle}\n data-gb-orientation={orientation}\n data-gb-target-style={showLegalTargets === false ? \"off\" : showLegalTargets}\n {...(viewOnly ? { \"data-gb-view-only\": \"true\" } : {})}\n >\n <BoardGrid\n orientation={orientation}\n onSquareClick={handleSquareClick}\n focusedSquare={focusedSquare}\n setSquareRef={setSquareRef}\n readOnly={viewOnly}\n model={game}\n getSquareAriaLabel={getSquareAriaLabel}\n onSquareFocus={onSquareFocus}\n {...(renderSquare !== undefined ? { renderSquare } : {})}\n {...(ariaLabel !== undefined ? { ariaLabel } : {})}\n />\n {game !== null && showCheckHighlight ? (\n <CheckLayer model={game} orientation={orientation} />\n ) : null}\n {game !== null ? (\n <PremoveLayer model={game} orientation={orientation} pieces={pieces} />\n ) : null}\n {/*\n * \"Below\" arrows — arrows marked `below: true` render beneath the\n * piece layer by DOM order (positioned elements without z-index\n * paint in tree order). Fresh subset per commit filters server\n * annotations / heatmap tints away from the top overlay.\n */}\n {game !== null ? (\n <ArrowsLayer model={game} orientation={orientation} palette={palette} below />\n ) : null}\n {game !== null ? (\n <PieceLayer model={game} orientation={orientation} pieces={pieces} />\n ) : fallbackBoard !== null ? (\n <StaticPieceLayer board={fallbackBoard} orientation={orientation} pieces={pieces} />\n ) : null}\n {game !== null ? (\n <AnimationRunner\n model={game}\n containerRef={containerRef}\n orientation={orientation}\n {...(animation !== undefined ? { options: animation } : {})}\n runtime={animationRuntime}\n />\n ) : null}\n <DragLayer ref={dragLayerRef} pieces={pieces} />\n {game !== null ? (\n <ArrowsLayer\n ref={arrowsLayerRef}\n model={game}\n orientation={orientation}\n palette={palette}\n />\n ) : null}\n {showCoordinates ? (\n <Coordinates orientation={orientation} ranksPosition={ranksPosition} />\n ) : null}\n <IllegalFlashLayer at={flashSquare} orientation={orientation} />\n {game !== null ? <LiveRegion model={game} /> : null}\n {pendingPromotion !== null ? (\n <PromotionOverlay\n from={pendingPromotion.from}\n to={pendingPromotion.to}\n color={pendingPromotion.color}\n orientation={orientation}\n pieces={pieces}\n onSelect={pendingPromotion.resolve}\n onCancel={pendingPromotion.cancel}\n getPromotionPieceAriaLabel={getPromotionPieceAriaLabel}\n />\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\n/**\n * Own a `BoardModel` across the lifetime of a component.\n *\n * The engine (`gigachess`) initializes synchronously (<0.5 ms), so the model\n * is active and non-null immediately on frame 0. Pieces are grabbable and\n * responsive to pointer events on the initial render commit without an\n * intermediate async gap.\n */\n\nimport { useEffect, useRef, useState } from \"react\";\nimport {\n type BoardModel,\n type BoardModelOptions,\n createBoardModel,\n createGigachessAdapter,\n} from \"../core/index.js\";\nimport type { UseChessGameOptions } from \"../types.js\";\n\n/**\n * Allocate a board model bound to a fresh `gigachess` engine. The model\n * is created synchronously on the initial render, lives for the lifetime of\n * the calling component, and is disposed on unmount.\n *\n * @remarks\n * Synchronous initialization on frame 0 ensures zero layout shift and 0 ms\n * long tasks during mount. Changing `options.fen` disposes the current model\n * and allocates a fresh one.\n */\nexport function useChessGame(options: UseChessGameOptions & BoardModelOptions = {}): BoardModel {\n const { fen, ...modelOptions } = options;\n const [initialModelOptions] = useState<BoardModelOptions>(() => modelOptions);\n\n // Synchronous initialization on frame 0 via createGigachessAdapter (<0.5 ms)\n const [model, setModel] = useState<BoardModel>(() => {\n const adapter = createGigachessAdapter(fen);\n return createBoardModel(adapter, modelOptions);\n });\n\n // Track FEN changes: reallocate model if lifecycle FEN input changes\n const prevFenRef = useRef<string | undefined>(fen);\n useEffect(() => {\n if (prevFenRef.current !== fen) {\n prevFenRef.current = fen;\n const adapter = createGigachessAdapter(fen);\n const nextModel = createBoardModel(adapter, initialModelOptions);\n setModel((prev) => {\n prev.dispose();\n return nextModel;\n });\n }\n }, [fen, initialModelOptions]);\n\n // Clean up on component unmount\n useEffect(() => {\n return () => {\n model.dispose();\n };\n }, [model]);\n\n return model;\n}\n","/**\n * `gigaboard` — ultra-fast interactive React chessboard.\n *\n * Hand-curated barrel; sub-modules are never re-exported wholesale so\n * consumers can tree-shake aggressively.\n *\n * Server-only entry (static SSR board, zero client JS): `gigaboard/server`.\n */\n\nexport { BoardEditor, type BoardEditorProps, formatFenPlacement } from \"./board-editor.js\";\n// ---- Components ----\nexport { Chessboard } from \"./chessboard.js\";\nexport type {\n BoardCell,\n BoardModel,\n BoardSnapshot,\n EngineAdapter,\n PackedMove,\n SquareIndex,\n ZobristKey,\n} from \"./core/index.js\";\n// ---- Core engine & models ----\nexport {\n Color,\n createBoardModel,\n createGigachessAdapter,\n isNullMove,\n isNullMoveSan,\n isNullMoveUci,\n NULL_MOVE_SAN,\n NULL_MOVE_SANS,\n NULL_MOVE_UCI,\n NULL_MOVE_WORD,\n PieceType,\n packMove,\n preloadGigachessAdapter,\n unpackMove,\n} from \"./core/index.js\";\nexport {\n CSS_VARS,\n DEFAULT_ILLEGAL_FLASH_TINT,\n DEFAULT_PREMOVE_TINT,\n defaultArrowColors,\n defaultTheme,\n} from \"./default-theme.js\";\nexport { AnimationRunner } from \"./hooks/use-animation.js\";\nexport { useArrowGesture } from \"./hooks/use-arrow-gesture.js\";\nexport {\n useBoardSlice,\n useBoardSnapshot,\n useSquareCell,\n} from \"./hooks/use-board-subscription.js\";\n// ---- Hooks ----\nexport { useChessGame } from \"./hooks/use-chess-game.js\";\nexport { useClickToMove } from \"./hooks/use-click-to-move.js\";\nexport { useDrag } from \"./hooks/use-drag.js\";\nexport { type HoverSquareContext, useHoverSquare } from \"./hooks/use-hover-square.js\";\nexport { useKeyboardNav } from \"./hooks/use-keyboard-nav.js\";\nexport type {\n MoveHapticKey,\n MoveHapticOptions,\n MoveHapticPatterns,\n TriggerMoveHaptic,\n} from \"./hooks/use-move-haptics.js\";\nexport { triggerMoveHaptic, useMoveHaptics } from \"./hooks/use-move-haptics.js\";\nexport type {\n MoveSoundKey,\n MoveSoundOptions,\n MoveSoundSources,\n TriggerMoveSound,\n} from \"./hooks/use-move-sound.js\";\nexport {\n DEFAULT_MOVE_SOUND_SOURCES,\n useMoveSound,\n} from \"./hooks/use-move-sound.js\";\n// ---- Geometry helpers ----\nexport { algebraicOf, getPointAtSquareCentre, getSquareAtPoint, squareOf } from \"./lib/geometry.js\";\nexport type { HapticFeedbackOptions, HapticInput, TriggerOptions } from \"./lib/haptics.js\";\nexport { triggerHaptic, warmupHaptics } from \"./lib/haptics.js\";\nexport type { MoveFeedbackKey } from \"./lib/move-feedback.js\";\nexport { classifyMoveFeedback, DEFAULT_MOVE_HAPTIC_PATTERNS } from \"./lib/move-feedback.js\";\n// ---- Defaults ----\nexport { defaultPieces } from \"./pieces/default-pieces.js\";\n\n// ---- Types ----\nexport type {\n AnimationOptions,\n ArrowColors,\n ChessboardProps,\n LegalTargetStyle,\n Orientation,\n PieceRenderer,\n PositionTransition,\n PromotionContext,\n RanksPosition,\n ResolvedArrowPalette,\n SquareContext,\n Theme,\n UseChessGameOptions,\n} from \"./types.js\";\n\n/** Package version — keep in sync with `package.json`. */\nexport const PACKAGE_VERSION = \"1.5.0\";\n"]}
1
+ {"version":3,"sources":["../src/components/coordinates.tsx","../src/hooks/use-board-subscription.ts","../src/components/piece-layer.tsx","../src/lib/geometry.ts","../src/board-editor.tsx","../src/components/arrows-layer.tsx","../src/components/square.tsx","../src/components/board-grid.tsx","../src/components/check-layer.tsx","../src/components/drag-layer.tsx","../src/components/illegal-flash-layer.tsx","../src/components/live-region.tsx","../src/components/premove-layer.tsx","../src/components/promotion-overlay.tsx","../src/components/static-piece-layer.tsx","../src/hooks/use-animation.ts","../src/hooks/use-arrow-gesture.ts","../src/hooks/use-click-to-move.ts","../src/hooks/use-cursor-controller.ts","../src/hooks/use-drag.ts","../src/hooks/use-hover-square.ts","../src/hooks/use-keyboard-nav.ts","../src/hooks/use-last-move-controller.ts","../src/lib/haptics.ts","../src/lib/move-feedback.ts","../src/hooks/use-move-haptics.ts","../src/hooks/use-move-sound.ts","../src/hooks/use-selection-controller.ts","../src/chessboard.tsx","../src/hooks/use-chess-game.ts","../src/index.ts"],"names":["jsx","PieceLayer","algebraicOf","useCallback","jsxs","tip","scale","dockX","halfH","path","memo","ArrowsLayer","useRef","useMemo","useEffect","BoardGrid","forwardRef","DragLayer","useImperativeHandle","positionOf","useLayoutEffect","pieceName","useState","srOnlyStyle","prefersReducedMotion","played","STYLE_ID","triggerMoveHaptic"],"mappings":";;;;;;;;;;AAcA,IAAM,YAAA,GAAe,CAAC,GAAA,EAAK,GAAA,EAAK,KAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA;AAarD,SAAS,WAAA,CAAY,EAAE,WAAA,EAAa,aAAA,GAAgB,QAAO,EAAqB;AACrF,EAAA,MAAM,eAAe,aAAA,KAAkB,OAAA;AACvC,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,aAAA,EAAY,MAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,KAAA,EAAO,CAAA;AAAA,QACP,aAAA,EAAe,MAAA;AAAA,QACf,QAAA,EAAU,oBAAA;AAAA,QACV,UAAA,EAAY,GAAA;AAAA,QACZ,UAAA,EAAY;AAAA,OACd;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,YAAA,CAAa,GAAA,CAAI,CAAC,MAAA,EAAQ,GAAA,KAAQ;AACjC,UAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,GAAA,GAAM,CAAA,GAAI,GAAA;AAIhD,UAAA,MAAM,UAAA,GAAa,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,CAAA;AACjD,UAAA,MAAM,aAAA,GAAA,CAAiB,GAAA,GAAM,UAAA,IAAc,CAAA,KAAM,CAAA;AACjD,UAAA,uBACE,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cAEC,KAAA,EAAO;AAAA,gBACL,QAAA,EAAU,UAAA;AAAA,gBACV,IAAA,EAAM,CAAA,EAAG,GAAA,GAAM,IAAA,GAAO,EAAE,CAAA,CAAA,CAAA;AAAA,gBACxB,MAAA,EAAQ,IAAA;AAAA,gBACR,OAAO,CAAA,IAAA,EAAO,aAAA,GAAgB,QAAA,CAAS,gBAAA,GAAmB,SAAS,eAAe,CAAA,CAAA;AAAA,eACpF;AAAA,cAEC,QAAA,EAAA;AAAA,aAAA;AAAA,YARI,QAAQ,MAAM,CAAA;AAAA,WASrB;AAAA,QAEJ,CAAC,CAAA;AAAA,QACA,YAAA,CAAa,GAAA,CAAI,CAAC,CAAA,EAAG,GAAA,KAAQ;AAE5B,UAAA,MAAM,IAAA,GAAO,GAAA;AACb,UAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,IAAA,GAAO,IAAA;AAKjD,UAAA,MAAM,QAAA,GAAW,eACb,WAAA,KAAgB,OAAA,GACd,IACA,CAAA,GACF,WAAA,KAAgB,UACd,CAAA,GACA,CAAA;AACN,UAAA,MAAM,aAAA,GAAA,CAAiB,QAAA,GAAW,IAAA,IAAQ,CAAA,KAAM,CAAA;AAChD,UAAA,MAAM,SAAA,GAAY,eAAe,EAAE,KAAA,EAAO,MAAK,GAAI,EAAE,MAAM,IAAA,EAAK;AAChE,UAAA,uBACE,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cAEC,KAAA,EAAO;AAAA,gBACL,QAAA,EAAU,UAAA;AAAA,gBACV,GAAA,EAAK,CAAA,EAAG,GAAA,GAAM,IAAA,GAAO,CAAC,CAAA,CAAA,CAAA;AAAA,gBACtB,GAAG,SAAA;AAAA,gBACH,OAAO,CAAA,IAAA,EAAO,aAAA,GAAgB,QAAA,CAAS,gBAAA,GAAmB,SAAS,eAAe,CAAA,CAAA;AAAA,eACpF;AAAA,cAEC,QAAA,EAAA,IAAA,GAAO;AAAA,aAAA;AAAA,YARH,QAAQ,IAAI,CAAA;AAAA,WASnB;AAAA,QAEJ,CAAC;AAAA;AAAA;AAAA,GACH;AAEJ;AC3EO,SAAS,iBAAiB,KAAA,EAAkC;AACjE,EAAA,OAAO,qBAAqB,KAAA,CAAM,SAAA,EAAW,KAAA,CAAM,WAAA,EAAa,MAAM,WAAW,CAAA;AACnF;AAWO,SAAS,aAAA,CAAiB,OAAmB,QAAA,EAA6C;AAC/F,EAAA,MAAM,WAAA,GAAc,WAAA,CAAY,MAAS,QAAA,CAAS,KAAA,CAAM,WAAA,EAAa,CAAA,EAAG,CAAC,KAAA,EAAO,QAAQ,CAAC,CAAA;AACzF,EAAA,OAAO,oBAAA,CAAqB,KAAA,CAAM,SAAA,EAAW,WAAA,EAAa,WAAW,CAAA;AACvE;AAaO,SAAS,aAAA,CAAc,OAAsC,KAAA,EAA4B;AAC9F,EAAA,MAAM,SAAA,GAAY,WAAA;AAAA,IAChB,CAAC,aAA0B,KAAA,GAAQ,KAAA,CAAM,gBAAgB,KAAA,EAAO,QAAQ,IAAI,MAAM;AAAA,IAAC,CAAA;AAAA,IACnF,CAAC,OAAO,KAAK;AAAA,GACf;AACA,EAAA,MAAM,WAAA,GAAc,YAAY,MAAc;AAC5C,IAAA,IAAI,CAAC,OAAO,OAAO,CAAA;AACnB,IAAA,MAAM,IAAA,GAAO,MAAM,WAAA,EAAY;AAC/B,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA,IAAK,CAAA;AAAA,EAC9B,CAAA,EAAG,CAAC,KAAA,EAAO,KAAK,CAAC,CAAA;AACjB,EAAA,OAAO,oBAAA,CAAqB,SAAA,EAAW,WAAA,EAAa,WAAW,CAAA;AACjE;ACzBO,SAAS,SAAA,CACd,OACA,WAAA,EAC8B;AAC9B,EAAA,MAAM,OAAO,KAAA,GAAQ,CAAA;AACrB,EAAA,MAAM,OAAO,KAAA,IAAS,CAAA;AACtB,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,IAAA,GAAO,IAAI,CAAA,GAAI,IAAA;AACrD,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,OAAO,IAAA,GAAO,CAAA;AACxD,EAAA,OAAO,EAAE,KAAK,GAAA,EAAI;AACpB;AAWO,SAAS,YAAY,KAAA,EAA4B;AACtD,EAAA,MAAM,OAAO,KAAA,GAAQ,CAAA;AACrB,EAAA,MAAM,OAAO,KAAA,IAAS,CAAA;AACtB,EAAA,OAAO,CAAA,EAAG,OAAO,YAAA,CAAa,EAAA,GAAO,IAAI,CAAC,CAAA,EAAG,OAAO,CAAC,CAAA,CAAA;AACvD;AAQO,IAAM,eAAA,GAAkB,OAAO,MAAA,CAAO;AAAA,EAC3C,OAAA,EAAS,MAAA;AAAA,EACT,UAAA,EAAY,QAAA;AAAA,EACZ,cAAA,EAAgB,QAAA;AAAA,EAChB,aAAA,EAAe,MAAA;AAAA,EACf,aAAA,EAAe;AACjB,CAAC,CAAA;AAED,SAAS,cAAc,EAAE,KAAA,EAAO,KAAA,EAAO,WAAA,EAAa,QAAO,EAAmB;AAC5E,EAAA,MAAM,IAAA,GAAO,aAAA,CAAc,KAAA,EAAO,KAAK,CAAA;AACvC,EAAA,IAAI,IAAA,KAAS,GAAG,OAAO,IAAA;AACvB,EAAA,MAAM,EAAE,GAAA,EAAK,GAAA,EAAI,GAAI,SAAA,CAAU,OAAO,WAAW,CAAA;AAQjD,EAAA,uBACEA,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,mBAAA,EAAmB,YAAY,KAAK,CAAA;AAAA,MACpC,iBAAA,EAAiB,IAAA;AAAA,MACjB,KAAA,EAAO;AAAA,QACL,GAAG,eAAA;AAAA,QACH,eAAA,EAAiB,GAAA;AAAA,QACjB,YAAA,EAAc,GAAA;AAAA,QACd,QAAQ,CAAA,IAAA,EAAO,IAAA,IAAQ,IAAI,QAAA,CAAS,kBAAA,GAAqB,SAAS,kBAAkB,CAAA,OAAA;AAAA,OACtF;AAAA,MAEC,QAAA,EAAA,MAAA,CAAO,EAAE,IAAA,EAAyB,MAAA,EAAQ,OAAO;AAAA;AAAA,GACpD;AAEJ;AACA,IAAM,SAAA,GAAY,KAAK,aAAa,CAAA;AACpC,SAAA,CAAU,WAAA,GAAc,WAAA;AAejB,IAAM,eAAA,GAAkB,OAAO,MAAA,CAAO;AAAA,EAC3C,QAAA,EAAU,UAAA;AAAA,EACV,KAAA,EAAO,CAAA;AAAA,EACP,OAAA,EAAS,MAAA;AAAA,EACT,mBAAA,EAAqB,gBAAA;AAAA,EACrB,gBAAA,EAAkB,gBAAA;AAAA,EAClB,aAAA,EAAe;AACjB,CAAC,CAAA;AAOM,IAAM,UAAA,GAAa,IAAA,CAAK,SAASC,WAAAA,CAAW;AAAA,EACjD,KAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAA,EAAoB;AAClB,EAAA,MAAM,QAA2B,EAAC;AAClC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,KAAA,CAAM,IAAA;AAAA,sBACJD,GAAAA;AAAA,QAAC,SAAA;AAAA,QAAA;AAAA,UAEC,KAAA,EAAO,CAAA;AAAA,UACP,KAAA;AAAA,UACA,WAAA;AAAA,UACA;AAAA,SAAA;AAAA,QAJK;AAAA;AAKP,KACF;AAAA,EACF;AACA,EAAA,uBACEA,GAAAA,CAAC,KAAA,EAAA,EAAI,eAAY,MAAA,EAAO,KAAA,EAAO,iBAC5B,QAAA,EAAA,KAAA,EACH,CAAA;AAEJ,CAAC,CAAA;;;AC1HM,SAAS,gBAAA,CACd,SAAA,EACA,OAAA,EACA,OAAA,EACA,WAAA,EACoB;AACpB,EAAA,MAAM,IAAA,GAAO,UAAU,qBAAA,EAAsB;AAC7C,EAAA,MAAM,IAAA,GAAO,UAAU,IAAA,CAAK,IAAA;AAC5B,EAAA,MAAM,IAAA,GAAO,UAAU,IAAA,CAAK,GAAA;AAC5B,EAAA,IAAI,IAAA,GAAO,CAAA,IAAK,IAAA,GAAO,CAAA,IAAK,IAAA,IAAQ,KAAK,KAAA,IAAS,IAAA,IAAQ,IAAA,CAAK,MAAA,EAAQ,OAAO,IAAA;AAC9E,EAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAO,IAAA,GAAO,IAAA,CAAK,QAAS,CAAC,CAAA;AAC9C,EAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAO,IAAA,GAAO,IAAA,CAAK,SAAU,CAAC,CAAA;AAC/C,EAAA,MAAM,IAAA,GAAO,WAAA,KAAgB,OAAA,GAAU,GAAA,GAAM,CAAA,GAAI,GAAA;AACjD,EAAA,MAAM,IAAA,GAAO,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,GAAA,GAAM,GAAA;AACjD,EAAA,OAAQ,OAAO,CAAA,GAAI,IAAA;AACrB;AAcO,SAAS,sBAAA,CACd,SAAA,EACA,MAAA,EACA,WAAA,EAC4C;AAC5C,EAAA,MAAM,IAAA,GAAO,UAAU,qBAAA,EAAsB;AAC7C,EAAA,MAAM,GAAA,GAAM,KAAK,KAAA,GAAQ,CAAA;AACzB,EAAA,MAAM,GAAA,GAAM,KAAK,MAAA,GAAS,CAAA;AAC1B,EAAA,MAAM,OAAO,MAAA,GAAS,CAAA;AACtB,EAAA,MAAM,OAAO,MAAA,IAAU,CAAA;AACvB,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,IAAA,GAAO,CAAA,GAAI,IAAA;AACjD,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,IAAA,GAAO,IAAA;AACjD,EAAA,OAAO;AAAA,IACL,CAAA,EAAG,IAAA,CAAK,IAAA,GAAO,GAAA,GAAM,MAAM,GAAA,GAAM,CAAA;AAAA,IACjC,CAAA,EAAG,IAAA,CAAK,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,GAAM;AAAA,GAClC;AACF;AAGO,SAASE,aAAY,MAAA,EAA6B;AACvD,EAAA,MAAM,OAAO,MAAA,GAAS,CAAA;AACtB,EAAA,MAAM,OAAO,MAAA,IAAU,CAAA;AACvB,EAAA,OAAO,CAAA,EAAG,OAAO,YAAA,CAAa,EAAA,GAAO,IAAI,CAAC,CAAA,EAAG,OAAO,CAAC,CAAA,CAAA;AACvD;AAGO,SAAS,SAAS,SAAA,EAAuC;AAC9D,EAAA,IAAI,SAAA,CAAU,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AACnC,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,UAAA,CAAW,CAAC,CAAA,GAAI,EAAA;AACvC,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,UAAA,CAAW,CAAC,CAAA,GAAI,EAAA;AACvC,EAAA,IAAI,IAAA,GAAO,KAAK,IAAA,GAAO,CAAA,IAAK,OAAO,CAAA,IAAK,IAAA,GAAO,GAAG,OAAO,IAAA;AACzD,EAAA,OAAS,QAAQ,CAAA,GAAK,IAAA;AACxB;ACjCA,IAAM,WAAA,GAAc,CAAC,EAAA,EAAI,GAAA,EAAK,KAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,KAAK,GAAG,CAAA;AAE5E,SAAS,mBAAmB,KAAA,EAA2B;AAC5D,EAAA,MAAM,OAAiB,EAAC;AACxB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,IAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,IAAA,IAAI,GAAA,GAAM,EAAA;AACV,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA,IAAK,CAAA;AACjC,MAAA,IAAI,SAAS,CAAA,EAAG;AACd,QAAA,KAAA,EAAA;AAAA,MACF,CAAA,MAAO;AACL,QAAA,IAAI,QAAQ,CAAA,EAAG;AACb,UAAA,GAAA,IAAO,OAAO,KAAK,CAAA;AACnB,UAAA,KAAA,GAAQ,CAAA;AAAA,QACV;AACA,QAAA,GAAA,IAAO,WAAA,CAAY,IAAI,CAAA,IAAK,EAAA;AAAA,MAC9B;AAAA,IACF;AACA,IAAA,IAAI,QAAQ,CAAA,EAAG;AACb,MAAA,GAAA,IAAO,OAAO,KAAK,CAAA;AAAA,IACrB;AACA,IAAA,IAAA,CAAK,KAAK,GAAG,CAAA;AAAA,EACf;AACA,EAAA,OAAO,IAAA,CAAK,KAAK,GAAG,CAAA;AACtB;AAEA,SAAS,kBAAA,CAAmB,aAAqB,YAAA,EAA8B;AAC7E,EAAA,MAAM,MAAA,GAAS,WAAA,CAAY,IAAA,EAAK,CAAE,MAAM,KAAK,CAAA;AAC7C,EAAA,IAAI,MAAA,CAAO,UAAU,CAAA,EAAG;AACtB,IAAA,OAAO,YAAA;AAAA,EACT;AACA,EAAA,MAAA,CAAO,CAAC,CAAA,GAAI,YAAA;AACZ,EAAA,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AACxB;AAEA,SAAS,kBAAkB,IAAA,EAAyB;AAClD,EAAA,IAAI,IAAA,KAAS,GAAG,OAAO,OAAA;AACvB,EAAA,MAAM,KAAA,GAAQ,IAAA,GAAO,CAAA,GAAI,OAAA,GAAU,OAAA;AACnC,EAAA,MAAM,IAAA,GAAA,CAAQ,OAAO,CAAA,IAAK,CAAA;AAC1B,EAAA,MAAM,QAAQ,CAAC,MAAA,EAAQ,UAAU,QAAA,EAAU,MAAA,EAAQ,SAAS,MAAM,CAAA;AAClE,EAAA,OAAO,GAAG,KAAK,CAAA,CAAA,EAAI,KAAA,CAAM,IAAI,KAAK,OAAO,CAAA,CAAA;AAC3C;AAEA,SAAS,kBAAA,CAAmB,QAAqB,IAAA,EAAyB;AACxE,EAAA,MAAM,EAAA,GAAKA,aAAY,MAAM,CAAA;AAC7B,EAAA,IAAI,SAAS,CAAA,EAAG;AACd,IAAA,OAAO,GAAG,EAAE,CAAA,OAAA,CAAA;AAAA,EACd;AACA,EAAA,OAAO,CAAA,EAAG,EAAE,CAAA,EAAA,EAAK,iBAAA,CAAkB,IAAI,CAAC,CAAA,CAAA;AAC1C;AAEA,SAAS,YAAY,GAAA,EAAwB;AAC3C,EAAA,QAAQ,GAAA;AAAK,IACX,KAAK,GAAA;AACH,MAAA,OAAO,aAAA;AAAA,IACT,KAAK,GAAA;AACH,MAAA,OAAO,aAAA;AAAA,IACT,KAAK,GAAA;AACH,MAAA,OAAO,aAAA;AAAA,IACT,KAAK,GAAA;AACH,MAAA,OAAO,aAAA;AAAA,IACT,KAAK,GAAA;AACH,MAAA,OAAO,aAAA;AAAA,IACT,KAAK,GAAA;AACH,MAAA,OAAO,aAAA;AAAA,IACT,KAAK,GAAA;AACH,MAAA,OAAO,aAAA;AAAA,IACT,KAAK,GAAA;AACH,MAAA,OAAO,aAAA;AAAA,IACT,KAAK,GAAA;AACH,MAAA,OAAO,aAAA;AAAA,IACT,KAAK,GAAA;AACH,MAAA,OAAO,aAAA;AAAA,IACT,KAAK,GAAA;AACH,MAAA,OAAO,aAAA;AAAA,IACT,KAAK,GAAA;AACH,MAAA,OAAO,aAAA;AAAA,IACT;AACE,MAAA,OAAO,CAAA;AAAA;AAEb;AAEA,SAAS,oBAAoB,KAAA,EAA6C;AACxE,EAAA,IAAI,CAAC,KAAA,IAAS,KAAA,KAAU,OAAA,EAAS,OAAO,CAAA;AACxC,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,MAAM,EAAA,GAAK,MAAM,CAAC,CAAA;AAClB,IAAA,MAAM,EAAA,GAAK,MAAM,CAAC,CAAA;AAClB,IAAA,IAAI,MAAM,EAAA,EAAI;AACZ,MAAA,MAAM,KAAA,GAAQ,GAAG,WAAA,EAAY;AAC7B,MAAA,MAAM,IAAA,GAAO,GAAG,WAAA,EAAY;AAC5B,MAAA,IAAI,KAAA,KAAU,GAAA,EAAK,OAAO,WAAA,CAAY,IAAI,CAAA;AAC1C,MAAA,IAAI,UAAU,GAAA,EAAK,OAAO,WAAA,CAAY,IAAA,CAAK,aAAa,CAAA;AAAA,IAC1D;AAAA,EACF;AACA,EAAA,OAAO,YAAY,KAAK,CAAA;AAC1B;AAEA,SAAS,uBAAuB,KAAA,EAAiD;AAC/E,EAAA,IAAI,CAAC,KAAA,IAAS,KAAA,KAAU,OAAA,EAAS,OAAO,IAAA;AACxC,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,MAAM,EAAA,GAAK,MAAM,CAAC,CAAA;AAClB,IAAA,MAAM,EAAA,GAAK,MAAM,CAAC,CAAA;AAClB,IAAA,IAAI,MAAM,EAAA,EAAI;AACZ,MAAA,MAAM,KAAA,GAAQ,EAAA,KAAO,GAAA,GAAM,GAAA,GAAM,GAAA;AACjC,MAAA,OAAO,CAAA,EAAG,KAAK,CAAA,EAAG,EAAE,CAAA,CAAA;AAAA,IACtB;AAAA,EACF;AACA,EAAA,OAAO,KAAA,KAAU,MAAM,WAAA,EAAY,GAAI,MAAM,WAAA,EAAY,GAAI,MAAM,WAAA,EAAY;AACjF;AAEA,SAAS,UAAA,CACP,OAAA,EACA,SAAA,EACA,WAAA,EACa;AACb,EAAA,MAAM,OAAO,OAAA,GAAU,CAAA;AACvB,EAAA,MAAM,OAAO,OAAA,IAAW,CAAA;AACxB,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,IAAA,GAAO,CAAA,GAAI,IAAA;AACjD,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,IAAA,GAAO,IAAA;AAEjD,EAAA,IAAI,MAAA,GAAS,GAAA;AACb,EAAA,IAAI,MAAA,GAAS,GAAA;AACb,EAAA,QAAQ,SAAA;AAAW,IACjB,KAAK,IAAA;AACH,MAAA,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAA,GAAM,CAAC,CAAA;AAC5B,MAAA;AAAA,IACF,KAAK,MAAA;AACH,MAAA,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAA,GAAM,CAAC,CAAA;AAC5B,MAAA;AAAA,IACF,KAAK,MAAA;AACH,MAAA,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAA,GAAM,CAAC,CAAA;AAC5B,MAAA;AAAA,IACF,KAAK,OAAA;AACH,MAAA,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAA,GAAM,CAAC,CAAA;AAC5B,MAAA;AAAA;AAGJ,EAAA,MAAM,OAAA,GAAU,WAAA,KAAgB,OAAA,GAAU,MAAA,GAAS,CAAA,GAAI,MAAA;AACvD,EAAA,MAAM,OAAA,GAAU,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,MAAA,GAAS,MAAA;AACvD,EAAA,OAAS,OAAA,GAAU,IAAI,OAAA,GAAW,EAAA;AACpC;AAEA,SAAS,aAAA,CACP,OAAA,EACA,KAAA,EACA,WAAA,EACa;AACb,EAAA,MAAM,OAAO,OAAA,IAAW,CAAA;AACxB,EAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,IAAA,OAAS,IAAA,IAAQ,CAAA,IAAM,KAAA,KAAU,MAAA,GAAS,CAAA,GAAI,CAAA,CAAA;AAAA,EAChD;AACA,EAAA,OAAS,IAAA,IAAQ,CAAA,IAAM,KAAA,KAAU,MAAA,GAAS,CAAA,GAAI,CAAA,CAAA;AAChD;AAiDO,SAAS,WAAA,CAAY;AAAA,EAC1B,GAAA,GAAM,2BAAA;AAAA,EACN,QAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,WAAA,GAAc,OAAA;AAAA,EACd,KAAA,GAAQ,YAAA;AAAA,EACR,MAAA,GAAS,aAAA;AAAA,EACT,eAAA,GAAkB,KAAA;AAAA,EAClB,KAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA,GAAY,cAAA;AAAA,EACZ,UAAA;AAAA,EACA,kBAAA;AAAA,EACA,aAAA,EAAe,iBAAA;AAAA,EACf,aAAA;AAAA,EACA,EAAA;AAAA,EACA,OAAA;AAAA,EACA,qBAAA;AAAA,EACA,kBAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,YAAA,GAAe,OAAuB,IAAI,CAAA;AAChD,EAAA,MAAM,aAAA,GAAgB,OAAuB,IAAI,CAAA;AACjD,EAAA,MAAM,WAAA,GAAc,OAAO,CAAC,CAAA;AAC5B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAqB,MAAM;AACnD,IAAA,IAAI;AACF,MAAA,OAAO,kBAAkB,GAAG,CAAA;AAAA,IAC9B,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAI,WAAW,EAAE,CAAA;AAAA,IAC1B;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAM,CAAC,qBAAA,EAAuB,wBAAwB,CAAA,GAAI,QAAA;AAAA,IACxD,MAAO,WAAA,KAAgB,OAAA,GAAU,EAAA,GAAK;AAAA;AAAA,GACxC;AACA,EAAA,MAAM,gBAAgB,iBAAA,IAAqB,qBAAA;AAC3C,EAAA,MAAM,gBAAA,GAAmB,wBAAA;AACzB,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,SAAS,KAAK,CAAA;AAG9D,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAKtB,IAAI,CAAA;AAEd,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,GAAY,kBAAkB,GAAG,CAAA;AACvC,MAAA,QAAA,CAAS,SAAS,CAAA;AAAA,IACpB,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,MAAM,QAAA,GAAWC,WAAAA;AAAA,IACf,CAAC,OAAA,KAAoB;AACnB,MAAA,UAAA,GAAa,OAAO,CAAA;AACpB,MAAA,MAAM,SAAS,aAAA,CAAc,OAAA;AAC7B,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,WAAA,CAAY,OAAA,EAAA;AACZ,QAAA,MAAA,CAAO,YAAA,CAAa,cAAA,EAAgB,MAAA,CAAO,WAAA,CAAY,OAAO,CAAC,CAAA;AAC/D,QAAA,MAAA,CAAO,WAAA,GAAc,EAAA;AACrB,QAAA,KAAK,MAAA,CAAO,YAAA;AACZ,QAAA,MAAA,CAAO,WAAA,GAAc,OAAA;AAAA,MACvB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,UAAU;AAAA,GACb;AAEA,EAAA,MAAM,oBAAA,GAAuBA,WAAAA;AAAA,IAC3B,CAAC,QAAqB,IAAA,KAAoB;AACxC,MAAA,MAAM,EAAA,GAAKD,aAAY,MAAM,CAAA;AAC7B,MAAA,IAAI,kBAAA,EAAoB;AACtB,QAAA,OAAO,kBAAA,CAAmB,MAAA,EAAQ,IAAA,EAAM,EAAE,CAAA;AAAA,MAC5C;AACA,MAAA,OAAO,kBAAA,CAAmB,QAAQ,IAAI,CAAA;AAAA,IACxC,CAAA;AAAA,IACA,CAAC,kBAAkB;AAAA,GACrB;AAEA,EAAA,MAAM,cAAA,GAAiBC,WAAAA;AAAA,IACrB,CAAC,MAAA,KAAwB;AACvB,MAAA,MAAM,IAAA,GAAQ,KAAA,CAAM,MAAM,CAAA,IAAK,CAAA;AAC/B,MAAA,MAAM,IAAA,GAAO,oBAAA,CAAqB,MAAA,EAAQ,IAAI,CAAA;AAC9C,MAAA,QAAA,CAAS,IAAI,CAAA;AACb,MAAA,aAAA,GAAgB,MAAA,EAAQ,IAAA,EAAMD,YAAAA,CAAY,MAAM,CAAC,CAAA;AAAA,IACnD,CAAA;AAAA,IACA,CAAC,QAAA,EAAU,KAAA,EAAO,oBAAA,EAAsB,aAAa;AAAA,GACvD;AAEA,EAAA,MAAM,WAAA,GAAcC,WAAAA;AAAA,IAClB,CAAC,SAAA,KAA0B;AACzB,MAAA,QAAA,CAAS,SAAS,CAAA;AAClB,MAAA,MAAM,YAAA,GAAe,mBAAmB,SAAS,CAAA;AACjD,MAAA,MAAM,UAAA,GAAa,kBAAA,CAAmB,GAAA,EAAK,YAAY,CAAA;AACvD,MAAA,QAAA,GAAW,UAAU,CAAA;AAAA,IACvB,CAAA;AAAA,IACA,CAAC,KAAK,QAAQ;AAAA,GAChB;AAEA,EAAA,MAAM,YAAA,GAAeA,WAAAA;AAAA,IACnB,CAAC,QAAqB,UAAA,KAAmC;AACvD,MAAA,MAAM,aACJ,OAAO,UAAA,KAAe,QAAA,GAAW,mBAAA,CAAoB,UAAU,CAAA,GAAI,UAAA;AACrE,MAAA,MAAM,WAAA,GAAe,KAAA,CAAM,MAAM,CAAA,IAAK,CAAA;AACtC,MAAA,MAAM,SAAA,GAAY,IAAI,UAAA,CAAW,KAAK,CAAA;AAEtC,MAAA,IAAI,UAAA,KAAe,CAAA,IAAK,WAAA,KAAgB,UAAA,EAAY;AAElD,QAAA,SAAA,CAAU,MAAM,CAAA,GAAI,CAAA;AACpB,QAAA,WAAA,CAAY,SAAS,CAAA;AACrB,QAAA,aAAA,GAAgB,MAAA,EAAQ,CAAA,EAAgBD,YAAAA,CAAY,MAAM,CAAC,CAAA;AAC3D,QAAA,QAAA,CAAS,CAAA,mBAAA,EAAsBA,YAAAA,CAAY,MAAM,CAAC,CAAA,CAAE,CAAA;AAAA,MACtD,CAAA,MAAA,IAAW,eAAe,CAAA,EAAG;AAC3B,QAAA,SAAA,CAAU,MAAM,CAAA,GAAI,UAAA;AACpB,QAAA,WAAA,CAAY,SAAS,CAAA;AACrB,QAAA,aAAA,GAAgB,MAAA,EAAQ,UAAA,EAAYA,YAAAA,CAAY,MAAM,CAAC,CAAA;AACvD,QAAA,MAAM,IAAA,GAAO,kBAAkB,UAAU,CAAA;AACzC,QAAA,QAAA,CAAS,GAAG,IAAI,CAAA,WAAA,EAAcA,YAAAA,CAAY,MAAM,CAAC,CAAA,CAAE,CAAA;AACnD,QAAA,MAAM,IAAA,GAAO,WAAA,CAAY,UAAU,CAAA,IAAK,EAAA;AACxC,QAAA,MAAM,IAAA,GAAO,cAAc,CAAA,GAAI,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,GAAK,CAAA,CAAA,EAAI,IAAA,CAAK,WAAA,EAAa,CAAA,CAAA;AAClE,QAAA,aAAA,GAAgB,IAAI,CAAA;AAAA,MACtB,CAAA,MAAO;AACL,QAAA,SAAA,CAAU,MAAM,CAAA,GAAI,CAAA;AACpB,QAAA,WAAA,CAAY,SAAS,CAAA;AACrB,QAAA,aAAA,GAAgB,MAAA,EAAQ,CAAA,EAAgBA,YAAAA,CAAY,MAAM,CAAC,CAAA;AAC3D,QAAA,QAAA,CAAS,CAAA,mBAAA,EAAsBA,YAAAA,CAAY,MAAM,CAAC,CAAA,CAAE,CAAA;AAAA,MACtD;AAAA,IACF,CAAA;AAAA,IACA,CAAC,QAAA,EAAU,KAAA,EAAO,WAAA,EAAa,eAAe,aAAa;AAAA,GAC7D;AAEA,EAAA,MAAM,aAAA,GAAgBC,WAAAA;AAAA,IACpB,CAAC,MAAA,KAAwB;AACvB,MAAA,MAAM,OAAA,GAAU,KAAA,CAAM,MAAM,CAAA,IAAK,CAAA;AACjC,MAAA,IAAI,YAAY,CAAA,EAAG;AACjB,QAAA,QAAA,CAAS,CAAA,EAAGD,YAAAA,CAAY,MAAM,CAAC,CAAA,SAAA,CAAW,CAAA;AAC1C,QAAA;AAAA,MACF;AACA,MAAA,MAAM,SAAA,GAAY,IAAI,UAAA,CAAW,KAAK,CAAA;AACtC,MAAA,SAAA,CAAU,MAAM,CAAA,GAAI,CAAA;AACpB,MAAA,WAAA,CAAY,SAAS,CAAA;AACrB,MAAA,aAAA,GAAgB,MAAA,EAAQ,CAAA,EAAgBA,YAAAA,CAAY,MAAM,CAAC,CAAA;AAC3D,MAAA,QAAA,CAAS,CAAA,mBAAA,EAAsBA,YAAAA,CAAY,MAAM,CAAC,CAAA,CAAE,CAAA;AAAA,IACtD,CAAA;AAAA,IACA,CAAC,QAAA,EAAU,KAAA,EAAO,WAAA,EAAa,aAAa;AAAA,GAC9C;AAEA,EAAA,MAAM,aAAA,GAAgBC,WAAAA;AAAA,IACpB,CAAC,CAAA,KAA2C;AAC1C,MAAA,IAAI,CAAA,CAAE,MAAA,IAAU,CAAA,CAAE,OAAA,IAAW,EAAE,OAAA,EAAS;AAGxC,MAAA,IAAI,CAAA,CAAE,GAAA,CAAI,UAAA,CAAW,OAAO,CAAA,EAAG;AAC7B,QAAA,IAAI,EAAE,QAAA,EAAU;AAChB,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,MAAM,GAAA,GACJ,CAAA,CAAE,GAAA,KAAQ,SAAA,GACN,IAAA,GACA,CAAA,CAAE,GAAA,KAAQ,WAAA,GACR,MAAA,GACA,CAAA,CAAE,GAAA,KAAQ,WAAA,GACR,MAAA,GACA,OAAA;AACV,QAAA,MAAM,IAAA,GAAO,UAAA,CAAW,aAAA,EAAe,GAAA,EAAK,WAAW,CAAA;AACvD,QAAA,gBAAA,CAAiB,IAAI,CAAA;AACrB,QAAA,cAAA,CAAe,IAAI,CAAA;AACnB,QAAA;AAAA,MACF;AAGA,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,MAAA,IAAU,CAAA,CAAE,QAAQ,KAAA,EAAO;AACvC,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,MAAM,IAAA,GAAO,cAAc,aAAA,EAAe,CAAA,CAAE,QAAQ,MAAA,GAAS,MAAA,GAAS,OAAO,WAAW,CAAA;AACxF,QAAA,gBAAA,CAAiB,IAAI,CAAA;AACrB,QAAA,cAAA,CAAe,IAAI,CAAA;AACnB,QAAA;AAAA,MACF;AAGA,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,WAAA,IAAe,CAAA,CAAE,GAAA,KAAQ,QAAA,IAAY,CAAA,CAAE,GAAA,KAAQ,GAAA,IAAO,CAAA,CAAE,GAAA,KAAQ,GAAA,EAAK;AACjF,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,aAAA,CAAc,aAAa,CAAA;AAC3B,QAAA;AAAA,MACF;AAGA,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,GAAA,IAAO,CAAA,CAAE,QAAQ,GAAA,EAAK;AAClC,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,OAAA,EAAQ;AAAA,QACV,CAAA,MAAO;AACL,UAAA,WAAA,CAAY,IAAI,UAAA,CAAW,EAAE,CAAC,CAAA;AAC9B,UAAA,QAAA,CAAS,eAAe,CAAA;AAAA,QAC1B;AACA,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,GAAA,IAAO,CAAA,CAAE,QAAQ,GAAA,EAAK;AAClC,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,IAAI,qBAAA,EAAuB;AACzB,UAAA,qBAAA,EAAsB;AAAA,QACxB,CAAA,MAAO;AACL,UAAA,WAAA,CAAY,iBAAA,CAAkB,YAAY,CAAC,CAAA;AAC3C,UAAA,QAAA,CAAS,mBAAmB,CAAA;AAAA,QAC9B;AACA,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,GAAA,IAAO,CAAA,CAAE,QAAQ,GAAA,EAAK;AAClC,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,kBAAA,IAAqB;AACrB,QAAA;AAAA,MACF;AAGA,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,OAAA,IAAW,CAAA,CAAE,QAAQ,GAAA,EAAK;AACtC,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,IAAI,aAAA,EAAe;AACjB,UAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,QAAA,GAAW,sBAAA,CAAuB,aAAa,CAAA,GAAI,aAAA;AACnE,UAAA,IAAI,KAAA,EAAO,YAAA,CAAa,aAAA,EAAe,KAAK,CAAA;AAAA,QAC9C;AACA,QAAA;AAAA,MACF;AAGA,MAAA,MAAM,SAAA,GAAY,WAAA,CAAY,CAAA,CAAE,GAAG,CAAA;AACnC,MAAA,IAAI,cAAc,CAAA,EAAG;AACnB,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,YAAA,CAAa,eAAe,SAAS,CAAA;AAAA,MACvC;AAAA,IACF,CAAA;AAAA,IACA;AAAA,MACE,QAAA;AAAA,MACA,cAAA;AAAA,MACA,WAAA;AAAA,MACA,aAAA;AAAA,MACA,OAAA;AAAA,MACA,qBAAA;AAAA,MACA,kBAAA;AAAA,MACA,WAAA;AAAA,MACA,YAAA;AAAA,MACA,aAAA;AAAA,MACA;AAAA;AACF,GACF;AAGA,EAAA,MAAM,iBAAA,GAAoB,CAAC,CAAA,KAA0C;AACnE,IAAA,IAAI,CAAA,CAAE,WAAW,CAAA,EAAG;AACpB,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,CAAC,SAAA,EAAW;AAEhB,IAAA,MAAM,KAAK,gBAAA,CAAiB,SAAA,EAAW,EAAE,OAAA,EAAS,CAAA,CAAE,SAAS,WAAW,CAAA;AACxE,IAAA,IAAI,OAAO,IAAA,EAAM;AAEjB,IAAA,SAAA,CAAU,KAAA,EAAM;AAChB,IAAA,gBAAA,CAAiB,EAAE,CAAA;AACnB,IAAA,aAAA,GAAgB,IAAK,KAAA,CAAM,EAAE,KAAK,CAAA,EAAiBD,YAAAA,CAAY,EAAE,CAAC,CAAA;AAClE,IAAA,MAAM,IAAA,GAAQ,KAAA,CAAM,EAAE,CAAA,IAAK,CAAA;AAE3B,IAAA,IAAI,SAAS,CAAA,EAAG;AAEd,MAAA,IAAI,aAAA,EAAe;AACjB,QAAA,YAAA,CAAa,IAAI,aAAa,CAAA;AAAA,MAChC;AACA,MAAA;AAAA,IACF;AAGA,IAAA,CAAA,CAAE,aAAA,CAAc,iBAAA,CAAkB,CAAA,CAAE,SAAS,CAAA;AAC7C,IAAA,WAAA,CAAY;AAAA,MACV,MAAA,EAAQ,EAAA;AAAA,MACR,IAAA;AAAA,MACA,GAAG,CAAA,CAAE,OAAA;AAAA,MACL,GAAG,CAAA,CAAE;AAAA,KACN,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,iBAAA,GAAoB,CAAC,CAAA,KAA0C;AACnE,IAAA,IAAI,CAAC,QAAA,EAAU;AACf,IAAA,WAAA,CAAY,CAAC,IAAA,KAAU,IAAA,GAAO,EAAE,GAAG,IAAA,EAAM,CAAA,EAAG,CAAA,CAAE,OAAA,EAAS,CAAA,EAAG,CAAA,CAAE,OAAA,KAAY,IAAK,CAAA;AAAA,EAC/E,CAAA;AAEA,EAAA,MAAM,eAAA,GAAkB,CAAC,CAAA,KAA0C;AACjE,IAAA,IAAI,CAAC,QAAA,EAAU;AACf,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,MAAM,WAAW,QAAA,CAAS,MAAA;AAC1B,IAAA,MAAM,YAAY,QAAA,CAAS,IAAA;AAC3B,IAAA,WAAA,CAAY,IAAI,CAAA;AAEhB,IAAA,IAAI,CAAC,SAAA,EAAW;AAChB,IAAA,MAAM,WAAW,gBAAA,CAAiB,SAAA,EAAW,EAAE,OAAA,EAAS,CAAA,CAAE,SAAS,WAAW,CAAA;AAE9E,IAAA,IAAI,aAAa,IAAA,EAAM;AAErB,MAAA,aAAA,CAAc,QAAQ,CAAA;AACtB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,aAAa,QAAA,EAAU;AAEzB,MAAA,IAAI,aAAA,EAAe;AACjB,QAAA,YAAA,CAAa,UAAU,aAAa,CAAA;AAAA,MACtC;AACA,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,SAAA,GAAY,IAAI,UAAA,CAAW,KAAK,CAAA;AACtC,IAAA,SAAA,CAAU,QAAQ,CAAA,GAAI,CAAA;AACtB,IAAA,SAAA,CAAU,QAAQ,CAAA,GAAI,SAAA;AACtB,IAAA,WAAA,CAAY,SAAS,CAAA;AACrB,IAAA,QAAA,CAAS,CAAA,EAAG,kBAAkB,SAAS,CAAC,aAAaA,YAAAA,CAAY,QAAQ,CAAC,CAAA,CAAE,CAAA;AAC5E,IAAA,gBAAA,CAAiB,QAAQ,CAAA;AAAA,EAC3B,CAAA;AAEA,EAAA,MAAM,iBAAA,GAAoB,CAAC,CAAA,KAAwC;AACjE,IAAA,CAAA,CAAE,cAAA,EAAe;AACjB,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,CAAC,SAAA,EAAW;AAChB,IAAA,MAAM,KAAK,gBAAA,CAAiB,SAAA,EAAW,EAAE,OAAA,EAAS,CAAA,CAAE,SAAS,WAAW,CAAA;AACxE,IAAA,IAAI,OAAO,IAAA,EAAM;AAEjB,IAAA,gBAAA,CAAiB,EAAE,CAAA;AACnB,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,MAAM,GAAA,GAAM,uBAAuB,aAAa,CAAA;AAChD,MAAA,IAAI,GAAA,EAAK,YAAA,CAAa,EAAA,EAAI,GAAG,CAAA;AAAA,IAC/B;AAAA,EACF,CAAA;AAGA,EAAA,MAAM,WAAA,GAAc,QAAQ,MAAM;AAChC,IAAA,MAAM,UAAyB,EAAC;AAChC,IAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,MAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,IAAQ,CAAA,EAAG,IAAA,EAAA,EAAQ;AACpC,QAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,GAAO,CAAA,EAAG,IAAA,EAAA,EAAQ;AACnC,UAAA,OAAA,CAAQ,IAAA,CAAM,IAAA,GAAO,CAAA,GAAI,IAAoB,CAAA;AAAA,QAC/C;AAAA,MACF;AAAA,IACF,CAAA,MAAO;AACL,MAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,GAAO,CAAA,EAAG,IAAA,EAAA,EAAQ;AACnC,QAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,IAAQ,CAAA,EAAG,IAAA,EAAA,EAAQ;AACpC,UAAA,OAAA,CAAQ,IAAA,CAAM,IAAA,GAAO,CAAA,GAAI,IAAoB,CAAA;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;AAEhB,EAAA,MAAM,cAAA,GAAgC;AAAA,IACpC,QAAA,EAAU,UAAA;AAAA,IACV,WAAA,EAAa,OAAA;AAAA,IACb,KAAA,EAAO,MAAA;AAAA,IACP,WAAA,EAAa,MAAA;AAAA,IACb,OAAA,EAAS,mBAAmB,2CAAA,GAA8C,MAAA;AAAA,IAC1E,aAAA,EAAe,KAAA;AAAA,IACf,YAAA,EAAc,KAAA;AAAA,IACd,GAAI,KAAA;AAAA,IACJ,GAAG;AAAA,GACL;AAEA,EAAA,uBACEE,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,YAAA;AAAA,MACL,EAAA;AAAA,MACA,IAAA,EAAK,aAAA;AAAA,MAEL,QAAA,EAAU,CAAA;AAAA,MACV,YAAA,EAAY,SAAA;AAAA,MACZ,mBAAA,EAAkB,yGAAA;AAAA,MAClB,SAAA,EAAW,aAAA;AAAA,MACX,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,QAAA,IAAI,CAAA,CAAE,MAAA,KAAW,CAAA,CAAE,aAAA,EAAe;AAChC,UAAA,mBAAA,CAAoB,IAAI,CAAA;AACxB,UAAA,cAAA,CAAe,aAAa,CAAA;AAAA,QAC9B;AACA,QAAA,OAAA,GAAU,CAAC,CAAA;AAAA,MACb,CAAA;AAAA,MACA,MAAA,EAAQ,CAAC,CAAA,KAAM;AACb,QAAA,IAAI,CAAA,CAAE,MAAA,KAAW,CAAA,CAAE,aAAA,EAAe;AAChC,UAAA,mBAAA,CAAoB,KAAK,CAAA;AAAA,QAC3B;AACA,QAAA,MAAA,GAAS,CAAC,CAAA;AAAA,MACZ,CAAA;AAAA,MACA,aAAA,EAAe,iBAAA;AAAA,MACf,aAAA,EAAe,iBAAA;AAAA,MACf,WAAA,EAAa,eAAA;AAAA,MACb,eAAA,EAAiB,MAAM,WAAA,CAAY,IAAI,CAAA;AAAA,MACvC,aAAA,EAAe,iBAAA;AAAA,MACf,SAAA;AAAA,MACA,KAAA,EAAO,cAAA;AAAA,MACP,gBAAA,EAAe,MAAA;AAAA,MACf,qBAAA,EAAqB,WAAA;AAAA,MAGrB,QAAA,EAAA;AAAA,wBAAAJ,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAY,MAAA;AAAA,YACZ,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,UAAA;AAAA,cACV,KAAA,EAAO,CAAA;AAAA,cACP,OAAA,EAAS,MAAA;AAAA,cACT,mBAAA,EAAqB,gBAAA;AAAA,cACrB,gBAAA,EAAkB,gBAAA;AAAA,cAClB,aAAA,EAAe;AAAA,aACjB;AAAA,YAEC,QAAA,EAAA,WAAA,CAAY,GAAA,CAAI,CAAC,EAAA,KAAO;AACvB,cAAA,MAAM,OAAO,EAAA,GAAK,CAAA;AAClB,cAAA,MAAM,OAAO,EAAA,IAAM,CAAA;AACnB,cAAA,MAAM,OAAA,GAAA,CAAY,IAAA,GAAO,IAAA,GAAQ,CAAA,MAAO,CAAA;AACxC,cAAA,MAAM,SAAA,GAAY,oBAAoB,aAAA,KAAkB,EAAA;AAExD,cAAA,uBACEA,GAAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBAEC,aAAA,EAAaE,aAAY,EAAE,CAAA;AAAA,kBAC3B,KAAA,EAAO;AAAA,oBACL,QAAA,EAAU,UAAA;AAAA,oBACV,iBAAiB,CAAA,IAAA,EAAO,OAAA,GAAU,QAAA,CAAS,QAAA,GAAW,SAAS,OAAO,CAAA,CAAA,CAAA;AAAA,oBACtE,iBAAiB,CAAA,IAAA,EAAO,OAAA,GAAU,QAAA,CAAS,cAAA,GAAiB,SAAS,aAAa,CAAA,MAAA,CAAA;AAAA,oBAClF,cAAA,EAAgB,CAAA,IAAA,EAAO,QAAA,CAAS,aAAa,CAAA,OAAA,CAAA;AAAA,oBAC7C,SAAA,EAAW,YAAY,0CAAA,GAA6C,MAAA;AAAA,oBACpE,UAAA,EAAY;AAAA;AACd,iBAAA;AAAA,gBATK;AAAA,eAUP;AAAA,YAEJ,CAAC;AAAA;AAAA,SACH;AAAA,wBAGAF,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAY,MAAA;AAAA,YACZ,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,UAAA;AAAA,cACV,KAAA,EAAO,CAAA;AAAA,cACP,OAAA,EAAS,MAAA;AAAA,cACT,mBAAA,EAAqB,gBAAA;AAAA,cACrB,gBAAA,EAAkB,gBAAA;AAAA,cAClB,aAAA,EAAe;AAAA,aACjB;AAAA,YAEC,QAAA,EAAA,WAAA,CAAY,GAAA,CAAI,CAAC,EAAA,KAAO;AACvB,cAAA,MAAM,IAAA,GAAQ,KAAA,CAAM,EAAE,CAAA,IAAK,CAAA;AAC3B,cAAA,IAAI,IAAA,KAAS,GAAG,OAAO,IAAA;AACvB,cAAA,MAAM,QAAA,GAAW,UAAU,MAAA,KAAW,EAAA;AACtC,cAAA,MAAM,EAAE,GAAA,EAAK,GAAA,EAAI,GAAI,SAAA,CAAU,IAAI,WAAW,CAAA;AAE9C,cAAA,uBACEA,GAAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBAEC,mBAAA,EAAmBE,aAAY,EAAE,CAAA;AAAA,kBACjC,KAAA,EAAO;AAAA,oBACL,GAAG,eAAA;AAAA,oBACH,eAAA,EAAiB,GAAA;AAAA,oBACjB,YAAA,EAAc,GAAA;AAAA,oBACd,OAAA,EAAS,WAAW,IAAA,GAAO,CAAA;AAAA,oBAC3B,QAAQ,CAAA,IAAA,EAAO,IAAA,IAAQ,IAAI,QAAA,CAAS,kBAAA,GAAqB,SAAS,kBAAkB,CAAA,OAAA,CAAA;AAAA,oBACpF,aAAA,EAAe;AAAA,mBACjB;AAAA,kBAEC,QAAA,EAAA,MAAA,CAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAI;AAAA,iBAAA;AAAA,gBAXvB;AAAA,eAYP;AAAA,YAEJ,CAAC;AAAA;AAAA,SACH;AAAA,QAGC,oCACCF,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAY,MAAA;AAAA,YACZ,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,UAAA;AAAA,cACV,KAAA,EAAO,CAAA;AAAA,cACP,OAAA,EAAS,MAAA;AAAA,cACT,mBAAA,EAAqB,gBAAA;AAAA,cACrB,gBAAA,EAAkB,gBAAA;AAAA,cAClB,aAAA,EAAe,MAAA;AAAA,cACf,MAAA,EAAQ;AAAA,aACV;AAAA,YAEE,QAAA,EAAA,CAAA,MAAM;AACN,cAAA,MAAM,EAAE,GAAA,EAAK,GAAA,EAAI,GAAI,SAAA,CAAU,eAAe,WAAW,CAAA;AACzD,cAAA,uBACEA,GAAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBACC,6BAAA,EAA6BE,aAAY,aAAa,CAAA;AAAA,kBACtD,KAAA,EAAO;AAAA,oBACL,eAAA,EAAiB,GAAA;AAAA,oBACjB,YAAA,EAAc,GAAA;AAAA,oBACd,OAAA,EAAS,8CAAA;AAAA,oBACT,aAAA,EAAe,MAAA;AAAA,oBACf,SAAA,EACE,wEAAA;AAAA,oBACF,YAAA,EAAc,KAAA;AAAA,oBACd,aAAA,EAAe;AAAA;AACjB;AAAA,eACF;AAAA,YAEJ,CAAA;AAAG;AAAA,SACL;AAAA,QAID,QAAA,IAAY,YAAA,CAAa,OAAA,mBACxBF,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAY,MAAA;AAAA,YACZ,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,OAAA;AAAA,cACV,IAAA,EAAM,SAAS,CAAA,GAAI,EAAA;AAAA,cACnB,GAAA,EAAK,SAAS,CAAA,GAAI,EAAA;AAAA,cAClB,KAAA,EAAO,EAAA;AAAA,cACP,MAAA,EAAQ,EAAA;AAAA,cACR,aAAA,EAAe,MAAA;AAAA,cACf,MAAA,EAAQ,GAAA;AAAA,cACR,MAAA,EAAQ,OAAO,QAAA,CAAS,IAAA,IAAQ,IAAI,QAAA,CAAS,kBAAA,GAAqB,SAAS,kBAAkB,CAAA,OAAA;AAAA,aAC/F;AAAA,YAEC,QAAA,EAAA,MAAA,CAAO,EAAE,IAAA,EAAM,QAAA,CAAS,MAAM,MAAA,EAAQ,QAAA,CAAS,QAAQ;AAAA;AAAA,SAC1D,GACE,IAAA;AAAA,QAGH,eAAA,mBAAkBA,GAAAA,CAAC,WAAA,EAAA,EAAY,aAA0B,CAAA,GAAK,IAAA;AAAA,wBAG/DA,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,aAAA;AAAA,YACL,IAAA,EAAK,QAAA;AAAA,YACL,WAAA,EAAU,WAAA;AAAA,YACV,aAAA,EAAY,MAAA;AAAA,YACZ,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,UAAA;AAAA,cACV,KAAA,EAAO,CAAA;AAAA,cACP,MAAA,EAAQ,CAAA;AAAA,cACR,OAAA,EAAS,CAAA;AAAA,cACT,MAAA,EAAQ,EAAA;AAAA,cACR,QAAA,EAAU,QAAA;AAAA,cACV,IAAA,EAAM,kBAAA;AAAA,cACN,UAAA,EAAY,QAAA;AAAA,cACZ,MAAA,EAAQ;AAAA;AACV;AAAA;AACF;AAAA;AAAA,GACF;AAEJ;ACpsBA,SAAS,eAAA,CAAgB,OAAe,WAAA,EAAsD;AAC5F,EAAA,MAAM,OAAO,KAAA,GAAQ,CAAA;AACrB,EAAA,MAAM,OAAO,KAAA,IAAS,CAAA;AACtB,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,IAAA,GAAO,CAAA,GAAI,IAAA;AACjD,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,IAAA,GAAO,IAAA;AACjD,EAAA,OAAO,EAAE,IAAI,GAAA,GAAM,IAAA,GAAO,MAAM,EAAA,EAAI,GAAA,GAAM,OAAO,IAAA,EAAK;AACxD;AAkBA,SAAS,YAAA,CAAa,WAAmB,OAAA,EAA0B;AACjE,EAAA,MAAM,YAAY,IAAA,CAAK,GAAA,CAAA,CAAK,OAAA,GAAU,CAAA,KAAM,YAAY,CAAA,CAAE,CAAA;AAC1D,EAAA,MAAM,YAAY,IAAA,CAAK,GAAA,CAAA,CAAK,OAAA,IAAW,CAAA,KAAM,aAAa,CAAA,CAAE,CAAA;AAC5D,EAAA,OAAQ,cAAc,CAAA,IAAK,SAAA,KAAc,CAAA,IAAO,SAAA,KAAc,KAAK,SAAA,KAAc,CAAA;AACnF;AAEA,SAAS,UAAA,CAAW,MAAa,EAAA,EAAyB;AACxD,EAAA,MAAM,EAAA,GAAK,EAAA,CAAG,CAAA,GAAI,IAAA,CAAK,CAAA;AACvB,EAAA,MAAM,EAAA,GAAK,EAAA,CAAG,CAAA,GAAI,IAAA,CAAK,CAAA;AACvB,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,EAAA,EAAI,EAAE,CAAA;AAC7B,EAAA,IAAI,GAAA,KAAQ,GAAG,OAAO,IAAA;AACtB,EAAA,OAAO,EAAE,CAAA,EAAG,EAAA,GAAK,GAAA,EAAK,CAAA,EAAG,KAAK,GAAA,EAAI;AACpC;AAEA,SAAS,UACP,SAAA,EACA,OAAA,EACA,OACA,GAAA,EACA,WAAA,EACA,WACA,UAAA,EACkB;AAClB,EAAA,IAAI,CAAC,YAAA,CAAa,SAAA,EAAW,OAAO,CAAA,EAAG;AACrC,IAAA,MAAM,IAAA,GAAO,UAAA,CAAW,KAAA,EAAO,GAAG,CAAA;AAClC,IAAA,IAAI,IAAA,KAAS,MAAM,OAAO,IAAA;AAC1B,IAAA,MAAMK,IAAAA,GAAM,EAAE,CAAA,EAAG,GAAA,CAAI,CAAA,GAAI,IAAA,CAAK,CAAA,GAAI,SAAA,EAAW,CAAA,EAAG,GAAA,CAAI,CAAA,GAAI,IAAA,CAAK,IAAI,SAAA,EAAU;AAC3E,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,EAAE,CAAA,EAAG,KAAA,CAAM,CAAA,GAAI,IAAA,CAAK,CAAA,GAAI,WAAA,EAAa,CAAA,EAAG,KAAA,CAAM,CAAA,GAAI,IAAA,CAAK,IAAI,WAAA,EAAY;AAAA,MAC9E,MAAA,EAAQ,IAAA;AAAA,MACR,QAAA,EAAU,EAAE,CAAA,EAAGA,IAAAA,CAAI,CAAA,GAAI,IAAA,CAAK,CAAA,GAAI,UAAA,EAAY,CAAA,EAAGA,IAAAA,CAAI,CAAA,GAAI,IAAA,CAAK,IAAI,UAAA,EAAW;AAAA,MAC3E,GAAA,EAAAA,IAAAA;AAAA,MACA,SAAA,EAAW;AAAA,KACb;AAAA,EACF;AAEA,EAAA,MAAM,EAAA,GAAK,GAAA,CAAI,CAAA,GAAI,KAAA,CAAM,CAAA;AACzB,EAAA,MAAM,EAAA,GAAK,GAAA,CAAI,CAAA,GAAI,KAAA,CAAM,CAAA;AACzB,EAAA,MAAM,MAAA,GAAS,KAAK,GAAA,CAAI,EAAE,IAAI,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,GAAI,EAAE,CAAA,EAAG,IAAI,CAAA,EAAG,CAAA,EAAG,KAAA,CAAM,CAAA,EAAE,GAAI,EAAE,GAAG,KAAA,CAAM,CAAA,EAAG,CAAA,EAAG,GAAA,CAAI,CAAA,EAAE;AAC/F,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,KAAA,EAAO,MAAM,CAAA;AAC1C,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,MAAA,EAAQ,GAAG,CAAA;AACxC,EAAA,IAAI,SAAA,KAAc,IAAA,IAAQ,SAAA,KAAc,IAAA,EAAM,OAAO,IAAA;AAErD,EAAA,MAAM,GAAA,GAAM,EAAE,CAAA,EAAG,GAAA,CAAI,CAAA,GAAI,SAAA,CAAU,CAAA,GAAI,SAAA,EAAW,CAAA,EAAG,GAAA,CAAI,CAAA,GAAI,SAAA,CAAU,IAAI,SAAA,EAAU;AACrF,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,EAAE,CAAA,EAAG,KAAA,CAAM,CAAA,GAAI,SAAA,CAAU,CAAA,GAAI,WAAA,EAAa,CAAA,EAAG,KAAA,CAAM,CAAA,GAAI,SAAA,CAAU,IAAI,WAAA,EAAY;AAAA,IACxF,MAAA;AAAA,IACA,QAAA,EAAU,EAAE,CAAA,EAAG,GAAA,CAAI,CAAA,GAAI,SAAA,CAAU,CAAA,GAAI,UAAA,EAAY,CAAA,EAAG,GAAA,CAAI,CAAA,GAAI,SAAA,CAAU,IAAI,UAAA,EAAW;AAAA,IACrF,GAAA;AAAA,IACA;AAAA,GACF;AACF;AAKA,SAAS,YAAA,CAAa,OAAc,OAAA,EAAmD;AACrF,EAAA,IAAI,KAAA,CAAM,KAAA,KAAU,MAAA,IAAa,OAAA,KAAY,MAAA,EAAW;AACtD,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA;AACnC,IAAA,IAAI,OAAA,KAAY,QAAW,OAAO,OAAA;AAAA,EACpC;AACA,EAAA,OAAO,KAAA,CAAM,KAAA;AACf;AAGA,SAAS,UACP,GAAA,EACA,SAAA,EACA,SACA,KAAA,EACA,MAAA,EACA,aACA,OAAA,EACM;AACN,EAAA,MAAM,CAAA,GAAI,eAAA,CAAgB,SAAA,EAAW,WAAW,CAAA;AAChD,EAAA,MAAM,CAAA,GAAI,eAAA,CAAgB,OAAA,EAAS,WAAW,CAAA;AAC9C,EAAA,MAAM,YAAY,MAAA,GAAS,CAAA;AAC3B,EAAA,MAAM,KAAA,GAAQ,EAAE,CAAA,EAAI,CAAA,CAAE,EAAA,GAAK,GAAA,GAAO,SAAA,EAAW,CAAA,EAAI,CAAA,CAAE,EAAA,GAAK,GAAA,GAAO,SAAA,EAAU;AACzE,EAAA,MAAM,GAAA,GAAM,EAAE,CAAA,EAAI,CAAA,CAAE,EAAA,GAAK,GAAA,GAAO,SAAA,EAAW,CAAA,EAAI,CAAA,CAAE,EAAA,GAAK,GAAA,GAAO,SAAA,EAAU;AAEvE,EAAA,IAAI,cAAc,OAAA,EAAS;AACzB,IAAA,GAAA,CAAI,WAAA,GAAc,KAAA;AAClB,IAAA,GAAA,CAAI,YAAY,MAAA,GAAS,IAAA;AACzB,IAAA,GAAA,CAAI,WAAA,GAAc,UAAU,IAAA,GAAO,CAAA;AACnC,IAAA,GAAA,CAAI,SAAA,EAAU;AACd,IAAA,GAAA,CAAI,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,KAAA,CAAM,CAAA,EAAG,SAAS,IAAA,EAAM,CAAA,EAAG,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA;AACvD,IAAA,GAAA,CAAI,MAAA,EAAO;AACX,IAAA,GAAA,CAAI,WAAA,GAAc,CAAA;AAClB,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,cAAc,MAAA,GAAS,IAAA;AAC7B,EAAA,MAAM,YAAY,MAAA,GAAS,IAAA;AAC3B,EAAA,MAAM,aAAa,MAAA,GAAS,IAAA;AAC5B,EAAA,MAAM,gBAAgB,MAAA,GAAS,IAAA;AAC/B,EAAA,MAAM,aAAa,MAAA,GAAS,IAAA;AAC5B,EAAA,MAAM,IAAA,GAAO,UAAU,SAAA,EAAW,OAAA,EAAS,OAAO,GAAA,EAAK,WAAA,EAAa,WAAW,UAAU,CAAA;AACzF,EAAA,IAAI,SAAS,IAAA,EAAM;AAEnB,EAAA,GAAA,CAAI,WAAA,GAAc,UAAU,IAAA,GAAO,CAAA;AACnC,EAAA,GAAA,CAAI,WAAA,GAAc,KAAA;AAClB,EAAA,GAAA,CAAI,SAAA,GAAY,UAAA;AAChB,EAAA,GAAA,CAAI,OAAA,GAAU,MAAA;AACd,EAAA,GAAA,CAAI,QAAA,GAAW,OAAA;AACf,EAAA,GAAA,CAAI,SAAA,EAAU;AACd,EAAA,GAAA,CAAI,OAAO,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,MAAM,CAAC,CAAA;AACrC,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,IAAA,EAAM,GAAA,CAAI,MAAA,CAAO,KAAK,MAAA,CAAO,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA;AACjE,EAAA,GAAA,CAAI,OAAO,IAAA,CAAK,QAAA,CAAS,CAAA,EAAG,IAAA,CAAK,SAAS,CAAC,CAAA;AAC3C,EAAA,GAAA,CAAI,MAAA,EAAO;AAEX,EAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,CAAK,SAAA,CAAU,CAAA;AAC9B,EAAA,MAAM,KAAA,GAAQ,KAAK,SAAA,CAAU,CAAA;AAC7B,EAAA,GAAA,CAAI,SAAA,GAAY,KAAA;AAChB,EAAA,GAAA,CAAI,SAAA,EAAU;AACd,EAAA,GAAA,CAAI,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,CAAC,CAAA;AACjC,EAAA,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,QAAA,CAAS,CAAA,GAAI,KAAA,GAAQ,eAAe,IAAA,CAAK,QAAA,CAAS,CAAA,GAAI,KAAA,GAAQ,aAAa,CAAA;AAC3F,EAAA,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,QAAA,CAAS,CAAA,GAAI,KAAA,GAAQ,eAAe,IAAA,CAAK,QAAA,CAAS,CAAA,GAAI,KAAA,GAAQ,aAAa,CAAA;AAC3F,EAAA,GAAA,CAAI,SAAA,EAAU;AACd,EAAA,GAAA,CAAI,IAAA,EAAK;AACT,EAAA,GAAA,CAAI,WAAA,GAAc,CAAA;AACpB;AAGA,SAAS,MAAA,CACP,MAAA,EACA,MAAA,EACA,OAAA,EACA,aACA,OAAA,EACM;AACN,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAClC,EAAA,IAAI,QAAQ,IAAA,EAAM;AAClB,EAAA,MAAM,MAAM,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,oBAAoB,CAAA,GAAI,CAAA;AAC3E,EAAA,MAAM,IAAA,GAAO,OAAO,qBAAA,EAAsB;AAC1C,EAAA,MAAM,WAAW,IAAA,CAAK,KAAA;AACtB,EAAA,MAAM,YAAY,IAAA,CAAK,MAAA;AACvB,EAAA,IAAI,QAAA,IAAY,CAAA,IAAK,SAAA,IAAa,CAAA,EAAG;AAErC,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,KAAA,CAAM,QAAA,GAAW,GAAG,CAAA;AAC9C,EAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,KAAA,CAAM,SAAA,GAAY,GAAG,CAAA;AAChD,EAAA,IAAI,MAAA,CAAO,KAAA,KAAU,YAAA,EAAc,MAAA,CAAO,KAAA,GAAQ,YAAA;AAClD,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,aAAA,EAAe,MAAA,CAAO,MAAA,GAAS,aAAA;AACrD,EAAA,GAAA,CAAI,aAAa,GAAA,EAAK,CAAA,EAAG,CAAA,EAAG,GAAA,EAAK,GAAG,CAAC,CAAA;AACrC,EAAA,GAAA,CAAI,SAAA,CAAU,CAAA,EAAG,CAAA,EAAG,QAAA,EAAU,SAAS,CAAA;AAEvC,EAAA,MAAM,SAAS,QAAA,GAAW,CAAA;AAC1B,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,IAAI,KAAA,CAAM,KAAA,EAAO,UAAA,KAAe,MAAA,EAAW;AAC3C,IAAA,SAAA,CAAU,GAAA,EAAK,KAAA,CAAM,IAAA,EAAM,KAAA,CAAM,EAAA,EAAI,YAAA,CAAa,KAAA,EAAO,OAAO,CAAA,EAAG,MAAA,EAAQ,WAAA,EAAa,KAAK,CAAA;AAAA,EAC/F;AACA,EAAA,IAAI,YAAY,IAAA,EAAM;AACpB,IAAA,SAAA,CAAU,GAAA,EAAK,QAAQ,IAAA,EAAM,OAAA,CAAQ,IAAI,OAAA,CAAQ,KAAA,EAAO,MAAA,EAAQ,WAAA,EAAa,IAAI,CAAA;AAAA,EACnF;AACF;AAUA,SAAS,SAAA,CACP,IAAA,EACA,EAAA,EACA,WAAA,EACA,MAAA,EAC4B;AAC5B,EAAA,MAAM,CAAA,GAAI,eAAA,CAAgB,IAAA,EAAM,WAAW,CAAA;AAC3C,EAAA,MAAM,CAAA,GAAI,eAAA,CAAgB,EAAA,EAAI,WAAW,CAAA;AACzC,EAAA,IAAI,MAAA,KAAW,QAAQ,OAAO,CAAA;AAC9B,EAAA,IAAI,MAAA,KAAW,QAAQ,OAAO,CAAA;AAC9B,EAAA,OAAO,EAAE,EAAA,EAAA,CAAK,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,EAAA,IAAM,CAAA,EAAG,EAAA,EAAA,CAAK,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,EAAA,IAAM,CAAA,EAAE;AACxD;AAkBO,SAAS,0BAAA,CACd,IAAA,EACA,KAAA,EACA,QAAA,EACA,aAAa,IAAA,EACK;AAClB,EAAA,MAAM,gBAAgB,KAAA,IAAS,aAAA;AAC/B,EAAA,MAAM,UAAU,OAAA,CAAQ,IAAA,IAAQ,KAAK,IAAA,EAAK,CAAE,SAAS,CAAC,CAAA;AAEtD,EAAA,IAAI,CAAC,OAAA,EAAS;AAIZ,IAAA,MAAMC,MAAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,WAAW,IAAI,CAAA;AACzC,IAAA,MAAM,OAAO,GAAA,GAAMA,MAAAA;AACnB,IAAA,MAAM,YAAY,GAAA,GAAMA,MAAAA;AACxB,IAAA,MAAM,QAAQ,IAAA,GAAOA,MAAAA;AACrB,IAAA,MAAMC,SAAQ,IAAA,GAAOD,MAAAA;AACrB,IAAA,MAAME,SAAQ,GAAA,GAAMF,MAAAA;AACpB,IAAA,MAAMG,KAAAA,GAAO,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,EAAI,CAACD,MAAK,CAAA,GAAA,EAAM,SAAS,CAAA,CAAA,EAAI,CAACA,MAAK,CAAA,GAAA,EAAM,IAAI,CAAA,KAAA,EAAQ,SAAS,CAAA,CAAA,EAAIA,MAAK,CAAA,GAAA,EAAM,KAAK,CAAA,CAAA,EAAIA,MAAK,CAAA,GAAA,EAAMD,MAAK,IAAIC,MAAK,CAAA,CAAA,EAAID,MAAK,CAAA,CAAA,EAAI,CAACC,MAAK,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,CAACA,MAAK,CAAA,EAAA,CAAA;AAC5K,IAAA,OAAO;AAAA,MACL,IAAA,EAAAC,KAAAA;AAAA,MACA,MAAA,EAAQ,IAAA;AAAA,MACR,SAAS,CAACF,MAAAA;AAAA,MACV,QAAA,EAAU,IAAA;AAAA,MACV,MAAA,EAAQ;AAAA,KACV;AAAA,EACF;AAEA,EAAA,MAAM,YAAY,QAAA,GAAW,GAAA;AAC7B,EAAA,MAAM,SAAA,GAAY,KAAM,MAAA,GAAS,SAAA;AACjC,EAAA,MAAM,YAAY,SAAA,GAAY,CAAA;AAE9B,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,WAAW,IAAI,CAAA;AAEzC,EAAA,MAAM,OAAO,IAAA,GAAO,KAAA;AACpB,EAAA,MAAM,SAAS,IAAA,CAAK,GAAA,CAAI,GAAA,GAAM,KAAA,EAAO,YAAY,IAAI,CAAA;AACrD,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,WAAW,GAAG,CAAA;AAG1C,EAAA,MAAM,YAAY,IAAA,GAAO,KAAA;AACzB,EAAA,MAAM,KAAA,GAAQ,CAAC,MAAA,GAAS,SAAA;AAExB,EAAA,IAAI,QAAA,GAAW,CAAA;AACf,EAAA,IAAI,IAAA,GAAO,EAAA;AAEX,EAAA,IAAI,kBAAkB,aAAA,EAAe;AACnC,IAAA,IAAI,UAAA,EAAY;AAEd,MAAA,MAAM,WAAW,IAAA,GAAO,KAAA;AACxB,MAAA,MAAM,OAAO,MAAA,GAAS,QAAA;AACtB,MAAA,QAAA,GAAW,IAAA;AACX,MAAA,IAAA,GAAO,KAAK,CAAC,MAAM,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,GAAA,EAAM,MAAM,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,GAAA,EAAM,IAAI,CAAA,KAAA,EAAQ,MAAM,IAAI,KAAK,CAAA,GAAA,EAAM,CAAC,MAAM,IAAI,KAAK,CAAA,GAAA,EAAM,KAAK,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,CAAA,EAAI,CAAC,MAAM,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,EAAA,CAAA;AAAA,IACxK,CAAA,MAAO;AACL,MAAA,QAAA,GAAW,MAAA,GAAS,SAAA;AACpB,MAAA,IAAA,GAAO,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,MAAM,MAAM,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,GAAA,EAAM,QAAQ,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,CAAA,EAAI,QAAQ,IAAI,KAAK,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA,EAAI,KAAK,MAAM,CAAC,MAAM,IAAI,KAAK,CAAA,GAAA,EAAM,KAAK,CAAA,CAAA,EAAI,KAAK,IAAI,KAAK,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,CAAA,EAAI,CAAC,MAAM,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,EAAA,CAAA;AAAA,IACvM;AAAA,EACF,CAAA,MAAA,IAAW,kBAAkB,eAAA,EAAiB;AAC5C,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,MAAM,OAAO,MAAA,GAAS,GAAA;AACtB,MAAA,QAAA,GAAW,IAAA;AACX,MAAA,IAAA,GAAO,CAAA,EAAA,EAAK,CAAC,MAAM,CAAA,QAAA,EAAW,CAAC,MAAA,GAAS,GAAG,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,GAAA,EAAM,MAAM,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,GAAA,EAAM,IAAI,CAAA,KAAA,EAAQ,MAAM,CAAA,CAAA,EAAI,KAAK,CAAA,GAAA,EAAM,CAAC,MAAA,GAAS,GAAG,CAAA,CAAA,EAAI,KAAK,CAAA,GAAA,EAAM,CAAC,MAAM,CAAA,MAAA,CAAA;AAAA,IACvJ,CAAA,MAAO;AACL,MAAA,QAAA,GAAW,MAAA,GAAS,GAAA;AACpB,MAAA,IAAA,GAAO,CAAA,EAAA,EAAK,CAAC,MAAM,CAAA,QAAA,EAAW,CAAC,MAAA,GAAS,GAAG,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,GAAA,EAAM,MAAA,GAAS,GAAG,IAAI,CAAC,KAAK,CAAA,GAAA,EAAM,MAAM,CAAA,QAAA,EAAW,MAAM,CAAA,OAAA,EAAU,MAAA,GAAS,GAAG,CAAA,CAAA,EAAI,KAAK,CAAA,GAAA,EAAM,CAAC,SAAS,GAAG,CAAA,CAAA,EAAI,KAAK,CAAA,GAAA,EAAM,CAAC,MAAM,CAAA,MAAA,CAAA;AAAA,IACxL;AAAA,EACF,CAAA,MAAA,IAAW,kBAAkB,aAAA,EAAe;AAC1C,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,MAAM,OAAO,MAAA,GAAS,GAAA;AACtB,MAAA,QAAA,GAAW,IAAA;AACX,MAAA,IAAA,GAAO,CAAA,EAAA,EAAK,CAAC,MAAM,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,GAAA,EAAM,MAAM,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,GAAA,EAAM,IAAI,IAAI,CAAC,KAAA,GAAQ,IAAI,CAAA,GAAA,EAAM,IAAI,IAAI,KAAA,GAAQ,IAAI,MAAM,MAAM,CAAA,CAAA,EAAI,KAAK,CAAA,GAAA,EAAM,CAAC,MAAM,CAAA,CAAA,EAAI,KAAK,MAAM,KAAK,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,EAAA,CAAA;AAAA,IACjN,CAAA,MAAO;AACL,MAAA,QAAA,GAAW,MAAA,GAAS,SAAA;AACpB,MAAA,IAAA,GAAO,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,MAAM,MAAM,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,GAAA,EAAM,QAAQ,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,CAAA,EAAI,QAAQ,IAAI,KAAK,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA,EAAI,KAAK,MAAM,CAAC,MAAM,IAAI,KAAK,CAAA,GAAA,EAAM,KAAK,CAAA,CAAA,EAAI,KAAK,IAAI,KAAK,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,CAAA,EAAI,CAAC,MAAM,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,EAAA,CAAA;AAAA,IACvM;AAAA,EACF,CAAA,MAAA,IAAW,kBAAkB,SAAA,EAAW;AACtC,IAAA,MAAM,WAAW,MAAA,GAAS,GAAA;AAC1B,IAAA,MAAM,QAAQ,KAAA,GAAQ,IAAA;AACtB,IAAA,MAAM,YAAY,MAAA,GAAS,IAAA;AAC3B,IAAA,MAAM,OAAO,MAAA,GAAS,GAAA;AACtB,IAAA,QAAA,GAAW,IAAA;AACX,IAAA,IAAA,GAAO,KAAK,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAC,SAAS,CAAC,QAAA,EAAU,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,EAAA,CAAK,CAAC,KAAA,EAAO,OAAA,CAAQ,CAAC,CAAC,CAAA,GAAA,EAAA,CAAO,CAAC,MAAA,EAAQ,QAAQ,CAAC,CAAC,CAAA,CAAA,EAAA,CAAK,CAAC,OAAO,OAAA,CAAQ,CAAC,CAAC,CAAA,GAAA,EAAM,UAAU,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,EAAA,CAAK,CAAC,KAAA,EAAO,OAAA,CAAQ,CAAC,CAAC,MAAM,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,QAAQ,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAC,IAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAC,OAAO,CAAC,MAAA,EAAQ,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,EAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,GAAA,EAAA,CAAO,CAAC,QAAA,EAAU,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,EAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,CAAA;AAAA,EACxV,CAAA,MAAO;AACL,IAAA,MAAM,QAAA,GAAW,IAAA;AACjB,IAAA,MAAM,OAAO,MAAA,GAAS,QAAA;AACtB,IAAA,QAAA,GAAW,IAAA;AACX,IAAA,IAAA,GAAO,KAAK,CAAC,MAAM,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,GAAA,EAAM,MAAM,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,GAAA,EAAM,IAAI,CAAA,KAAA,EAAQ,MAAM,IAAI,KAAK,CAAA,GAAA,EAAM,CAAC,MAAM,IAAI,KAAK,CAAA,GAAA,EAAM,KAAK,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,CAAA,EAAI,CAAC,MAAM,CAAA,CAAA,EAAI,CAAC,KAAK,CAAA,EAAA,CAAA;AAAA,EACxK;AAEA,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,MAAA,EAAQ,QAAA;AAAA,IACR,SAAS,CAAC,KAAA;AAAA,IACV,QAAA;AAAA,IACA;AAAA,GACF;AACF;AAMA,SAAS,kBAAA,CACP,SAAA,EACA,OAAA,EACA,SAAA,EACA,WAAA,EACO;AACP,EAAA,MAAM,CAAA,GAAI,eAAA,CAAgB,SAAA,EAAW,WAAW,CAAA;AAChD,EAAA,MAAM,CAAA,GAAI,eAAA,CAAgB,OAAA,EAAS,WAAW,CAAA;AAE9C,EAAA,MAAM,EAAA,GAAK,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,EAAA;AACpB,EAAA,MAAM,EAAA,GAAK,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,EAAA;AAGpB,EAAA,MAAM,UAAU,EAAE,CAAA,EAAG,EAAE,EAAA,EAAI,CAAA,EAAG,EAAE,EAAA,EAAG;AAGnC,EAAA,MAAM,UAAU,EAAE,CAAA,EAAG,EAAE,EAAA,EAAI,CAAA,EAAG,EAAE,EAAA,EAAG;AAInC,EAAA,MAAM,WAAW,SAAA,GAAY,CAAA;AAC7B,EAAA,MAAM,yBAAyB,SAAA,CAAU,IAAA;AAAA,IACvC,CAAC,KAAA,KAAU,KAAA,CAAM,SAAS,SAAA,IAAA,CAAc,KAAA,CAAM,OAAO,CAAA,MAAO;AAAA,GAC9D;AAEA,EAAA,IAAI,sBAAA,EAAwB;AAC1B,IAAA,OAAO,OAAA;AAAA,EACT;AAEA,EAAA,OAAO,IAAA,CAAK,IAAI,EAAE,CAAA,GAAI,KAAK,GAAA,CAAI,EAAE,IAAI,OAAA,GAAU,OAAA;AACjD;AAGA,SAAS,6BAAA,CACP,KAAA,EACA,WAAA,EACA,SAAA,EACA;AACA,EAAA,MAAM,QAAQ,KAAA,CAAM,KAAA;AACpB,EAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,UAAA,KAAe,QAAW,OAAO,IAAA;AAErD,EAAA,MAAM,CAAA,GAAI,eAAA,CAAgB,KAAA,CAAM,IAAA,EAAM,WAAW,CAAA;AACjD,EAAA,MAAM,CAAA,GAAI,eAAA,CAAgB,KAAA,CAAM,EAAA,EAAI,WAAW,CAAA;AAC/C,EAAA,IAAI,KAAA,CAAM,IAAA,KAAS,KAAA,CAAM,EAAA,EAAI,OAAO,IAAA;AAEpC,EAAA,MAAM,QAAA,GAAW,YAAA,CAAa,KAAA,CAAM,IAAA,EAAM,MAAM,EAAE,CAAA;AAClD,EAAA,MAAM,QAAA,GAAW,MAAM,QAAA,IAAY,IAAA;AACnC,EAAA,MAAM,OAAO,0BAAA,CAA2B,KAAA,CAAM,MAAM,KAAA,CAAM,SAAA,EAAW,UAAU,IAAI,CAAA;AAEnF,EAAA,IAAI,SAAA;AACJ,EAAA,IAAI,SAAA;AACJ,EAAA,IAAI,MAAA,GAAuB,IAAA;AAE3B,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,MAAM,IAAI,UAAA,CAAW,EAAE,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,EAAG,CAAA,CAAE,EAAA,EAAG,EAAG,EAAE,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA;AAC/D,IAAA,IAAI,CAAA,KAAM,MAAM,OAAO,IAAA;AACvB,IAAA,SAAA,GAAY,CAAA;AACZ,IAAA,SAAA,GAAY,CAAA;AAAA,EACd,CAAA,MAAO;AACL,IAAA,MAAA,GAAS,mBAAmB,KAAA,CAAM,IAAA,EAAM,KAAA,CAAM,EAAA,EAAI,WAAW,WAAW,CAAA;AACxE,IAAA,SAAA,GAAY,UAAA,CAAW,EAAE,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,EAAG,CAAA,CAAE,EAAA,EAAG,EAAG,MAAM,CAAA;AACnD,IAAA,SAAA,GAAY,UAAA,CAAW,QAAQ,EAAE,CAAA,EAAG,EAAE,EAAA,EAAI,CAAA,EAAG,CAAA,CAAE,EAAA,EAAI,CAAA;AACnD,IAAA,IAAI,SAAA,KAAc,IAAA,IAAQ,SAAA,KAAc,IAAA,EAAM,OAAO,IAAA;AAAA,EACvD;AAIA,EAAA,MAAM,GAAA,GAAM;AAAA,IACV,CAAA,EAAG,CAAA,CAAE,EAAA,GAAK,SAAA,CAAU,CAAA,GAAI,IAAA;AAAA,IACxB,CAAA,EAAG,CAAA,CAAE,EAAA,GAAK,SAAA,CAAU,CAAA,GAAI;AAAA,GAC1B;AAEA,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,CAAA,EAAG,GAAA,CAAI,CAAA,GAAI,SAAA,CAAU,IAAI,IAAA,CAAK,QAAA;AAAA,IAC9B,CAAA,EAAG,GAAA,CAAI,CAAA,GAAI,SAAA,CAAU,IAAI,IAAA,CAAK;AAAA,GAChC;AAEA,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAA,EAAG,UAAA,CAAW,CAAA,GAAI,SAAA,CAAU,IAAI,IAAA,CAAK,OAAA;AAAA,IACrC,CAAA,EAAG,UAAA,CAAW,CAAA,GAAI,SAAA,CAAU,IAAI,IAAA,CAAK;AAAA,GACvC;AAEA,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,EAAA,GAAK,EAAE,EAAA,EAAI,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,EAAE,CAAA;AAChD,EAAA,MAAM,WAAA,GAAc,IAAA,GAAO,EAAA,GAAK,GAAA,GAAM,GAAA;AACtC,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,CAAA,EAAG,CAAA,CAAE,EAAA,GAAK,SAAA,CAAU,CAAA,GAAI,WAAA;AAAA,IACxB,CAAA,EAAG,CAAA,CAAE,EAAA,GAAK,SAAA,CAAU,CAAA,GAAI;AAAA,GAC1B;AAEA,EAAA,MAAM,WAAW,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,CAAA,EAAG,UAAU,CAAC,CAAA;AACpD,EAAA,MAAM,QAAA,GAAY,QAAA,GAAW,GAAA,GAAO,IAAA,CAAK,EAAA;AAEzC,EAAA,IAAI,OAAA,GAAU,CAAA;AACd,EAAA,MAAM,OAAA,GAAU,MAAM,YAAA,IAAgB,MAAA;AACtC,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,OAAA,GAAU,CAAC,QAAA;AAAA,EACb,CAAA,MAAA,IAAW,YAAY,MAAA,EAAQ;AAC7B,IAAA,MAAM,IAAA,GAAA,CAAS,QAAA,GAAW,GAAA,GAAO,GAAA,IAAO,GAAA;AACxC,IAAA,IAAI,IAAA,GAAO,EAAA,IAAM,IAAA,GAAO,GAAA,EAAK;AAC3B,MAAA,OAAA,GAAU,GAAA;AAAA,IACZ;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GACJ,MAAA,KAAW,IAAA,GACP,CAAA,EAAA,EAAK,WAAW,CAAC,CAAA,CAAA,EAAI,UAAA,CAAW,CAAC,CAAA,GAAA,EAAM,MAAA,CAAO,CAAC,CAAA,CAAA,EAAI,OAAO,CAAC,CAAA,GAAA,EAAM,QAAA,CAAS,CAAC,CAAA,CAAA,EAAI,QAAA,CAAS,CAAC,CAAA,CAAA,GACzF,KAAK,UAAA,CAAW,CAAC,CAAA,CAAA,EAAI,UAAA,CAAW,CAAC,CAAA,GAAA,EAAM,QAAA,CAAS,CAAC,CAAA,CAAA,EAAI,SAAS,CAAC,CAAA,CAAA;AAErE,EAAA,MAAM,QAAA,GAAA,CACH,QAAA,CAAS,CAAA,GAAI,UAAA,CAAW,CAAA,IAAK,SAAA,CAAU,CAAA,GAAA,CAAK,QAAA,CAAS,CAAA,GAAI,UAAA,CAAW,CAAA,IAAK,SAAA,CAAU,CAAA;AACtF,EAAA,MAAM,SAAA,GAAY,YAAY,QAAA,GAAW,GAAA;AAEzC,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,QAAA;AAAA,IACA,IAAA;AAAA,IACA,UAAA;AAAA,IACA,MAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACF;AACF;AAGA,SAAS,qBAAA,CACP,KAAA,EACA,KAAA,EACA,WAAA,EACA,KACA,SAAA,EACqB;AACrB,EAAA,MAAM,CAAA,GAAI,6BAAA,CAA8B,KAAA,EAAO,WAAA,EAAa,SAAS,CAAA;AACrE,EAAA,IAAI,CAAA,KAAM,IAAA,IAAQ,CAAC,CAAA,CAAE,WAAW,OAAO,IAAA;AAEvC,EAAA,MAAM,IAAA,GAAO,CAAA,CAAE,KAAA,CAAM,OAAA,KAAY,KAAA;AACjC,EAAA,MAAM,QAAA,GAAW,OAAO,0BAAA,GAA6B,uBAAA;AAErD,EAAA,uBACEH,IAAAA,CAAC,GAAA,EAAA,EAAuB,MAAA,EAAQ,QAAA,EAE9B,QAAA,EAAA;AAAA,oBAAAJ,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,GAAG,CAAA,CAAE,MAAA;AAAA,QACL,IAAA,EAAK,MAAA;AAAA,QACL,MAAA,EAAQ,OAAO,wBAAA,GAA2B,KAAA;AAAA,QAC1C,WAAA,EAAa,OAAO,KAAA,GAAQ,KAAA;AAAA,QAC5B,aAAA,EAAc,OAAA;AAAA,QACd,cAAA,EAAe;AAAA;AAAA,KACjB;AAAA,oBAEAA,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,GAAG,CAAA,CAAE,MAAA;AAAA,QACL,IAAA,EAAK,MAAA;AAAA,QACL,MAAA,EAAQ,KAAA;AAAA,QACR,WAAA,EAAY,KAAA;AAAA,QACZ,aAAA,EAAc,OAAA;AAAA,QACd,cAAA,EAAe;AAAA;AAAA,KACjB;AAAA,IAEC,wBACCA,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,GAAG,CAAA,CAAE,MAAA;AAAA,QACL,IAAA,EAAK,MAAA;AAAA,QACL,MAAA,EAAO,0BAAA;AAAA,QACP,WAAA,EAAY,KAAA;AAAA,QACZ,aAAA,EAAc,OAAA;AAAA,QACd,cAAA,EAAe;AAAA;AAAA;AACjB,GAAA,EAAA,EA5BI,CAAA,EAAG,GAAG,CAAA,MAAA,CA8Bd,CAAA;AAEJ;AAGA,SAAS,oBAAA,CACP,KAAA,EACA,MAAA,EACA,WAAA,EACA,KACA,SAAA,EACqB;AACrB,EAAA,MAAM,CAAA,GAAI,6BAAA,CAA8B,KAAA,EAAO,WAAA,EAAa,SAAS,CAAA;AACrE,EAAA,IAAI,CAAA,KAAM,MAAM,OAAO,IAAA;AAEvB,EAAA,MAAM,IAAA,GAAO,CAAA,CAAE,KAAA,CAAM,OAAA,KAAY,KAAA;AACjC,EAAA,MAAM,QAAA,GAAW,OAAO,0BAAA,GAA6B,uBAAA;AACrD,EAAA,MAAM,QAAA,GACJ,EAAE,KAAA,CAAM,UAAA,KAAe,aAAa,IAAA,GAAO,2BAAA,GAA8B,EAAE,KAAA,CAAM,UAAA;AACnF,EAAA,MAAM,UAAA,GAAa,CAAA,CAAE,KAAA,CAAM,WAAA,IAAe,SAAA;AAE1C,EAAA,uBACEA,IAAC,GAAA,EAAA,EAAsB,MAAA,EAAQ,UAC7B,QAAA,kBAAAI,IAAAA,CAAC,OAAE,SAAA,EAAW,CAAA,UAAA,EAAa,EAAE,UAAA,CAAW,CAAC,KAAK,CAAA,CAAE,UAAA,CAAW,CAAC,CAAA,SAAA,EAAY,CAAA,CAAE,QAAQ,CAAA,CAAA,CAAA,EAChF,QAAA,EAAA;AAAA,oBAAAJ,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,CAAA,EAAG,EAAE,IAAA,CAAK,IAAA;AAAA,QACV,IAAA,EAAM,QAAA;AAAA,QACN,MAAA,EAAQ,UAAA;AAAA,QACR,WAAA,EAAY,KAAA;AAAA,QACZ,cAAA,EAAe;AAAA;AAAA,KACjB;AAAA,IACC,OAAA,CAAQ,CAAA,CAAE,KAAA,CAAM,IAAA,IAAQ,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,IAAA,EAAK,CAAE,MAAA,GAAS,CAAC,CAAA,oBACrDA,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,CAAA,EAAG,CAAA;AAAA,QACH,CAAA,EAAG,CAAA;AAAA,QACH,WAAW,CAAA,CAAE,OAAA,KAAY,IAAI,CAAA,OAAA,EAAU,CAAA,CAAE,OAAO,CAAA,CAAA,CAAA,GAAM,MAAA;AAAA,QACtD,IAAA,EAAM,CAAA,CAAE,KAAA,CAAM,IAAA,IAAQ,SAAA;AAAA,QACtB,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,UAAA,EAAW,KAAA;AAAA,QACX,UAAA,EAAW,2CAAA;AAAA,QACX,UAAA,EAAW,QAAA;AAAA,QACX,gBAAA,EAAiB,SAAA;AAAA,QACjB,KAAA,EAAO,EAAE,UAAA,EAAY,MAAA,EAAO;AAAA,QAE3B,YAAE,KAAA,CAAM;AAAA;AAAA;AACX,GAAA,EAEJ,CAAA,EAAA,EAzBM,CAAA,EAAG,GAAG,CAAA,KAAA,CA0Bd,CAAA;AAEJ;AAIO,IAAM,WAAA,GAAcU,IAAAA;AAAA,EACzB,UAAA,CAAgD,SAASC,YAAAA,CACvD,EAAE,KAAA,EAAO,aAAa,OAAA,EAAS,KAAA,GAAQ,KAAA,EAAM,EAC7C,MAAA,EACA;AACA,IAAA,MAAM,SAAA,GAAYC,OAAiC,IAAI,CAAA;AACvD,IAAA,MAAM,UAAA,GAAaA,OAA4B,IAAI,CAAA;AACnD,IAAA,MAAM,YAAY,aAAA,CAAc,KAAA,EAAO,CAAC,CAAA,KAAM,EAAE,MAAM,CAAA;AAKtD,IAAA,MAAM,MAAA,GAASC,OAAAA;AAAA,MACb,MAAM,UAAU,MAAA,CAAO,CAAC,MAAO,CAAA,CAAE,KAAA,KAAU,SAAU,KAAK,CAAA;AAAA,MAC1D,CAAC,WAAW,KAAK;AAAA,KACnB;AAKA,IAAA,MAAM,cAAA,GAAiBA,OAAAA;AAAA,MACrB,MAAM,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,EAAE,KAAA,KAAU,MAAA,IAAa,CAAA,CAAE,SAAA,KAAc,MAAS,CAAA;AAAA,MAC3E,CAAC,MAAM;AAAA,KACT;AAIA,IAAA,mBAAA;AAAA,MACE,MAAA;AAAA,MACA,OAAO;AAAA,QACL,WAAW,OAAA,EAAoC;AAC7C,UAAA,IAAI,KAAA,EAAO;AACX,UAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AACrB,UAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AACzB,UAAA,IAAI,WAAW,IAAA,EAAM,MAAA,CAAO,QAAQ,MAAA,EAAQ,OAAA,EAAS,aAAa,OAAO,CAAA;AAAA,QAC3E;AAAA,OACF,CAAA;AAAA,MACA,CAAC,MAAA,EAAQ,WAAA,EAAa,OAAA,EAAS,KAAK;AAAA,KACtC;AAEA,IAAA,eAAA,CAAgB,MAAM;AACpB,MAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AACzB,MAAA,IAAI,WAAW,IAAA,EAAM;AACrB,MAAA,MAAA,CAAO,MAAA,EAAQ,MAAA,EAAQ,UAAA,CAAW,OAAA,EAAS,aAAa,OAAO,CAAA;AAAA,IACjE,CAAA,EAAG,CAAC,MAAA,EAAQ,WAAA,EAAa,OAAO,CAAC,CAAA;AAEjC,IAAAC,UAAU,MAAM;AACd,MAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AACzB,MAAA,IAAI,WAAW,IAAA,EAAM;AACrB,MAAA,MAAM,SAAS,MAAA,CAAO,aAAA;AACtB,MAAA,IAAI,MAAA,KAAW,IAAA,IAAQ,OAAO,cAAA,KAAmB,WAAA,EAAa;AAC9D,MAAA,MAAM,QAAA,GAAW,IAAI,cAAA,CAAe,MAAM;AACxC,QAAA,MAAA,CAAO,MAAA,EAAQ,MAAA,EAAQ,UAAA,CAAW,OAAA,EAAS,aAAa,OAAO,CAAA;AAAA,MACjE,CAAC,CAAA;AACD,MAAA,QAAA,CAAS,QAAQ,MAAM,CAAA;AACvB,MAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,IACnC,CAAA,EAAG,CAAC,MAAA,EAAQ,WAAA,EAAa,OAAO,CAAC,CAAA;AAEjC,IAAA,MAAM,WAAA,GAAc,QAAQ,MAAA,GAAY,EAAA;AAExC,IAAA,uBACEV,KAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,sBAAAJ,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,SAAA;AAAA,UACL,YAAA,EAAY,QAAQ,cAAA,GAAiB,QAAA;AAAA,UACrC,KAAA,EAAO;AAAA,YACL,QAAA,EAAU,UAAA;AAAA,YACV,KAAA,EAAO,CAAA;AAAA,YACP,KAAA,EAAO,MAAA;AAAA,YACP,MAAA,EAAQ,MAAA;AAAA,YACR,aAAA,EAAe,MAAA;AAAA,YACf,GAAI,WAAA,KAAgB,MAAA,GAAY,EAAE,MAAA,EAAQ,WAAA,KAAgB;AAAC;AAC7D;AAAA,OACF;AAAA,MACC,iCACCI,IAAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,YAAA,EAAY,QAAQ,oBAAA,GAAuB,cAAA;AAAA,UAC3C,OAAA,EAAQ,aAAA;AAAA,UACR,mBAAA,EAAoB,MAAA;AAAA,UACpB,aAAA,EAAY,MAAA;AAAA,UACZ,KAAA,EAAO;AAAA,YACL,QAAA,EAAU,UAAA;AAAA,YACV,KAAA,EAAO,CAAA;AAAA,YACP,KAAA,EAAO,MAAA;AAAA,YACP,MAAA,EAAQ,MAAA;AAAA,YACR,aAAA,EAAe,MAAA;AAAA;AAAA,YAEf,GAAI,WAAA,KAAgB,MAAA,GAAY,EAAE,MAAA,EAAQ,WAAA,KAAgB;AAAC,WAC7D;AAAA,UAEA,QAAA,EAAA;AAAA,4BAAAA,KAAC,MAAA,EAAA,EACC,QAAA,EAAA;AAAA,8BAAAJ,GAAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,EAAA,EAAG,iBAAA;AAAA,kBACH,WAAA,EAAY,gBAAA;AAAA,kBACZ,CAAA,EAAE,KAAA;AAAA,kBACF,CAAA,EAAE,KAAA;AAAA,kBACF,KAAA,EAAM,KAAA;AAAA,kBACN,MAAA,EAAO,KAAA;AAAA,kBAEP,QAAA,kBAAAA,GAAAA;AAAA,oBAAC,cAAA;AAAA,oBAAA;AAAA,sBACC,EAAA,EAAG,GAAA;AAAA,sBACH,EAAA,EAAG,KAAA;AAAA,sBACH,YAAA,EAAa,KAAA;AAAA,sBACb,UAAA,EAAW,SAAA;AAAA,sBACX,YAAA,EAAa;AAAA;AAAA;AACf;AAAA,eACF;AAAA,8BACAI,IAAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,EAAA,EAAG,oBAAA;AAAA,kBACH,WAAA,EAAY,gBAAA;AAAA,kBACZ,CAAA,EAAE,KAAA;AAAA,kBACF,CAAA,EAAE,KAAA;AAAA,kBACF,KAAA,EAAM,KAAA;AAAA,kBACN,MAAA,EAAO,KAAA;AAAA,kBAEP,QAAA,EAAA;AAAA,oCAAAJ,GAAAA;AAAA,sBAAC,cAAA;AAAA,sBAAA;AAAA,wBACC,EAAA,EAAG,GAAA;AAAA,wBACH,EAAA,EAAG,KAAA;AAAA,wBACH,YAAA,EAAa,KAAA;AAAA,wBACb,UAAA,EAAW,SAAA;AAAA,wBACX,YAAA,EAAa;AAAA;AAAA,qBACf;AAAA,oCACAA,GAAAA;AAAA,sBAAC,cAAA;AAAA,sBAAA;AAAA,wBACC,EAAA,EAAG,GAAA;AAAA,wBACH,EAAA,EAAG,KAAA;AAAA,wBACH,YAAA,EAAa,KAAA;AAAA,wBACb,UAAA,EAAW,SAAA;AAAA,wBACX,YAAA,EAAa;AAAA;AAAA;AACf;AAAA;AAAA,eACF;AAAA,8BACAI,IAAAA,CAAC,gBAAA,EAAA,EAAe,EAAA,EAAG,qBAAA,EAAsB,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,MAAA,EAClE,QAAA,EAAA;AAAA,gCAAAJ,IAAC,MAAA,EAAA,EAAK,MAAA,EAAO,MAAK,SAAA,EAAU,SAAA,EAAU,aAAY,GAAA,EAAI,CAAA;AAAA,gCACtDA,IAAC,MAAA,EAAA,EAAK,MAAA,EAAO,OAAM,SAAA,EAAU,SAAA,EAAU,aAAY,GAAA,EAAI,CAAA;AAAA,gCACvDA,IAAC,MAAA,EAAA,EAAK,MAAA,EAAO,QAAO,SAAA,EAAU,SAAA,EAAU,aAAY,GAAA,EAAI;AAAA,eAAA,EAC1D;AAAA,aAAA,EACF,CAAA;AAAA,YAEC,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,KAAU;AACrB,cAAA,IAAI,KAAA,CAAM,KAAA,EAAO,UAAA,KAAe,MAAA,EAAW,OAAO,IAAA;AAClD,cAAA,MAAM,GAAA,GAAM,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA,CAAA,EAAI,KAAA,CAAM,EAAE,CAAA,CAAA,EAAI,KAAA,CAAM,KAAK,CAAA,CAAA,EAAI,KAAA,CAAM,SAAS,EAAE,CAAA,CAAA;AACzE,cAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,KAAA,EAAO,OAAO,CAAA;AACzC,cAAA,OAAO,qBAAA,CAAsB,KAAA,EAAO,KAAA,EAAO,WAAA,EAAa,KAAK,MAAM,CAAA;AAAA,YACrE,CAAC,CAAA;AAAA,YAEA,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,KAAU;AACrB,cAAA,IAAI,KAAA,CAAM,KAAA,EAAO,UAAA,KAAe,MAAA,EAAW,OAAO,IAAA;AAClD,cAAA,MAAM,GAAA,GAAM,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA,CAAA,EAAI,KAAA,CAAM,EAAE,CAAA,CAAA,EAAI,KAAA,CAAM,KAAK,CAAA,CAAA,EAAI,KAAA,CAAM,SAAS,EAAE,CAAA,CAAA;AACzE,cAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,KAAA,EAAO,OAAO,CAAA;AACzC,cAAA,OAAO,oBAAA,CAAqB,KAAA,EAAO,KAAA,EAAO,WAAA,EAAa,KAAK,MAAM,CAAA;AAAA,YACpE,CAAC,CAAA;AAAA,YAEA,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,KAAU;AACrB,cAAA,IAAI,KAAA,CAAM,KAAA,EAAO,UAAA,KAAe,MAAA,EAAW,OAAO,IAAA;AAClD,cAAA,MAAM,GAAA,GAAM,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA,CAAA,EAAI,KAAA,CAAM,EAAE,CAAA,CAAA,EAAI,KAAA,CAAM,KAAK,CAAA,CAAA,EAAI,KAAA,CAAM,SAAS,EAAE,CAAA,CAAA;AACzE,cAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,KAAA,EAAO,OAAO,CAAA;AACzC,cAAA,MAAM,QAAwB,EAAC;AAC/B,cAAA,IAAI,KAAA,CAAM,UAAU,MAAA,EAAW;AAC7B,gBAAA,MAAM,EAAE,EAAA,EAAI,EAAA,EAAG,GAAI,SAAA,CAAU,MAAM,IAAA,EAAM,KAAA,CAAM,EAAA,EAAI,WAAA,EAAa,OAAO,CAAA;AACvE,gBAAA,KAAA,CAAM,IAAA;AAAA,kCACJA,GAAAA;AAAA,oBAAC,MAAA;AAAA,oBAAA;AAAA,sBAEC,CAAA,EAAG,EAAA;AAAA,sBACH,CAAA,EAAG,EAAA;AAAA,sBACH,IAAA,EAAM,KAAA,CAAM,KAAA,CAAM,IAAA,IAAQ,KAAA;AAAA,sBAC1B,QAAA,EAAS,GAAA;AAAA,sBACT,UAAA,EAAW,KAAA;AAAA,sBACX,UAAA,EAAW,QAAA;AAAA,sBACX,gBAAA,EAAiB,SAAA;AAAA,sBACjB,KAAA,EAAO,EAAE,UAAA,EAAY,MAAA,EAAO;AAAA,sBAE3B,gBAAM,KAAA,CAAM;AAAA,qBAAA;AAAA,oBAVR,GAAG,GAAG,CAAA,MAAA;AAAA;AAWb,iBACF;AAAA,cACF;AACA,cAAA,IAAI,KAAA,CAAM,cAAc,MAAA,EAAW;AACjC,gBAAA,MAAM,EAAE,EAAA,EAAI,EAAA,EAAG,GAAI,SAAA;AAAA,kBACjB,KAAA,CAAM,IAAA;AAAA,kBACN,KAAA,CAAM,EAAA;AAAA,kBACN,WAAA;AAAA,kBACA,KAAA,CAAM,UAAU,MAAA,IAAU;AAAA,iBAC5B;AACA,gBAAA,KAAA,CAAM,IAAA;AAAA,kCACJA,GAAAA;AAAA,oBAAC,GAAA;AAAA,oBAAA;AAAA,sBAEC,SAAA,EAAW,CAAA,UAAA,EAAa,EAAE,CAAA,EAAA,EAAK,EAAE,CAAA,CAAA,CAAA;AAAA,sBAEjC,uBAAA,EAAyB,EAAE,MAAA,EAAQ,KAAA,CAAM,UAAU,IAAA;AAAK,qBAAA;AAAA,oBAHnD,GAAG,GAAG,CAAA,IAAA;AAAA;AAIb,iBACF;AAAA,cACF;AACA,cAAA,OAAO,KAAA,CAAM,WAAW,CAAA,GAAI,IAAA,mBAAOA,GAAAA,CAAC,GAAA,EAAA,EAAa,mBAAN,GAAY,CAAA;AAAA,YACzD,CAAC;AAAA;AAAA;AAAA,OACH,GACE;AAAA,KAAA,EACN,CAAA;AAAA,EAEJ,CAAC;AACH,CAAA;ACjxBA,IAAM,cAAA,GAAiB,sBAAA;AASvB,SAAS,qBAAA,GAA8B;AACrC,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,EAAA,IAAI,QAAA,CAAS,cAAA,CAAe,cAAc,CAAA,KAAM,IAAA,EAAM;AACtD,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA;AAC5C,EAAA,KAAA,CAAM,EAAA,GAAK,cAAA;AACX,EAAA,KAAA,CAAM,WAAA,GAAc;AAAA;AAAA;AAAA;AAAA,CAAA;AAKpB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,KAAK,CAAA;AACjC;AAGA,SAASE,aAAY,KAAA,EAA4B;AAC/C,EAAA,MAAM,OAAO,KAAA,GAAQ,CAAA;AACrB,EAAA,MAAM,OAAO,KAAA,IAAS,CAAA;AACtB,EAAA,OAAO,CAAA,EAAG,OAAO,YAAA,CAAa,EAAA,GAAO,IAAI,CAAC,CAAA,EAAG,OAAO,CAAC,CAAA,CAAA;AACvD;AAwBA,SAAS,UAAA,CAAW;AAAA,EAClB,KAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA,KAAA;AAAA,EACA,kBAAA;AAAA,EACA;AACF,CAAA,EAAgB;AACd,EAAA,MAAM,OAAO,KAAA,GAAQ,CAAA;AACrB,EAAA,MAAM,OAAO,KAAA,IAAS,CAAA;AACtB,EAAA,MAAM,OAAA,GAAA,CAAW,IAAA,GAAO,IAAA,IAAQ,CAAA,KAAM,CAAA;AACtC,EAAA,MAAM,IAAA,GAAO,aAAA,CAAc,KAAA,EAAO,KAAK,CAAA;AACvC,EAAA,MAAM,QAAQ,kBAAA,GAAqB,kBAAA,CAAmB,OAAO,IAAI,CAAA,GAAIA,aAAY,KAAK,CAAA;AAEtF,EAAA,MAAM,WAAA,GAAcU,OAA8B,IAAI,CAAA;AACtD,EAAA,MAAM,oBAAA,GAAuBA,OAAgB,KAAK,CAAA;AAIlD,EAAA,MAAM,MAAA,GAAST,WAAAA;AAAA,IACb,CAAC,EAAA,KAA8B;AAC7B,MAAA,WAAA,CAAY,OAAA,GAAU,EAAA;AACtB,MAAA,YAAA,GAAe,OAAO,EAAE,CAAA;AAAA,IAC1B,CAAA;AAAA,IACA,CAAC,OAAO,YAAY;AAAA,GACtB;AAIA,EAAAW,UAAU,MAAM;AACd,IAAA,qBAAA,EAAsB;AAAA,EACxB,CAAA,EAAG,EAAE,CAAA;AAOL,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,oBAAA,CAAqB,OAAA,GAAU,KAAA;AAC/B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,KAAK,WAAA,CAAY,OAAA;AACvB,IAAA,IAAI,OAAO,IAAA,EAAM;AACjB,IAAA,MAAM,IAAA,GAAO,EAAA,CAAG,OAAA,CAAQ,eAAe,CAAA;AACvC,IAAA,IAAI,SAAS,IAAA,EAAM;AACnB,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,QAAA,CAAS,aAAa,CAAA,EAAG;AAE5C,IAAA,IAAI,QAAA,CAAS,aAAA,KAAkB,EAAA,EAAI,EAAA,CAAG,KAAA,EAAM;AAC5C,IAAA,IAAI,CAAC,qBAAqB,OAAA,EAAS;AACjC,MAAA,oBAAA,CAAqB,OAAA,GAAU,IAAA;AAC/B,MAAA,OAAA,GAAU,OAAO,IAAI,CAAA;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,SAAA,EAAW,KAAA,EAAO,IAAA,EAAM,OAAO,CAAC,CAAA;AAEpC,EAAA,MAAM,WAAA,GAAcX,YAAY,MAAM;AACpC,IAAA,oBAAA,CAAqB,OAAA,GAAU,IAAA;AAC/B,IAAA,OAAA,GAAU,OAAO,IAAI,CAAA;AAAA,EACvB,CAAA,EAAG,CAAC,KAAA,EAAO,IAAA,EAAM,OAAO,CAAC,CAAA;AAEzB,EAAA,MAAM,WAAA,GAAc,MAAY,OAAA,CAAQ,KAAK,CAAA;AAE7C,EAAA,uBACEH,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,MAAA;AAAA,MACL,IAAA,EAAK,UAAA;AAAA,MACL,YAAA,EAAY,KAAA;AAAA,MACZ,iBAAe,IAAA,GAAO,CAAA;AAAA,MACtB,iBAAe,IAAA,GAAO,CAAA;AAAA,MACtB,QAAA,EAAU,YAAY,CAAA,GAAI,EAAA;AAAA,MAC1B,aAAA,EAAaE,aAAY,KAAK,CAAA;AAAA,MAC9B,gBAAA,EAAe,EAAA;AAAA,MACf,YAAA,EAAY,UAAU,MAAA,GAAS,OAAA;AAAA,MAC/B,OAAA,EAAS,WAAA;AAAA,MACT,OAAA,EAAS,WAAA;AAAA,MACT,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA;AAAA;AAAA;AAAA,QAIV,iBAAiB,CAAA,IAAA,EAAO,OAAA,GAAU,QAAA,CAAS,QAAA,GAAW,SAAS,OAAO,CAAA,CAAA,CAAA;AAAA,QACtE,iBAAiB,CAAA,IAAA,EAAO,OAAA,GAAU,QAAA,CAAS,cAAA,GAAiB,SAAS,aAAa,CAAA,MAAA,CAAA;AAAA,QAClF,cAAA,EAAgB,CAAA,IAAA,EAAO,QAAA,CAAS,aAAa,CAAA,OAAA,CAAA;AAAA,QAC7C,mBAAA,EAAqB,CAAA,IAAA,EAAO,QAAA,CAAS,aAAa,CAAA,QAAA,CAAA;AAAA;AAAA;AAAA;AAAA,QAIlD,UAAA,EAAY,MAAA;AAAA;AAAA;AAAA,QAGZ,OAAA,EAAS,MAAA;AAAA;AAAA;AAAA,QAGT,aAAA,EAAe;AAAA,OACjB;AAAA,MAEC,QAAA,EAAA,YAAA,KAAiB,SAAY,YAAA,CAAa,EAAE,OAAO,OAAA,EAAS,KAAA,EAAO,CAAA,GAAI;AAAA;AAAA,GAC1E;AAEJ;AAOO,IAAM,MAAA,GAASQ,KAAK,UAAU,CAAA;AACrC,MAAA,CAAO,WAAA,GAAc,QAAA;ACtMrB,SAAS,iBAAiB,WAAA,EAAyC;AACjE,EAAA,MAAM,UAAyB,EAAC;AAChC,EAAA,IAAI,gBAAgB,OAAA,EAAS;AAE3B,IAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,IAAQ,CAAA,EAAG,IAAA,EAAA,EAAQ;AACpC,MAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,GAAO,CAAA,EAAG,IAAA,EAAA,EAAQ;AACnC,QAAA,OAAA,CAAQ,IAAA,CAAM,IAAA,GAAO,CAAA,GAAI,IAAoB,CAAA;AAAA,MAC/C;AAAA,IACF;AAAA,EACF,CAAA,MAAO;AAEL,IAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,GAAO,CAAA,EAAG,IAAA,EAAA,EAAQ;AACnC,MAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,IAAQ,CAAA,EAAG,IAAA,EAAA,EAAQ;AACpC,QAAA,OAAA,CAAQ,IAAA,CAAM,IAAA,GAAO,CAAA,GAAI,IAAoB,CAAA;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAqCO,IAAM,SAAA,GAAYA,IAAAA,CAAK,SAASK,UAAAA,CAAU;AAAA,EAC/C,WAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,kBAAA;AAAA,EACA;AACF,CAAA,EAAmB;AACjB,EAAA,MAAM,OAAA,GAAUF,QAAQ,MAAM,gBAAA,CAAiB,WAAW,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;AAE1E,EAAA,uBACEb,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,MAAA;AAAA,MACL,cAAY,SAAA,IAAa,aAAA;AAAA,MACzB,eAAA,EAAe,CAAA;AAAA,MACf,eAAA,EAAe,CAAA;AAAA,MACd,GAAI,QAAA,KAAa,IAAA,GAAO,EAAE,eAAA,EAAiB,IAAA,KAAS,EAAC;AAAA,MACtD,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,KAAA,EAAO,CAAA;AAAA,QACP,OAAA,EAAS,MAAA;AAAA,QACT,mBAAA,EAAqB,gBAAA;AAAA,QACrB,gBAAA,EAAkB;AAAA,OACpB;AAAA,MAEC,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,KAAA,qBACZA,GAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UAEC,KAAA;AAAA,UACA,OAAA,EAAS,aAAA;AAAA,UACT,WAAW,aAAA,KAAkB,KAAA;AAAA,UAC7B,KAAA;AAAA,UACA,kBAAA;AAAA,UACA,OAAA,EAAS,aAAA;AAAA,UACR,GAAI,YAAA,KAAiB,MAAA,GAAY,EAAE,YAAA,KAAiB,EAAC;AAAA,UACrD,GAAI,YAAA,KAAiB,MAAA,GAAY,EAAE,YAAA,KAAiB;AAAC,SAAA;AAAA,QARjD;AAAA,OAUR;AAAA;AAAA,GACH;AAEJ,CAAC,CAAA;ACnGD,IAAM,UAAA,GAAa,CAAA;AACnB,IAAM,UAAA,GAAa,EAAA;AAGnB,SAAS,QAAA,CAAS,OAA6B,IAAA,EAAiC;AAC9E,EAAA,MAAM,IAAA,GAAO,IAAA,KAAS,CAAA,GAAI,UAAA,GAAa,UAAA;AACvC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,IAAI,KAAA,CAAM,CAAC,CAAA,KAAM,IAAA,EAAM,OAAO,CAAA;AAAA,EAChC;AACA,EAAA,OAAO,IAAA;AACT;AAGA,SAAS,UAAA,CACP,OACA,WAAA,EAIA;AACA,EAAA,MAAM,OAAO,KAAA,GAAQ,CAAA;AACrB,EAAA,MAAM,OAAO,KAAA,IAAS,CAAA;AACtB,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,IAAA,GAAO,CAAA,GAAI,IAAA;AACjD,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,IAAA,GAAO,IAAA;AACjD,EAAA,OAAO,EAAE,CAAA,EAAG,GAAA,GAAM,IAAA,EAAM,CAAA,EAAG,MAAM,IAAA,EAAK;AACxC;AAmBO,SAAS,UAAA,CAAW,EAAE,KAAA,EAAO,WAAA,EAAY,EAAoB;AAClE,EAAA,MAAM,UAAU,aAAA,CAAc,KAAA,EAAO,CAAC,CAAA,KAAM,EAAE,OAAO,CAAA;AACrD,EAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AACrB,EAAA,uBAAOA,GAAAA,CAAC,eAAA,EAAA,EAAgB,KAAA,EAAc,WAAA,EAA0B,CAAA;AAClE;AAEA,SAAS,eAAA,CAAgB,EAAE,KAAA,EAAO,WAAA,EAAY,EAAoB;AAChE,EAAA,MAAM,OAAO,aAAA,CAAc,KAAA,EAAO,CAAC,CAAA,KAAM,EAAE,IAAI,CAAA;AAC/C,EAAA,MAAM,QAAQ,aAAA,CAAc,KAAA,EAAO,CAAC,CAAA,KAAM,EAAE,KAAK,CAAA;AACjD,EAAA,MAAM,UAAA,GAAa,QAAA,CAAS,KAAA,EAAO,IAAI,CAAA;AACvC,EAAA,IAAI,UAAA,KAAe,MAAM,OAAO,IAAA;AAChC,EAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAE,GAAI,UAAA,CAAW,YAAY,WAAW,CAAA;AAEnD,EAAA,uBACEA,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,YAAA,EAAW,OAAA;AAAA,MACX,aAAA,EAAY,MAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,IAAA,EAAM,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,QACV,GAAA,EAAK,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,QACT,KAAA,EAAO,OAAA;AAAA,QACP,MAAA,EAAQ,OAAA;AAAA,QACR,UAAA,EAAY,CAAA,IAAA,EAAO,QAAA,CAAS,KAAK,CAAA,CAAA,CAAA;AAAA,QACjC,aAAA,EAAe,MAAA;AAAA,QACf,MAAA,EAAQ;AAAA;AACV;AAAA,GACF;AAEJ;ACtDA,IAAM,aAAA,GAAgB,OAAO,MAAA,CAAO;AAAA,EAClC,QAAA,EAAU,UAAA;AAAA,EACV,GAAA,EAAK,CAAA;AAAA,EACL,IAAA,EAAM,CAAA;AAAA,EACN,KAAA,EAAO,OAAA;AAAA,EACP,MAAA,EAAQ,OAAA;AAAA,EACR,aAAA,EAAe,MAAA;AAAA,EACf,UAAA,EAAY,WAAA;AAAA,EACZ,MAAA,EAAQ,EAAA;AAAA,EACR,aAAA,EAAe,MAAA;AAAA,EACf,OAAA,EAAS,CAAA;AAAA,EACT,SAAA,EAAW;AACb,CAAC,CAAA;AAOD,IAAM,UAAA,GAAa,OAAO,MAAA,CAAO;AAAA,EAC/B,QAAA,EAAU,UAAA;AAAA,EACV,KAAA,EAAO,CAAA;AAAA,EACP,OAAA,EAAS,CAAA;AAAA,EACT,aAAA,EAAe;AACjB,CAAC,CAAA;AAmCM,IAAM,YAAYgB,UAAAA,CAA4C,SAASC,WAC5E,EAAE,MAAA,IACF,GAAA,EACA;AACA,EAAA,MAAM,UAAA,GAAaL,OAA8B,IAAI,CAAA;AAGrD,EAAA,MAAM,QAAA,GAAWA,OAAqC,IAAI,KAAA,CAAM,EAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAI9E,EAAA,MAAM,KAAA,GAAQC,QAAQ,MAAM;AAC1B,IAAA,MAAM,QAAgC,EAAC;AACvC,IAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,IAAQ,EAAA,EAAI,IAAA,EAAA,EAAQ;AACrC,MAAA,MAAM,QAAQ,MAAA,CAAO,EAAE,IAAA,EAAyB,MAAA,EAAQ,GAAY,CAAA;AACpE,MAAA,KAAA,CAAM,IAAA;AAAA,wBACJb,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YAEC,GAAA,EAAK,CAAC,EAAA,KAAO;AACX,cAAA,QAAA,CAAS,OAAA,CAAQ,IAAI,CAAA,GAAI,EAAA;AAAA,YAC3B,CAAA;AAAA,YACA,gBAAA,EAAgB,IAAA;AAAA,YAChB,KAAA,EAAO;AAAA,cACL,GAAG,UAAA;AAAA,cACH,QAAQ,CAAA,IAAA,EAAO,IAAA,IAAQ,IAAI,QAAA,CAAS,kBAAA,GAAqB,SAAS,kBAAkB,CAAA,OAAA;AAAA,aACtF;AAAA,YAEC,QAAA,EAAA;AAAA,WAAA;AAAA,UAVI;AAAA;AAWP,OACF;AAAA,IACF;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAAkB,mBAAAA;AAAA,IACE,GAAA;AAAA,IACA,OAAO;AAAA,MACL,KAAK,IAAA,EAAY;AACf,QAAA,MAAM,UAAU,UAAA,CAAW,OAAA;AAC3B,QAAA,IAAI,YAAY,IAAA,EAAM;AACtB,QAAA,OAAA,CAAQ,MAAM,OAAA,GAAU,GAAA;AACxB,QAAA,OAAA,CAAQ,OAAA,CAAQ,QAAQ,CAAA,GAAI,MAAA;AAE5B,QAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,EAAA,EAAI,CAAA,EAAA,EAAK;AAC5B,UAAA,MAAM,EAAA,GAAK,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAA;AAC7B,UAAA,IAAI,EAAA,KAAO,IAAA,IAAQ,EAAA,KAAO,MAAA,EAAW;AACnC,YAAA,EAAA,CAAG,KAAA,CAAM,OAAA,GAAU,CAAA,KAAM,IAAA,GAAO,GAAA,GAAM,GAAA;AAAA,UACxC;AAAA,QACF;AAAA,MACF,CAAA;AAAA,MACA,IAAA,GAAa;AACX,QAAA,MAAM,UAAU,UAAA,CAAW,OAAA;AAC3B,QAAA,IAAI,YAAY,IAAA,EAAM;AACtB,QAAA,OAAA,CAAQ,MAAM,OAAA,GAAU,GAAA;AACxB,QAAA,OAAA,CAAQ,OAAA,CAAQ,QAAQ,CAAA,GAAI,OAAA;AAAA,MAC9B,CAAA;AAAA,MACA,YAAA,CAAa,GAAG,CAAA,EAAS;AACvB,QAAA,MAAM,UAAU,UAAA,CAAW,OAAA;AAC3B,QAAA,IAAI,YAAY,IAAA,EAAM;AACtB,QAAA,OAAA,CAAQ,KAAA,CAAM,SAAA,GAAY,CAAA,YAAA,EAAe,CAAC,OAAO,CAAC,CAAA,MAAA,CAAA;AAAA,MACpD,CAAA;AAAA,MACA,OAAA,GAAiC;AAC/B,QAAA,OAAO,UAAA,CAAW,OAAA;AAAA,MACpB;AAAA,KACF,CAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,uBACElB,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,UAAA;AAAA,MACL,YAAA,EAAW,MAAA;AAAA,MACX,aAAA,EAAY,OAAA;AAAA,MACZ,aAAA,EAAY,MAAA;AAAA,MACZ,KAAA,EAAO,aAAA;AAAA,MAEN,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ,CAAC,CAAA;AC3JD,SAASmB,WAAAA,CACP,OACA,WAAA,EAIA;AACA,EAAA,MAAM,OAAO,KAAA,GAAQ,CAAA;AACrB,EAAA,MAAM,OAAO,KAAA,IAAS,CAAA;AACtB,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,IAAA,GAAO,CAAA,GAAI,IAAA;AACjD,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,IAAA,GAAO,IAAA;AACjD,EAAA,OAAO,EAAE,CAAA,EAAG,GAAA,GAAM,IAAA,EAAM,CAAA,EAAG,MAAM,IAAA,EAAK;AACxC;AAEA,SAAS,oBAAA,GAAgC;AACvC,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,MAAA,CAAO,eAAe,UAAA,EAAY;AAC5E,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,MAAA,CAAO,UAAA,CAAW,kCAAkC,CAAA,CAAE,OAAA;AAC/D;AAGA,IAAM,iBAAA,GAAoB,GAAA;AAanB,SAAS,iBAAA,CAAkB,EAAE,EAAA,EAAI,WAAA,EAAY,EAA2B;AAC7E,EAAA,MAAM,KAAA,GAAQP,OAA8B,IAAI,CAAA;AAEhD,EAAAQ,gBAAgB,MAAM;AACpB,IAAA,IAAI,OAAO,IAAA,EAAM;AACjB,IAAA,MAAM,KAAK,KAAA,CAAM,OAAA;AACjB,IAAA,IAAI,EAAA,KAAO,IAAA,IAAQ,OAAO,EAAA,CAAG,YAAY,UAAA,EAAY;AACrD,IAAA,MAAM,QAAA,GAAW,oBAAA,EAAqB,GAAI,CAAA,GAAI,iBAAA;AAC9C,IAAA,EAAA,CAAG,OAAA;AAAA,MACD;AAAA,QACE,EAAE,OAAA,EAAS,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAE;AAAA,QACxB,EAAE,OAAA,EAAS,CAAA,EAAG,MAAA,EAAQ,IAAA,EAAK;AAAA,QAC3B,EAAE,OAAA,EAAS,CAAA,EAAG,MAAA,EAAQ,CAAA;AAAE,OAC1B;AAAA,MACA,EAAE,QAAA,EAAU,MAAA,EAAQ,UAAA,EAAY,MAAM,UAAA;AAAW,KACnD;AAAA,EACF,CAAA,EAAG,CAAC,EAAE,CAAC,CAAA;AAEP,EAAA,IAAI,EAAA,KAAO,MAAM,OAAO,IAAA;AACxB,EAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAE,GAAID,WAAAA,CAAW,IAAI,WAAW,CAAA;AAC3C,EAAA,uBACEnB,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,KAAA;AAAA,MACL,YAAA,EAAW,eAAA;AAAA,MACX,aAAA,EAAY,MAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,IAAA,EAAM,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,QACV,GAAA,EAAK,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,QACT,KAAA,EAAO,OAAA;AAAA,QACP,MAAA,EAAQ,OAAA;AAAA,QACR,UAAA,EAAY,0BAAA;AAAA,QACZ,OAAA,EAAS,CAAA;AAAA,QACT,aAAA,EAAe,MAAA;AAAA,QACf,MAAA,EAAQ;AAAA;AACV;AAAA,GACF;AAEJ;ACrEA,SAASE,aAAY,KAAA,EAAuB;AAC1C,EAAA,MAAM,OAAO,KAAA,GAAQ,CAAA;AACrB,EAAA,MAAM,OAAO,KAAA,IAAS,CAAA;AACtB,EAAA,OAAO,CAAA,EAAG,OAAO,YAAA,CAAa,EAAA,GAAO,IAAI,CAAC,CAAA,EAAG,OAAO,CAAC,CAAA,CAAA;AACvD;AAGA,SAAS,UAAU,IAAA,EAAsB;AACvC,EAAA,IAAI,IAAA,KAAS,GAAG,OAAO,OAAA;AACvB,EAAA,MAAM,KAAA,GAAQ,IAAA,GAAO,CAAA,GAAI,OAAA,GAAU,OAAA;AACnC,EAAA,MAAM,IAAA,GAAA,CAAQ,OAAO,CAAA,IAAK,CAAA;AAC1B,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,CAAA;AACH,MAAA,OAAO,GAAG,KAAK,CAAA,KAAA,CAAA;AAAA,IACjB,KAAK,CAAA;AACH,MAAA,OAAO,GAAG,KAAK,CAAA,OAAA,CAAA;AAAA,IACjB,KAAK,CAAA;AACH,MAAA,OAAO,GAAG,KAAK,CAAA,OAAA,CAAA;AAAA,IACjB,KAAK,CAAA;AACH,MAAA,OAAO,GAAG,KAAK,CAAA,KAAA,CAAA;AAAA,IACjB,KAAK,CAAA;AACH,MAAA,OAAO,GAAG,KAAK,CAAA,MAAA,CAAA;AAAA,IACjB,KAAK,CAAA;AACH,MAAA,OAAO,GAAG,KAAK,CAAA,KAAA,CAAA;AAAA,IACjB;AACE,MAAA,OAAO,GAAG,KAAK,CAAA,MAAA,CAAA;AAAA;AAErB;AAGA,SAAS,eAAA,CACP,QAAA,EACA,KAAA,EACA,UAAA,EACQ;AACR,EAAA,MAAM,EAAE,IAAA,EAAM,EAAA,EAAI,MAAM,SAAA,EAAU,GAAI,iBAAiB,QAAQ,CAAA;AAI/D,EAAA,IAAI,IAAA,KAAS,QAAQ,OAAO,SAAA;AAE5B,EAAA,IAAI,SAAS,QAAA,EAAU;AACrB,IAAA,MAAM,UAAA,GAAA,CAAc,EAAA,GAAK,CAAA,KAAM,IAAA,GAAO,CAAA,CAAA;AACtC,IAAA,OAAO,aAAa,mBAAA,GAAsB,oBAAA;AAAA,EAC5C;AAGA,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,EAAE,CAAA,IAAK,CAAA;AAC5B,EAAA,MAAM,IAAA,GAAO,UAAU,MAAM,CAAA;AAC7B,EAAA,MAAM,MAAA,GAASA,aAAY,IAAI,CAAA;AAC/B,EAAA,MAAM,IAAA,GAAOA,aAAY,EAAE,CAAA;AAE3B,EAAA,IAAI,IAAA,KAAS,WAAA,IAAe,SAAA,KAAc,IAAA,EAAM;AAC9C,IAAA,MAAM,QAAA,GACJ,cAAc,CAAA,GAAI,QAAA,GAAW,cAAc,CAAA,GAAI,QAAA,GAAW,SAAA,KAAc,CAAA,GAAI,MAAA,GAAS,OAAA;AACvF,IAAA,MAAM,MAAA,GAAS,aAAa,uBAAA,GAA0B,UAAA;AACtD,IAAA,OAAO,QAAQ,MAAM,CAAA,CAAA,EAAI,MAAM,CAAA,IAAA,EAAO,QAAQ,OAAO,IAAI,CAAA,CAAA,CAAA;AAAA,EAC3D;AAEA,EAAA,IAAI,SAAS,YAAA,EAAc;AACzB,IAAA,OAAO,GAAG,UAAA,CAAW,IAAI,CAAC,CAAA,CAAA,EAAI,MAAM,2BAA2B,IAAI,CAAA,CAAA,CAAA;AAAA,EACrE;AAEA,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,OAAO,GAAG,UAAA,CAAW,IAAI,CAAC,CAAA,CAAA,EAAI,MAAM,gBAAgB,IAAI,CAAA,CAAA,CAAA;AAAA,EAC1D;AAEA,EAAA,OAAO,GAAG,UAAA,CAAW,IAAI,CAAC,CAAA,CAAA,EAAI,MAAM,OAAO,IAAI,CAAA,CAAA,CAAA;AACjD;AAEA,SAAS,WAAW,CAAA,EAAmB;AACrC,EAAA,OAAO,CAAA,CAAE,MAAA,KAAW,CAAA,GAAI,CAAA,GAAI,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAY,GAAI,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA;AACnE;AAGA,IAAM,WAAA,GAAc;AAAA,EAClB,QAAA,EAAU,UAAA;AAAA,EACV,KAAA,EAAO,KAAA;AAAA,EACP,MAAA,EAAQ,KAAA;AAAA,EACR,OAAA,EAAS,CAAA;AAAA,EACT,MAAA,EAAQ,MAAA;AAAA,EACR,QAAA,EAAU,QAAA;AAAA,EACV,IAAA,EAAM,kBAAA;AAAA,EACN,UAAA,EAAY,QAAA;AAAA,EACZ,MAAA,EAAQ;AACV,CAAA;AAYO,SAAS,UAAA,CAAW,EAAE,KAAA,EAAM,EAAoB;AAOrD,EAAA,MAAM,WAAW,aAAA,CAAc,KAAA,EAAO,CAAC,CAAA,KAAM,EAAE,QAAQ,CAAA;AAEvD,EAAA,MAAM,OAAA,GAAUW,QAAQ,MAAM;AAC5B,IAAA,IAAI,QAAA,KAAa,MAAM,OAAO,EAAA;AAI9B,IAAA,MAAM,UAAA,GAAa,MAAM,cAAA,CAAe,IAAA;AAAA,MACtC,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,SAAA,IAAa,EAAE,IAAA,KAAS;AAAA,KAC5C;AACA,IAAA,OAAO,gBAAgB,QAAA,EAAU,KAAA,CAAM,WAAA,EAAY,CAAE,OAAO,UAAU,CAAA;AAAA,EACxE,CAAA,EAAG,CAAC,QAAA,EAAU,KAAK,CAAC,CAAA;AAEpB,EAAA,uBACEb,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,WAAA,EAAU,QAAA;AAAA,MACV,aAAA,EAAY,MAAA;AAAA,MACZ,YAAA,EAAW,aAAA;AAAA,MACX,KAAA,EAAO,WAAA;AAAA,MAEN,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ;ACjIA,SAASmB,WAAAA,CACP,OACA,WAAA,EAIA;AACA,EAAA,MAAM,OAAO,KAAA,GAAQ,CAAA;AACrB,EAAA,MAAM,OAAO,KAAA,IAAS,CAAA;AACtB,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,IAAA,GAAO,CAAA,GAAI,IAAA;AACjD,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,IAAA,GAAO,IAAA;AACjD,EAAA,OAAO,EAAE,CAAA,EAAG,GAAA,GAAM,IAAA,EAAM,CAAA,EAAG,MAAM,IAAA,EAAK;AACxC;AAiBO,SAAS,YAAA,CAAa,EAAE,KAAA,EAAO,WAAA,EAAa,QAAO,EAAsB;AAC9E,EAAA,MAAM,WAAW,aAAA,CAAc,KAAA,EAAO,CAAC,CAAA,KAAM,EAAE,QAAQ,CAAA;AACvD,EAAA,IAAI,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAClC,EAAA,MAAM,IAAA,GAAO,SAAS,CAAC,CAAA;AACvB,EAAA,IAAI,IAAA,KAAS,QAAW,OAAO,IAAA;AAC/B,EAAA,uBACEnB,GAAAA;AAAA,IAAC,iBAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,WAAA;AAAA,MACA,MAAA;AAAA,MACA,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,IAAI,IAAA,CAAK;AAAA;AAAA,GACX;AAEJ;AAUA,SAAS,kBAAkB,EAAE,KAAA,EAAO,aAAa,MAAA,EAAQ,IAAA,EAAM,IAAG,EAA2B;AAC3F,EAAA,MAAM,IAAA,GAAO,aAAA,CAAc,KAAA,EAAO,IAAI,CAAA;AACtC,EAAA,IAAI,IAAA,KAAS,GAAG,OAAO,IAAA;AACvB,EAAA,MAAM,MAAA,GAASmB,WAAAA,CAAW,IAAA,EAAM,WAAW,CAAA;AAC3C,EAAA,MAAM,MAAA,GAASA,WAAAA,CAAW,EAAA,EAAI,WAAW,CAAA;AAEzC,EAAA,uBACEf,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,YAAA,EAAW,SAAA;AAAA,MACX,aAAA,EAAY,MAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,KAAA,EAAO,CAAA;AAAA,QACP,aAAA,EAAe,MAAA;AAAA,QACf,MAAA,EAAQ;AAAA,OACV;AAAA,MAGA,QAAA,EAAA;AAAA,wBAAAJ,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,UAAA;AAAA,cACV,IAAA,EAAM,CAAA,EAAG,MAAA,CAAO,CAAC,CAAA,CAAA,CAAA;AAAA,cACjB,GAAA,EAAK,CAAA,EAAG,MAAA,CAAO,CAAC,CAAA,CAAA,CAAA;AAAA,cAChB,KAAA,EAAO,OAAA;AAAA,cACP,MAAA,EAAQ,OAAA;AAAA,cACR,UAAA,EAAY,oBAAA;AAAA,cACZ,OAAA,EAAS;AAAA;AACX;AAAA,SACF;AAAA,wBAEAA,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,UAAA;AAAA,cACV,IAAA,EAAM,CAAA,EAAG,MAAA,CAAO,CAAC,CAAA,CAAA,CAAA;AAAA,cACjB,GAAA,EAAK,CAAA,EAAG,MAAA,CAAO,CAAC,CAAA,CAAA,CAAA;AAAA,cAChB,KAAA,EAAO,OAAA;AAAA,cACP,MAAA,EAAQ,OAAA;AAAA,cACR,UAAA,EAAY;AAAA;AACd;AAAA,SACF;AAAA,wBACAA,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,oBAAA,EAAmB,MAAA;AAAA,YACnB,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,UAAA;AAAA,cACV,IAAA,EAAM,CAAA,EAAG,MAAA,CAAO,CAAC,CAAA,CAAA,CAAA;AAAA,cACjB,GAAA,EAAK,CAAA,EAAG,MAAA,CAAO,CAAC,CAAA,CAAA,CAAA;AAAA,cAChB,KAAA,EAAO,OAAA;AAAA,cACP,MAAA,EAAQ,OAAA;AAAA,cACR,OAAA,EAAS,MAAA;AAAA,cACT,UAAA,EAAY,QAAA;AAAA,cACZ,cAAA,EAAgB,QAAA;AAAA,cAChB,OAAA,EAAS,IAAA;AAAA,cACT,aAAA,EAAe;AAAA,aACjB;AAAA,YAEC,QAAA,EAAA,MAAA,CAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAI;AAAA;AAAA;AAC9B;AAAA;AAAA,GACF;AAEJ;ACzFA,SAASmB,WAAAA,CACP,OACA,WAAA,EAIA;AACA,EAAA,MAAM,OAAO,KAAA,GAAQ,CAAA;AACrB,EAAA,MAAM,OAAO,KAAA,IAAS,CAAA;AACtB,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,IAAA,GAAO,CAAA,GAAI,IAAA;AACjD,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,IAAA,GAAO,IAAA;AACjD,EAAA,OAAO,EAAE,CAAA,EAAG,GAAA,GAAM,IAAA,EAAM,CAAA,EAAG,MAAM,IAAA,EAAK;AACxC;AAGA,IAAM,YAAA,GAAqC;AAAA,EACzC,SAAA,CAAU,KAAA;AAAA,EACV,SAAA,CAAU,MAAA;AAAA,EACV,SAAA,CAAU,IAAA;AAAA,EACV,SAAA,CAAU;AACZ,CAAA;AAGA,IAAM,SAAA,GAAiD;AAAA,EACrD,GAAG,SAAA,CAAU,KAAA;AAAA,EACb,GAAG,SAAA,CAAU,IAAA;AAAA,EACb,GAAG,SAAA,CAAU,MAAA;AAAA,EACb,GAAG,SAAA,CAAU,MAAA;AAAA,EACb,GAAG,SAAA,CAAU,KAAA;AAAA,EACb,GAAG,SAAA,CAAU,IAAA;AAAA,EACb,GAAG,SAAA,CAAU,MAAA;AAAA,EACb,GAAG,SAAA,CAAU;AACf,CAAA;AAEO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,IAAA,EAAM,KAAA;AAAA,EACN,EAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAA0B;AACxB,EAAA,MAAM,UAAA,GAAaP,MAAAA,CAAqC,EAAE,CAAA;AAE1D,EAAA,MAAM,QAAA,GAAWT,WAAAA;AAAA,IACf,CAAC,UACC,0BAAA,GACI,0BAAA,CAA2B,OAAO,KAAc,CAAA,GAChDkB,WAAU,KAAK,CAAA;AAAA,IACrB,CAAC,4BAA4B,KAAK;AAAA,GACpC;AAEA,EAAA,MAAM,CAAC,kBAAA,EAAoB,qBAAqB,CAAA,GAAIC,QAAAA;AAAA,IAAiB,MACnE,QAAA,CAAS,YAAA,CAAa,CAAC,CAAA,IAAK,UAAU,KAAK;AAAA,GAC7C;AAGA,EAAAR,UAAU,MAAM;AACd,IAAA,UAAA,CAAW,OAAA,CAAQ,CAAC,CAAA,EAAG,KAAA,EAAM;AAAA,EAC/B,CAAA,EAAG,EAAE,CAAA;AAGL,EAAAA,UAAU,MAAM;AACd,IAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,KAA2B;AACxC,MAAA,IAAI,CAAA,CAAE,QAAQ,QAAA,EAAU;AACtB,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,QAAA,EAAS;AACT,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,CAAA,CAAE,QAAQ,KAAA,EAAO;AACnB,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,MAAM,WAAW,QAAA,CAAS,aAAA;AAC1B,QAAA,MAAM,UAAA,GAAa,UAAA,CAAW,OAAA,CAAQ,OAAA,CAAQ,QAAQ,CAAA;AACtD,QAAA,IAAI,OAAA;AACJ,QAAA,IAAI,EAAE,QAAA,EAAU;AACd,UAAA,OAAA,GAAU,cAAc,CAAA,GAAI,UAAA,CAAW,OAAA,CAAQ,MAAA,GAAS,IAAI,UAAA,GAAa,CAAA;AAAA,QAC3E,CAAA,MAAO;AACL,UAAA,OAAA,GAAU,cAAc,UAAA,CAAW,OAAA,CAAQ,MAAA,GAAS,CAAA,GAAI,IAAI,UAAA,GAAa,CAAA;AAAA,QAC3E;AACA,QAAA,UAAA,CAAW,OAAA,CAAQ,OAAO,CAAA,EAAG,KAAA,EAAM;AACnC,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,WAAA,IAAe,CAAA,CAAE,QAAQ,YAAA,EAAc;AACnD,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,MAAM,WAAW,QAAA,CAAS,aAAA;AAC1B,QAAA,MAAM,UAAA,GAAa,UAAA,CAAW,OAAA,CAAQ,OAAA,CAAQ,QAAQ,CAAA;AACtD,QAAA,MAAM,UAAU,UAAA,GAAa,CAAA,GAAI,CAAA,GAAA,CAAK,UAAA,GAAa,KAAK,YAAA,CAAa,MAAA;AACrE,QAAA,UAAA,CAAW,OAAA,CAAQ,OAAO,CAAA,EAAG,KAAA,EAAM;AACnC,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,SAAA,IAAa,CAAA,CAAE,QAAQ,WAAA,EAAa;AAChD,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,MAAM,WAAW,QAAA,CAAS,aAAA;AAC1B,QAAA,MAAM,UAAA,GAAa,UAAA,CAAW,OAAA,CAAQ,OAAA,CAAQ,QAAQ,CAAA;AACtD,QAAA,MAAM,UAAU,UAAA,IAAc,CAAA,GAAI,YAAA,CAAa,MAAA,GAAS,IAAI,UAAA,GAAa,CAAA;AACzE,QAAA,UAAA,CAAW,OAAA,CAAQ,OAAO,CAAA,EAAG,KAAA,EAAM;AACnC,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,CAAA,CAAE,QAAQ,MAAA,EAAQ;AACpB,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,UAAA,CAAW,OAAA,CAAQ,CAAC,CAAA,EAAG,KAAA,EAAM;AAC7B,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,CAAA,CAAE,QAAQ,KAAA,EAAO;AACnB,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,UAAA,CAAW,OAAA,CAAQ,YAAA,CAAa,MAAA,GAAS,CAAC,GAAG,KAAA,EAAM;AACnD,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,MAAA,GAAS,SAAA,CAAU,CAAA,CAAE,GAAG,CAAA;AAC9B,MAAA,IAAI,WAAW,MAAA,EAAW;AACxB,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,QAAA,CAAS,MAAM,CAAA;AAAA,MACjB;AAAA,IACF,CAAA;AACA,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,KAAK,CAAA;AACxC,IAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,KAAK,CAAA;AAAA,EAC1D,CAAA,EAAG,CAAC,QAAA,EAAU,QAAQ,CAAC,CAAA;AAEvB,EAAA,MAAM,SAAA,GAAYK,WAAAA,CAAW,EAAA,EAAI,WAAW,CAAA;AAK5C,EAAA,MAAM,wBAAwB,KAAA,KAAU,CAAA;AACxC,EAAA,MAAM,WAAA,GAAc,WAAA,KAAgB,OAAA,GAAU,qBAAA,GAAwB,CAAC,qBAAA;AAEvE,EAAA,uBACEf,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,cAAA;AAAA,MACL,YAAA,EAAW,mBAAA;AAAA,MACX,OAAA,EAAS,QAAA;AAAA,MACT,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,KAAA,EAAO,CAAA;AAAA,QACP,UAAA,EAAY,qBAAA;AAAA,QACZ,MAAA,EAAQ,EAAA;AAAA,QACR,MAAA,EAAQ;AAAA,OACV;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAJ,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,YAAA,EAAW,MAAA;AAAA,YACX,YAAA,EAAY,CAAA,0BAAA,EAA6BE,YAAAA,CAAY,EAAE,CAAC,CAAA,CAAA;AAAA,YACxD,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,eAAA,EAAgB;AAAA,YAClC,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,UAAA;AAAA,cACV,IAAA,EAAM,CAAA,EAAG,SAAA,CAAU,CAAC,CAAA,CAAA,CAAA;AAAA,cACpB,GAAA,EAAK,GAAG,WAAA,GAAc,SAAA,CAAU,IAAI,IAAA,GAAO,CAAA,GAAI,UAAU,CAAC,CAAA,CAAA,CAAA;AAAA,cAC1D,KAAA,EAAO,OAAA;AAAA,cACP,MAAA,EAAQ,CAAA,EAAG,IAAA,GAAO,CAAC,CAAA,CAAA,CAAA;AAAA,cACnB,OAAA,EAAS,MAAA;AAAA,cACT,aAAA,EAAe,cAAc,gBAAA,GAAmB,QAAA;AAAA,cAChD,UAAA,EAAY,SAAA;AAAA,cACZ,SAAA,EAAW,gCAAA;AAAA,cACX,YAAA,EAAc,KAAA;AAAA,cACd,QAAA,EAAU;AAAA,aACZ;AAAA,YAEC,QAAA,EAAA,YAAA,CAAa,GAAA,CAAI,CAAC,KAAA,EAAO,KAAA,KAAU;AAClC,cAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,KAAA,EAAgB,KAAK,CAAA;AAClD,cAAA,MAAM,KAAA,GAAQ,SAAS,KAAK,CAAA;AAC5B,cAAA,uBACEF,GAAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBAEC,GAAA,EAAK,CAAC,EAAA,KAAO;AACX,oBAAA,UAAA,CAAW,OAAA,CAAQ,KAAK,CAAA,GAAI,EAAA;AAAA,kBAC9B,CAAA;AAAA,kBACA,IAAA,EAAK,QAAA;AAAA,kBACL,OAAA,EAAS,MAAM,QAAA,CAAS,KAAK,CAAA;AAAA,kBAC7B,OAAA,EAAS,MAAM,qBAAA,CAAsB,KAAK,CAAA;AAAA,kBAC1C,YAAA,EAAY,KAAA;AAAA,kBACZ,KAAA,EAAO;AAAA,oBACL,IAAA,EAAM,CAAA;AAAA,oBACN,OAAA,EAAS,MAAA;AAAA,oBACT,UAAA,EAAY,QAAA;AAAA,oBACZ,cAAA,EAAgB,QAAA;AAAA,oBAChB,MAAA,EAAQ,MAAA;AAAA,oBACR,UAAA,EAAY,aAAA;AAAA,oBACZ,MAAA,EAAQ,SAAA;AAAA,oBACR,OAAA,EAAS,CAAA;AAAA,oBACT,MAAA,EAAQ,CAAA;AAAA,oBACR,IAAA,EAAM,SAAA;AAAA,oBACN,aAAA,EAAe;AAAA,mBACjB;AAAA,kBACA,sBAAA,EAAsBqB,WAAU,KAAK,CAAA;AAAA,kBAEpC,QAAA,EAAA,MAAA,CAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAI;AAAA,iBAAA;AAAA,gBAvBvB;AAAA,eAwBP;AAAA,YAEJ,CAAC;AAAA;AAAA,SACH;AAAA,wBACArB,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAU,WAAA,EAAU,QAAA,EAAS,aAAA,EAAY,MAAA,EAAO,KAAA,EAAOuB,YAAAA,EACpE,QAAA,EAAA,kBAAA,EACH,CAAA;AAAA,wBACAvB,GAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,SAAA,EAAU,KAAA,EAAOuB,cAAa,QAAA,EAAA,qFAAA,EAE9C;AAAA;AAAA;AAAA,GACF;AAEJ;AAGA,IAAMA,YAAAA,GAAc;AAAA,EAClB,QAAA,EAAU,UAAA;AAAA,EACV,KAAA,EAAO,KAAA;AAAA,EACP,MAAA,EAAQ,KAAA;AAAA,EACR,OAAA,EAAS,CAAA;AAAA,EACT,MAAA,EAAQ,MAAA;AAAA,EACR,QAAA,EAAU,QAAA;AAAA,EACV,IAAA,EAAM,kBAAA;AAAA,EACN,UAAA,EAAY,QAAA;AAAA,EACZ,MAAA,EAAQ;AACV,CAAA;AAEA,SAASF,WAAU,CAAA,EAAsB;AACvC,EAAA,QAAQ,CAAA;AAAG,IACT,KAAK,SAAA,CAAU,KAAA;AACb,MAAA,OAAO,OAAA;AAAA,IACT,KAAK,SAAA,CAAU,IAAA;AACb,MAAA,OAAO,MAAA;AAAA,IACT,KAAK,SAAA,CAAU,MAAA;AACb,MAAA,OAAO,QAAA;AAAA,IACT,KAAK,SAAA,CAAU,MAAA;AACb,MAAA,OAAO,QAAA;AAAA,IACT;AACE,MAAA,OAAO,OAAA;AAAA;AAEb;AAEA,SAASnB,aAAY,KAAA,EAA4B;AAC/C,EAAA,MAAM,OAAO,KAAA,GAAQ,CAAA;AACrB,EAAA,MAAM,OAAO,KAAA,IAAS,CAAA;AACtB,EAAA,OAAO,CAAA,EAAG,OAAO,YAAA,CAAa,EAAA,GAAO,IAAI,CAAC,CAAA,EAAG,OAAO,CAAC,CAAA,CAAA;AACvD;ACpPO,SAAS,gBAAA,CAAiB,EAAE,KAAA,EAAO,WAAA,EAAa,QAAO,EAA0B;AACtF,EAAA,MAAM,QAA2B,EAAC;AAClC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,CAAC,CAAA,IAAK,CAAA;AACzB,IAAA,IAAI,SAAS,CAAA,EAAG;AAChB,IAAA,MAAM,KAAA,GAAQ,CAAA;AACd,IAAA,MAAM,EAAE,GAAA,EAAK,GAAA,EAAI,GAAI,SAAA,CAAU,OAAO,WAAW,CAAA;AACjD,IAAA,KAAA,CAAM,IAAA;AAAA,sBACJF,GAAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UAEC,mBAAA,EAAmB,YAAY,KAAK,CAAA;AAAA,UACpC,iBAAA,EAAiB,IAAA;AAAA,UACjB,KAAA,EAAO;AAAA,YACL,GAAG,eAAA;AAAA,YACH,eAAA,EAAiB,GAAA;AAAA,YACjB,YAAA,EAAc,GAAA;AAAA,YACd,QAAQ,CAAA,IAAA,EAAO,IAAA,IAAQ,IAAI,QAAA,CAAS,kBAAA,GAAqB,SAAS,kBAAkB,CAAA,OAAA;AAAA,WACtF;AAAA,UAEC,QAAA,EAAA,MAAA,CAAO,EAAE,IAAA,EAAyB,MAAA,EAAQ,OAAO;AAAA,SAAA;AAAA,QAV7C;AAAA;AAWP,KACF;AAAA,EACF;AACA,EAAA,uBACEA,GAAAA,CAAC,KAAA,EAAA,EAAI,eAAY,MAAA,EAAO,KAAA,EAAO,iBAC5B,QAAA,EAAA,KAAA,EACH,CAAA;AAEJ;AClCA,IAAM,mBAAA,GAAsB,EAAA;AAC5B,IAAM,cAAA,GAAiB,mCAAA;AAGvB,SAASE,aAAY,KAAA,EAA4B;AAC/C,EAAA,MAAM,OAAO,KAAA,GAAQ,CAAA;AACrB,EAAA,MAAM,OAAO,KAAA,IAAS,CAAA;AACtB,EAAA,OAAO,CAAA,EAAG,OAAO,YAAA,CAAa,EAAA,GAAO,IAAI,CAAC,CAAA,EAAG,OAAO,CAAC,CAAA,CAAA;AACvD;AAOA,SAAS,WAAA,CACP,IAAA,EACA,EAAA,EACA,UAAA,EACA,WAAA,EAC4B;AAC5B,EAAA,MAAM,WAAW,IAAA,GAAO,CAAA;AACxB,EAAA,MAAM,WAAW,IAAA,IAAQ,CAAA;AACzB,EAAA,MAAM,SAAS,EAAA,GAAK,CAAA;AACpB,EAAA,MAAM,SAAS,EAAA,IAAM,CAAA;AACrB,EAAA,MAAM,OAAA,GAAU,WAAA,KAAgB,OAAA,GAAU,QAAA,GAAW,CAAA,GAAI,QAAA;AACzD,EAAA,MAAM,OAAA,GAAU,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,QAAA,GAAW,QAAA;AACzD,EAAA,MAAM,KAAA,GAAQ,WAAA,KAAgB,OAAA,GAAU,MAAA,GAAS,CAAA,GAAI,MAAA;AACrD,EAAA,MAAM,KAAA,GAAQ,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,MAAA,GAAS,MAAA;AACrD,EAAA,OAAO;AAAA,IACL,EAAA,EAAA,CAAK,UAAU,KAAA,IAAS,UAAA;AAAA,IACxB,EAAA,EAAA,CAAK,UAAU,KAAA,IAAS;AAAA,GAC1B;AACF;AAGA,SAAS,iBAAiB,OAAA,EAAwB;AAEhD,EAAA,IAAI,OAAO,OAAA,CAAQ,aAAA,KAAkB,UAAA,EAAY;AACjD,EAAA,KAAA,MAAW,IAAA,IAAQ,OAAA,CAAQ,aAAA,EAAc,OAAQ,MAAA,EAAO;AAC1D;AAMA,SAASsB,qBAAAA,GAAgC;AACvC,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,MAAA,CAAO,eAAe,UAAA,EAAY;AAC5E,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,MAAA,CAAO,UAAA,CAAW,kCAAkC,CAAA,CAAE,OAAA;AAC/D;AAOA,SAAS,YAAA,CACP,OAAA,EACA,EAAA,EACA,EAAA,EACA,UACA,MAAA,EACM;AACN,EAAA,gBAAA,CAAiB,OAAO,CAAA;AACxB,EAAA,IAAI,QAAA,IAAY,CAAA,IAAK,OAAO,OAAA,CAAQ,YAAY,UAAA,EAAY;AAC5D,EAAA,OAAA,CAAQ,OAAA;AAAA,IACN,CAAC,EAAE,SAAA,EAAW,CAAA,UAAA,EAAa,EAAE,CAAA,IAAA,EAAO,EAAE,CAAA,GAAA,CAAA,EAAM,EAAG,EAAE,SAAA,EAAW,iBAAA,EAAmB,CAAA;AAAA,IAC/E,EAAE,QAAA,EAAU,MAAA,EAAQ,IAAA,EAAM,MAAA;AAAO,GACnC;AACF;AA2CA,SAAS,aAAA,CACP,WAAA,EACA,SAAA,EACA,WAAA,EACA,UACA,MAAA,EACM;AACN,EAAA,MAAM,IAAA,GAAO,UAAU,qBAAA,EAAsB;AAC7C,EAAA,MAAM,MAAA,GAAS,KAAK,KAAA,GAAQ,CAAA;AAC5B,EAAA,IAAI,UAAU,CAAA,EAAG;AAEjB,EAAA,KAAA,MAAW,KAAK,WAAA,EAAa;AAC3B,IAAA,QAAQ,EAAE,IAAA;AAAM,MACd,KAAK,MAAA;AAAA,MACL,KAAK,SAAA;AAAA,MACL,KAAK,YAAA;AAAA,MACL,KAAK,WAAA,EAAa;AAChB,QAAA,MAAM,OAAO,SAAA,CAAU,aAAA;AAAA,UACrB,CAAA,oBAAA,EAAuBtB,YAAAA,CAAY,CAAA,CAAE,EAAE,CAAC,CAAA,EAAA;AAAA,SAC1C;AACA,QAAA,IAAI,SAAS,IAAA,EAAM;AACnB,QAAA,MAAM,EAAE,EAAA,EAAI,EAAA,EAAG,GAAI,WAAA,CAAY,EAAE,IAAA,EAAM,CAAA,CAAE,EAAA,EAAI,MAAA,EAAQ,WAAW,CAAA;AAChE,QAAA,YAAA,CAAa,IAAA,EAAM,EAAA,EAAI,EAAA,EAAI,QAAA,EAAU,MAAM,CAAA;AAC3C,QAAA;AAAA,MACF;AAAA,MACA,KAAK,QAAA,EAAU;AACb,QAAA,MAAM,SAAS,SAAA,CAAU,aAAA;AAAA,UACvB,CAAA,oBAAA,EAAuBA,YAAAA,CAAY,CAAA,CAAE,MAAM,CAAC,CAAA,EAAA;AAAA,SAC9C;AACA,QAAA,MAAM,SAAS,SAAA,CAAU,aAAA;AAAA,UACvB,CAAA,oBAAA,EAAuBA,YAAAA,CAAY,CAAA,CAAE,MAAM,CAAC,CAAA,EAAA;AAAA,SAC9C;AACA,QAAA,IAAI,WAAW,IAAA,EAAM;AACnB,UAAA,MAAM,EAAE,EAAA,EAAI,EAAA,EAAG,GAAI,WAAA,CAAY,EAAE,QAAA,EAAU,CAAA,CAAE,MAAA,EAAQ,MAAA,EAAQ,WAAW,CAAA;AACxE,UAAA,YAAA,CAAa,MAAA,EAAQ,EAAA,EAAI,EAAA,EAAI,QAAA,EAAU,MAAM,CAAA;AAAA,QAC/C;AACA,QAAA,IAAI,WAAW,IAAA,EAAM;AACnB,UAAA,MAAM,EAAE,EAAA,EAAI,EAAA,EAAG,GAAI,WAAA,CAAY,EAAE,QAAA,EAAU,CAAA,CAAE,MAAA,EAAQ,MAAA,EAAQ,WAAW,CAAA;AACxE,UAAA,YAAA,CAAa,MAAA,EAAQ,EAAA,EAAI,EAAA,EAAI,QAAA,EAAU,MAAM,CAAA;AAAA,QAC/C;AACA,QAAA;AAAA,MACF;AAKE;AACJ,EACF;AACF;AAkBO,SAAS,eAAA,CAAgB;AAAA,EAC9B,KAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAAoC;AAClC,EAAA,MAAM,QAAA,GAAW,SAAS,UAAA,IAAc,mBAAA;AACxC,EAAA,MAAM,MAAA,GAAS,SAAS,MAAA,IAAU,cAAA;AAClC,EAAA,MAAM,cAAc,OAAA,EAAS,WAAA;AAQ7B,EAAA,MAAM,aAAa,aAAA,CAAc,KAAA,EAAO,CAAC,CAAA,KAAM,EAAE,UAAU,CAAA;AAC3D,EAAA,MAAM,kBAAA,GAAqBU,OAAsB,IAAI,CAAA;AAErD,EAAAQ,gBAAgB,MAAM;AACpB,IAAA,IAAI,kBAAA,CAAmB,YAAY,UAAA,EAAY;AAC/C,IAAA,kBAAA,CAAmB,OAAA,GAAU,UAAA;AAC7B,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,cAAc,IAAA,EAAM;AACxB,IAAA,MAAM,cAAc,KAAA,CAAM,cAAA;AAC1B,IAAA,IAAI,WAAA,CAAY,WAAW,CAAA,EAAG;AAK9B,IAAA,IAAI,aAAa,OAAA,EAAS;AACxB,MAAA,WAAA,CAAY,OAAA,GAAU,KAAA;AACtB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,iBAAA,GAAoBI,qBAAAA,EAAqB,GAAI,CAAA,GAAI,QAAA;AACvD,IAAA,IAAI,qBAAqB,CAAA,EAAG;AAE5B,IAAA,aAAA,CAAc,WAAA,EAAa,SAAA,EAAW,WAAA,EAAa,iBAAA,EAAmB,MAAM,CAAA;AAAA,EAC9E,CAAA,EAAG,CAAC,UAAA,EAAY,KAAA,EAAO,cAAc,WAAA,EAAa,QAAA,EAAU,MAAA,EAAQ,WAAW,CAAC,CAAA;AAEhF,EAAA,OAAO,IAAA;AACT;AC9OA,SAAS,iBAAA,CAAkB,GAAiB,OAAA,EAAuC;AACjF,EAAA,IAAI,CAAA,CAAE,QAAA,EAAU,OAAO,OAAA,CAAQ,KAAA;AAC/B,EAAA,IAAI,CAAA,CAAE,MAAA,EAAQ,OAAO,OAAA,CAAQ,GAAA;AAC7B,EAAA,IAAI,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,OAAA,SAAgB,OAAA,CAAQ,IAAA;AAC3C,EAAA,OAAO,OAAA,CAAQ,OAAA;AACjB;AAwBO,SAAS,gBAAgB,OAAA,EAAuC;AACrE,EAAA,MAAM,EAAE,MAAM,WAAA,EAAa,YAAA,EAAc,gBAAgB,OAAA,EAAS,OAAA,EAAS,iBAAgB,GACzF,OAAA;AAEF,EAAAV,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,SAAA,KAAc,IAAA,IAAQ,IAAA,KAAS,IAAA,EAAM;AAEzC,IAAA,IAAI,MAAA,GAA6B,IAAA;AACjC,IAAA,IAAI,eAAA,GAAiC,IAAA;AAErC,IAAA,MAAM,eAAe,MAAY;AAC/B,MAAA,cAAA,CAAe,OAAA,EAAS,WAAW,IAAI,CAAA;AAAA,IACzC,CAAA;AAUA,IAAA,MAAM,IAAA,GAAO,CAAC,SAAA,KAAwC;AACpD,MAAA,IAAI,CAAC,iBAAiB,OAAO,SAAA;AAC7B,MAAA,IAAI,MAAA,KAAW,MAAM,OAAO,SAAA;AAC5B,MAAA,IAAI,SAAA,KAAc,QAAQ,OAAO,SAAA;AACjC,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AACpC,MAAA,IAAI,OAAO,IAAA,KAAS,CAAA,IAAK,OAAO,GAAA,CAAI,SAAS,GAAG,OAAO,SAAA;AAGvD,MAAA,MAAM,KAAK,SAAA,GAAY,CAAA;AACvB,MAAA,MAAM,KAAK,SAAA,IAAa,CAAA;AACxB,MAAA,IAAI,IAAA,GAAO,SAAA;AACX,MAAA,IAAI,QAAA,GAAW,QAAA;AACf,MAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,QAAA,MAAM,EAAA,GAAA,CAAM,IAAI,CAAA,IAAK,EAAA;AACrB,QAAA,MAAM,EAAA,GAAA,CAAM,KAAK,CAAA,IAAK,EAAA;AACtB,QAAA,MAAM,CAAA,GAAI,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,EAAA;AACzB,QAAA,IAAI,IAAI,QAAA,EAAU;AAChB,UAAA,QAAA,GAAW,CAAA;AACX,UAAA,IAAA,GAAO,CAAA;AAAA,QACT;AAAA,MACF;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAA;AAEA,IAAA,MAAM,UAAA,GAAa,CAAC,EAAA,EAAiB,KAAA,KAAwB;AAC3D,MAAA,IAAI,WAAW,IAAA,EAAM;AACrB,MAAA,cAAA,CAAe,OAAA,EAAS,UAAA,CAAW,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAI,IAAA,CAAK,EAAE,CAAA,EAAG,KAAA,EAAO,CAAA;AAAA,IAC1E,CAAA;AAEA,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAAwB;AAI7C,MAAA,CAAA,CAAE,cAAA,EAAe;AAAA,IACnB,CAAA;AAEA,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAA0B;AAC/C,MAAA,IAAI,CAAA,CAAE,WAAW,CAAA,EAAG;AACpB,MAAA,MAAM,KAAK,gBAAA,CAAiB,SAAA,EAAW,EAAE,OAAA,EAAS,CAAA,CAAE,SAAS,WAAW,CAAA;AACxE,MAAA,IAAI,OAAO,IAAA,EAAM;AACjB,MAAA,MAAA,GAAS,EAAA;AACT,MAAA,eAAA,GAAkB,CAAA,CAAE,SAAA;AAEpB,MAAA,UAAA,CAAW,EAAA,EAAI,iBAAA,CAAkB,CAAA,EAAG,OAAO,CAAC,CAAA;AAC5C,MAAA,IAAI;AACF,QAAA,SAAA,CAAU,iBAAA,CAAkB,EAAE,SAAS,CAAA;AAAA,MACzC,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAA0B;AAC/C,MAAA,IAAI,WAAW,IAAA,EAAM;AACrB,MAAA,IAAI,eAAA,KAAoB,IAAA,IAAQ,CAAA,CAAE,SAAA,KAAc,eAAA,EAAiB;AACjE,MAAA,MAAM,KAAK,gBAAA,CAAiB,SAAA,EAAW,EAAE,OAAA,EAAS,CAAA,CAAE,SAAS,WAAW,CAAA;AACxE,MAAA,IAAI,OAAO,IAAA,EAAM;AAEf,QAAA,UAAA,CAAW,MAAA,EAAQ,iBAAA,CAAkB,CAAA,EAAG,OAAO,CAAC,CAAA;AAChD,QAAA;AAAA,MACF;AACA,MAAA,UAAA,CAAW,EAAA,EAAI,iBAAA,CAAkB,CAAA,EAAG,OAAO,CAAC,CAAA;AAAA,IAC9C,CAAA;AAEA,IAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAA0B;AAC7C,MAAA,IAAI,WAAW,IAAA,EAAM;AACrB,MAAA,IAAI,eAAA,KAAoB,IAAA,IAAQ,CAAA,CAAE,SAAA,KAAc,eAAA,EAAiB;AACjE,MAAA,MAAM,GAAA,GAAM,iBAAiB,SAAA,EAAW,CAAA,CAAE,SAAS,CAAA,CAAE,OAAA,EAAS,WAAW,CAAA,IAAK,MAAA;AAC9E,MAAA,MAAM,MAAA,GAAS,KAAK,GAAG,CAAA;AACvB,MAAA,MAAM,KAAA,GAAQ,iBAAA,CAAkB,CAAA,EAAG,OAAO,CAAA;AAC1C,MAAA,IAAA,CAAK,YAAY,EAAE,IAAA,EAAM,QAAQ,EAAA,EAAI,MAAA,EAAQ,OAAO,CAAA;AACpD,MAAA,MAAA,GAAS,IAAA;AACT,MAAA,eAAA,GAAkB,IAAA;AAClB,MAAA,YAAA,EAAa;AAAA,IACf,CAAA;AAEA,IAAA,MAAM,eAAA,GAAkB,CAAC,CAAA,KAA0B;AACjD,MAAA,IAAI,WAAW,IAAA,EAAM;AACrB,MAAA,IAAI,eAAA,KAAoB,IAAA,IAAQ,CAAA,CAAE,SAAA,KAAc,eAAA,EAAiB;AACjE,MAAA,MAAA,GAAS,IAAA;AACT,MAAA,eAAA,GAAkB,IAAA;AAClB,MAAA,YAAA,EAAa;AAAA,IACf,CAAA;AAEA,IAAA,SAAA,CAAU,gBAAA,CAAiB,eAAe,aAAa,CAAA;AACvD,IAAA,SAAA,CAAU,gBAAA,CAAiB,eAAe,aAAa,CAAA;AACvD,IAAA,SAAA,CAAU,iBAAiB,aAAA,EAAe,aAAA,EAAe,EAAE,OAAA,EAAS,MAAM,CAAA;AAC1E,IAAA,SAAA,CAAU,gBAAA,CAAiB,aAAa,WAAW,CAAA;AACnD,IAAA,SAAA,CAAU,gBAAA,CAAiB,iBAAiB,eAAe,CAAA;AAE3D,IAAA,OAAO,MAAY;AACjB,MAAA,SAAA,CAAU,mBAAA,CAAoB,eAAe,aAAa,CAAA;AAC1D,MAAA,SAAA,CAAU,mBAAA,CAAoB,eAAe,aAAa,CAAA;AAC1D,MAAA,SAAA,CAAU,mBAAA,CAAoB,eAAe,aAAa,CAAA;AAC1D,MAAA,SAAA,CAAU,mBAAA,CAAoB,aAAa,WAAW,CAAA;AACtD,MAAA,SAAA,CAAU,mBAAA,CAAoB,iBAAiB,eAAe,CAAA;AAC9D,MAAA,YAAA,EAAa;AAAA,IACf,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,IAAA,EAAM,WAAA,EAAa,cAAc,cAAA,EAAgB,OAAA,EAAS,OAAA,EAAS,eAAe,CAAC,CAAA;AACzF;ACtIA,SAAS,YAAA,CAAa,UAAkB,OAAA,EAA+B;AACrE,EAAA,IAAI,QAAA,KAAa,GAAG,OAAO,KAAA;AAC3B,EAAA,MAAM,SAAA,GAAA,CAAa,WAAW,CAAA,IAAK,CAAA;AACnC,EAAA,IAAI,SAAA,KAAc,SAAA,CAAU,IAAA,EAAM,OAAO,KAAA;AACzC,EAAA,MAAM,SAAS,OAAA,IAAW,CAAA;AAC1B,EAAA,OAAO,MAAA,KAAW,KAAK,MAAA,KAAW,CAAA;AACpC;AAYO,SAAS,cAAA,CACd,KAAA,EACA,MAAA,EACA,iBAAA,EACA,UAAU,IAAA,EACoB;AAC9B,EAAA,OAAOX,WAAAA;AAAA,IACL,CAAC,KAAA,KAAuB;AACtB,MAAA,IAAI,CAAC,OAAA,EAAS;AACd,MAAA,IAAI,UAAU,IAAA,EAAM;AACpB,MAAA,MAAM,IAAA,GAAO,MAAM,WAAA,EAAY;AAC/B,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA,IAAK,CAAA;AAClC,MAAA,MAAM,WAAA,GAAc,SAAS,CAAA,GAAI,EAAA,GAAK,OAAO,CAAA,GAAI,KAAA,CAAM,QAAQ,KAAA,CAAM,KAAA;AAErE,MAAA,IAAI,IAAA,CAAK,aAAa,IAAA,EAAM;AAC1B,QAAA,IAAI,WAAA,KAAgB,IAAA,CAAK,IAAA,EAAM,KAAA,CAAM,aAAa,KAAK,CAAA;AACvD,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,IAAA,CAAK,aAAa,KAAA,EAAO;AAC3B,QAAA,KAAA,CAAM,aAAa,IAAI,CAAA;AACvB,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,KAAK,CAAA,EAAG;AAChC,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA,IAAK,CAAA;AAC9C,QAAA,IAAI,YAAA,CAAa,QAAA,EAAU,KAAK,CAAA,EAAG;AACjC,UAAA,IAAI,sBAAsB,MAAA,EAAW;AACnC,YAAA,iBAAA,CAAkB,IAAA,CAAK,UAAU,KAAK,CAAA;AACtC,YAAA;AAAA,UACF;AACA,UAAA,MAAMsB,UAAS,KAAA,CAAM,OAAA,CAAQ,KAAK,QAAA,EAAU,KAAA,EAAO,UAAU,KAAK,CAAA;AAClE,UAAA,IAAIA,OAAAA,KAAW,IAAA,IAAQ,MAAA,KAAW,MAAA,SAAkBA,OAAM,CAAA;AAC1D,UAAA;AAAA,QACF;AACA,QAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,UAAU,KAAK,CAAA;AACjD,QAAA,IAAI,MAAA,KAAW,IAAA,IAAQ,MAAA,KAAW,MAAA,SAAkB,MAAM,CAAA;AAC1D,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,WAAA,KAAgB,KAAK,IAAA,EAAM;AAC7B,QAAA,KAAA,CAAM,aAAa,KAAK,CAAA;AACxB,QAAA;AAAA,MACF;AAEA,MAAA,KAAA,CAAM,aAAa,IAAI,CAAA;AAAA,IACzB,CAAA;AAAA,IACA,CAAC,KAAA,EAAO,MAAA,EAAQ,iBAAA,EAAmB,OAAO;AAAA,GAC5C;AACF;ACxDA,IAAM,QAAA,GAAW,kBAAA;AAejB,SAAS,kBAAA,GAA2B;AAClC,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,EAAA,IAAI,QAAA,CAAS,cAAA,CAAe,QAAQ,CAAA,KAAM,IAAA,EAAM;AAChD,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA;AAC5C,EAAA,KAAA,CAAM,EAAA,GAAK,QAAA;AACX,EAAA,KAAA,CAAM,WAAA,GAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAuCpB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,KAAK,CAAA;AACjC;AAiBO,SAAS,mBAAA,CACd,KAAA,EACA,YAAA,EACA,SAAA,EACA,YAAA,EACM;AACN,EAAAX,UAAU,MAAM;AACd,IAAA,kBAAA,EAAmB;AAAA,EACrB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,UAAU,IAAA,EAAM;AAMpB,IAAA,IAAI,QAAA,GAAqC,IAAA;AACzC,IAAA,IAAI,WAAA,GAA8B,IAAA;AAElC,IAAA,MAAM,QAAQ,MAAY;AACxB,MAAA,MAAM,KAAK,YAAA,CAAa,OAAA;AACxB,MAAA,IAAI,OAAO,IAAA,EAAM;AACjB,MAAA,IAAI,CAAC,SAAA,EAAW;AAGd,QAAA,IAAI,aAAa,IAAA,EAAM;AACrB,UAAA,OAAO,EAAA,CAAG,QAAQ,QAAQ,CAAA;AAC1B,UAAA,QAAA,GAAW,IAAA;AAAA,QACb;AACA,QAAA,IAAI,gBAAgB,IAAA,EAAM;AACxB,UAAA,OAAO,EAAA,CAAG,QAAQ,WAAW,CAAA;AAC7B,UAAA,WAAA,GAAc,IAAA;AAAA,QAChB;AACA,QAAA;AAAA,MACF;AACA,MAAA,MAAM,OAAO,KAAA,CAAM,WAAA,EAAY,CAAE,IAAA,KAAS,IAAI,OAAA,GAAU,OAAA;AACxD,MAAA,IAAI,SAAS,QAAA,EAAU;AACrB,QAAA,EAAA,CAAG,OAAA,CAAQ,QAAQ,CAAA,GAAI,IAAA;AACvB,QAAA,QAAA,GAAW,IAAA;AAAA,MACb;AACA,MAAA,IAAI,iBAAiB,WAAA,EAAa;AAChC,QAAA,IAAI,YAAA,EAAc;AAChB,UAAA,EAAA,CAAG,OAAA,CAAQ,WAAW,CAAA,GAAI,MAAA;AAAA,QAC5B,CAAA,MAAO;AACL,UAAA,OAAO,EAAA,CAAG,QAAQ,WAAW,CAAA;AAAA,QAC/B;AACA,QAAA,WAAA,GAAc,YAAA;AAAA,MAChB;AAAA,IACF,CAAA;AAEA,IAAA,KAAA,EAAM;AACN,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,SAAA,CAAU,KAAK,CAAA;AACzC,IAAA,OAAO,MAAM;AACX,MAAA,WAAA,EAAY;AACZ,MAAA,MAAM,KAAK,YAAA,CAAa,OAAA;AACxB,MAAA,IAAI,OAAO,IAAA,EAAM;AACf,QAAA,OAAO,EAAA,CAAG,QAAQ,QAAQ,CAAA;AAC1B,QAAA,OAAO,EAAA,CAAG,QAAQ,WAAW,CAAA;AAAA,MAC/B;AAAA,IACF,CAAA;AAAA,EACF,GAAG,CAAC,KAAA,EAAO,YAAA,EAAc,SAAA,EAAW,YAAY,CAAC,CAAA;AACnD;ACvIA,IAAM,oBAAoB,QAAA,CAAS,kBAAA;AAoC5B,SAAS,QAAQ,OAAA,EAA+B;AACrD,EAAA,MAAM;AAAA,IACJ,IAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA;AAAA,IACA,kBAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF,GAAI,OAAA;AAKJ,EAAA,MAAM,eAAA,GAAkBF,OAAO,YAAY,CAAA;AAC3C,EAAAE,UAAU,MAAM;AACd,IAAA,eAAA,CAAgB,OAAA,GAAU,YAAA;AAAA,EAC5B,CAAC,CAAA;AAED,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,SAAA,KAAc,IAAA,IAAQ,IAAA,KAAS,IAAA,EAAM;AAEzC,IAAA,MAAM,UAAA,GAAa,oBAAA;AAAA,MACjB,kBAAA,KAAuB,MAAA,GAAY,EAAC,GAAI,EAAE,kBAAA;AAAmB,KAC/D;AAGA,IAAA,IAAI,QAAA,GAA+B,IAAA;AACnC,IAAA,IAAI,MAAA,GAAS,KAAA;AACb,IAAA,IAAI,eAAA,GAAiC,IAAA;AAErC,IAAA,MAAM,cAAA,GAAiB,CAAC,OAAA,EAAiB,OAAA,KAA0B;AACjE,MAAA,MAAM,QAAQ,YAAA,CAAa,OAAA;AAC3B,MAAA,IAAI,UAAU,IAAA,EAAM;AACpB,MAAA,MAAM,IAAA,GAAO,UAAU,qBAAA,EAAsB;AAC7C,MAAA,MAAM,MAAA,GAAS,KAAK,KAAA,GAAQ,CAAA;AAE5B,MAAA,MAAM,CAAA,GAAI,OAAA,GAAU,IAAA,CAAK,IAAA,GAAO,MAAA,GAAS,CAAA;AACzC,MAAA,MAAM,CAAA,GAAI,OAAA,GAAU,IAAA,CAAK,GAAA,GAAM,MAAA,GAAS,CAAA;AACxC,MAAA,KAAA,CAAM,YAAA,CAAa,GAAG,CAAC,CAAA;AAAA,IACzB,CAAA;AAEA,IAAA,MAAM,gBAAgB,MAAY;AAChC,MAAA,IAAI,aAAa,IAAA,EAAM;AACrB,QAAA,QAAA,CAAS,MAAM,OAAA,GAAU,EAAA;AACzB,QAAA,QAAA,GAAW,IAAA;AAAA,MACb;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,UAAU,MAAY;AAC1B,MAAA,aAAA,EAAc;AAEd,MAAA,YAAA,CAAa,SAAS,IAAA,EAAK;AAC3B,MAAA,MAAA,GAAS,KAAA;AACT,MAAA,eAAA,GAAkB,IAAA;AAClB,MAAA,SAAA,EAAU;AAAA,IACZ,CAAA;AAEA,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAA0B;AAG/C,MAAA,IAAI,CAAA,CAAE,WAAW,CAAA,EAAG;AACpB,MAAA,MAAM,KAAK,gBAAA,CAAiB,SAAA,EAAW,EAAE,OAAA,EAAS,CAAA,CAAE,SAAS,WAAW,CAAA;AACxE,MAAA,IAAI,OAAO,IAAA,EAAM;AACjB,MAAA,MAAM,OAAO,IAAA,CAAK,WAAA,EAAY,CAAE,KAAA,CAAM,EAAE,CAAA,IAAK,CAAA;AAC7C,MAAA,IAAI,SAAS,CAAA,EAAG;AAGhB,MAAA,MAAM,UAAU,eAAA,CAAgB,OAAA;AAChC,MAAA,IAAI,OAAA,KAAY,UAAa,CAAC,OAAA,CAAQ,EAAE,MAAA,EAAQ,EAAA,EAAI,IAAA,EAAyB,CAAA,EAAG;AAC9E,QAAA;AAAA,MACF;AACA,MAAA,MAAM,QAAA,GAAW,WAAW,WAAA,CAAY,EAAA,EAAI,EAAE,SAAA,EAAW,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,OAAO,CAAA;AAC7E,MAAA,IAAI,QAAA,oBAA4B,CAAA,CAAE,SAAA;AAAA,IACpC,CAAA;AAEA,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAA0B;AAC/C,MAAA,MAAM,GAAA,GAAM,WAAW,WAAA,CAAY,CAAA,CAAE,WAAW,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACpE,MAAA,IAAI,QAAQ,IAAA,EAAM;AAElB,MAAA,IAAI,GAAA,CAAI,SAAS,YAAA,EAAc;AAC7B,QAAA,MAAM,OAAQ,IAAA,CAAK,WAAA,GAAc,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,IAAK,CAAA;AACpD,QAAA,IAAI,SAAS,CAAA,EAAG;AAEd,UAAA,UAAA,CAAW,MAAA,EAAO;AAClB,UAAA;AAAA,QACF;AAQA,QAAA,MAAM,WAAA,GAAcZ,YAAAA,CAAY,GAAA,CAAI,IAAI,CAAA;AACxC,QAAA,QAAA,GAAW,SAAA,CAAU,aAAA,CAA2B,CAAA,oBAAA,EAAuB,WAAW,CAAA,EAAA,CAAI,CAAA;AACtF,QAAA,IAAI,aAAa,IAAA,EAAM;AAKrB,UAAA,QAAA,CAAS,KAAA,CAAM,OAAA,GAAU,CAAA,IAAA,EAAO,iBAAiB,CAAA,OAAA,CAAA;AAAA,QACnD;AAEA,QAAA,MAAA,GAAS,IAAA;AACT,QAAA,IAAI;AACF,UAAA,SAAA,CAAU,iBAAA,CAAkB,EAAE,SAAS,CAAA;AAAA,QACzC,CAAA,CAAA,MAAQ;AAAA,QAER;AAMA,QAAA,YAAA,CAAa,OAAA,EAAS,KAAK,IAAI,CAAA;AAC/B,QAAA,cAAA,CAAe,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,OAAO,CAAA;AAMnC,QAAA,WAAA,CAAY,GAAA,CAAI,MAAM,IAAI,CAAA;AAC1B,QAAA;AAAA,MACF;AAGA,MAAA,cAAA,CAAe,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,OAAO,CAAA;AAAA,IACrC,CAAA;AAEA,IAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAA0B;AAC7C,MAAA,MAAM,GAAA,GAAM,WAAW,SAAA,CAAU,CAAA,CAAE,WAAW,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AAClE,MAAA,IAAI,QAAQ,IAAA,EAAM;AAElB,MAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAQ;AACvB,QAAA,MAAM,SAAS,gBAAA,CAAiB,SAAA,EAAW,EAAE,OAAA,EAAS,CAAA,CAAE,SAAS,WAAW,CAAA;AAC5E,QAAA,IAAI,MAAA,KAAW,IAAA,IAAQ,MAAA,KAAW,GAAA,CAAI,IAAA,EAAM;AAC1C,UAAA,MAAA,CAAO,GAAA,CAAI,MAAM,MAAM,CAAA;AAAA,QACzB;AAAA,MACF;AAIA,MAAA,IAAI,QAAQ,OAAA,EAAQ;AACpB,MAAA,eAAA,GAAkB,IAAA;AAAA,IACpB,CAAA;AAEA,IAAA,MAAM,eAAA,GAAkB,CAAC,CAAA,KAA0B;AACjD,MAAA,IAAI,eAAA,KAAoB,IAAA,IAAQ,CAAA,CAAE,SAAA,KAAc,eAAA,EAAiB;AACjE,MAAA,UAAA,CAAW,MAAA,EAAO;AAClB,MAAA,IAAI,QAAQ,OAAA,EAAQ;AACpB,MAAA,eAAA,GAAkB,IAAA;AAAA,IACpB,CAAA;AAIA,IAAA,SAAA,CAAU,gBAAA,CAAiB,eAAe,aAAa,CAAA;AACvD,IAAA,SAAA,CAAU,iBAAiB,aAAA,EAAe,aAAA,EAAe,EAAE,OAAA,EAAS,MAAM,CAAA;AAC1E,IAAA,SAAA,CAAU,gBAAA,CAAiB,aAAa,WAAW,CAAA;AACnD,IAAA,SAAA,CAAU,gBAAA,CAAiB,iBAAiB,eAAe,CAAA;AAE3D,IAAA,OAAO,MAAY;AACjB,MAAA,SAAA,CAAU,mBAAA,CAAoB,eAAe,aAAa,CAAA;AAC1D,MAAA,SAAA,CAAU,mBAAA,CAAoB,eAAe,aAAa,CAAA;AAC1D,MAAA,SAAA,CAAU,mBAAA,CAAoB,aAAa,WAAW,CAAA;AACtD,MAAA,SAAA,CAAU,mBAAA,CAAoB,iBAAiB,eAAe,CAAA;AAC9D,MAAA,IAAI,QAAQ,OAAA,EAAQ;AAAA,IACtB,CAAA;AAAA,EACF,CAAA,EAAG;AAAA,IACD,IAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA;AAAA,IACA,kBAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACD,CAAA;AACH;AC/OO,SAAS,eAAe,OAAA,EAAsC;AACnE,EAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,cAAc,OAAA,EAAS,OAAA,EAAS,SAAQ,GAAI,OAAA;AAEvE,EAAA,MAAM,UAAA,GAAaU,OAAO,OAAO,CAAA;AACjC,EAAA,MAAM,UAAA,GAAaA,OAAO,OAAO,CAAA;AACjC,EAAAE,UAAU,MAAM;AACd,IAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AACrB,IAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AAAA,EACvB,CAAC,CAAA;AAED,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,cAAc,IAAA,EAAM;AAExB,IAAA,IAAI,OAAA,GAA8B,IAAA;AAElC,IAAA,MAAM,MAAA,GAAS,CAAC,EAAA,KACd,IAAA,KAAS,IAAA,GAAQ,CAAA,GAAoB,IAAA,CAAK,WAAA,EAAY,CAAE,KAAA,CAAM,EAAE,CAAA,IAAK,CAAA;AAEvE,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAA0B;AAC/C,MAAA,MAAM,KAAK,gBAAA,CAAiB,SAAA,EAAW,EAAE,OAAA,EAAS,CAAA,CAAE,SAAS,WAAW,CAAA;AACxE,MAAA,IAAI,OAAO,OAAA,EAAS;AACpB,MAAA,IAAI,OAAA,KAAY,IAAA,EAAM,UAAA,CAAW,OAAA,GAAU,EAAE,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAM,MAAA,CAAO,OAAO,CAAA,EAAG,CAAA;AACrF,MAAA,IAAI,EAAA,KAAO,IAAA,EAAM,UAAA,CAAW,OAAA,GAAU,EAAE,MAAA,EAAQ,EAAA,EAAI,IAAA,EAAM,MAAA,CAAO,EAAE,CAAA,EAAG,CAAA;AACtE,MAAA,OAAA,GAAU,EAAA;AAAA,IACZ,CAAA;AAEA,IAAA,MAAM,iBAAiB,MAAY;AACjC,MAAA,IAAI,YAAY,IAAA,EAAM;AACtB,MAAA,UAAA,CAAW,OAAA,GAAU,EAAE,MAAA,EAAQ,OAAA,EAAS,MAAM,MAAA,CAAO,OAAO,GAAG,CAAA;AAC/D,MAAA,OAAA,GAAU,IAAA;AAAA,IACZ,CAAA;AAEA,IAAA,SAAA,CAAU,iBAAiB,aAAA,EAAe,aAAA,EAAe,EAAE,OAAA,EAAS,MAAM,CAAA;AAC1E,IAAA,SAAA,CAAU,gBAAA,CAAiB,gBAAgB,cAAc,CAAA;AAEzD,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,CAAU,mBAAA,CAAoB,eAAe,aAAa,CAAA;AAC1D,MAAA,SAAA,CAAU,mBAAA,CAAoB,gBAAgB,cAAc,CAAA;AAC5D,MAAA,IAAI,YAAY,IAAA,EAAM;AACpB,QAAA,UAAA,CAAW,OAAA,GAAU,EAAE,MAAA,EAAQ,OAAA,EAAS,MAAM,MAAA,CAAO,OAAO,GAAG,CAAA;AAC/D,QAAA,OAAA,GAAU,IAAA;AAAA,MACZ;AAAA,IACF,CAAA;AAAA,EACF,GAAG,CAAC,IAAA,EAAM,WAAA,EAAa,YAAA,EAAc,OAAO,CAAC,CAAA;AAC/C;ACnDA,SAAS,SAAA,CACP,OAAA,EACA,SAAA,EACA,WAAA,EACa;AACb,EAAA,MAAM,OAAO,OAAA,GAAU,CAAA;AACvB,EAAA,MAAM,OAAO,OAAA,IAAW,CAAA;AACxB,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,IAAA,GAAO,CAAA,GAAI,IAAA;AACjD,EAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,IAAA,GAAO,IAAA;AAEjD,EAAA,IAAI,MAAA,GAAS,GAAA;AACb,EAAA,IAAI,MAAA,GAAS,GAAA;AACb,EAAA,QAAQ,SAAA;AAAW,IACjB,KAAK,IAAA;AACH,MAAA,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAA,GAAM,CAAC,CAAA;AAC5B,MAAA;AAAA,IACF,KAAK,MAAA;AACH,MAAA,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAA,GAAM,CAAC,CAAA;AAC5B,MAAA;AAAA,IACF,KAAK,MAAA;AACH,MAAA,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAA,GAAM,CAAC,CAAA;AAC5B,MAAA;AAAA,IACF,KAAK,OAAA;AACH,MAAA,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAA,GAAM,CAAC,CAAA;AAC5B,MAAA;AAAA;AAGJ,EAAA,MAAM,OAAA,GAAU,WAAA,KAAgB,OAAA,GAAU,MAAA,GAAS,CAAA,GAAI,MAAA;AACvD,EAAA,MAAM,OAAA,GAAU,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,MAAA,GAAS,MAAA;AACvD,EAAA,OAAQ,UAAU,CAAA,GAAI,OAAA;AACxB;AAGA,SAAS,OAAA,CACP,OAAA,EACA,KAAA,EACA,WAAA,EACa;AACb,EAAA,MAAM,OAAO,OAAA,IAAW,CAAA;AACxB,EAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,IAAA,OAAS,IAAA,IAAQ,CAAA,IAAM,KAAA,KAAU,MAAA,GAAS,CAAA,GAAI,CAAA,CAAA;AAAA,EAChD;AACA,EAAA,OAAS,IAAA,IAAQ,CAAA,IAAM,KAAA,KAAU,MAAA,GAAS,CAAA,GAAI,CAAA,CAAA;AAChD;AAGA,SAAS,WAAA,CAAY,OAAuB,WAAA,EAAuC;AAEjF,EAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,IAAA,OAAQ,KAAA,KAAU,SAAS,EAAA,GAAK,CAAA;AAAA,EAClC;AACA,EAAA,OAAQ,KAAA,KAAU,SAAS,CAAA,GAAI,EAAA;AACjC;AAkBO,SAAS,eAAe,OAAA,EAAsC;AACnE,EAAA,MAAM;AAAA,IACJ,YAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAA;AAAA,IACA,gBAAA;AAAA,IACA,UAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACF,GAAI,OAAA;AAEJ,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,cAAc,IAAA,EAAM;AAExB,IAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KAA2B;AAI5C,MAAA,IAAI,CAAC,SAAA,CAAU,QAAA,CAAS,CAAA,CAAE,MAAc,CAAA,EAAG;AAC3C,MAAA,MAAM,OAAA,GAAU,aAAA;AAChB,MAAA,IAAI,YAAY,IAAA,EAAM;AAEtB,MAAA,QAAQ,EAAE,GAAA;AAAK,QACb,KAAK,SAAA;AACH,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,gBAAA,CAAiB,SAAA,CAAU,OAAA,EAAS,IAAA,EAAM,WAAW,CAAC,CAAA;AACtD,UAAA;AAAA,QACF,KAAK,WAAA;AACH,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,gBAAA,CAAiB,SAAA,CAAU,OAAA,EAAS,MAAA,EAAQ,WAAW,CAAC,CAAA;AACxD,UAAA;AAAA,QACF,KAAK,WAAA;AACH,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,gBAAA,CAAiB,SAAA,CAAU,OAAA,EAAS,MAAA,EAAQ,WAAW,CAAC,CAAA;AACxD,UAAA;AAAA,QACF,KAAK,YAAA;AACH,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,gBAAA,CAAiB,SAAA,CAAU,OAAA,EAAS,OAAA,EAAS,WAAW,CAAC,CAAA;AACzD,UAAA;AAAA,QACF,KAAK,MAAA;AACH,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,gBAAA;AAAA,YACE,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,OAAA,GACX,WAAA,CAAY,MAAA,EAAQ,WAAW,CAAA,GAC/B,OAAA,CAAQ,OAAA,EAAS,MAAA,EAAQ,WAAW;AAAA,WAC1C;AACA,UAAA;AAAA,QACF,KAAK,KAAA;AACH,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,gBAAA;AAAA,YACE,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,OAAA,GACX,WAAA,CAAY,KAAA,EAAO,WAAW,CAAA,GAC9B,OAAA,CAAQ,OAAA,EAAS,KAAA,EAAO,WAAW;AAAA,WACzC;AACA,UAAA;AAAA,QACF,KAAK,OAAA;AAAA,QACL,KAAK,GAAA;AACH,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,UAAA,CAAW,OAAO,CAAA;AAClB,UAAA;AAAA,QACF,KAAK,QAAA;AACH,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,QAAA,EAAS;AACT,UAAA;AAAA,QACF;AACE,UAAA;AAAA;AACJ,IACF,CAAA;AAEA,IAAA,SAAA,CAAU,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAC/C,IAAA,OAAO,MAAM,SAAA,CAAU,mBAAA,CAAoB,SAAA,EAAW,SAAS,CAAA;AAAA,EACjE,CAAA,EAAG,CAAC,YAAA,EAAc,WAAA,EAAa,eAAe,gBAAA,EAAkB,UAAA,EAAY,QAAA,EAAU,OAAO,CAAC,CAAA;AAChG;ACpIA,IAAMY,SAAAA,GAAW,qBAAA;AAajB,SAAS,oBAAA,GAA6B;AACpC,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,EAAA,IAAI,QAAA,CAAS,cAAA,CAAeA,SAAQ,CAAA,KAAM,IAAA,EAAM;AAChD,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA;AAC5C,EAAA,KAAA,CAAM,EAAA,GAAKA,SAAAA;AACX,EAAA,KAAA,CAAM,WAAA,GAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAYpB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,KAAK,CAAA;AACjC;AAaO,SAAS,qBAAA,CACd,KAAA,EACA,UAAA,EACA,OAAA,EACM;AACN,EAAAZ,UAAU,MAAM;AACd,IAAA,oBAAA,EAAqB;AAAA,EACvB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,UAAU,IAAA,EAAM;AAGpB,IAAA,IAAI,QAAA,GAA+B,IAAA;AACnC,IAAA,IAAI,MAAA,GAA6B,IAAA;AAEjC,IAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,EAAgB,GAAA,KAAoC;AACjE,MAAA,MAAM,EAAA,GAAK,UAAA,CAAW,OAAA,GAAU,CAAC,CAAA;AACjC,MAAA,IAAI,EAAA,KAAO,IAAA,IAAQ,EAAA,KAAO,MAAA,EAAW;AACrC,MAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,QAAA,OAAO,EAAA,CAAG,QAAQ,YAAY,CAAA;AAAA,MAChC,CAAA,MAAO;AACL,QAAA,EAAA,CAAG,OAAA,CAAQ,YAAY,CAAA,GAAI,GAAA;AAAA,MAC7B;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,WAAW,MAAY;AAC3B,MAAA,IAAI,QAAA,KAAa,IAAA,EAAM,KAAA,CAAM,QAAA,EAAU,IAAI,CAAA;AAC3C,MAAA,IAAI,MAAA,KAAW,IAAA,EAAM,KAAA,CAAM,MAAA,EAAQ,IAAI,CAAA;AACvC,MAAA,QAAA,GAAW,IAAA;AACX,MAAA,MAAA,GAAS,IAAA;AAAA,IACX,CAAA;AAEA,IAAA,IAAI,CAAC,OAAA,EAAS;AAEZ,MAAA,OAAO,QAAA;AAAA,IACT;AAEA,IAAA,MAAM,SAAS,MAAY;AACzB,MAAA,MAAM,IAAA,GAAO,MAAM,WAAA,EAAY;AAC/B,MAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AAEtB,MAAA,IAAI,IAAA,GAA2B,IAAA;AAC/B,MAAA,IAAI,EAAA,GAAyB,IAAA;AAI7B,MAAA,IAAI,QAAA,KAAa,IAAA,IAAQ,CAAC,UAAA,CAAW,QAAQ,CAAA,EAAG;AAC9C,QAAA,IAAA,GAAQ,QAAA,GAAW,EAAA;AACnB,QAAA,EAAA,GAAO,YAAY,CAAA,GAAK,EAAA;AAAA,MAC1B;AAGA,MAAA,IAAI,IAAA,KAAS,QAAA,IAAY,EAAA,KAAO,MAAA,EAAQ;AAKxC,MAAA,IAAI,QAAA,KAAa,IAAA,IAAQ,QAAA,KAAa,IAAA,IAAQ,aAAa,EAAA,EAAI;AAC7D,QAAA,KAAA,CAAM,UAAU,IAAI,CAAA;AAAA,MACtB;AACA,MAAA,IAAI,MAAA,KAAW,IAAA,IAAQ,MAAA,KAAW,IAAA,IAAQ,WAAW,EAAA,EAAI;AACvD,QAAA,KAAA,CAAM,QAAQ,IAAI,CAAA;AAAA,MACpB;AAKA,MAAA,IAAI,SAAS,IAAA,IAAQ,IAAA,KAAS,EAAA,EAAI,KAAA,CAAM,MAAM,MAAM,CAAA;AACpD,MAAA,IAAI,EAAA,KAAO,IAAA,EAAM,KAAA,CAAM,EAAA,EAAI,IAAI,CAAA;AAE/B,MAAA,QAAA,GAAW,IAAA;AACX,MAAA,MAAA,GAAS,EAAA;AAAA,IACX,CAAA;AAEA,IAAA,MAAA,EAAO;AACP,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,SAAA,CAAU,MAAM,CAAA;AAC1C,IAAA,OAAO,MAAM;AACX,MAAA,WAAA,EAAY;AACZ,MAAA,QAAA,EAAS;AAAA,IACX,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,EAAO,UAAA,EAAY,OAAO,CAAC,CAAA;AACjC;;;ACnKA,IAAM,oBAAA,GAAuB,kCAAA;AAE7B,IAAI,MAAA;AACJ,IAAI,OAAA,GAA6C,IAAA;AAEjD,SAAS,eAAA,GAA2B;AAClC,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,MAAA,CAAO,eAAe,UAAA,EAAY;AAC5E,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,MAAA,CAAO,UAAA,CAAW,oBAAoB,CAAA,CAAE,OAAA;AACjD;AAEA,SAAS,iBAAiB,OAAA,EAGd;AACV,EAAA,IAAI,OAAA,CAAQ,OAAA,KAAY,KAAA,EAAO,OAAO,KAAA;AACtC,EAAA,IAAI,OAAA,CAAQ,UAAA,KAAe,KAAA,EAAO,OAAO,IAAA;AACzC,EAAA,OAAO,eAAA,EAAgB;AACzB;AAEA,eAAe,WAAA,GAA0C;AACvD,EAAA,IAAI,WAAW,MAAA,EAAW;AACxB,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,YAAY,IAAA,EAAM;AACpB,IAAA,OAAO,OAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,MAAA,GAAS,IAAA;AACT,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,OAAA,GAAU,OAAO,aAAa,CAAA,CAC3B,KAAK,CAAC,EAAE,YAAW,KAAM;AACxB,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,IAAI,UAAA,EAAW;AAAA,IAC1B,CAAA,CAAA,MAAQ;AACN,MAAA,MAAA,GAAS,IAAA;AAAA,IACX;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AACX,IAAA,MAAA,GAAS,IAAA;AACT,IAAA,OAAO,MAAA;AAAA,EACT,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,IAAA,OAAA,GAAU,IAAA;AAAA,EACZ,CAAC,CAAA;AAEH,EAAA,OAAO,OAAA;AACT;AASO,SAAS,aAAA,CAAc,KAAA,EAAqB,OAAA,GAAiC,EAAC,EAAS;AAC5F,EAAA,IAAI,CAAC,gBAAA,CAAiB,OAAO,CAAA,EAAG;AAC9B,IAAA;AAAA,EACF;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,QAAA,EAAU,YAAY,WAAA,EAAa,GAAG,gBAAe,GAAI,OAAA;AAC1E,EAAA,KAAK,WAAA,EAAY,CAAE,IAAA,CAAK,CAAC,QAAA,KAAa;AACpC,IAAA,KAAK,QAAA,EAAU,OAAA,CAAQ,KAAA,EAAO,cAAc,CAAA;AAAA,EAC9C,CAAC,CAAA;AACH;AAEO,SAAS,aAAA,CAAc,OAAA,GAAiC,EAAC,EAAS;AACvE,EAAA,IAAI,CAAC,gBAAA,CAAiB,OAAO,CAAA,EAAG;AAC9B,IAAA;AAAA,EACF;AACA,EAAA,KAAK,WAAA,EAAY;AACnB;;;AClEO,IAAM,4BAAA,GACX,OAAO,MAAA,CAAO;AAAA,EACZ,QAAA,EAAU,WAAA;AAAA,EACV,YAAA,EAAc,WAAA;AAAA,EACd,OAAA,EAAS,QAAA;AAAA,EACT,MAAA,EAAQ,QAAA;AAAA,EACR,SAAA,EAAW,SAAA;AAAA,EACX,OAAA,EAAS,SAAA;AAAA,EACT,OAAA,EAAS;AACX,CAAC;AAYI,SAAS,oBAAA,CACd,UAAA,EACA,QAAA,EACA,WAAA,EACiB;AACjB,EAAA,IAAI,QAAA,CAAS,YAAY,OAAO,SAAA;AAEhC,EAAA,IAAI,YAAA,GAAe,KAAA;AACnB,EAAA,IAAI,SAAA,GAAY,KAAA;AAChB,EAAA,IAAI,UAAA,GAAa,KAAA;AACjB,EAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC1B,IAAA,IAAI,CAAA,CAAE,IAAA,KAAS,WAAA,EAAa,YAAA,GAAe,IAAA;AAAA,SAAA,IAClC,CAAA,CAAE,IAAA,KAAS,QAAA,EAAU,SAAA,GAAY,IAAA;AAAA,SAAA,IACjC,EAAE,IAAA,KAAS,SAAA,IAAa,CAAA,CAAE,IAAA,KAAS,cAAc,UAAA,GAAa,IAAA;AAAA,EACzE;AAEA,EAAA,IAAI,cAAc,OAAO,SAAA;AACzB,EAAA,IAAI,WAAW,OAAO,QAAA;AACtB,EAAA,IAAI,QAAA,CAAS,SAAS,OAAO,WAAA;AAC7B,EAAA,IAAI,YAAY,OAAO,SAAA;AAGvB,EAAA,IAAI,gBAAgB,MAAA,EAAW;AAC7B,IAAA,MAAM,UAAA,GAAa,SAAS,IAAA,KAAS,WAAA;AACrC,IAAA,OAAO,aAAa,UAAA,GAAa,cAAA;AAAA,EACnC;AACA,EAAA,OAAO,UAAA;AACT;;;ACvBA,IAAM,uBAAA,GAA0B,EAAA;AAEzB,SAAS,kBACd,GAAA,EACA;AAAA,EACE,OAAA,GAAU,IAAA;AAAA,EACV,QAAA;AAAA,EACA,UAAA,GAAa,IAAA;AAAA,EACb;AACF,CAAA,GAAkF,EAAC,EAC7E;AACN,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA;AAAA,EACF;AACA,EAAA,MAAM,KAAA,GAAQ,QAAA,GAAW,GAAG,CAAA,IAAK,6BAA6B,GAAG,CAAA;AACjE,EAAA,aAAA,CAAc,KAAA,EAAO;AAAA,IACnB,OAAA;AAAA,IACA,UAAA;AAAA,IACA,GAAI,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,KAAc;AAAC,GAChD,CAAA;AACH;AAEO,SAAS,cAAA,CACd,KAAA,EACA,OAAA,GAA6B,EAAC,EACX;AACnB,EAAA,MAAM;AAAA,IACJ,OAAA,GAAU,IAAA;AAAA,IACV,QAAA;AAAA,IACA,WAAA;AAAA,IACA,UAAA,GAAa,IAAA;AAAA,IACb,aAAA,GAAgB,uBAAA;AAAA,IAChB,wBAAA,GAA2B,IAAA;AAAA,IAC3B;AAAA,GACF,GAAI,OAAA;AAEJ,EAAA,MAAM,WAAA,GAAcF,OAAO,QAAQ,CAAA;AACnC,EAAAE,UAAU,MAAM;AACd,IAAA,WAAA,CAAY,OAAA,GAAU,QAAA;AAAA,EACxB,CAAC,CAAA;AAED,EAAA,MAAM,cAAA,GAAiBF,OAAO,WAAW,CAAA;AACzC,EAAAE,UAAU,MAAM;AACd,IAAA,cAAA,CAAe,OAAA,GAAU,WAAA;AAAA,EAC3B,CAAC,CAAA;AAED,EAAA,MAAM,aAAA,GAAgBF,OAAO,UAAU,CAAA;AACvC,EAAAE,UAAU,MAAM;AACd,IAAA,aAAA,CAAc,OAAA,GAAU,UAAA;AAAA,EAC1B,CAAC,CAAA;AAED,EAAA,MAAM,YAAA,GAAeF,OAAO,SAAS,CAAA;AACrC,EAAAE,UAAU,MAAM;AACd,IAAA,YAAA,CAAa,OAAA,GAAU,SAAA;AAAA,EACzB,CAAC,CAAA;AAED,EAAA,MAAM,gBAAA,GAAmBF,OAAO,CAAC,CAAA;AAEjC,EAAA,MAAM,OAAA,GAAUT,WAAAA;AAAA,IACd,CAAC,GAAA,KAAQ;AACP,MAAA,iBAAA,CAAkB,GAAA,EAAK;AAAA,QACrB,OAAA;AAAA,QACA,GAAI,YAAY,OAAA,KAAY,MAAA,GAAY,EAAE,QAAA,EAAU,WAAA,CAAY,OAAA,EAAQ,GAAI,EAAC;AAAA,QAC7E,YAAY,aAAA,CAAc,OAAA;AAAA,QAC1B,GAAI,aAAa,OAAA,KAAY,MAAA,GAAY,EAAE,SAAA,EAAW,YAAA,CAAa,OAAA,EAAQ,GAAI;AAAC,OACjF,CAAA;AAAA,IACH,CAAA;AAAA,IACA,CAAC,OAAO;AAAA,GACV;AAEA,EAAAW,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,wBAAA,EAA0B;AACzC,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,MAAA,GAAS,KAAA;AACb,IAAA,MAAM,SAAS,MAAM;AACnB,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA;AAAA,MACF;AACA,MAAA,MAAA,GAAS,IAAA;AACT,MAAA,aAAA,CAAc,EAAE,UAAA,EAAY,aAAA,CAAc,OAAA,EAAS,CAAA;AACnD,MAAA,MAAA,CAAO,mBAAA,CAAoB,aAAA,EAAe,MAAA,EAAQ,IAAI,CAAA;AACtD,MAAA,MAAA,CAAO,mBAAA,CAAoB,YAAA,EAAc,MAAA,EAAQ,IAAI,CAAA;AACrD,MAAA,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,MAAA,EAAQ,IAAI,CAAA;AAAA,IACpD,CAAA;AAEA,IAAA,MAAA,CAAO,gBAAA,CAAiB,eAAe,MAAA,EAAQ,EAAE,SAAS,IAAA,EAAM,OAAA,EAAS,MAAM,CAAA;AAC/E,IAAA,MAAA,CAAO,gBAAA,CAAiB,cAAc,MAAA,EAAQ,EAAE,SAAS,IAAA,EAAM,OAAA,EAAS,MAAM,CAAA;AAC9E,IAAA,MAAA,CAAO,iBAAiB,SAAA,EAAW,MAAA,EAAQ,EAAE,OAAA,EAAS,MAAM,CAAA;AAE5D,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,mBAAA,CAAoB,aAAA,EAAe,MAAA,EAAQ,IAAI,CAAA;AACtD,MAAA,MAAA,CAAO,mBAAA,CAAoB,YAAA,EAAc,MAAA,EAAQ,IAAI,CAAA;AACrD,MAAA,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,MAAA,EAAQ,IAAI,CAAA;AAAA,IACpD,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,wBAAwB,CAAC,CAAA;AAEtC,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,IAAW,KAAA,KAAU,IAAA,EAAM;AAEhC,IAAA,IAAI,OAAA,GAAU,KAAA,CAAM,WAAA,EAAY,CAAE,UAAA;AAElC,IAAA,OAAO,KAAA,CAAM,UAAU,MAAM;AAC3B,MAAA,MAAM,IAAA,GAAO,MAAM,WAAA,EAAY;AAC/B,MAAA,IAAI,IAAA,CAAK,cAAc,OAAA,EAAS;AAC9B,QAAA,OAAA,GAAU,IAAA,CAAK,UAAA;AACf,QAAA;AAAA,MACF;AACA,MAAA,OAAA,GAAU,IAAA,CAAK,UAAA;AAEf,MAAA,MAAM,KAAA,GAAQ,YAAY,GAAA,EAAI;AAC9B,MAAA,IAAI,KAAA,GAAQ,gBAAA,CAAiB,OAAA,GAAU,aAAA,EAAe;AACpD,QAAA;AAAA,MACF;AACA,MAAA,gBAAA,CAAiB,OAAA,GAAU,KAAA;AAE3B,MAAA,MAAM,MAAM,oBAAA,CAAqB,KAAA,CAAM,cAAA,EAAgB,IAAA,EAAM,eAAe,OAAO,CAAA;AACnF,MAAA,OAAA,CAAQ,GAAG,CAAA;AAAA,IACb,CAAC,CAAA;AAAA,EACH,GAAG,CAAC,OAAA,EAAS,aAAA,EAAe,KAAA,EAAO,OAAO,CAAC,CAAA;AAE3C,EAAA,OAAO,OAAA;AACT;AClHO,IAAM,0BAAA,GAAqE,OAAO,MAAA,CAAO;AAAA,EAC9F,QAAA,EACE,OAAO,MAAA,CAAA,IAAA,CAAY,GAAA,KAAQ,QAAA,GACvB,IAAI,GAAA,CAAI,wBAAA,EAA0B,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA,CAAE,IAAA,GACnD,wBAAA;AAAA,EACN,YAAA,EACE,OAAO,MAAA,CAAA,IAAA,CAAY,GAAA,KAAQ,QAAA,GACvB,IAAI,GAAA,CAAI,4BAAA,EAA8B,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA,CAAE,IAAA,GACvD,4BAAA;AAAA,EACN,OAAA,EACE,OAAO,MAAA,CAAA,IAAA,CAAY,GAAA,KAAQ,QAAA,GACvB,IAAI,GAAA,CAAI,sBAAA,EAAwB,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA,CAAE,IAAA,GACjD,sBAAA;AAAA,EACN,MAAA,EACE,OAAO,MAAA,CAAA,IAAA,CAAY,GAAA,KAAQ,QAAA,GACvB,IAAI,GAAA,CAAI,qBAAA,EAAuB,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA,CAAE,IAAA,GAChD,qBAAA;AAAA,EACN,SAAA,EACE,OAAO,MAAA,CAAA,IAAA,CAAY,GAAA,KAAQ,QAAA,GACvB,IAAI,GAAA,CAAI,yBAAA,EAA2B,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA,CAAE,IAAA,GACpD,yBAAA;AAAA,EACN,OAAA,EACE,OAAO,MAAA,CAAA,IAAA,CAAY,GAAA,KAAQ,QAAA,GACvB,IAAI,GAAA,CAAI,sBAAA,EAAwB,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA,CAAE,IAAA,GACjD,sBAAA;AAAA,EACN,OAAA,EACE,OAAO,MAAA,CAAA,IAAA,CAAY,GAAA,KAAQ,QAAA,GACvB,IAAI,GAAA,CAAI,uBAAA,EAAyB,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA,CAAE,IAAA,GAClD;AACR,CAAC;AAqBD,IAAM,SAAA,GAAY,CAAA;AAQlB,SAAS,WAAA,CACP,SACA,OAAA,EAC4B;AAC5B,EAAA,MAAM,QAAQ,EAAC;AACf,EAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA,EAAqB;AACxD,IAAA,MAAM,GAAA,GAAM,QAAQ,GAAG,CAAA;AACvB,IAAA,MAAM,WAA+B,EAAC;AACtC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,EAAW,CAAA,EAAA,EAAK;AAClC,MAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM,GAAG,CAAA;AAC3B,MAAA,KAAA,CAAM,UAAU,OAAA,IAAW,MAAA;AAC3B,MAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AAAA,IACrB;AACA,IAAA,KAAA,CAAM,GAAG,CAAA,GAAI,EAAE,QAAA,EAAU,QAAQ,CAAA,EAAE;AAAA,EACrC;AACA,EAAA,OAAO,KAAA;AACT;AAYO,SAAS,YAAA,CACd,KAAA,EACA,OAAA,GAA4B,EAAC,EACX;AAClB,EAAA,MAAM,EAAE,UAAU,IAAA,EAAM,MAAA,GAAS,GAAG,OAAA,GAAU,MAAA,EAAQ,OAAA,EAAS,WAAA,EAAY,GAAI,OAAA;AAE/E,EAAA,MAAM,QAAA,GAAWF,OAA0C,IAAI,CAAA;AAC/D,EAAA,MAAM,UAAA,GAAaA,OAA+C,0BAA0B,CAAA;AAC5F,EAAA,MAAM,UAAA,GAAaA,OAAO,OAAO,CAAA;AAKjC,EAAA,MAAM,SAAA,GAAYA,OAAO,MAAM,CAAA;AAC/B,EAAAE,UAAU,MAAM;AACd,IAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAAA,EACtB,CAAC,CAAA;AAED,EAAA,MAAM,cAAA,GAAiBF,OAAO,WAAW,CAAA;AACzC,EAAAE,UAAU,MAAM;AACd,IAAA,cAAA,CAAe,OAAA,GAAU,WAAA;AAAA,EAC3B,CAAC,CAAA;AAED,EAAAA,UAAU,MAAM;AACd,IAAA,UAAA,CAAW,OAAA,GAAU;AAAA,MACnB,GAAG,0BAAA;AAAA,MACH,GAAI,WAAW;AAAC,KAClB;AACA,IAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AAAA,EACrB,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAAA,UAAU,MAAM;AACd,IAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AACrB,IAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AAAA,EACrB,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AAAA,IACrB;AAAA,EACF,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,MAAM,gBAAA,GAAmBX,WAAAA;AAAA,IACvB,CAAC,GAAA,KAAQ;AACP,MAAA,IAAI,CAAC,OAAA,EAAS;AACd,MAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,MAAA,IAAI,OAAO,UAAU,WAAA,EAAa;AAElC,MAAA,MAAM,QAAQ,QAAA,CAAS,OAAA,IAAW,YAAY,UAAA,CAAW,OAAA,EAAS,WAAW,OAAO,CAAA;AACpF,MAAA,QAAA,CAAS,OAAA,GAAU,KAAA;AAEnB,MAAA,MAAM,IAAA,GAAO,MAAM,GAAG,CAAA;AACtB,MAAA,IAAI,SAAS,MAAA,EAAW;AAExB,MAAA,IAAA,CAAK,MAAA,GAAA,CAAU,IAAA,CAAK,MAAA,GAAS,CAAA,IAAK,KAAK,QAAA,CAAS,MAAA;AAChD,MAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA;AACpC,MAAA,IAAI,OAAO,MAAA,EAAW;AACtB,MAAA,EAAA,CAAG,MAAA,GAAS,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,SAAA,CAAU,OAAO,CAAC,CAAA;AACtD,MAAA,EAAA,CAAG,WAAA,GAAc,CAAA;AAGjB,MAAA,KAAK,EAAA,CAAG,IAAA,EAAK,CAAE,KAAA,CAAM,MAAM;AAAA,MAE3B,CAAC,CAAA;AAAA,IACH,CAAA;AAAA,IACA,CAAC,OAAO;AAAA,GACV;AAMA,EAAAW,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,IAAW,KAAA,KAAU,IAAA,EAAM;AAEhC,IAAA,IAAI,OAAA,GAAU,KAAA,CAAM,WAAA,EAAY,CAAE,UAAA;AAElC,IAAA,OAAO,KAAA,CAAM,UAAU,MAAM;AAC3B,MAAA,MAAM,IAAA,GAAO,MAAM,WAAA,EAAY;AAC/B,MAAA,IAAI,IAAA,CAAK,cAAc,OAAA,EAAS;AAC9B,QAAA,OAAA,GAAU,IAAA,CAAK,UAAA;AACf,QAAA;AAAA,MACF;AACA,MAAA,OAAA,GAAU,IAAA,CAAK,UAAA;AAEf,MAAA,MAAM,MAAM,oBAAA,CAAqB,KAAA,CAAM,cAAA,EAAgB,IAAA,EAAM,eAAe,OAAO,CAAA;AACnF,MAAA,gBAAA,CAAiB,GAAG,CAAA;AAAA,IACtB,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,OAAA,EAAS,KAAA,EAAO,gBAAgB,CAAC,CAAA;AAErC,EAAA,OAAO,gBAAA;AACT;ACjLA,IAAMY,SAAAA,GAAW,qBAAA;AAyBjB,SAAS,qBAAA,GAA8B;AACrC,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,EAAA,IAAI,QAAA,CAAS,cAAA,CAAeA,SAAQ,CAAA,KAAM,IAAA,EAAM;AAChD,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA;AAC5C,EAAA,KAAA,CAAM,EAAA,GAAKA,SAAAA;AACX,EAAA,KAAA,CAAM,WAAA,GAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AA2BpB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,KAAK,CAAA;AACjC;AAYO,SAAS,sBAAA,CACd,KAAA,EACA,UAAA,EACA,KAAA,EACM;AACN,EAAAZ,UAAU,MAAM;AACd,IAAA,qBAAA,EAAsB;AAAA,EACxB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,UAAU,IAAA,EAAM;AAGpB,IAAA,IAAI,YAAA,GAAmC,IAAA;AACvC,IAAA,IAAI,WAAA,uBAA4C,GAAA,EAAI;AAEpD,IAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,EAAgB,GAAA,KAA8B;AAC3D,MAAA,MAAM,EAAA,GAAK,UAAA,CAAW,OAAA,GAAU,CAAC,CAAA;AACjC,MAAA,IAAI,EAAA,KAAO,IAAA,IAAQ,EAAA,KAAO,MAAA,EAAW;AACrC,MAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,QAAA,OAAO,EAAA,CAAG,QAAQ,aAAa,CAAA;AAAA,MACjC,CAAA,MAAO;AACL,QAAA,EAAA,CAAG,OAAA,CAAQ,aAAa,CAAA,GAAI,GAAA;AAAA,MAC9B;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,QAAQ,MAAY;AACxB,MAAA,IAAI,YAAA,KAAiB,IAAA,EAAM,KAAA,CAAM,YAAA,EAAc,MAAM,CAAA;AACrD,MAAA,KAAA,MAAW,EAAA,IAAM,WAAA,EAAa,KAAA,CAAM,EAAA,EAAI,MAAM,CAAA;AAC9C,MAAA,YAAA,GAAe,IAAA;AACf,MAAA,WAAA,uBAAkB,GAAA,EAAI;AAAA,IACxB,CAAA;AAEA,IAAA,MAAM,SAAS,MAAY;AACzB,MAAA,MAAM,IAAA,GAAO,MAAM,WAAA,EAAY;AAC/B,MAAA,MAAM,EAAE,QAAA,EAAU,YAAA,EAAc,KAAA,EAAM,GAAI,IAAA;AAK1C,MAAA,IAAI,UAAU,KAAA,EAAO;AAEnB,QAAA,KAAA,MAAW,MAAM,WAAA,EAAa;AAC5B,UAAA,IAAI,EAAA,KAAO,QAAA,EAAU,KAAA,CAAM,EAAA,EAAI,MAAM,CAAA;AAAA,QACvC;AAEA,QAAA,IAAI,YAAA,KAAiB,IAAA,IAAQ,YAAA,KAAiB,QAAA,EAAU;AACtD,UAAA,KAAA,CAAM,cAAc,MAAM,CAAA;AAAA,QAC5B;AACA,QAAA,IAAI,QAAA,KAAa,IAAA,EAAM,KAAA,CAAM,QAAA,EAAU,UAAU,CAAA;AACjD,QAAA,YAAA,GAAe,QAAA;AACf,QAAA,WAAA,uBAAkB,GAAA,EAAI;AACtB,QAAA;AAAA,MACF;AAKA,MAAA,IAAI,QAAA,KAAa,YAAA,IAAgB,YAAA,KAAiB,WAAA,EAAa;AAG/D,MAAA,IAAI,YAAA,KAAiB,QAAQ,YAAA,KAAiB,QAAA,IAAY,CAAC,YAAA,CAAa,GAAA,CAAI,YAAY,CAAA,EAAG;AACzF,QAAA,KAAA,CAAM,cAAc,MAAM,CAAA;AAAA,MAC5B;AACA,MAAA,KAAA,MAAW,MAAM,WAAA,EAAa;AAC5B,QAAA,IAAI,EAAA,KAAO,YAAY,CAAC,YAAA,CAAa,IAAI,EAAE,CAAA,EAAG,KAAA,CAAM,EAAA,EAAI,MAAM,CAAA;AAAA,MAChE;AAGA,MAAA,IAAI,QAAA,KAAa,IAAA,EAAM,KAAA,CAAM,QAAA,EAAU,UAAU,CAAA;AACjD,MAAA,KAAA,MAAW,MAAM,YAAA,EAAc;AAC7B,QAAA,IAAI,OAAO,QAAA,EAAU;AACrB,QAAA,MAAM,UAAA,GAAa,KAAA,CAAM,EAAE,CAAA,IAAK,CAAA;AAChC,QAAA,KAAA,CAAM,EAAA,EAAI,UAAA,KAAe,CAAA,GAAI,aAAA,GAAgB,eAAe,CAAA;AAAA,MAC9D;AAEA,MAAA,YAAA,GAAe,QAAA;AACf,MAAA,WAAA,GAAc,YAAA;AAAA,IAChB,CAAA;AAEA,IAAA,MAAA,EAAO;AACP,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,SAAA,CAAU,MAAM,CAAA;AAC1C,IAAA,OAAO,MAAM;AACX,MAAA,WAAA,EAAY;AACZ,MAAA,KAAA,EAAM;AAAA,IACR,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,EAAO,UAAA,EAAY,KAAK,CAAC,CAAA;AAC/B;AC/HA,SAAS,YAAY,IAAA,EAAqB;AACxC,EAAA,OAAQ,IAAA,GAAO,IAAI,CAAA,GAAI,CAAA;AACzB;AAGA,SAAS,gBAAA,CAAiB,UAAkB,EAAA,EAA0B;AACpE,EAAA,IAAI,QAAA,KAAa,GAAG,OAAO,KAAA;AAC3B,EAAA,MAAM,SAAA,GAAA,CAAa,WAAW,CAAA,IAAK,CAAA;AACnC,EAAA,IAAI,SAAA,KAAc,GAAc,OAAO,KAAA;AACvC,EAAA,MAAM,SAAS,EAAA,IAAM,CAAA;AACrB,EAAA,OAAO,MAAA,KAAW,KAAK,MAAA,KAAW,CAAA;AACpC;AAGA,IAAM,qBAAA,GAAwB,GAAA;AAE9B,IAAM,iCAAA,GAAoC,EAAA;AAC1C,IAAM,4BAAA,GAA+B,mCAAA;AACrC,IAAM,iBAAA,GAAoB,sCAAA;AAQ1B,SAAS,iBAAiB,UAAA,EAAyC;AACjE,EAAA,OAAO,aAAA,CAAc,WAAW,GAAG,CAAA;AACrC;AAiBA,SAASU,qBAAAA,GAAgC;AACvC,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,MAAA,CAAO,eAAe,UAAA,EAAY;AAC5E,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,MAAA,CAAO,UAAA,CAAW,kCAAkC,CAAA,CAAE,OAAA;AAC/D;AAEA,SAAS,wBAAwB,OAAA,EAA4B;AAC3D,EAAA,IAAI,OAAO,OAAA,CAAQ,aAAA,KAAkB,UAAA,EAAY;AACjD,EAAA,KAAA,MAAW,IAAA,IAAQ,OAAA,CAAQ,aAAA,EAAc,OAAQ,MAAA,EAAO;AAC1D;AAEA,SAAS,YAAA,CAAa,WAAwB,MAAA,EAAoC;AAChF,EAAA,OAAO,SAAA,CAAU,aAAA,CAA2B,CAAA,oBAAA,EAAuB,MAAM,CAAA,EAAA,CAAI,CAAA;AAC/E;AAEA,SAAS,kBAAkB,MAAA,EAA6B;AACtD,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,UAAA,CAAW,CAAC,CAAA,GAAI,EAAA;AACpC,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,CAAC,CAAC,CAAA,GAAI,CAAA;AACjC,EAAA,OAAS,QAAQ,CAAA,GAAK,IAAA;AACxB;AAEA,SAAS,oBAAA,CACP,IAAA,EACA,EAAA,EACA,UAAA,EACA,WAAA,EAC4B;AAC5B,EAAA,MAAM,SAAA,GAAY,kBAAkB,IAAI,CAAA;AACxC,EAAA,MAAM,OAAA,GAAU,kBAAkB,EAAE,CAAA;AACpC,EAAA,MAAM,WAAW,SAAA,GAAY,CAAA;AAC7B,EAAA,MAAM,WAAW,SAAA,IAAa,CAAA;AAC9B,EAAA,MAAM,SAAS,OAAA,GAAU,CAAA;AACzB,EAAA,MAAM,SAAS,OAAA,IAAW,CAAA;AAC1B,EAAA,MAAM,OAAA,GAAU,WAAA,KAAgB,OAAA,GAAU,QAAA,GAAW,CAAA,GAAI,QAAA;AACzD,EAAA,MAAM,OAAA,GAAU,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,QAAA,GAAW,QAAA;AACzD,EAAA,MAAM,KAAA,GAAQ,WAAA,KAAgB,OAAA,GAAU,MAAA,GAAS,CAAA,GAAI,MAAA;AACrD,EAAA,MAAM,KAAA,GAAQ,WAAA,KAAgB,OAAA,GAAU,CAAA,GAAI,MAAA,GAAS,MAAA;AACrD,EAAA,OAAO;AAAA,IACL,EAAA,EAAA,CAAK,UAAU,KAAA,IAAS,UAAA;AAAA,IACxB,EAAA,EAAA,CAAK,UAAU,KAAA,IAAS;AAAA,GAC1B;AACF;AAEA,SAAS,oBAAA,CAAqB,MAAc,EAAA,EAAqC;AAC/E,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,CAAC,CAAA;AAClC,EAAA,MAAM,MAAA,GAAS,EAAA,CAAG,UAAA,CAAW,CAAC,CAAA;AAC9B,EAAA,IAAI,QAAA,KAAa,OAAgB,IAAA,CAAK,GAAA,CAAI,SAAS,QAAQ,CAAA,KAAM,GAAG,OAAO,IAAA;AAC3E,EAAA,MAAM,IAAA,GAAO,KAAK,CAAC,CAAA;AACnB,EAAA,IAAI,IAAA,KAAS,GAAA,IAAO,IAAA,KAAS,GAAA,EAAK,OAAO,IAAA;AACzC,EAAA,MAAM,WAAW,MAAA,GAAS,QAAA;AAC1B,EAAA,OAAO;AAAA,IACL,MAAM,CAAA,EAAG,QAAA,GAAW,GAAA,GAAM,GAAG,GAAG,IAAI,CAAA,CAAA;AAAA,IACpC,IAAI,CAAA,EAAG,QAAA,GAAW,GAAA,GAAM,GAAG,GAAG,IAAI,CAAA;AAAA,GACpC;AACF;AAEA,SAAS,kBAAkB,UAAA,EAAoD;AAE7E,EAAA,IAAI,gBAAA,CAAiB,UAAU,CAAA,EAAG,OAAO,EAAC;AAC1C,EAAA,MAAM,MAAA,GAAS,kBAAkB,IAAA,CAAK,UAAA,CAAW,IAAI,IAAA,EAAK,CAAE,aAAa,CAAA;AACzE,EAAA,IAAI,MAAA,KAAW,IAAA,EAAM,OAAO,EAAC;AAE7B,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,CAAC,CAAA,IAAK,EAAA;AAC9B,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,CAAC,CAAA,IAAK,EAAA;AAC5B,EAAA,MAAM,UAA8B,CAAC,EAAE,MAAM,QAAA,EAAU,EAAA,EAAI,QAAQ,CAAA;AACnE,EAAA,MAAM,IAAA,GAAO,oBAAA,CAAqB,QAAA,EAAU,MAAM,CAAA;AAClD,EAAA,IAAI,IAAA,KAAS,IAAA,EAAM,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA;AAEpC,EAAA,OAAO,UAAA,CAAW,SAAA,KAAc,SAAA,GAC5B,OAAA,GACA,QAAQ,GAAA,CAAI,CAAC,IAAA,MAAU,EAAE,MAAM,IAAA,CAAK,EAAA,EAAI,EAAA,EAAI,IAAA,CAAK,MAAK,CAAE,CAAA;AAC9D;AAEA,SAAS,oBAAoB,UAAA,EAA6D;AAGxF,EAAA,IAAI,gBAAA,CAAiB,UAAU,CAAA,EAAG,OAAO,IAAA;AACzC,EAAA,MAAM,MAAA,GAAS,kBAAkB,IAAA,CAAK,UAAA,CAAW,IAAI,IAAA,EAAK,CAAE,aAAa,CAAA;AACzE,EAAA,IAAI,MAAA,KAAW,MAAM,OAAO,IAAA;AAC5B,EAAA,MAAM,IAAA,GAAO,OAAO,CAAC,CAAA;AACrB,EAAA,MAAM,EAAA,GAAK,OAAO,CAAC,CAAA;AACnB,EAAA,IAAI,IAAA,KAAS,MAAA,IAAa,EAAA,KAAO,MAAA,EAAW,OAAO,IAAA;AACnD,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,kBAAkB,IAAI,CAAA;AAAA,IAC5B,EAAA,EAAI,kBAAkB,EAAE,CAAA;AAAA,IACxB,SAAA,EAAW,MAAA,CAAO,CAAC,CAAA,IAAK;AAAA,GAC1B;AACF;AAEA,SAAS,OAAO,IAAA,EAA0B;AACxC,EAAA,OAAO,CAAC,WAAA,CAAY,IAAI,CAAA,IAAK,WAAA,CAAY,IAAI,CAAA,KAAM,CAAA;AACrD;AAEA,SAAS,6BAAA,CACP,UAAA,EACA,aAAA,EACA,SAAA,EAC6B;AAC7B,EAAA,IAAI,UAAA,KAAe,IAAA,IAAQ,UAAA,KAAe,MAAA,EAAW,OAAO,IAAA;AAE5D,EAAA,MAAM,MAAA,GAAS,oBAAoB,UAAU,CAAA;AAC7C,EAAA,IAAI,MAAA,KAAW,MAAM,OAAO,IAAA;AAK5B,EAAA,MAAM,MAAA,GAAS,UAAA,CAAW,SAAA,KAAc,SAAA,GAAY,aAAA,GAAgB,SAAA;AACpE,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,SAAA,KAAc,SAAA,GAAY,SAAA,GAAY,aAAA;AAC/D,EAAA,MAAM,WAAA,GAAe,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,IAAK,CAAA;AAC5C,EAAA,IAAI,WAAA,CAAY,WAAW,CAAA,EAAG,OAAO,IAAA;AAErC,EAAA,MAAM,QAAA,GAAW,OAAO,IAAA,GAAO,CAAA;AAC/B,EAAA,MAAM,MAAA,GAAS,OAAO,EAAA,GAAK,CAAA;AAC3B,EAAA,MAAM,YAAA,GAAgB,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA,IAAK,CAAA;AAC3C,EAAA,MAAM,WAAA,GAAe,KAAA,CAAM,MAAA,CAAO,EAAE,CAAA,IAAK,CAAA;AAEzC,EAAA,IAAI,WAAA,CAAY,WAAW,CAAA,KAAM,CAAA,IAAK,KAAK,GAAA,CAAI,MAAA,GAAS,QAAQ,CAAA,KAAM,CAAA,EAAG;AACvE,IAAA,OAAO,CAAC,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA;AAAA,EAC5B;AAEA,EAAA,IACE,MAAA,CAAO,cAAc,IAAA,IACpB,MAAA,CAAO,WAAW,CAAA,KAChB,MAAA,CAAO,MAAM,CAAA,KAAM,CAAA,IAAK,OAAO,EAAA,IAAM,CAAA,KAAM,MAC5C,CAAC,WAAA,CAAY,WAAW,CAAA,IACxB,WAAA,CAAY,WAAW,CAAA,KAAM,CAAA,EAC/B;AACA,IAAA,OAAO,CAAC,EAAE,IAAA,EAAM,WAAA,EAAa,CAAA;AAAA,EAC/B;AAEA,EAAA,IAAI,CAAC,YAAY,YAAY,CAAA,IAAK,QAAQ,YAAY,CAAA,KAAM,OAAA,CAAQ,WAAW,CAAA,EAAG;AAChF,IAAA,OAAO,CAAC,EAAE,IAAA,EAAM,SAAA,EAAW,CAAA;AAAA,EAC7B;AAEA,EAAA,IAAI,OAAO,WAAW,CAAA,IAAK,aAAa,MAAA,IAAU,WAAA,CAAY,YAAY,CAAA,EAAG;AAC3E,IAAA,MAAM,cAAA,GAAmB,MAAA,CAAO,IAAA,GAAO,EAAC,GAAK,MAAA;AAC7C,IAAA,MAAM,cAAA,GAAkB,MAAA,CAAO,cAAc,CAAA,IAAK,CAAA;AAClD,IAAA,MAAM,aAAA,GAAiB,KAAA,CAAM,cAAc,CAAA,IAAK,CAAA;AAChD,IAAA,IACE,CAAC,WAAA,CAAY,cAAc,CAAA,IAC3B,OAAA,CAAQ,cAAc,CAAA,KAAM,OAAA,CAAQ,WAAW,CAAA,IAC/C,WAAA,CAAY,aAAa,CAAA,EACzB;AACA,MAAA,OAAO,CAAC,EAAE,IAAA,EAAM,YAAA,EAAc,CAAA;AAAA,IAChC;AAAA,EACF;AAEA,EAAA,OAAO,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,CAAA;AAC1B;AAEA,SAAS,yBAAA,CACP,SAAA,EACA,WAAA,EACA,OAAA,EACA,WAAA,EACM;AACN,EAAA,MAAM,UAAU,MAAY;AAC1B,IAAA,MAAM,IAAA,GAAO,UAAU,qBAAA,EAAsB;AAC7C,IAAA,MAAM,UAAA,GAAa,KAAK,KAAA,GAAQ,CAAA;AAChC,IAAA,IAAI,cAAc,CAAA,EAAG;AAErB,IAAA,KAAA,MAAW,QAAQ,WAAA,EAAa;AAC9B,MAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,SAAA,EAAW,IAAA,CAAK,EAAE,CAAA;AAC7C,MAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,CAAM,YAAY,UAAA,EAAY;AAC3D,MAAA,MAAM,EAAE,EAAA,EAAI,EAAA,EAAG,GAAI,oBAAA,CAAqB,KAAK,IAAA,EAAM,IAAA,CAAK,EAAA,EAAI,UAAA,EAAY,WAAW,CAAA;AACnF,MAAA,IAAI,IAAA,CAAK,IAAI,EAAE,CAAA,GAAI,OAAO,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,GAAI,GAAA,EAAK;AAE9C,MAAA,uBAAA,CAAwB,KAAK,CAAA;AAC7B,MAAA,KAAA,CAAM,OAAA;AAAA,QACJ,CAAC,EAAE,SAAA,EAAW,CAAA,UAAA,EAAa,EAAE,CAAA,IAAA,EAAO,EAAE,CAAA,GAAA,CAAA,EAAM,EAAG,EAAE,SAAA,EAAW,iBAAA,EAAmB,CAAA;AAAA,QAC/E,EAAE,UAAU,OAAA,CAAQ,UAAA,EAAY,QAAQ,OAAA,CAAQ,MAAA,EAAQ,MAAM,MAAA;AAAO,OACvE;AAAA,IACF;AAAA,EACF,CAAA;AAEA,EAAA,IAAI,OAAO,MAAA,CAAO,qBAAA,KAA0B,UAAA,EAAY;AACtD,IAAA,MAAA,CAAO,sBAAsB,OAAO,CAAA;AAAA,EACtC,CAAA,MAAO;AACL,IAAA,MAAA,CAAO,UAAA,CAAW,SAAS,CAAC,CAAA;AAAA,EAC9B;AACF;AAEA,SAAS,eAAA,CACP,MACA,SAAA,EACA,UAAA,EACA,eACA,kBAAA,EACA,SAAA,EACA,WACA,WAAA,EACS;AACT,EAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,MAAA,CAAO,GAAA,EAAI,KAAM,SAAA;AAC9C,EAAA,MAAM,UAAA,GAAa,WAAW,UAAA,IAAc,iCAAA;AAC5C,EAAA,MAAM,MAAA,GAAS,WAAW,MAAA,IAAU,4BAAA;AACpC,EAAA,MAAM,aAAA,GACJ,eAAA,IACA,UAAA,KAAe,IAAA,IACf,UAAA,KAAe,MAAA,IACf,SAAA,KAAc,IAAA,IACd,UAAA,GAAa,CAAA,IACb,CAACA,qBAAAA,EAAqB;AAExB,EAAA,MAAM,cAAkC,EAAC;AACzC,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,KAAA,MAAW,IAAA,IAAQ,iBAAA,CAAkB,UAAU,CAAA,EAAG;AAChD,MAAA,IAAI,YAAA,CAAa,WAAW,IAAA,CAAK,IAAI,MAAM,IAAA,EAAM,WAAA,CAAY,KAAK,IAAI,CAAA;AAAA,IACxE;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,IAAI,kBAAkB,KAAA,CAAA,EAAW;AAC/B,MAAA,IAAI,CAAC,iBAAiB,OAAO,KAAA;AAC7B,MAAA,IAAA,CAAK,KAAK,SAAS,CAAA;AAAA,IACrB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,YAAA,CAAa;AAAA,QAChB,GAAA,EAAK,SAAA;AAAA,QACL,aAAA;AAAA,QACA,oBAAoB,kBAAA,KAAuB;AAAA,OAC5C,CAAA;AAAA,IACH;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,WAAA,CAAY,MAAA,GAAS,CAAA,IAAK,SAAA,KAAc,IAAA,EAAM;AAChD,IAAA,yBAAA,CAA0B,WAAW,WAAA,EAAa,EAAE,UAAA,EAAY,MAAA,IAAU,WAAW,CAAA;AAAA,EACvF;AACA,EAAA,OAAO,eAAA;AACT;AAgBO,SAAS,WAAW,KAAA,EAAwB;AACjD,EAAA,MAAM;AAAA,IACJ,IAAA;AAAA,IACA,WAAA;AAAA,IACA,WAAA;AAAA,IACA,kBAAA,GAAqB,IAAA;AAAA,IACrB,aAAA;AAAA,IACA,gCAAA;AAAA,IACA,WAAA,GAAc,OAAA;AAAA,IACd,KAAA,GAAQ,YAAA;AAAA,IACR,MAAA,GAAS,aAAA;AAAA,IACT,eAAA,GAAkB,IAAA;AAAA,IAClB,aAAA,GAAgB,MAAA;AAAA,IAChB,gBAAA,GAAmB,OAAA;AAAA,IACnB,iBAAA,GAAoB,IAAA;AAAA,IACpB,MAAA;AAAA,IACA,SAAA;AAAA,IACA,YAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA,GAAY,IAAA;AAAA,IACZ,kBAAA,GAAqB,IAAA;AAAA,IACrB,iBAAA,GAAoB,IAAA;AAAA,IACpB,kBAAA,GAAqB,IAAA;AAAA,IACrB,WAAA;AAAA,IACA,qBAAA,GAAwB,KAAA;AAAA,IACxB,YAAA,GAAe,KAAA;AAAA,IACf,kBAAA,GAAqB,IAAA;AAAA,IACrB,gBAAA,GAAmB,IAAA;AAAA,IACnB,KAAA,GAAQ,IAAA;AAAA,IACR,OAAA,GAAU,KAAA;AAAA,IACV,QAAA,GAAW,KAAA;AAAA,IACX,YAAA;AAAA,IACA,kBAAA;AAAA,IACA,kBAAA;AAAA,IACA,kBAAA,GAAqB,IAAA;AAAA,IACrB,kBAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF,GAAI,KAAA;AAOJ,EAAA,MAAM,WAAA,GAAc,aAAa,CAAC,QAAA;AAClC,EAAA,MAAM,mBAAA,GAAsB,sBAAsB,CAAC,QAAA;AACnD,EAAA,MAAM,qBAAqB,CAAC,QAAA;AAC5B,EAAA,MAAM,qBAAqB,CAAC,QAAA;AAO5B,EAAA,MAAM,aAAA,GAAgBX,QAA2B,MAAM;AACrD,IAAA,IAAI,WAAA,KAAgB,MAAA,IAAa,WAAA,KAAgB,EAAA,EAAI,OAAO,IAAA;AAC5D,IAAA,IAAI;AACF,MAAA,OAAO,kBAAkB,WAAW,CAAA;AAAA,IACtC,CAAA,CAAA,MAAQ;AAIN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;AAKhB,EAAA,MAAM,YAAA,GAAeA,QAA0B,MAAM;AACnD,IAAA,IAAI,KAAA,KAAU,IAAA,EAAM,OAAO,EAAE,SAAS,IAAA,EAAK;AAC3C,IAAA,IAAI,UAAU,KAAA,IAAS,KAAA,KAAU,QAAW,OAAO,EAAE,SAAS,KAAA,EAAM;AACpE,IAAA,OAAO,KAAA;AAAA,EACT,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,MAAM,aAAA,GAAgBA,QAA2B,MAAM;AACrD,IAAA,IAAI,OAAA,KAAY,IAAA,EAAM,OAAO,EAAE,SAAS,IAAA,EAAK;AAC7C,IAAA,IAAI,YAAY,KAAA,IAAS,OAAA,KAAY,QAAW,OAAO,EAAE,SAAS,KAAA,EAAM;AACxE,IAAA,OAAO,OAAA;AAAA,EACT,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,MAAM,YAAA,GAAeD,OAA8B,IAAI,CAAA;AACvD,EAAA,MAAM,YAAA,GAAeA,OAA+B,IAAI,CAAA;AACxD,EAAA,MAAM,cAAA,GAAiBA,OAAiC,IAAI,CAAA;AAC5D,EAAA,MAAM,4BAAA,GAA+BA,OAAsB,IAAI,CAAA;AAI/D,EAAA,MAAM,UAAA,GAAaA,OAAkC,IAAI,KAAA,CAAM,EAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAC7E,EAAA,MAAM,YAAA,GAAeT,WAAAA,CAAY,CAAC,KAAA,EAAoB,EAAA,KAA2B;AAC/E,IAAA,UAAA,CAAW,OAAA,CAAQ,KAAK,CAAA,GAAI,EAAA;AAAA,EAC9B,CAAA,EAAG,EAAE,CAAA;AAQL,EAAA,MAAM,oBAAA,GAAuBS,OAAO,KAAK,CAAA;AAIzC,EAAA,MAAM,SAAA,GAAYA,OAAO,MAAM,CAAA;AAC/B,EAAA,MAAM,YAAA,GAAeA,OAAO,SAAS,CAAA;AACrC,EAAAE,UAAU,MAAM;AACd,IAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AACpB,IAAA,YAAA,CAAa,OAAA,GAAU,SAAA;AAAA,EACzB,CAAC,CAAA;AAID,EAAA,MAAM,gBAAA,GAAmB,YAAA,CAAa,IAAA,EAAM,YAAY,CAAA;AACxD,EAAA,MAAMa,kBAAAA,GAAoB,cAAA,CAAe,IAAA,EAAM,aAAa,CAAA;AAE5D,EAAAP,gBAAgB,MAAM;AACpB,IAAA,IAAI,IAAA,KAAS,IAAA,IAAQ,WAAA,KAAgB,MAAA,IAAa,gBAAgB,EAAA,EAAI;AACtE,IAAA,MAAM,sBAAsB,4BAAA,CAA6B,OAAA;AACzD,IAAA,MAAM,gBAAA,GAAmB,KAAK,WAAA,EAAY;AAC1C,IAAA,IAAI,KAAK,MAAA,CAAO,GAAA,EAAI,KAAM,WAAA,IAAe,kBAAkB,MAAA,EAAW;AACpE,MAAA,4BAAA,CAA6B,OAAA,GAAU,WAAA;AACvC,MAAA;AAAA,IACF;AACA,IAAA,MAAM,eAAA,GAAkB,eAAA;AAAA,MACtB,IAAA;AAAA,MACA,WAAA;AAAA,MACA,kBAAA;AAAA,MACA,aAAA;AAAA,MACA,gCAAA;AAAA,MACA,YAAA,CAAa,OAAA;AAAA,MACb,SAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,4BAAA,CAA6B,OAAA,GAAU,WAAA;AAEvC,IAAA,IAAI,CAAC,eAAA,IAAmB,mBAAA,KAAwB,IAAA,IAAQ,wBAAwB,WAAA,EAAa;AAC3F,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,GAAW,KAAK,WAAA,EAAY;AAClC,IAAA,MAAM,mBAAA,GACJ,8BAA8B,kBAAA,EAAoB,gBAAA,CAAiB,OAAO,QAAA,CAAS,KAAK,KACxF,IAAA,CAAK,cAAA;AACP,IAAA,MAAM,gBAAA,GACJ,kBAAA,EAAoB,SAAA,KAAc,UAAA,GAAa,gBAAA,GAAmB,QAAA;AACpE,IAAA,gBAAA;AAAA,MACE,oBAAA,CAAqB,mBAAA,EAAqB,gBAAA,EAAkB,YAAA,CAAa,WAAW;AAAA,KACtF;AACA,IAAAO,kBAAAA;AAAA,MACE,oBAAA,CAAqB,mBAAA,EAAqB,gBAAA,EAAkB,aAAA,CAAc,WAAW;AAAA,KACvF;AAAA,EACF,CAAA,EAAG;AAAA,IACD,SAAA;AAAA,IACA,IAAA;AAAA,IACA,aAAA,CAAc,WAAA;AAAA,IACd,WAAA;AAAA,IACA,kBAAA;AAAA,IACA,aAAA;AAAA,IACA,gCAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA,CAAa,WAAA;AAAA,IACbA,kBAAAA;AAAA,IACA;AAAA,GACD,CAAA;AAQD,EAAA,MAAM,OAAA,GAAUd,QAA8B,MAAM;AAClD,IAAA,MAAM,MAAA,GAAkC;AAAA,MACtC,SAAS,kBAAA,CAAmB,OAAA;AAAA,MAC5B,OAAO,kBAAA,CAAmB,KAAA;AAAA,MAC1B,KAAK,kBAAA,CAAmB,GAAA;AAAA,MACxB,MAAM,kBAAA,CAAmB;AAAA,KAC3B;AACA,IAAA,IAAI,gBAAgB,MAAA,EAAW;AAC7B,MAAA,KAAA,MAAW,KAAK,WAAA,EAAa;AAC3B,QAAA,MAAM,CAAA,GAAK,YAA4B,CAAC,CAAA;AACxC,QAAA,IAAI,CAAA,KAAM,MAAA,EAAW,MAAA,CAAO,CAAC,CAAA,GAAI,CAAA;AAAA,MACnC;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;AAUhB,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAIS,SAAkC,IAAI,CAAA;AAMtF,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAIA,SAA6B,IAAI,CAAA;AAI3E,EAAA,MAAM,oBAAA,GAAuBnB,WAAAA;AAAA,IAC3B,MAAoB,WAAA,KAAgB,OAAA,GAAU,EAAA,GAAK,EAAA;AAAA,IACnD,CAAC,WAAW;AAAA,GACd;AAGA,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAImB,SAA6B,IAAI,CAAA;AACvE,EAAA,MAAM,aAAA,GAAgBV,OAA6C,IAAI,CAAA;AACvE,EAAA,MAAM,mBAAA,GAAsBT,WAAAA;AAAA,IAC1B,CAAC,MAAA,KAA8B;AAC7B,MAAA,IAAI,CAAC,gBAAA,EAAkB;AACvB,MAAA,cAAA,CAAe,MAAM,CAAA;AACrB,MAAA,IAAI,aAAA,CAAc,OAAA,KAAY,IAAA,EAAM,YAAA,CAAa,cAAc,OAAO,CAAA;AACtE,MAAA,aAAA,CAAc,OAAA,GAAU,WAAW,MAAM;AACvC,QAAA,cAAA,CAAe,IAAI,CAAA;AACnB,QAAA,aAAA,CAAc,OAAA,GAAU,IAAA;AAAA,MAC1B,GAAG,qBAAqB,CAAA;AAAA,IAC1B,CAAA;AAAA,IACA,CAAC,gBAAgB;AAAA,GACnB;AAEA,EAAAW,SAAAA;AAAA,IACE,MAAM,MAAM;AACV,MAAA,IAAI,aAAA,CAAc,OAAA,KAAY,IAAA,EAAM,YAAA,CAAa,cAAc,OAAO,CAAA;AAAA,IACxE,CAAA;AAAA,IACA;AAAC,GACH;AASA,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,IAAA,KAAS,IAAA,IAAQ,CAAC,iBAAA,EAAmB;AACzC,IAAA,IAAI,OAAA,GAAU,IAAA,CAAK,WAAA,EAAY,CAAE,UAAA;AACjC,IAAA,OAAO,IAAA,CAAK,UAAU,MAAM;AAC1B,MAAA,MAAM,IAAA,GAAO,KAAK,WAAA,EAAY;AAC9B,MAAA,IAAI,KAAK,UAAA,GAAa,OAAA,IAAW,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA,EAAG;AACvD,QAAA,IAAA,CAAK,eAAA,EAAgB;AAAA,MACvB;AACA,MAAA,OAAA,GAAU,IAAA,CAAK,UAAA;AAAA,IACjB,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,IAAA,EAAM,iBAAiB,CAAC,CAAA;AAM5B,EAAA,MAAM,gBAAA,GAAmBX,WAAAA;AAAA,IACvB,CAAC,MAAmB,EAAA,KAA0B;AAC5C,MAAA,IAAI,SAAS,IAAA,EAAM;AACnB,MAAA,MAAM,WAAW,IAAA,CAAK,WAAA,EAAY,CAAE,KAAA,CAAM,IAAI,CAAA,IAAK,CAAA;AACnD,MAAA,MAAM,KAAA,GAAQ,YAAY,QAAQ,CAAA;AAElC,MAAA,MAAM,YAAA,GAAe,CAAC,KAAA,KAA2B;AAC/C,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,IAAA,EAAM,IAAI,KAAK,CAAA;AAC3C,QAAA,MAAM,KAAK,SAAA,CAAU,OAAA;AACrB,QAAA,IAAI,MAAA,KAAW,IAAA,IAAQ,EAAA,KAAO,MAAA,KAAc,MAAM,CAAA;AAAA,MACpD,CAAA;AAEA,MAAA,MAAM,iBAAiB,YAAA,CAAa,OAAA;AACpC,MAAA,IAAI,mBAAmB,MAAA,EAAW;AAEhC,QAAA,OAAA,CAAQ,OAAA,CAAQ,cAAA,CAAe,EAAE,IAAA,EAAM,EAAA,EAAI,KAAA,EAAO,CAAC,CAAA,CAAE,IAAA,CAAK,YAAA,EAAc,MAAM;AAI5E,UAAA,oBAAA,CAAqB,OAAA,GAAU,KAAA;AAAA,QACjC,CAAC,CAAA;AACD,QAAA;AAAA,MACF;AAGA,MAAA,mBAAA,CAAoB;AAAA,QAClB,IAAA;AAAA,QACA,EAAA;AAAA,QACA,KAAA;AAAA,QACA,OAAA,EAAS,CAAC,KAAA,KAAU;AAClB,UAAA,mBAAA,CAAoB,IAAI,CAAA;AACxB,UAAA,YAAA,CAAa,KAAK,CAAA;AAAA,QACpB,CAAA;AAAA,QACA,QAAQ,MAAM;AAIZ,UAAA,oBAAA,CAAqB,OAAA,GAAU,KAAA;AAC/B,UAAA,mBAAA,CAAoB,IAAI,CAAA;AAAA,QAC1B;AAAA,OACD,CAAA;AAAA,IACH,CAAA;AAAA,IACA,CAAC,IAAI;AAAA,GACP;AAEA,EAAA,MAAM,WAAA,GAAc,cAAA,CAAe,IAAA,EAAM,MAAA,EAAQ,kBAAkB,kBAAkB,CAAA;AAOrF,EAAA,MAAM,gBAAA,GAAmBA,YAAY,MAAY;AAC/C,IAAA,IAAI,CAAC,kBAAA,IAAsB,IAAA,KAAS,IAAA,EAAM;AAI1C,IAAA,IAAI,KAAK,WAAA,EAAY,CAAE,OAAO,MAAA,GAAS,CAAA,OAAQ,eAAA,EAAgB;AAAA,EACjE,CAAA,EAAG,CAAC,kBAAA,EAAoB,IAAI,CAAC,CAAA;AAG7B,EAAA,MAAM,iBAAA,GAAoBA,WAAAA;AAAA,IACxB,CAAC,KAAA,KAA6B;AAK5B,MAAA,IAAI,QAAA,EAAU;AACd,MAAA,gBAAA,EAAiB;AACjB,MAAA,WAAA,CAAY,KAAK,CAAA;AAAA,IACnB,CAAA;AAAA,IACA,CAAC,QAAA,EAAU,gBAAA,EAAkB,WAAW;AAAA,GAC1C;AAGA,EAAAW,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,kBAAA,IAAsB,IAAA,KAAS,IAAA,IAAQ,QAAA,EAAU;AACtD,IAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,KAA2B;AACxC,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,QAAA,EAAU,gBAAA,EAAiB;AAAA,IAC3C,CAAA;AACA,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,KAAK,CAAA;AACxC,IAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,KAAK,CAAA;AAAA,EAC1D,GAAG,CAAC,kBAAA,EAAoB,IAAA,EAAM,gBAAA,EAAkB,QAAQ,CAAC,CAAA;AASzD,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,QAAA,IAAY,kBAAA,KAAuB,KAAA,IAAS,IAAA,KAAS,IAAA,EAAM;AAC/D,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,cAAc,IAAA,EAAM;AACxB,IAAA,MAAM,gBAAA,GAAmB,CAAC,CAAA,KAAwB;AAChD,MAAA,IAAI,CAAA,CAAE,WAAW,CAAA,EAAG;AACpB,MAAA,MAAM,SAAS,CAAA,CAAE,MAAA;AACjB,MAAA,IAAI,WAAW,IAAA,EAAM;AAIrB,MAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,qBAAqB,CAAA,KAAM,IAAA,EAAM;AACpD,MAAA,MAAM,KAAK,gBAAA,CAAiB,SAAA,EAAW,EAAE,OAAA,EAAS,CAAA,CAAE,SAAS,WAAW,CAAA;AACxE,MAAA,IAAI,OAAO,IAAA,EAAM;AACjB,MAAA,iBAAA,CAAkB,EAAE,CAAA;AAAA,IACtB,CAAA;AACA,IAAA,SAAA,CAAU,gBAAA,CAAiB,SAAS,gBAAgB,CAAA;AACpD,IAAA,OAAO,MAAM,SAAA,CAAU,mBAAA,CAAoB,OAAA,EAAS,gBAAgB,CAAA;AAAA,EACtE,GAAG,CAAC,QAAA,EAAU,oBAAoB,IAAA,EAAM,WAAA,EAAa,iBAAiB,CAAC,CAAA;AAUvE,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,kBAAA,EAAoB;AACzB,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,cAAc,IAAA,EAAM;AACxB,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAAwB;AAC7C,MAAA,CAAA,CAAE,cAAA,EAAe;AAAA,IACnB,CAAA;AACA,IAAA,SAAA,CAAU,gBAAA,CAAiB,eAAe,aAAa,CAAA;AACvD,IAAA,OAAO,MAAM,SAAA,CAAU,mBAAA,CAAoB,aAAA,EAAe,aAAa,CAAA;AAAA,EACzE,CAAA,EAAG,CAAC,kBAAkB,CAAC,CAAA;AAOvB,EAAA,MAAM,WAAA,GAAcX,WAAAA;AAAA,IAClB,CAAC,MAAmB,KAAA,KAA2B;AAC7C,MAAA,gBAAA,EAAiB;AAGjB,MAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,MAAA,IAAI,SAAA,KAAc,IAAA,EAAM,SAAA,CAAU,OAAA,CAAQ,YAAY,CAAA,GAAI,MAAA;AAK1D,MAAA,IAAA,EAAM,aAAa,IAAI,CAAA;AAAA,IACzB,CAAA;AAAA,IACA,CAAC,MAAM,gBAAgB;AAAA,GACzB;AACA,EAAA,MAAM,SAAA,GAAYA,YAAY,MAAY;AAGxC,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,SAAA,KAAc,IAAA,EAAM,OAAO,SAAA,CAAU,QAAQ,YAAY,CAAA;AAAA,EAI/D,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,MAAA,GAASA,WAAAA;AAAA,IACb,CAAC,MAAmB,EAAA,KAA0B;AAC5C,MAAA,IAAI,SAAS,IAAA,EAAM;AACnB,MAAA,MAAM,IAAA,GAAO,KAAK,WAAA,EAAY;AAC9B,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,IAAK,CAAA;AACrC,MAAA,MAAM,WAAA,GAAc,YAAY,QAAQ,CAAA;AAMxC,MAAA,IAAI,QAAA,KAAa,CAAA,IAAK,WAAA,KAAgB,IAAA,CAAK,IAAA,EAAM;AAC/C,QAAA,IAAI,CAAC,YAAA,EAAc;AACjB,UAAA,mBAAA,CAAoB,IAAI,CAAA;AACxB,UAAA;AAAA,QACF;AAGA,QAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,QAAA,EAAU,EAAE,IAAK,CAAA,GAA8B,MAAA;AAClF,QAAA,IAAA,CAAK,YAAA,CAAa,SAAA,KAAc,MAAA,GAAY,EAAE,IAAA,EAAM,EAAA,EAAG,GAAI,EAAE,IAAA,EAAM,EAAA,EAAI,SAAA,EAAW,CAAA;AAClF,QAAA;AAAA,MACF;AAKA,MAAA,oBAAA,CAAqB,OAAA,GAAU,IAAA;AAE/B,MAAA,IAAI,gBAAA,CAAiB,QAAA,EAAU,EAAE,CAAA,IAAK,IAAA,CAAK,OAAA;AAAA,QAAQ,IAAA;AAAA,QAAM,EAAA;AAAA,QAAI;AAAA;AAAA,OAAa,EAAG;AAC3E,QAAA,gBAAA,CAAiB,MAAM,EAAE,CAAA;AACzB,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,IAAA,EAAM,EAAE,CAAA;AACpC,MAAA,MAAM,KAAK,SAAA,CAAU,OAAA;AACrB,MAAA,IAAI,WAAW,IAAA,EAAM;AACnB,QAAA,IAAI,EAAA,KAAO,MAAA,EAAW,EAAA,CAAG,MAAM,CAAA;AAAA,MACjC,CAAA,MAAO;AACL,QAAA,oBAAA,CAAqB,OAAA,GAAU,KAAA;AAC/B,QAAA,mBAAA,CAAoB,IAAI,CAAA;AACxB,QAAA,IAAA,CAAK,aAAa,IAAI,CAAA;AAAA,MACxB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,IAAA,EAAM,gBAAA,EAAkB,YAAA,EAAc,mBAAmB;AAAA,GAC5D;AAEA,EAAA,OAAA,CAAQ;AAAA,IACN,IAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA,EAAS,eAAe,IAAA,KAAS,IAAA;AAAA,IACjC,WAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,GAAI,YAAA,KAAiB,MAAA,GAAY,EAAE,YAAA,KAAiB;AAAC,GACtD,CAAA;AAMD,EAAAW,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,kBAAA,EAAoB;AACvB,MAAA,gBAAA,CAAiB,IAAI,CAAA;AACrB,MAAA;AAAA,IACF;AACA,IAAA,gBAAA,CAAiB,CAAC,OAAA,KAAY,OAAA,IAAW,oBAAA,EAAsB,CAAA;AAAA,EACjE,CAAA,EAAG,CAAC,oBAAA,EAAsB,kBAAkB,CAAC,CAAA;AAE7C,EAAA,MAAM,kBAAA,GAAqBX,WAAAA;AAAA,IACzB,CAAC,KAAA,KAA6B;AAC5B,MAAA,gBAAA,EAAiB;AACjB,MAAA,WAAA,CAAY,KAAK,CAAA;AAAA,IACnB,CAAA;AAAA,IACA,CAAC,kBAAkB,WAAW;AAAA,GAChC;AACA,EAAA,MAAM,gBAAA,GAAmBA,YAAY,MAAY;AAC/C,IAAA,gBAAA,EAAiB;AACjB,IAAA,IAAA,EAAM,aAAa,IAAI,CAAA;AAAA,EACzB,CAAA,EAAG,CAAC,gBAAA,EAAkB,IAAI,CAAC,CAAA;AAE3B,EAAA,cAAA,CAAe;AAAA,IACb,YAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAA;AAAA,IACA,gBAAA;AAAA,IACA,UAAA,EAAY,kBAAA;AAAA,IACZ,QAAA,EAAU,gBAAA;AAAA,IACV,OAAA,EAAS,SAAS,IAAA,IAAQ;AAAA,GAC3B,CAAA;AAMD,EAAA,cAAA,CAAe;AAAA,IACb,IAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA,EAAS,kBAAA,KAAuB,MAAA,IAAa,kBAAA,KAAuB,MAAA;AAAA,IACpE,GAAI,kBAAA,KAAuB,MAAA,GAAY,EAAE,OAAA,EAAS,kBAAA,KAAuB,EAAC;AAAA,IAC1E,GAAI,kBAAA,KAAuB,MAAA,GAAY,EAAE,OAAA,EAAS,kBAAA,KAAuB;AAAC,GAC3E,CAAA;AAED,EAAA,eAAA,CAAgB;AAAA,IACd,IAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA;AAAA,IACA,cAAA;AAAA,IACA,OAAA,EAAS,uBAAuB,IAAA,KAAS,IAAA;AAAA,IACzC,OAAA;AAAA,IACA,eAAA,EAAiB;AAAA,GAClB,CAAA;AAOD,EAAA,sBAAA,CAAuB,IAAA,EAAM,YAAY,gBAAgB,CAAA;AAOzD,EAAA,qBAAA,CAAsB,IAAA,EAAM,YAAY,iBAAiB,CAAA;AASzD,EAAA,mBAAA,CAAoB,IAAA,EAAM,YAAA,EAAc,WAAA,EAAa,YAAY,CAAA;AAIjE,EAAA,MAAM,gBAAA,GAAmBU,QAAQ,OAAO,EAAE,aAAa,oBAAA,EAAqB,CAAA,EAAI,EAAE,CAAA;AAGlF,EAAA,MAAM,cAAA,GAAgC;AAAA,IACpC,QAAA,EAAU,UAAA;AAAA,IACV,WAAA,EAAa,OAAA;AAAA,IACb,KAAA,EAAO,MAAA;AAAA,IACP,WAAA,EAAa,MAAA;AAAA;AAAA,IACb,GAAI,KAAA;AAAA,IACJ,GAAG;AAAA,GACL;AAEA,EAAA,uBACET,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,YAAA;AAAA,MACL,SAAA;AAAA,MACA,KAAA,EAAO,cAAA;AAAA,MACP,qBAAA,EAAqB,WAAA;AAAA,MACrB,sBAAA,EAAsB,gBAAA,KAAqB,KAAA,GAAQ,KAAA,GAAQ,gBAAA;AAAA,MAC1D,GAAI,QAAA,GAAW,EAAE,mBAAA,EAAqB,MAAA,KAAW,EAAC;AAAA,MAEnD,QAAA,EAAA;AAAA,wBAAAJ,GAAAA;AAAA,UAAC,SAAA;AAAA,UAAA;AAAA,YACC,WAAA;AAAA,YACA,aAAA,EAAe,iBAAA;AAAA,YACf,aAAA;AAAA,YACA,YAAA;AAAA,YACA,QAAA,EAAU,QAAA;AAAA,YACV,KAAA,EAAO,IAAA;AAAA,YACP,kBAAA;AAAA,YACA,aAAA;AAAA,YACC,GAAI,YAAA,KAAiB,MAAA,GAAY,EAAE,YAAA,KAAiB,EAAC;AAAA,YACrD,GAAI,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,KAAc;AAAC;AAAA,SAClD;AAAA,QACC,IAAA,KAAS,QAAQ,kBAAA,mBAChBA,IAAC,UAAA,EAAA,EAAW,KAAA,EAAO,IAAA,EAAM,WAAA,EAA0B,CAAA,GACjD,IAAA;AAAA,QACH,IAAA,KAAS,uBACRA,GAAAA,CAAC,gBAAa,KAAA,EAAO,IAAA,EAAM,WAAA,EAA0B,MAAA,EAAgB,CAAA,GACnE,IAAA;AAAA,QAOH,IAAA,KAAS,IAAA,mBACRA,GAAAA,CAAC,WAAA,EAAA,EAAY,KAAA,EAAO,IAAA,EAAM,WAAA,EAA0B,OAAA,EAAkB,KAAA,EAAK,IAAA,EAAC,CAAA,GAC1E,IAAA;AAAA,QACH,SAAS,IAAA,mBACRA,IAAC,UAAA,EAAA,EAAW,KAAA,EAAO,MAAM,WAAA,EAA0B,MAAA,EAAgB,IACjE,aAAA,KAAkB,IAAA,mBACpBA,GAAAA,CAAC,gBAAA,EAAA,EAAiB,OAAO,aAAA,EAAe,WAAA,EAA0B,QAAgB,CAAA,GAChF,IAAA;AAAA,QACH,IAAA,KAAS,uBACRA,GAAAA;AAAA,UAAC,eAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO,IAAA;AAAA,YACP,YAAA;AAAA,YACA,WAAA;AAAA,YACC,GAAI,SAAA,KAAc,MAAA,GAAY,EAAE,OAAA,EAAS,SAAA,KAAc,EAAC;AAAA,YACzD,OAAA,EAAS;AAAA;AAAA,SACX,GACE,IAAA;AAAA,wBACJA,GAAAA,CAAC,SAAA,EAAA,EAAU,GAAA,EAAK,cAAc,MAAA,EAAgB,CAAA;AAAA,QAC7C,IAAA,KAAS,uBACRA,GAAAA;AAAA,UAAC,WAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,cAAA;AAAA,YACL,KAAA,EAAO,IAAA;AAAA,YACP,WAAA;AAAA,YACA;AAAA;AAAA,SACF,GACE,IAAA;AAAA,QACH,kCACCA,GAAAA,CAAC,WAAA,EAAA,EAAY,WAAA,EAA0B,eAA8B,CAAA,GACnE,IAAA;AAAA,wBACJA,GAAAA,CAAC,iBAAA,EAAA,EAAkB,EAAA,EAAI,aAAa,WAAA,EAA0B,CAAA;AAAA,QAC7D,SAAS,IAAA,mBAAOA,IAAC,UAAA,EAAA,EAAW,KAAA,EAAO,MAAM,CAAA,GAAK,IAAA;AAAA,QAC9C,gBAAA,KAAqB,uBACpBA,GAAAA;AAAA,UAAC,gBAAA;AAAA,UAAA;AAAA,YACC,MAAM,gBAAA,CAAiB,IAAA;AAAA,YACvB,IAAI,gBAAA,CAAiB,EAAA;AAAA,YACrB,OAAO,gBAAA,CAAiB,KAAA;AAAA,YACxB,WAAA;AAAA,YACA,MAAA;AAAA,YACA,UAAU,gBAAA,CAAiB,OAAA;AAAA,YAC3B,UAAU,gBAAA,CAAiB,MAAA;AAAA,YAC3B;AAAA;AAAA,SACF,GACE;AAAA;AAAA;AAAA,GACN;AAEJ;AC99BO,SAAS,YAAA,CAAa,OAAA,GAAmD,EAAC,EAAe;AAC9F,EAAA,MAAM,EAAE,GAAA,EAAK,GAAG,YAAA,EAAa,GAAI,OAAA;AACjC,EAAA,MAAM,CAAC,mBAAmB,CAAA,GAAIsB,QAAAA,CAA4B,MAAM,YAAY,CAAA;AAG5E,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,SAAqB,MAAM;AACnD,IAAA,MAAM,OAAA,GAAU,uBAAuB,GAAG,CAAA;AAC1C,IAAA,OAAO,gBAAA,CAAiB,SAAS,YAAY,CAAA;AAAA,EAC/C,CAAC,CAAA;AAGD,EAAA,MAAM,UAAA,GAAaV,OAA2B,GAAG,CAAA;AACjD,EAAAE,UAAU,MAAM;AACd,IAAA,IAAI,UAAA,CAAW,YAAY,GAAA,EAAK;AAC9B,MAAA,UAAA,CAAW,OAAA,GAAU,GAAA;AACrB,MAAA,MAAM,OAAA,GAAU,uBAAuB,GAAG,CAAA;AAC1C,MAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,OAAA,EAAS,mBAAmB,CAAA;AAC/D,MAAA,QAAA,CAAS,CAAC,IAAA,KAAS;AACjB,QAAA,IAAA,CAAK,OAAA,EAAQ;AACb,QAAA,OAAO,SAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACH;AAAA,EACF,CAAA,EAAG,CAAC,GAAA,EAAK,mBAAmB,CAAC,CAAA;AAG7B,EAAAA,UAAU,MAAM;AACd,IAAA,OAAO,MAAM;AACX,MAAA,KAAA,CAAM,OAAA,EAAQ;AAAA,IAChB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,OAAO,KAAA;AACT;;;ACwCO,IAAM,eAAA,GAAkB","file":"index.js","sourcesContent":["\"use client\";\n\n/**\n * Algebraic coordinate labels on the board edges.\n *\n * Static overlay — no subscriptions. Files (a–h) render along the bottom\n * edge; ranks (1–8) along the left edge. Orientation flips the order.\n * Label colours come from `--gb-coord-light` / `--gb-coord-dark` so the\n * label contrasts against whichever square it sits on.\n */\n\nimport { CSS_VARS } from \"../default-theme.js\";\nimport type { Orientation, RanksPosition } from \"../types.js\";\n\nconst FILE_LETTERS = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\"] as const;\n\n/** Props for {@link Coordinates}. */\nexport interface CoordinatesProps {\n readonly orientation: Orientation;\n /** Which side of the board the rank labels sit on. Default `\"left\"`. */\n readonly ranksPosition?: RanksPosition;\n}\n\n/**\n * Overlay of file and rank labels. `pointer-events: none` so clicks fall\n * through to squares underneath.\n */\nexport function Coordinates({ orientation, ranksPosition = \"left\" }: CoordinatesProps) {\n const ranksOnRight = ranksPosition === \"right\";\n return (\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n pointerEvents: \"none\",\n fontSize: \"min(1.6vmin, 11px)\",\n fontWeight: 600,\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n }}\n >\n {FILE_LETTERS.map((letter, idx) => {\n const col = orientation === \"white\" ? idx : 7 - idx;\n // Bottom rank label colour depends on the bottom-row square colour at `col`.\n // Bottom rank index is 0 (white-bottom) or 7 (black-bottom). File `col`\n // on rank 0: (col + 0) % 2 === 1 → light. We want label to contrast.\n const bottomRank = orientation === \"white\" ? 0 : 7;\n const isLightSquare = (col + bottomRank) % 2 === 1;\n return (\n <span\n key={`file-${letter}`}\n style={{\n position: \"absolute\",\n left: `${col * 12.5 + 10}%`,\n bottom: \"1%\",\n color: `var(${isLightSquare ? CSS_VARS.COORDINATE_LIGHT : CSS_VARS.COORDINATE_DARK})`,\n }}\n >\n {letter}\n </span>\n );\n })}\n {FILE_LETTERS.map((_, idx) => {\n // Re-use letter loop for ranks; the index maps directly to 1..8.\n const rank = idx; // 0..7 corresponds to ranks 1..8\n const row = orientation === \"white\" ? 7 - rank : rank;\n // `edgeFile` is the file the rank label sits on — 0 (left column)\n // for `ranksPosition=\"left\"`, 7 (right column) for `\"right\"`.\n // In black orientation the visual edges stay put but the file\n // indices flip.\n const edgeFile = ranksOnRight\n ? orientation === \"white\"\n ? 7\n : 0\n : orientation === \"white\"\n ? 0\n : 7;\n const isLightSquare = (edgeFile + rank) % 2 === 1;\n const sideStyle = ranksOnRight ? { right: \"1%\" } : { left: \"1%\" };\n return (\n <span\n key={`rank-${rank}`}\n style={{\n position: \"absolute\",\n top: `${row * 12.5 + 1}%`,\n ...sideStyle,\n color: `var(${isLightSquare ? CSS_VARS.COORDINATE_LIGHT : CSS_VARS.COORDINATE_DARK})`,\n }}\n >\n {rank + 1}\n </span>\n );\n })}\n </div>\n );\n}\n","\"use client\";\n\n/**\n * Thin `useSyncExternalStore` wrappers for the `BoardModel` subscribe store.\n *\n * Rationale: components should read the slice they actually care about and\n * nothing more. Reading the whole snapshot triggers a re-render on every\n * commit (arrow add, premove queue, selection change — anything). Reading a\n * single field leverages React's `Object.is` bailout and limits re-renders\n * to commits that actually moved that field.\n *\n * The per-byte square hook uses the store's `subscribeSquare` path, so a\n * component that reads `board[12]` only wakes up on commits that changed\n * that byte.\n */\n\nimport { useCallback, useSyncExternalStore } from \"react\";\nimport type { BoardModel, BoardSnapshot, SquareIndex } from \"../core/index.js\";\n\n/** Subscribe to the entire board snapshot. Wakes up on every commit. */\nexport function useBoardSnapshot(model: BoardModel): BoardSnapshot {\n return useSyncExternalStore(model.subscribe, model.getSnapshot, model.getSnapshot);\n}\n\n/**\n * Subscribe to a slice derived from the snapshot. Re-renders only when the\n * selector's return value changes by `Object.is`.\n *\n * The selector is called on every `getSnapshot` tick, so it should be cheap\n * (a field access) and must return a stable reference when the underlying\n * data didn't change. Our snapshot store guarantees stability for primitive\n * fields and for the `legalTargets` / `arrows` / `premoves` collections.\n */\nexport function useBoardSlice<T>(model: BoardModel, selector: (snapshot: BoardSnapshot) => T): T {\n const getSnapshot = useCallback((): T => selector(model.getSnapshot()), [model, selector]);\n return useSyncExternalStore(model.subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Subscribe to a single board byte via `subscribeSquare`. The component\n * receives the byte's current value (0 for empty, 1–12 for a piece) and\n * wakes up only when that byte changes.\n *\n * @remarks\n * The returned value is a primitive number, so React's default `Object.is`\n * bailout handles equality. The `useCallback` pins the subscribe function\n * to `(model, index)` — a Square that re-renders for unrelated reasons\n * doesn't force a re-subscription.\n */\nexport function useSquareCell(model: BoardModel | null | undefined, index: SquareIndex): number {\n const subscribe = useCallback(\n (listener: () => void) => (model ? model.subscribeSquare(index, listener) : () => {}),\n [model, index],\n );\n const getSnapshot = useCallback((): number => {\n if (!model) return 0;\n const snap = model.getSnapshot();\n return snap.board[index] ?? 0;\n }, [model, index]);\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n","\"use client\";\n\n/**\n * Piece overlay: 64 `PieceSlot` children, one per square. Each slot\n * subscribes to a single byte of the board snapshot — so a move that\n * touches 2–4 bytes wakes 2–4 slots, not all 64.\n *\n * Layout is an 8×8 CSS grid. A slot's position is expressed with\n * `gridColumnStart` / `gridRowStart` — two integer CSS properties —\n * instead of the `left: \"${x}%\"; top: \"${y}%\"` percentage math we used\n * to do. That removes per-render string interpolation and lets the\n * browser's grid layout path short-circuit: only slots whose integer\n * coordinates changed get a layout update. Paint cost drops too —\n * composited grid cells are cheaper than absolute-positioned ones\n * because the layout root stays the grid container, not each sibling.\n *\n * The layer itself (`pointer-events: none`) never intercepts clicks; the\n * board grid beneath owns pointer events.\n */\n\nimport { memo } from \"react\";\nimport type { BoardCell, BoardModel, SquareIndex } from \"../core/index.js\";\nimport { CSS_VARS } from \"../default-theme.js\";\nimport { useSquareCell } from \"../hooks/use-board-subscription.js\";\nimport type { Orientation, PieceRenderer } from \"../types.js\";\n\n/**\n * Compute the 1-based CSS grid column + row for a square. The grid has\n * 8 columns and 8 rows; white orientation puts rank 1 at row 8 (the\n * bottom) and rank 8 at row 1 (the top).\n *\n * Exported so the subscription-free `<StaticPieceLayer/>` can share the\n * same geometry and produce DOM identical to what this layer emits —\n * keeps the \"null game → fallback FEN\" transition free of layout shift.\n */\nexport function gridCoord(\n index: SquareIndex,\n orientation: Orientation,\n): { col: number; row: number } {\n const file = index & 7;\n const rank = index >> 3;\n const col = orientation === \"white\" ? file + 1 : 8 - file;\n const row = orientation === \"white\" ? 8 - rank : rank + 1;\n return { col, row };\n}\n\n/** Props for each individual piece slot. */\ninterface PieceSlotProps {\n readonly index: SquareIndex;\n readonly model: BoardModel;\n readonly orientation: Orientation;\n readonly pieces: PieceRenderer;\n}\n\n/** Algebraic name for a square index — used as a debug/test attribute. */\nexport function algebraicOf(index: SquareIndex): string {\n const file = index & 7;\n const rank = index >> 3;\n return `${String.fromCharCode(0x61 + file)}${rank + 1}`;\n}\n\n/**\n * Shared base style object for every slot. Pre-frozen so React's\n * shallow prop-diff short-circuits; the per-square placement is added\n * on top of this as an `inline-style` spread. Exported for\n * `<StaticPieceLayer/>` so both layers emit bit-identical DOM.\n */\nexport const SLOT_BASE_STYLE = Object.freeze({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"none\",\n containerType: \"size\" as const,\n});\n\nfunction PieceSlotImpl({ index, model, orientation, pieces }: PieceSlotProps) {\n const cell = useSquareCell(model, index);\n if (cell === 0) return null;\n const { col, row } = gridCoord(index, orientation);\n // Return-null on empty squares keeps the mutation count at 1 childList\n // per square per move. An earlier attempt to keep all 64 slots\n // persistently mounted (swap only the inner <img>) pushed per-move\n // mutations UP — childList on the slot *plus* a data-piece-cell\n // attribute write per slot = 2 mutations where the mount/unmount was\n // 1. See `bench/playwright/mutation-audit.spec.ts` — the assertion\n // guards this.\n return (\n <div\n data-piece-square={algebraicOf(index)}\n data-piece-cell={cell}\n style={{\n ...SLOT_BASE_STYLE,\n gridColumnStart: col,\n gridRowStart: row,\n filter: `var(${cell <= 6 ? CSS_VARS.PIECE_FILTER_WHITE : CSS_VARS.PIECE_FILTER_BLACK}, none)`,\n }}\n >\n {pieces({ cell: cell as BoardCell, square: index })}\n </div>\n );\n}\nconst PieceSlot = memo(PieceSlotImpl);\nPieceSlot.displayName = \"PieceSlot\";\n\n/** Props for {@link PieceLayer}. */\nexport interface PieceLayerProps {\n readonly model: BoardModel;\n readonly orientation: Orientation;\n readonly pieces: PieceRenderer;\n}\n\n/**\n * CSS-grid container style. 8×8, stretches to fill the board; each\n * occupied slot drops in at its `gridColumnStart` / `gridRowStart`.\n * Frozen so the outer `<div>`'s prop identity is stable across\n * renders. Exported so `<StaticPieceLayer/>` can reuse it.\n */\nexport const CONTAINER_STYLE = Object.freeze({\n position: \"absolute\" as const,\n inset: 0,\n display: \"grid\" as const,\n gridTemplateColumns: \"repeat(8, 1fr)\",\n gridTemplateRows: \"repeat(8, 1fr)\",\n pointerEvents: \"none\" as const,\n});\n\n/**\n * Render 64 `PieceSlot` children. React keys by square index so each slot\n * has a stable identity across rerenders — necessary for M3's WAAPI\n * animation to find and animate the right DOM node.\n */\nexport const PieceLayer = memo(function PieceLayer({\n model,\n orientation,\n pieces,\n}: PieceLayerProps) {\n const slots: React.ReactNode[] = [];\n for (let i = 0; i < 64; i++) {\n slots.push(\n <PieceSlot\n key={i}\n index={i as SquareIndex}\n model={model}\n orientation={orientation}\n pieces={pieces}\n />,\n );\n }\n return (\n <div aria-hidden=\"true\" style={CONTAINER_STYLE}>\n {slots}\n </div>\n );\n});\n","/**\n * Board geometry helpers.\n *\n * Pure, framework-agnostic utilities for mapping between viewport pixel\n * coordinates and `SquareIndex` (LERF 0..63). Single source of truth\n * consumed by {@link useDrag}, {@link useArrowGesture}, the spare-piece\n * drag hook, and any consumer who wants to hit-test the board from\n * custom React code (analysis overlays, piece tooltips, screenshots).\n *\n * No DOM mutation; no side effects. Each call reads\n * `container.getBoundingClientRect()` once — cheap but not free, so\n * hot-path callers should batch calls per pointer event.\n */\nimport type { SquareIndex } from \"../core/index.js\";\nimport type { Orientation } from \"../types.js\";\n\n/**\n * Resolve a viewport point to the `SquareIndex` it lies inside, or\n * `null` when the point is outside the board rect.\n *\n * The hit-test assumes the container has 1:1 geometry with the 8×8 grid\n * — i.e. the outer `<div>` of `<Chessboard/>`. Coordinates/edge padding\n * layers do **not** sit inside a smaller sub-rect; they're overlays on\n * the same box.\n *\n * @param container The board container element.\n * @param clientX `MouseEvent.clientX` / `PointerEvent.clientX`.\n * @param clientY `MouseEvent.clientY` / `PointerEvent.clientY`.\n * @param orientation Board orientation (flips file/rank derivation).\n * @returns The square under the point, or `null` if out of bounds.\n */\nexport function getSquareAtPoint(\n container: HTMLElement,\n clientX: number,\n clientY: number,\n orientation: Orientation,\n): SquareIndex | null {\n const rect = container.getBoundingClientRect();\n const relX = clientX - rect.left;\n const relY = clientY - rect.top;\n if (relX < 0 || relY < 0 || relX >= rect.width || relY >= rect.height) return null;\n const col = Math.floor((relX / rect.width) * 8);\n const row = Math.floor((relY / rect.height) * 8);\n const file = orientation === \"white\" ? col : 7 - col;\n const rank = orientation === \"white\" ? 7 - row : row;\n return (rank * 8 + file) as SquareIndex;\n}\n\n/**\n * Inverse of {@link getSquareAtPoint}: the viewport point at the centre\n * of a given square, expressed in client (viewport) coordinates.\n *\n * Useful for drawing tooltips, floating annotations, or anchoring DOM\n * nodes against a specific square without sampling the actual DOM child.\n *\n * @param container The board container element.\n * @param square Square index in LERF order.\n * @param orientation Board orientation.\n * @returns `{ x, y }` in viewport pixel coordinates.\n */\nexport function getPointAtSquareCentre(\n container: HTMLElement,\n square: SquareIndex,\n orientation: Orientation,\n): { readonly x: number; readonly y: number } {\n const rect = container.getBoundingClientRect();\n const sqW = rect.width / 8;\n const sqH = rect.height / 8;\n const file = square & 7;\n const rank = square >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n return {\n x: rect.left + sqW * col + sqW / 2,\n y: rect.top + sqH * row + sqH / 2,\n };\n}\n\n/** Algebraic name (`\"a1\"`, `\"h8\"`, …) for a square index. */\nexport function algebraicOf(square: SquareIndex): string {\n const file = square & 7;\n const rank = square >> 3;\n return `${String.fromCharCode(0x61 + file)}${rank + 1}`;\n}\n\n/** Square index for an algebraic name (`\"a1\"`, `\"h8\"`, …), or `null` if invalid. */\nexport function squareOf(algebraic: string): SquareIndex | null {\n if (algebraic.length !== 2) return null;\n const file = algebraic.charCodeAt(0) - 0x61;\n const rank = algebraic.charCodeAt(1) - 0x31;\n if (file < 0 || file > 7 || rank < 0 || rank > 7) return null;\n return ((rank << 3) | file) as SquareIndex;\n}\n","\"use client\";\n\n/**\n * `BoardEditor` — First-class accessible chess workstation board editor.\n *\n * Implements a unified, high-performance editor with `role=\"application\"`\n * so screen readers (JAWS, NVDA, VoiceOver) bypass virtual PC cursor browse\n * mode on single-key shortcuts:\n *\n * - Single-key piece placement:\n * - `p` / `P` (pawn: lowercase = Black, uppercase = White)\n * - `n` / `N` (knight)\n * - `b` / `B` (bishop)\n * - `r` / `R` (rook)\n * - `q` / `Q` (queen)\n * - `k` / `K` (king)\n * - Deletion: `Backspace`, `Delete`, `x`, `X` (clears focused cell)\n * - Walk cell-by-cell: `ArrowUp`, `ArrowDown`, `ArrowLeft`, `ArrowRight` (orientation-aware)\n * - Row edges: `Home`, `End`\n * - Board corners: `Ctrl+Home`, `Ctrl+End`\n * - Clear board: `c` / `C`\n * - Reset starting position: `s` / `S`\n * - Toggle side to move: `t` / `T`\n * - Palette placement: `Enter` / `Space`\n * - Free drag-and-drop between squares + drag off board to delete\n */\n\nimport React, {\n type CSSProperties,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Coordinates } from \"./components/coordinates.js\";\nimport { gridCoord, SLOT_BASE_STYLE } from \"./components/piece-layer.js\";\nimport {\n BOARD_CELL_BB,\n BOARD_CELL_BK,\n BOARD_CELL_BN,\n BOARD_CELL_BP,\n BOARD_CELL_BQ,\n BOARD_CELL_BR,\n BOARD_CELL_WB,\n BOARD_CELL_WK,\n BOARD_CELL_WN,\n BOARD_CELL_WP,\n BOARD_CELL_WQ,\n BOARD_CELL_WR,\n type BoardCell,\n type SquareIndex,\n} from \"./core/index.js\";\nimport { CSS_VARS, defaultTheme } from \"./default-theme.js\";\nimport { parseFenPlacement, STARTING_FEN } from \"./fen.js\";\nimport { algebraicOf, getSquareAtPoint } from \"./lib/geometry.js\";\nimport { defaultPieces } from \"./pieces/default-pieces.js\";\nimport type { Orientation, PieceRenderer, Theme } from \"./types.js\";\n\nconst PIECE_CHARS = [\"\", \"P\", \"N\", \"B\", \"R\", \"Q\", \"K\", \"p\", \"n\", \"b\", \"r\", \"q\", \"k\"] as const;\n\nexport function formatFenPlacement(board: Uint8Array): string {\n const rows: string[] = [];\n for (let r = 7; r >= 0; r--) {\n let empty = 0;\n let row = \"\";\n for (let f = 0; f < 8; f++) {\n const cell = board[r * 8 + f] ?? 0;\n if (cell === 0) {\n empty++;\n } else {\n if (empty > 0) {\n row += String(empty);\n empty = 0;\n }\n row += PIECE_CHARS[cell] ?? \"\";\n }\n }\n if (empty > 0) {\n row += String(empty);\n }\n rows.push(row);\n }\n return rows.join(\"/\");\n}\n\nfunction updateFenPlacement(originalFen: string, newPlacement: string): string {\n const tokens = originalFen.trim().split(/\\s+/);\n if (tokens.length <= 1) {\n return newPlacement;\n }\n tokens[0] = newPlacement;\n return tokens.join(\" \");\n}\n\nfunction pieceNameFromCell(cell: BoardCell): string {\n if (cell === 0) return \"empty\";\n const color = cell > 6 ? \"black\" : \"white\";\n const type = (cell - 1) % 6;\n const names = [\"pawn\", \"knight\", \"bishop\", \"rook\", \"queen\", \"king\"];\n return `${color} ${names[type] ?? \"piece\"}`;\n}\n\nfunction defaultSquareLabel(square: SquareIndex, cell: BoardCell): string {\n const sq = algebraicOf(square);\n if (cell === 0) {\n return `${sq}, empty`;\n }\n return `${sq}, ${pieceNameFromCell(cell)}`;\n}\n\nfunction cellFromKey(key: string): BoardCell {\n switch (key) {\n case \"P\":\n return BOARD_CELL_WP;\n case \"N\":\n return BOARD_CELL_WN;\n case \"B\":\n return BOARD_CELL_WB;\n case \"R\":\n return BOARD_CELL_WR;\n case \"Q\":\n return BOARD_CELL_WQ;\n case \"K\":\n return BOARD_CELL_WK;\n case \"p\":\n return BOARD_CELL_BP;\n case \"n\":\n return BOARD_CELL_BN;\n case \"b\":\n return BOARD_CELL_BB;\n case \"r\":\n return BOARD_CELL_BR;\n case \"q\":\n return BOARD_CELL_BQ;\n case \"k\":\n return BOARD_CELL_BK;\n default:\n return 0 as BoardCell;\n }\n}\n\nfunction cellFromPieceString(piece: string | null | undefined): BoardCell {\n if (!piece || piece === \"erase\") return 0 as BoardCell;\n if (piece.length === 2) {\n const c0 = piece[0];\n const c1 = piece[1];\n if (c0 && c1) {\n const color = c0.toLowerCase();\n const type = c1.toUpperCase();\n if (color === \"w\") return cellFromKey(type);\n if (color === \"b\") return cellFromKey(type.toLowerCase());\n }\n }\n return cellFromKey(piece);\n}\n\nfunction getOppositePieceString(piece: string | null | undefined): string | null {\n if (!piece || piece === \"erase\") return null;\n if (piece.length === 2) {\n const c0 = piece[0];\n const c1 = piece[1];\n if (c0 && c1) {\n const color = c0 === \"w\" ? \"b\" : \"w\";\n return `${color}${c1}`;\n }\n }\n return piece === piece.toUpperCase() ? piece.toLowerCase() : piece.toUpperCase();\n}\n\nfunction moveSquare(\n current: SquareIndex,\n direction: \"up\" | \"down\" | \"left\" | \"right\",\n orientation: Orientation,\n): SquareIndex {\n const file = current & 7;\n const rank = current >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n\n let newCol = col;\n let newRow = row;\n switch (direction) {\n case \"up\":\n newRow = Math.max(0, row - 1);\n break;\n case \"down\":\n newRow = Math.min(7, row + 1);\n break;\n case \"left\":\n newCol = Math.max(0, col - 1);\n break;\n case \"right\":\n newCol = Math.min(7, col + 1);\n break;\n }\n\n const newFile = orientation === \"white\" ? newCol : 7 - newCol;\n const newRank = orientation === \"white\" ? 7 - newRow : newRow;\n return ((newRank * 8 + newFile) & 0x3f) as SquareIndex;\n}\n\nfunction rankEndSquare(\n current: SquareIndex,\n which: \"home\" | \"end\",\n orientation: Orientation,\n): SquareIndex {\n const rank = current >> 3;\n if (orientation === \"white\") {\n return ((rank << 3) | (which === \"home\" ? 0 : 7)) as SquareIndex;\n }\n return ((rank << 3) | (which === \"home\" ? 7 : 0)) as SquareIndex;\n}\n\nexport interface BoardEditorProps {\n /** Current FEN or placement string. */\n fen?: string;\n /** Called whenever the board placement changes. */\n onChange?: (fen: string) => void;\n /** Called when a specific square piece changes. */\n onPieceChange?: (square: SquareIndex, cell: BoardCell, algebraic: string) => void;\n /** Currently selected piece for placement (e.g. \"wP\", \"bP\", \"wK\", or null for eraser). */\n selectedPiece?: string | null;\n /** Callback when shortcut piece is chosen. */\n onSelectPiece?: (piece: string | null) => void;\n /** Board orientation (default \"white\"). */\n orientation?: Orientation;\n /** Board visual theme. */\n theme?: Theme;\n /** Piece renderer. */\n pieces?: PieceRenderer;\n /** Whether algebraic coordinates are shown. */\n showCoordinates?: boolean;\n /** Container style overrides. */\n style?: CSSProperties;\n /** Container class name. */\n className?: string;\n /** Accessible label. */\n ariaLabel?: string;\n /** Announce feedback callback (e.g. forward to useAriaLive). */\n onAnnounce?: (message: string) => void;\n /** Custom generator for square speech labels. */\n getSquareAriaLabel?: (square: SquareIndex, cell: BoardCell, algebraic: string) => string;\n /** Current focused square (controlled). */\n focusedSquare?: SquareIndex;\n /** Square focus callback. */\n onSquareFocus?: (square: SquareIndex, cell: BoardCell, algebraic: string) => void;\n /** Optional container element id. */\n id?: string;\n /** Clear board callback. */\n onClear?: () => void;\n /** Set starting position callback. */\n onSetStartingPosition?: () => void;\n /** Toggle side to move callback. */\n onToggleSideToMove?: () => void;\n /** Callback when editor receives container focus. */\n onFocus?: (e: React.FocusEvent<HTMLDivElement>) => void;\n /** Callback when editor loses container focus. */\n onBlur?: (e: React.FocusEvent<HTMLDivElement>) => void;\n}\n\nexport function BoardEditor({\n fen = \"8/8/8/8/8/8/8/8 w - - 0 1\",\n onChange,\n onPieceChange,\n selectedPiece,\n onSelectPiece,\n orientation = \"white\",\n theme = defaultTheme,\n pieces = defaultPieces,\n showCoordinates = false,\n style,\n className,\n ariaLabel = \"Board editor\",\n onAnnounce,\n getSquareAriaLabel,\n focusedSquare: propFocusedSquare,\n onSquareFocus,\n id,\n onClear,\n onSetStartingPosition,\n onToggleSideToMove,\n onFocus,\n onBlur,\n}: BoardEditorProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const liveRegionRef = useRef<HTMLDivElement>(null);\n const liveCounter = useRef(0);\n const [board, setBoard] = useState<Uint8Array>(() => {\n try {\n return parseFenPlacement(fen);\n } catch {\n return new Uint8Array(64);\n }\n });\n\n const [internalFocusedSquare, setInternalFocusedSquare] = useState<SquareIndex>(\n () => (orientation === \"white\" ? 28 : 36) as SquareIndex, // e4 or e5\n );\n const focusedSquare = propFocusedSquare ?? internalFocusedSquare;\n const setFocusedSquare = setInternalFocusedSquare;\n const [hasKeyboardFocus, setHasKeyboardFocus] = useState(false);\n\n // Active dragging state\n const [dragging, setDragging] = useState<{\n origin: SquareIndex;\n cell: BoardCell;\n x: number;\n y: number;\n } | null>(null);\n\n useEffect(() => {\n try {\n const nextBoard = parseFenPlacement(fen);\n setBoard(nextBoard);\n } catch {\n // Keep current board on parse failure\n }\n }, [fen]);\n\n const announce = useCallback(\n (message: string) => {\n onAnnounce?.(message);\n const region = liveRegionRef.current;\n if (region) {\n liveCounter.current++;\n region.setAttribute(\"data-live-id\", String(liveCounter.current));\n region.textContent = \"\";\n void region.offsetHeight;\n region.textContent = message;\n }\n },\n [onAnnounce],\n );\n\n const getSquareDescription = useCallback(\n (square: SquareIndex, cell: BoardCell) => {\n const sq = algebraicOf(square);\n if (getSquareAriaLabel) {\n return getSquareAriaLabel(square, cell, sq);\n }\n return defaultSquareLabel(square, cell);\n },\n [getSquareAriaLabel],\n );\n\n const announceSquare = useCallback(\n (square: SquareIndex) => {\n const cell = (board[square] ?? 0) as BoardCell;\n const desc = getSquareDescription(square, cell);\n announce(desc);\n onSquareFocus?.(square, cell, algebraicOf(square));\n },\n [announce, board, getSquareDescription, onSquareFocus],\n );\n\n const commitBoard = useCallback(\n (nextBoard: Uint8Array) => {\n setBoard(nextBoard);\n const newPlacement = formatFenPlacement(nextBoard);\n const updatedFen = updateFenPlacement(fen, newPlacement);\n onChange?.(updatedFen);\n },\n [fen, onChange],\n );\n\n const placePieceAt = useCallback(\n (square: SquareIndex, cellOrCode: BoardCell | string) => {\n const targetCell =\n typeof cellOrCode === \"string\" ? cellFromPieceString(cellOrCode) : cellOrCode;\n const currentCell = (board[square] ?? 0) as BoardCell;\n const nextBoard = new Uint8Array(board);\n\n if (targetCell !== 0 && currentCell === targetCell) {\n // Toggle off\n nextBoard[square] = 0;\n commitBoard(nextBoard);\n onPieceChange?.(square, 0 as BoardCell, algebraicOf(square));\n announce(`Piece removed from ${algebraicOf(square)}`);\n } else if (targetCell !== 0) {\n nextBoard[square] = targetCell;\n commitBoard(nextBoard);\n onPieceChange?.(square, targetCell, algebraicOf(square));\n const name = pieceNameFromCell(targetCell);\n announce(`${name} placed on ${algebraicOf(square)}`);\n const char = PIECE_CHARS[targetCell] ?? \"\";\n const code = targetCell <= 6 ? `w${char}` : `b${char.toUpperCase()}`;\n onSelectPiece?.(code);\n } else {\n nextBoard[square] = 0;\n commitBoard(nextBoard);\n onPieceChange?.(square, 0 as BoardCell, algebraicOf(square));\n announce(`Piece removed from ${algebraicOf(square)}`);\n }\n },\n [announce, board, commitBoard, onPieceChange, onSelectPiece],\n );\n\n const removePieceAt = useCallback(\n (square: SquareIndex) => {\n const current = board[square] ?? 0;\n if (current === 0) {\n announce(`${algebraicOf(square)} is empty`);\n return;\n }\n const nextBoard = new Uint8Array(board);\n nextBoard[square] = 0;\n commitBoard(nextBoard);\n onPieceChange?.(square, 0 as BoardCell, algebraicOf(square));\n announce(`Piece removed from ${algebraicOf(square)}`);\n },\n [announce, board, commitBoard, onPieceChange],\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.altKey || e.ctrlKey || e.metaKey) return;\n\n // 1. Arrow navigation\n if (e.key.startsWith(\"Arrow\")) {\n if (e.shiftKey) return;\n e.preventDefault();\n const dir =\n e.key === \"ArrowUp\"\n ? \"up\"\n : e.key === \"ArrowDown\"\n ? \"down\"\n : e.key === \"ArrowLeft\"\n ? \"left\"\n : \"right\";\n const next = moveSquare(focusedSquare, dir, orientation);\n setFocusedSquare(next);\n announceSquare(next);\n return;\n }\n\n // 2. Home / End\n if (e.key === \"Home\" || e.key === \"End\") {\n e.preventDefault();\n const next = rankEndSquare(focusedSquare, e.key === \"Home\" ? \"home\" : \"end\", orientation);\n setFocusedSquare(next);\n announceSquare(next);\n return;\n }\n\n // 3. Delete / Backspace\n if (e.key === \"Backspace\" || e.key === \"Delete\" || e.key === \"x\" || e.key === \"X\") {\n e.preventDefault();\n removePieceAt(focusedSquare);\n return;\n }\n\n // 4. Clear board / Set start / Toggle side\n if (e.key === \"c\" || e.key === \"C\") {\n e.preventDefault();\n if (onClear) {\n onClear();\n } else {\n commitBoard(new Uint8Array(64));\n announce(\"Board cleared\");\n }\n return;\n }\n\n if (e.key === \"s\" || e.key === \"S\") {\n e.preventDefault();\n if (onSetStartingPosition) {\n onSetStartingPosition();\n } else {\n commitBoard(parseFenPlacement(STARTING_FEN));\n announce(\"Starting position\");\n }\n return;\n }\n\n if (e.key === \"t\" || e.key === \"T\") {\n e.preventDefault();\n onToggleSideToMove?.();\n return;\n }\n\n // 5. Enter / Space: place selected piece\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (selectedPiece) {\n const piece = e.shiftKey ? getOppositePieceString(selectedPiece) : selectedPiece;\n if (piece) placePieceAt(focusedSquare, piece);\n }\n return;\n }\n\n // 6. Quick piece shortcuts (FEN letters: p, P, n, N, b, B, r, R, q, Q, k, K)\n const pieceCell = cellFromKey(e.key);\n if (pieceCell !== 0) {\n e.preventDefault();\n placePieceAt(focusedSquare, pieceCell);\n }\n },\n [\n announce,\n announceSquare,\n commitBoard,\n focusedSquare,\n onClear,\n onSetStartingPosition,\n onToggleSideToMove,\n orientation,\n placePieceAt,\n removePieceAt,\n selectedPiece,\n ],\n );\n\n // Pointer drag and drop\n const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n if (e.button !== 0) return; // left click only\n const container = containerRef.current;\n if (!container) return;\n\n const sq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (sq === null) return;\n\n container.focus();\n setFocusedSquare(sq);\n onSquareFocus?.(sq, (board[sq] ?? 0) as BoardCell, algebraicOf(sq));\n const cell = (board[sq] ?? 0) as BoardCell;\n\n if (cell === 0) {\n // Empty square clicked: place selected piece\n if (selectedPiece) {\n placePieceAt(sq, selectedPiece);\n }\n return;\n }\n\n // Occupied square: start drag\n e.currentTarget.setPointerCapture(e.pointerId);\n setDragging({\n origin: sq,\n cell,\n x: e.clientX,\n y: e.clientY,\n });\n };\n\n const handlePointerMove = (e: React.PointerEvent<HTMLDivElement>) => {\n if (!dragging) return;\n setDragging((prev) => (prev ? { ...prev, x: e.clientX, y: e.clientY } : null));\n };\n\n const handlePointerUp = (e: React.PointerEvent<HTMLDivElement>) => {\n if (!dragging) return;\n const container = containerRef.current;\n const originSq = dragging.origin;\n const movedCell = dragging.cell;\n setDragging(null);\n\n if (!container) return;\n const targetSq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n\n if (targetSq === null) {\n // Dropped off the board: delete piece\n removePieceAt(originSq);\n return;\n }\n\n if (targetSq === originSq) {\n // Click without drag: place selected piece if palette has one\n if (selectedPiece) {\n placePieceAt(originSq, selectedPiece);\n }\n return;\n }\n\n // Move piece from origin to target\n const nextBoard = new Uint8Array(board);\n nextBoard[originSq] = 0;\n nextBoard[targetSq] = movedCell;\n commitBoard(nextBoard);\n announce(`${pieceNameFromCell(movedCell)} moved to ${algebraicOf(targetSq)}`);\n setFocusedSquare(targetSq);\n };\n\n const handleContextMenu = (e: React.MouseEvent<HTMLDivElement>) => {\n e.preventDefault();\n const container = containerRef.current;\n if (!container) return;\n const sq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (sq === null) return;\n\n setFocusedSquare(sq);\n if (selectedPiece) {\n const opp = getOppositePieceString(selectedPiece);\n if (opp) placePieceAt(sq, opp);\n }\n };\n\n // Build 64 squares visually\n const squareOrder = useMemo(() => {\n const squares: SquareIndex[] = [];\n if (orientation === \"white\") {\n for (let rank = 7; rank >= 0; rank--) {\n for (let file = 0; file < 8; file++) {\n squares.push((rank * 8 + file) as SquareIndex);\n }\n }\n } else {\n for (let rank = 0; rank < 8; rank++) {\n for (let file = 7; file >= 0; file--) {\n squares.push((rank * 8 + file) as SquareIndex);\n }\n }\n }\n return squares;\n }, [orientation]);\n\n const containerStyle: CSSProperties = {\n position: \"relative\",\n aspectRatio: \"1 / 1\",\n width: \"100%\",\n touchAction: \"none\",\n outline: hasKeyboardFocus ? \"3px solid var(--gb-editor-focus, #d97706)\" : \"none\",\n outlineOffset: \"2px\",\n borderRadius: \"8px\",\n ...(theme as CSSProperties),\n ...style,\n };\n\n return (\n <div\n ref={containerRef}\n id={id}\n role=\"application\"\n // biome-ignore lint/a11y/noNoninteractiveTabindex: role=\"application\" container owns keyboard focus\n tabIndex={0}\n aria-label={ariaLabel}\n aria-keyshortcuts=\"ArrowUp ArrowDown ArrowLeft ArrowRight Enter Space Backspace Delete p P n N b B r R q Q k K c C s S t T\"\n onKeyDown={handleKeyDown}\n onFocus={(e) => {\n if (e.target === e.currentTarget) {\n setHasKeyboardFocus(true);\n announceSquare(focusedSquare);\n }\n onFocus?.(e);\n }}\n onBlur={(e) => {\n if (e.target === e.currentTarget) {\n setHasKeyboardFocus(false);\n }\n onBlur?.(e);\n }}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={() => setDragging(null)}\n onContextMenu={handleContextMenu}\n className={className}\n style={containerStyle}\n data-gb-editor=\"true\"\n data-gb-orientation={orientation}\n >\n {/* 8x8 Board Grid */}\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"grid\",\n gridTemplateColumns: \"repeat(8, 1fr)\",\n gridTemplateRows: \"repeat(8, 1fr)\",\n pointerEvents: \"none\",\n }}\n >\n {squareOrder.map((sq) => {\n const file = sq & 7;\n const rank = sq >> 3;\n const isLight = ((file + rank) & 1) !== 0;\n const isFocused = hasKeyboardFocus && focusedSquare === sq;\n\n return (\n <div\n key={sq}\n data-square={algebraicOf(sq)}\n style={{\n position: \"relative\",\n backgroundColor: `var(${isLight ? CSS_VARS.SQ_LIGHT : CSS_VARS.SQ_DARK})`,\n backgroundImage: `var(${isLight ? CSS_VARS.SQ_LIGHT_IMAGE : CSS_VARS.SQ_DARK_IMAGE},none)`,\n backgroundSize: `var(${CSS_VARS.SQ_IMAGE_SIZE},cover)`,\n boxShadow: isFocused ? \"inset 0 0 0 3px rgba(255, 206, 76, 0.95)\" : undefined,\n userSelect: \"none\",\n }}\n />\n );\n })}\n </div>\n\n {/* Piece Layer */}\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"grid\",\n gridTemplateColumns: \"repeat(8, 1fr)\",\n gridTemplateRows: \"repeat(8, 1fr)\",\n pointerEvents: \"none\",\n }}\n >\n {squareOrder.map((sq) => {\n const cell = (board[sq] ?? 0) as BoardCell;\n if (cell === 0) return null;\n const isOrigin = dragging?.origin === sq;\n const { col, row } = gridCoord(sq, orientation);\n\n return (\n <div\n key={sq}\n data-piece-square={algebraicOf(sq)}\n style={{\n ...SLOT_BASE_STYLE,\n gridColumnStart: col,\n gridRowStart: row,\n opacity: isOrigin ? 0.25 : 1,\n filter: `var(${cell <= 6 ? CSS_VARS.PIECE_FILTER_WHITE : CSS_VARS.PIECE_FILTER_BLACK}, none)`,\n pointerEvents: \"none\",\n }}\n >\n {pieces({ cell, square: sq })}\n </div>\n );\n })}\n </div>\n\n {/* Visual square focus indicator for keyboard/active navigation (sighted users) */}\n {hasKeyboardFocus && (\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"grid\",\n gridTemplateColumns: \"repeat(8, 1fr)\",\n gridTemplateRows: \"repeat(8, 1fr)\",\n pointerEvents: \"none\",\n zIndex: 10,\n }}\n >\n {(() => {\n const { col, row } = gridCoord(focusedSquare, orientation);\n return (\n <div\n data-gb-editor-focus-square={algebraicOf(focusedSquare)}\n style={{\n gridColumnStart: col,\n gridRowStart: row,\n outline: \"3px solid var(--gb-editor-sq-focus, #f59e0b)\",\n outlineOffset: \"-3px\",\n boxShadow:\n \"inset 0 0 0 1.5px rgba(0, 0, 0, 0.75), 0 0 8px rgba(245, 158, 11, 0.7)\",\n borderRadius: \"2px\",\n pointerEvents: \"none\",\n }}\n />\n );\n })()}\n </div>\n )}\n\n {/* Dragging Piece Floating Overlay */}\n {dragging && containerRef.current ? (\n <div\n aria-hidden=\"true\"\n style={{\n position: \"fixed\",\n left: dragging.x - 30,\n top: dragging.y - 30,\n width: 60,\n height: 60,\n pointerEvents: \"none\",\n zIndex: 100,\n filter: `var(${dragging.cell <= 6 ? CSS_VARS.PIECE_FILTER_WHITE : CSS_VARS.PIECE_FILTER_BLACK}, none)`,\n }}\n >\n {pieces({ cell: dragging.cell, square: dragging.origin })}\n </div>\n ) : null}\n\n {/* Coordinates */}\n {showCoordinates ? <Coordinates orientation={orientation} /> : null}\n\n {/* Accessible Live Region */}\n <div\n ref={liveRegionRef}\n role=\"status\"\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n style={{\n position: \"absolute\",\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\",\n border: 0,\n }}\n />\n </div>\n );\n}\n","\"use client\";\n\n/**\n * Canvas-2D arrow overlay with optional SVG decorations.\n *\n * Renders every committed arrow from `snapshot.arrows` (optionally\n * filtered by the `below` flag) plus an in-flight preview arrow the\n * user is currently dragging. The preview is owned by\n * `useArrowGesture` via a ref; this component only exposes redraw\n * hooks and lets the gesture hook invalidate the canvas imperatively.\n *\n * ### Two-layer instantiation\n *\n * The board mounts `<ArrowsLayer below/>` before the piece layer and\n * `<ArrowsLayer/>` (above, default) after. Each instance filters its\n * arrows by the `below` flag; the `above` instance also renders the\n * active preview. No z-index juggling: pieces paint between them by\n * DOM order.\n *\n * ### Why Canvas instead of SVG\n *\n * SVG forces a React reconcile per arrow-set change (one React element\n * per arrow). During a right-click drag the preview arrow moves with\n * the pointer — an SVG approach would re-render on every pointermove.\n * A single `<canvas>` with an imperative redraw costs one React commit\n * per arrow-set mutation and zero React renders per drag frame.\n *\n * ### SVG child overlay for labels and customSvg\n *\n * `label` and `customSvg` require DOM, not a 2D context. When the\n * current arrow set contains at least one of either, the component\n * renders a sibling `<svg>` on top of the canvas. When the set has\n * none, the `<svg>` is not rendered at all — zero cost for plain\n * arrow boards.\n *\n * ### HiDPI handling\n *\n * `canvas.width`/`height` are set to `CSS pixels * devicePixelRatio`\n * so strokes stay crisp on retina displays. A `ResizeObserver`\n * re-provisions the backing store whenever the board resizes.\n *\n * ### Arrow drawing\n *\n * A normal move uses a straight shaft from the source-square centre to\n * the target square. A knight move uses a bent, Russian Г-shaped shaft:\n * first along the two-square axis, then along the one-square axis. In\n * both cases the shaft stops at the arrowhead base so translucent\n * arrows do not darken where the shaft and head meet. `from === to` is\n * a special case: rendered as a stroked circle at the centre of the\n * square — the convention the right-click gesture uses for \"mark this\n * square\".\n */\n\nimport {\n forwardRef,\n memo,\n type ReactElement,\n type RefObject,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport type { Arrow, ArrowHeadStyle, BoardModel } from \"../core/index.js\";\nimport { useBoardSlice } from \"../hooks/use-board-subscription.js\";\nimport type { Orientation, ResolvedArrowPalette } from \"../types.js\";\n\n/** Shape rendered mid-gesture, before the user releases the button. */\nexport interface PreviewArrow {\n readonly from: number;\n readonly to: number;\n readonly color: string;\n}\n\n/** Imperative API exposed by `<ArrowsLayer/>` to `useArrowGesture`. */\nexport interface ArrowsLayerHandle {\n /** Update the preview arrow (null to clear) and redraw. */\n setPreview(preview: PreviewArrow | null): void;\n}\n\n/** Props for {@link ArrowsLayer}. */\nexport interface ArrowsLayerProps {\n readonly model: BoardModel;\n readonly orientation: Orientation;\n /**\n * Optional palette resolving arrow `brush` keys to CSS colours. When\n * an arrow carries both `color` and `brush`, the brush wins if the\n * key is present in the palette; otherwise `color` is used as-is.\n */\n readonly palette?: ResolvedArrowPalette;\n /**\n * When `true`, only arrows with `below: true` are rendered and the\n * preview is suppressed — this is the \"beneath pieces\" layer.\n * Default `false` (the top layer).\n */\n readonly below?: boolean;\n}\n\n/* ============================================================ geometry */\n\n/** Square-index → (centreX%, centreY%) in board-local coordinates. */\nfunction squareCentrePct(index: number, orientation: Orientation): { cx: number; cy: number } {\n const file = index & 7;\n const rank = index >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n return { cx: col * 12.5 + 6.25, cy: row * 12.5 + 6.25 };\n}\n\n/** A point in board-local CSS-pixel coordinates. */\ninterface Point {\n readonly x: number;\n readonly y: number;\n}\n\n/** Geometry needed to paint a shaft and head without translucent self-overlap. */\ninterface ArrowPath {\n readonly start: Point;\n readonly corner: Point | null;\n readonly shaftEnd: Point;\n readonly tip: Point;\n readonly finalUnit: Point;\n}\n\n/** Does the square pair describe a knight's L-shaped move? */\nfunction isKnightMove(fromIndex: number, toIndex: number): boolean {\n const fileDelta = Math.abs((toIndex & 7) - (fromIndex & 7));\n const rankDelta = Math.abs((toIndex >> 3) - (fromIndex >> 3));\n return (fileDelta === 1 && rankDelta === 2) || (fileDelta === 2 && rankDelta === 1);\n}\n\nfunction unitVector(from: Point, to: Point): Point | null {\n const dx = to.x - from.x;\n const dy = to.y - from.y;\n const len = Math.hypot(dx, dy);\n if (len === 0) return null;\n return { x: dx / len, y: dy / len };\n}\n\nfunction arrowPath(\n fromIndex: number,\n toIndex: number,\n start: Point,\n end: Point,\n startOffset: number,\n tipOffset: number,\n headLength: number,\n): ArrowPath | null {\n if (!isKnightMove(fromIndex, toIndex)) {\n const unit = unitVector(start, end);\n if (unit === null) return null;\n const tip = { x: end.x - unit.x * tipOffset, y: end.y - unit.y * tipOffset };\n return {\n start: { x: start.x + unit.x * startOffset, y: start.y + unit.y * startOffset },\n corner: null,\n shaftEnd: { x: tip.x - unit.x * headLength, y: tip.y - unit.y * headLength },\n tip,\n finalUnit: unit,\n };\n }\n\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const corner = Math.abs(dx) > Math.abs(dy) ? { x: end.x, y: start.y } : { x: start.x, y: end.y };\n const firstUnit = unitVector(start, corner);\n const finalUnit = unitVector(corner, end);\n if (firstUnit === null || finalUnit === null) return null;\n\n const tip = { x: end.x - finalUnit.x * tipOffset, y: end.y - finalUnit.y * tipOffset };\n return {\n start: { x: start.x + firstUnit.x * startOffset, y: start.y + firstUnit.y * startOffset },\n corner,\n shaftEnd: { x: tip.x - finalUnit.x * headLength, y: tip.y - finalUnit.y * headLength },\n tip,\n finalUnit,\n };\n}\n\n/* ======================================================= draw primitives */\n\n/** Resolve the final colour for an arrow given an optional palette. */\nfunction resolveColor(arrow: Arrow, palette: ResolvedArrowPalette | undefined): string {\n if (arrow.brush !== undefined && palette !== undefined) {\n const brushed = palette[arrow.brush];\n if (brushed !== undefined) return brushed;\n }\n return arrow.color;\n}\n\n/** Draw a standard arrow (or same-square circle) onto the canvas. */\nfunction drawArrow(\n ctx: CanvasRenderingContext2D,\n fromIndex: number,\n toIndex: number,\n color: string,\n sqSize: number,\n orientation: Orientation,\n preview: boolean,\n): void {\n const a = squareCentrePct(fromIndex, orientation);\n const b = squareCentrePct(toIndex, orientation);\n const boardSize = sqSize * 8;\n const start = { x: (a.cx / 100) * boardSize, y: (a.cy / 100) * boardSize };\n const end = { x: (b.cx / 100) * boardSize, y: (b.cy / 100) * boardSize };\n\n if (fromIndex === toIndex) {\n ctx.strokeStyle = color;\n ctx.lineWidth = sqSize * 0.08;\n ctx.globalAlpha = preview ? 0.65 : 1;\n ctx.beginPath();\n ctx.arc(start.x, start.y, sqSize * 0.44, 0, Math.PI * 2);\n ctx.stroke();\n ctx.globalAlpha = 1;\n return;\n }\n\n const startOffset = sqSize * 0.28;\n const tipOffset = sqSize * 0.08;\n const headLength = sqSize * 0.36;\n const headHalfWidth = sqSize * 0.28;\n const shaftWidth = sqSize * 0.18;\n const path = arrowPath(fromIndex, toIndex, start, end, startOffset, tipOffset, headLength);\n if (path === null) return;\n\n ctx.globalAlpha = preview ? 0.65 : 1;\n ctx.strokeStyle = color;\n ctx.lineWidth = shaftWidth;\n ctx.lineCap = \"butt\";\n ctx.lineJoin = \"round\";\n ctx.beginPath();\n ctx.moveTo(path.start.x, path.start.y);\n if (path.corner !== null) ctx.lineTo(path.corner.x, path.corner.y);\n ctx.lineTo(path.shaftEnd.x, path.shaftEnd.y);\n ctx.stroke();\n\n const perpX = -path.finalUnit.y;\n const perpY = path.finalUnit.x;\n ctx.fillStyle = color;\n ctx.beginPath();\n ctx.moveTo(path.tip.x, path.tip.y);\n ctx.lineTo(path.shaftEnd.x + perpX * headHalfWidth, path.shaftEnd.y + perpY * headHalfWidth);\n ctx.lineTo(path.shaftEnd.x - perpX * headHalfWidth, path.shaftEnd.y - perpY * headHalfWidth);\n ctx.closePath();\n ctx.fill();\n ctx.globalAlpha = 1;\n}\n\n/** Redraw the full arrow set + preview onto the canvas. */\nfunction redraw(\n canvas: HTMLCanvasElement,\n arrows: readonly Arrow[],\n preview: PreviewArrow | null,\n orientation: Orientation,\n palette: ResolvedArrowPalette | undefined,\n): void {\n const ctx = canvas.getContext(\"2d\");\n if (ctx === null) return;\n const dpr = typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1;\n const rect = canvas.getBoundingClientRect();\n const cssWidth = rect.width;\n const cssHeight = rect.height;\n if (cssWidth <= 0 || cssHeight <= 0) return;\n\n const backingWidth = Math.round(cssWidth * dpr);\n const backingHeight = Math.round(cssHeight * dpr);\n if (canvas.width !== backingWidth) canvas.width = backingWidth;\n if (canvas.height !== backingHeight) canvas.height = backingHeight;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.clearRect(0, 0, cssWidth, cssHeight);\n\n const sqSize = cssWidth / 8;\n for (const arrow of arrows) {\n if (arrow.label?.background !== undefined) continue;\n drawArrow(ctx, arrow.from, arrow.to, resolveColor(arrow, palette), sqSize, orientation, false);\n }\n if (preview !== null) {\n drawArrow(ctx, preview.from, preview.to, preview.color, sqSize, orientation, true);\n }\n}\n\n/* ====================================================== decorations */\n\n/** ViewBox span (0..100) for the SVG decoration overlay. */\n/**\n * Anchor-point for label/customSvg rendering, returned in viewport\n * percent (0..100) so the SVG overlay can position nodes without a\n * second `getBoundingClientRect` call.\n */\nfunction anchorPct(\n from: number,\n to: number,\n orientation: Orientation,\n center: \"orig\" | \"dest\" | \"label\",\n): { cx: number; cy: number } {\n const a = squareCentrePct(from, orientation);\n const b = squareCentrePct(to, orientation);\n if (center === \"orig\") return a;\n if (center === \"dest\") return b;\n return { cx: (a.cx + b.cx) / 2, cy: (a.cy + b.cy) / 2 };\n}\n\n/** Geometry needed to paint an aerodynamic pointing head with integrated text. */\nexport interface AeroHeadGeometry {\n readonly path: string;\n readonly tipLen: number;\n readonly dockLen: number;\n readonly frontLen: number;\n readonly cabinW: number;\n}\n\n/**\n * Compute aerodynamic arrowhead geometry with dynamic rectangular auto-centering:\n * - The evaluation text is mathematically 100% centered at (0, 0).\n * - The rectangular cabin extends dynamically from -cabinW to +cabinW based on text length.\n * - The forward nose taper begins strictly AFTER +cabinW, so outer digits like `+32.3` or `#18`\n * never clip or cramp into the beveled nose cone!\n */\nexport function computeDynamicAeroGeometry(\n text: string | undefined,\n style: ArrowHeadStyle | undefined,\n fontSize: number,\n isTerminal = true,\n): AeroHeadGeometry {\n const resolvedStyle = style ?? \"aero_chisel\";\n const hasText = Boolean(text && text.trim().length > 0);\n\n if (!hasText) {\n // Sculpted Aero-Sharp pointer: compact, athletic chisel arrowhead\n // for non-evaluation moves, idle engine states, and user-drawn arrows.\n // Total length: 4.6u at 2.45u baseline, scaling with fontSize when provided.\n const scale = Math.max(1, fontSize / 2.45);\n const tipX = 2.8 * scale;\n const shoulderX = 0.2 * scale;\n const rearX = -1.2 * scale;\n const dockX = -1.8 * scale;\n const halfH = 2.2 * scale;\n const path = `M ${rearX},${-halfH} L ${shoulderX},${-halfH} L ${tipX},0 L ${shoulderX},${halfH} L ${rearX},${halfH} C ${dockX},${halfH} ${dockX},${-halfH} ${rearX},${-halfH} Z`;\n return {\n path,\n tipLen: tipX,\n dockLen: -dockX,\n frontLen: tipX,\n cabinW: 0,\n };\n }\n\n const charWidth = fontSize * 0.6;\n const textWidth = text!.length * charWidth;\n const halfTextW = textWidth / 2;\n\n const scale = Math.max(1, fontSize / 2.45);\n // Equal padding around the text (0.75 at baseline, scaling with fontSize)\n const padX = 0.75 * scale;\n const cabinW = Math.max(3.2 * scale, halfTextW + padX);\n const halfH = Math.max(2.3, fontSize * 0.9);\n\n // Scaled rear dock socket\n const rearInset = 0.65 * scale;\n const dockX = -cabinW - rearInset;\n\n let frontLen = 0;\n let path = \"\";\n\n if (resolvedStyle === \"aero_chisel\") {\n if (isTerminal) {\n // Modern 60° beveled chisel nose closing forward (1.25 at baseline, scaling with fontSize)\n const noseLead = 1.25 * scale;\n const tipX = cabinW + noseLead;\n frontLen = tipX;\n path = `M ${-cabinW},${-halfH} L ${cabinW},${-halfH} L ${tipX},0 L ${cabinW},${halfH} L ${-cabinW},${halfH} C ${dockX},${halfH} ${dockX},${-halfH} ${-cabinW},${-halfH} Z`;\n } else {\n frontLen = cabinW + rearInset;\n path = `M ${-cabinW},${-halfH} L ${cabinW},${-halfH} C ${frontLen},${-halfH} ${frontLen},${halfH} ${cabinW},${halfH} L ${-cabinW},${halfH} C ${dockX},${halfH} ${dockX},${-halfH} ${-cabinW},${-halfH} Z`;\n }\n } else if (resolvedStyle === \"chamfer_arrow\") {\n if (isTerminal) {\n const tipX = cabinW + 1.4;\n frontLen = tipX;\n path = `M ${-cabinW},-1.2 L ${-cabinW + 1.2},${-halfH} L ${cabinW},${-halfH} L ${tipX},0 L ${cabinW},${halfH} L ${-cabinW + 1.2},${halfH} L ${-cabinW},1.2 Z`;\n } else {\n frontLen = cabinW + 0.8;\n path = `M ${-cabinW},-1.2 L ${-cabinW + 1.2},${-halfH} L ${cabinW - 1.2},${-halfH} L ${cabinW},-1.2 L ${cabinW},1.2 L ${cabinW - 1.2},${halfH} L ${-cabinW + 1.2},${halfH} L ${-cabinW},1.2 Z`;\n }\n } else if (resolvedStyle === \"blunt_wedge\") {\n if (isTerminal) {\n const tipX = cabinW + 1.1;\n frontLen = tipX;\n path = `M ${-cabinW},${-halfH} L ${cabinW},${-halfH} L ${tipX},${-halfH * 0.35} L ${tipX},${halfH * 0.35} L ${cabinW},${halfH} L ${-cabinW},${halfH} C ${dockX},${halfH} ${dockX},${-halfH} ${-cabinW},${-halfH} Z`;\n } else {\n frontLen = cabinW + rearInset;\n path = `M ${-cabinW},${-halfH} L ${cabinW},${-halfH} C ${frontLen},${-halfH} ${frontLen},${halfH} ${cabinW},${halfH} L ${-cabinW},${halfH} C ${dockX},${halfH} ${dockX},${-halfH} ${-cabinW},${-halfH} Z`;\n }\n } else if (resolvedStyle === \"stealth\") {\n const wingBack = cabinW + 2.3;\n const wingY = halfH + 0.35;\n const shoulderX = cabinW * 0.35;\n const tipX = cabinW + 3.6;\n frontLen = tipX;\n path = `M ${dockX.toFixed(2)},0 L ${(-wingBack).toFixed(2)},${(-wingY).toFixed(2)} L ${(-cabinW).toFixed(2)},${(-halfH).toFixed(2)} L ${shoulderX.toFixed(2)},${(-halfH).toFixed(2)} L ${tipX.toFixed(2)},0 L ${shoulderX.toFixed(2)},${halfH.toFixed(2)} L ${(-cabinW).toFixed(2)},${halfH.toFixed(2)} L ${(-wingBack).toFixed(2)},${wingY.toFixed(2)} Z`;\n } else {\n const noseLead = 1.25;\n const tipX = cabinW + noseLead;\n frontLen = tipX;\n path = `M ${-cabinW},${-halfH} L ${cabinW},${-halfH} L ${tipX},0 L ${cabinW},${halfH} L ${-cabinW},${halfH} C ${dockX},${halfH} ${dockX},${-halfH} ${-cabinW},${-halfH} Z`;\n }\n\n return {\n path,\n tipLen: frontLen,\n dockLen: -dockX,\n frontLen,\n cabinW,\n };\n}\n\n/**\n * Select the optimal Russian Г-shape corner for knight moves to avoid collisions\n * with friendly pawns and co-linear arrows along the file/rank.\n */\nfunction chooseKnightCorner(\n fromIndex: number,\n toIndex: number,\n allArrows: readonly Arrow[],\n orientation: Orientation,\n): Point {\n const a = squareCentrePct(fromIndex, orientation);\n const b = squareCentrePct(toIndex, orientation);\n\n const dx = b.cx - a.cx;\n const dy = b.cy - a.cy;\n\n // Candidate 1: step along rank to toIndex's file, then along file to toIndex (b.cx, a.cy)\n const corner1 = { x: b.cx, y: a.cy };\n\n // Candidate 2: step along file to toIndex's rank, then along rank to toIndex (a.cx, b.cy)\n const corner2 = { x: a.cx, y: b.cy };\n\n // If another arrow shares the origin file (e.g. pawn on g7 moving while knight on g8 moves),\n // step off the file immediately (corner1) so the knight path does not collide with the pawn ray!\n const fromFile = fromIndex & 7;\n const hasColinearArrowOnFile = allArrows.some(\n (other) => other.from !== fromIndex && (other.from & 7) === fromFile,\n );\n\n if (hasColinearArrowOnFile) {\n return corner1;\n }\n\n return Math.abs(dx) > Math.abs(dy) ? corner1 : corner2;\n}\n\n/** Compute flight vectors, pointing clearance, and cabin geometry for integrated eval arrows. */\nfunction computeIntegratedArrowVectors(\n arrow: Arrow,\n orientation: Orientation,\n allArrows: readonly Arrow[],\n) {\n const label = arrow.label;\n if (!label || label.background === undefined) return null;\n\n const a = squareCentrePct(arrow.from, orientation);\n const b = squareCentrePct(arrow.to, orientation);\n if (arrow.from === arrow.to) return null;\n\n const isKnight = isKnightMove(arrow.from, arrow.to);\n const fontSize = label.fontSize ?? 2.45;\n const geom = computeDynamicAeroGeometry(label.text, label.headStyle, fontSize, true);\n\n let startUnit: Point | null;\n let finalUnit: Point | null;\n let corner: Point | null = null;\n\n if (!isKnight) {\n const u = unitVector({ x: a.cx, y: a.cy }, { x: b.cx, y: b.cy });\n if (u === null) return null;\n startUnit = u;\n finalUnit = u;\n } else {\n corner = chooseKnightCorner(arrow.from, arrow.to, allArrows, orientation);\n startUnit = unitVector({ x: a.cx, y: a.cy }, corner);\n finalUnit = unitVector(corner, { x: b.cx, y: b.cy });\n if (startUnit === null || finalUnit === null) return null;\n }\n\n // Pointing clearance: leaves >= 1/3 of destination square (4.17%) open after the arrow tip\n // In 100x100 coordinates with 12.5% squares, center + 2.08% stops 4.17% before far edge\n const tip = {\n x: b.cx + finalUnit.x * 2.08,\n y: b.cy + finalUnit.y * 2.08,\n };\n\n const headCenter = {\n x: tip.x - finalUnit.x * geom.frontLen,\n y: tip.y - finalUnit.y * geom.frontLen,\n };\n\n const shaftEnd = {\n x: headCenter.x - finalUnit.x * geom.dockLen,\n y: headCenter.y - finalUnit.y * geom.dockLen,\n };\n\n const dist = Math.hypot(b.cx - a.cx, b.cy - a.cy);\n const startOffset = dist < 18 ? 0.5 : 2.4;\n const shaftStart = {\n x: a.cx + startUnit.x * startOffset,\n y: a.cy + startUnit.y * startOffset,\n };\n\n const angleRad = Math.atan2(finalUnit.y, finalUnit.x);\n const angleDeg = (angleRad * 180) / Math.PI;\n\n let textRot = 0;\n const rotMode = label.textRotation ?? \"auto\";\n if (rotMode === \"flat\") {\n textRot = -angleDeg;\n } else if (rotMode === \"auto\") {\n const norm = ((angleDeg % 360) + 360) % 360;\n if (norm > 90 && norm < 270) {\n textRot = 180;\n }\n }\n\n const shaftD =\n corner !== null\n ? `M ${shaftStart.x} ${shaftStart.y} L ${corner.x} ${corner.y} L ${shaftEnd.x} ${shaftEnd.y}`\n : `M ${shaftStart.x} ${shaftStart.y} L ${shaftEnd.x} ${shaftEnd.y}`;\n\n const shaftLen =\n (shaftEnd.x - shaftStart.x) * startUnit.x + (shaftEnd.y - shaftStart.y) * startUnit.y;\n const showShaft = isKnight || shaftLen > 0.2;\n\n return {\n label,\n fontSize,\n geom,\n headCenter,\n shaftD,\n showShaft,\n angleDeg,\n textRot,\n };\n}\n\n/** Render the shaft of an integrated arrow (with trench casing and contact shadow). */\nfunction renderIntegratedShaft(\n arrow: Arrow,\n color: string,\n orientation: Orientation,\n key: string,\n allArrows: readonly Arrow[],\n): ReactElement | null {\n const v = computeIntegratedArrowVectors(arrow, orientation, allArrows);\n if (v === null || !v.showShaft) return null;\n\n const is3d = v.label.style3d !== false;\n const filterId = is3d ? \"url(#gb-apple-elevation)\" : \"url(#gb-arrow-shadow)\";\n\n return (\n <g key={`${key}-shaft`} filter={filterId}>\n {/* Trench casing under-stroke */}\n <path\n d={v.shaftD}\n fill=\"none\"\n stroke={is3d ? \"rgba(44, 27, 20, 0.75)\" : color}\n strokeWidth={is3d ? \"3.2\" : \"2.2\"}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n {/* Core stroke */}\n <path\n d={v.shaftD}\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2.1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n {/* 3D highlight micro-spine */}\n {is3d && (\n <path\n d={v.shaftD}\n fill=\"none\"\n stroke=\"rgba(255, 255, 255, 0.3)\"\n strokeWidth=\"0.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n )}\n </g>\n );\n}\n\n/** Render the Aero-Chisel arrowhead pod with dynamic centered numerical evaluation. */\nfunction renderIntegratedHead(\n arrow: Arrow,\n _color: string,\n orientation: Orientation,\n key: string,\n allArrows: readonly Arrow[],\n): ReactElement | null {\n const v = computeIntegratedArrowVectors(arrow, orientation, allArrows);\n if (v === null) return null;\n\n const is3d = v.label.style3d !== false;\n const filterId = is3d ? \"url(#gb-apple-elevation)\" : \"url(#gb-arrow-shadow)\";\n const headFill =\n v.label.background === \"#F59E0B\" && is3d ? \"url(#gb-apple-amber-grad)\" : v.label.background;\n const headStroke = v.label.borderColor ?? \"#78350F\";\n\n return (\n <g key={`${key}-head`} filter={filterId}>\n <g transform={`translate(${v.headCenter.x}, ${v.headCenter.y}) rotate(${v.angleDeg})`}>\n <path\n d={v.geom.path}\n fill={headFill}\n stroke={headStroke}\n strokeWidth=\"0.7\"\n strokeLinejoin=\"round\"\n />\n {Boolean(v.label.text && v.label.text.trim().length > 0) && (\n <text\n x={0}\n y={0}\n transform={v.textRot !== 0 ? `rotate(${v.textRot})` : undefined}\n fill={v.label.fill ?? \"#000000\"}\n fontSize={v.fontSize}\n fontWeight=\"800\"\n fontFamily=\"'JetBrains Mono', ui-monospace, monospace\"\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n style={{ userSelect: \"none\" }}\n >\n {v.label.text}\n </text>\n )}\n </g>\n </g>\n );\n}\n\n/* ====================================================== component */\n\nexport const ArrowsLayer = memo(\n forwardRef<ArrowsLayerHandle, ArrowsLayerProps>(function ArrowsLayer(\n { model, orientation, palette, below = false },\n handle,\n ) {\n const canvasRef = useRef<HTMLCanvasElement | null>(null);\n const previewRef = useRef<PreviewArrow | null>(null);\n const allArrows = useBoardSlice(model, (s) => s.arrows);\n\n // Filter by the `below` flag. A fresh reference is produced only\n // when the subset changes — preserves `useLayoutEffect` dep\n // stability across renders that don't affect this layer.\n const arrows = useMemo(\n () => allArrows.filter((a) => (a.below === true) === below),\n [allArrows, below],\n );\n\n // Does any arrow in this subset carry a label/customSvg? If not,\n // the SVG overlay isn't rendered at all — zero cost for the common\n // \"plain arrows only\" case.\n const hasDecorations = useMemo(\n () => arrows.some((a) => a.label !== undefined || a.customSvg !== undefined),\n [arrows],\n );\n\n // Preview is owned by the top layer only; the below layer ignores\n // gesture previews (drawings always land on top during creation).\n useImperativeHandle(\n handle,\n () => ({\n setPreview(preview: PreviewArrow | null): void {\n if (below) return;\n previewRef.current = preview;\n const canvas = canvasRef.current;\n if (canvas !== null) redraw(canvas, arrows, preview, orientation, palette);\n },\n }),\n [arrows, orientation, palette, below],\n );\n\n useLayoutEffect(() => {\n const canvas = canvasRef.current;\n if (canvas === null) return;\n redraw(canvas, arrows, previewRef.current, orientation, palette);\n }, [arrows, orientation, palette]);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (canvas === null) return;\n const parent = canvas.parentElement;\n if (parent === null || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(() => {\n redraw(canvas, arrows, previewRef.current, orientation, palette);\n });\n observer.observe(parent);\n return () => observer.disconnect();\n }, [arrows, orientation, palette]);\n\n const layerZIndex = below ? undefined : 15;\n\n return (\n <>\n <canvas\n ref={canvasRef}\n data-layer={below ? \"arrows-below\" : \"arrows\"}\n style={{\n position: \"absolute\",\n inset: 0,\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n ...(layerZIndex !== undefined ? { zIndex: layerZIndex } : {}),\n }}\n />\n {hasDecorations ? (\n <svg\n data-layer={below ? \"arrows-below-decor\" : \"arrows-decor\"}\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n // Decorations share the z-plane of the canvas they annotate.\n ...(layerZIndex !== undefined ? { zIndex: layerZIndex } : {}),\n }}\n >\n <defs>\n <filter\n id=\"gb-arrow-shadow\"\n filterUnits=\"userSpaceOnUse\"\n x=\"-20\"\n y=\"-20\"\n width=\"140\"\n height=\"140\"\n >\n <feDropShadow\n dx=\"0\"\n dy=\"1.2\"\n stdDeviation=\"1.2\"\n floodColor=\"#000000\"\n floodOpacity=\"0.55\"\n />\n </filter>\n <filter\n id=\"gb-apple-elevation\"\n filterUnits=\"userSpaceOnUse\"\n x=\"-20\"\n y=\"-20\"\n width=\"140\"\n height=\"140\"\n >\n <feDropShadow\n dx=\"0\"\n dy=\"2.8\"\n stdDeviation=\"2.2\"\n floodColor=\"#000000\"\n floodOpacity=\"0.4\"\n />\n <feDropShadow\n dx=\"0\"\n dy=\"1.0\"\n stdDeviation=\"0.7\"\n floodColor=\"#000000\"\n floodOpacity=\"0.6\"\n />\n </filter>\n <linearGradient id=\"gb-apple-amber-grad\" x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#FBBF24\" stopOpacity=\"1\" />\n <stop offset=\"60%\" stopColor=\"#F59E0B\" stopOpacity=\"1\" />\n <stop offset=\"100%\" stopColor=\"#D97706\" stopOpacity=\"1\" />\n </linearGradient>\n </defs>\n {/* Pass 1: Integrated arrow shafts (rendered before heads for Dual Aero overlap) */}\n {arrows.map((arrow) => {\n if (arrow.label?.background === undefined) return null;\n const key = `${arrow.from}-${arrow.to}-${arrow.color}-${arrow.brush ?? \"\"}`;\n const color = resolveColor(arrow, palette);\n return renderIntegratedShaft(arrow, color, orientation, key, arrows);\n })}\n {/* Pass 2: Integrated arrow pointing heads */}\n {arrows.map((arrow) => {\n if (arrow.label?.background === undefined) return null;\n const key = `${arrow.from}-${arrow.to}-${arrow.color}-${arrow.brush ?? \"\"}`;\n const color = resolveColor(arrow, palette);\n return renderIntegratedHead(arrow, color, orientation, key, arrows);\n })}\n {/* Pass 3: Non-integrated labels and customSvg */}\n {arrows.map((arrow) => {\n if (arrow.label?.background !== undefined) return null;\n const key = `${arrow.from}-${arrow.to}-${arrow.color}-${arrow.brush ?? \"\"}`;\n const color = resolveColor(arrow, palette);\n const nodes: ReactElement[] = [];\n if (arrow.label !== undefined) {\n const { cx, cy } = anchorPct(arrow.from, arrow.to, orientation, \"label\");\n nodes.push(\n <text\n key={`${key}-label`}\n x={cx}\n y={cy}\n fill={arrow.label.fill ?? color}\n fontSize=\"4\"\n fontWeight=\"700\"\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n style={{ userSelect: \"none\" }}\n >\n {arrow.label.text}\n </text>,\n );\n }\n if (arrow.customSvg !== undefined) {\n const { cx, cy } = anchorPct(\n arrow.from,\n arrow.to,\n orientation,\n arrow.customSvg.center ?? \"dest\",\n );\n nodes.push(\n <g\n key={`${key}-svg`}\n transform={`translate(${cx}, ${cy})`}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted consumer-supplied SVG\n dangerouslySetInnerHTML={{ __html: arrow.customSvg.html }}\n />,\n );\n }\n return nodes.length === 0 ? null : <g key={key}>{nodes}</g>;\n })}\n </svg>\n ) : null}\n </>\n );\n }),\n);\n\n/** Utility for external hooks: the singleton reference shape. */\nexport type ArrowsLayerRef = RefObject<ArrowsLayerHandle | null>;\n","\"use client\";\n\n/**\n * A single static board square.\n *\n * Static in content — dynamic highlights and pieces live on sibling\n * overlays (piece layer, arrows canvas, drag ghost), so a square\n * renders exactly once per mount except when its `isFocused` prop\n * flips. This preserves the \"0 re-renders per hover\" budget in\n * PERFORMANCE.md.\n *\n * ### ARIA grid pattern\n *\n * - `role=\"gridcell\"` with algebraic `aria-label` so screen readers\n * announce \"square e4\".\n * - `aria-rowindex` / `aria-colindex` let assistive tech describe the\n * cell's grid position without relying on row groups in the DOM.\n * - Roving tabindex: the one focused cell has `tabindex=0`, every other\n * cell has `tabindex=-1`. Tab steps into the board once, then out.\n * - When the `isFocused` prop flips to `true` **and the board already\n * owns DOM focus** (arrow-key nav), the cell programmatically focuses\n * itself. The initial \"seed\" of `focusedSquare` on mount does **not**\n * move DOM focus, so the board stays dormant until the user engages.\n *\n * ### Focus ring is painted via `:focus-visible`, not inline\n *\n * The amber focus ring used to ship as an always-on inline `boxShadow`\n * keyed off the `isFocused` prop, which meant the square that held the\n * roving `tabindex=0` showed the ring on page load — even when the user\n * had never touched the board. The ring now ships as a CSS rule that\n * only matches `:focus-visible`, so browser heuristics keep it hidden\n * for mouse / pointer interaction and surface it only when the user is\n * actually navigating with the keyboard.\n *\n * ### Selection + legal-target highlights are NOT rendered here\n *\n * Chessground-style: a `useSelectionController` hook sets the\n * `data-gb-selection` attribute on this `<div>` imperatively, and the\n * CSS shipped by `injectSelectionStyles()` paints a `::before`\n * pseudo-element overlay. That bypasses React reconciliation entirely\n * on selection changes — critical for the drag-start peak frame.\n *\n * To support that, the square uses `backgroundColor` (the `color` part\n * of the CSS `background` shorthand) rather than the full `background`\n * shorthand — which would otherwise reset `background-image` to `none`\n * and wipe out any CSS-set gradient overlay.\n */\n\nimport { memo, type ReactNode, useCallback, useEffect, useRef } from \"react\";\nimport type { BoardCell, BoardModel, SquareIndex } from \"../core/index.js\";\nimport { CSS_VARS } from \"../default-theme.js\";\nimport { useSquareCell } from \"../hooks/use-board-subscription.js\";\nimport type { SquareContext } from \"../types.js\";\n\n/** Singleton id used to dedupe the injected focus-ring style element. */\nconst FOCUS_STYLE_ID = \"gb-focus-ring-styles\";\n\n/**\n * Inject the keyboard-focus ring CSS once per document. SSR-safe\n * (early-returns when there's no `document`). The rule uses\n * `:focus-visible` so the ring only appears for genuine keyboard\n * navigation — page-load hydration, programmatic focus without prior\n * keyboard activity, and pointer clicks all keep it hidden.\n */\nfunction injectFocusRingStyles(): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(FOCUS_STYLE_ID) !== null) return;\n const style = document.createElement(\"style\");\n style.id = FOCUS_STYLE_ID;\n style.textContent = `\n[data-gb-square]:focus-visible {\n box-shadow: inset 0 0 0 3px rgba(255, 206, 76, 0.95);\n}\n`;\n document.head.appendChild(style);\n}\n\n/** Algebraic name (`\"a1\"`, `\"h8\"`, …) for a square index. */\nfunction algebraicOf(index: SquareIndex): string {\n const file = index & 7;\n const rank = index >> 3;\n return `${String.fromCharCode(0x61 + file)}${rank + 1}`;\n}\n\n/** Props for {@link Square}. */\nexport interface SquareProps {\n readonly index: SquareIndex;\n readonly onClick: (index: SquareIndex) => void;\n readonly renderSquare?: ((ctx: SquareContext) => ReactNode) | undefined;\n /**\n * `true` for the single square that currently owns the roving tabindex.\n * When this flips to `true`, the cell focuses itself programmatically.\n */\n readonly isFocused: boolean;\n /**\n * Stable setter called with `(index, element | null)` whenever the\n * square's DOM node mounts or unmounts. Consumers (the selection\n * controller) use this to build a 64-entry refs array so they can\n * write `data-gb-selection` imperatively on the right square.\n */\n readonly setSquareRef?: ((index: SquareIndex, el: HTMLElement | null) => void) | undefined;\n readonly model?: BoardModel | null | undefined;\n readonly getSquareAriaLabel?: ((square: SquareIndex, cell: BoardCell) => string) | undefined;\n readonly onFocus?: ((square: SquareIndex, cell: BoardCell) => void) | undefined;\n}\n\nfunction SquareImpl({\n index,\n onClick,\n renderSquare,\n isFocused,\n setSquareRef,\n model,\n getSquareAriaLabel,\n onFocus,\n}: SquareProps) {\n const file = index & 7;\n const rank = index >> 3;\n const isLight = (file + rank) % 2 === 1;\n const cell = useSquareCell(model, index) as BoardCell;\n const label = getSquareAriaLabel ? getSquareAriaLabel(index, cell) : algebraicOf(index);\n\n const internalRef = useRef<HTMLDivElement | null>(null);\n const lastReportedFocusRef = useRef<boolean>(false);\n\n // Stable ref-setter: React only calls it when the DOM node\n // mounts/unmounts, not per render, so `memo`'s prop-diff stays valid.\n const setRef = useCallback(\n (el: HTMLDivElement | null) => {\n internalRef.current = el;\n setSquareRef?.(index, el);\n },\n [index, setSquareRef],\n );\n\n // One-time CSS injection for the `:focus-visible` ring. Idempotent\n // across remounts via a singleton `<style>` id.\n useEffect(() => {\n injectFocusRingStyles();\n }, []);\n\n // When focus state flips to `true`, move DOM focus to this cell — but\n // ONLY if the board already contains focus. That gate prevents the\n // initial roving-tabindex seed (which happens after mount) from\n // stealing page focus on load. Once the user has actually entered the\n // board via Tab or click, this effect takes over for arrow-key nav.\n useEffect(() => {\n if (!isFocused) {\n lastReportedFocusRef.current = false;\n return;\n }\n const el = internalRef.current;\n if (el === null) return;\n const grid = el.closest('[role=\"grid\"]');\n if (grid === null) return;\n if (!grid.contains(document.activeElement)) return;\n // Only focus if we aren't already, to avoid thrashing.\n if (document.activeElement !== el) el.focus();\n if (!lastReportedFocusRef.current) {\n lastReportedFocusRef.current = true;\n onFocus?.(index, cell);\n }\n }, [isFocused, index, cell, onFocus]);\n\n const handleFocus = useCallback(() => {\n lastReportedFocusRef.current = true;\n onFocus?.(index, cell);\n }, [index, cell, onFocus]);\n\n const handleClick = (): void => onClick(index);\n\n return (\n <div\n ref={setRef}\n role=\"gridcell\"\n aria-label={label}\n aria-rowindex={rank + 1}\n aria-colindex={file + 1}\n tabIndex={isFocused ? 0 : -1}\n data-square={algebraicOf(index)}\n data-gb-square=\"\"\n data-light={isLight ? \"true\" : \"false\"}\n onClick={handleClick}\n onFocus={handleFocus}\n style={{\n position: \"relative\",\n // `backgroundColor` (not the `background` shorthand) so the\n // CSS `background-image` set by `useSelectionController` (or pseudo-elements)\n // can layer on top without clobbering this base colour.\n backgroundColor: `var(${isLight ? CSS_VARS.SQ_LIGHT : CSS_VARS.SQ_DARK})`,\n backgroundImage: `var(${isLight ? CSS_VARS.SQ_LIGHT_IMAGE : CSS_VARS.SQ_DARK_IMAGE},none)`,\n backgroundSize: `var(${CSS_VARS.SQ_IMAGE_SIZE},cover)`,\n backgroundBlendMode: `var(${CSS_VARS.SQ_BLEND_MODE},normal)`,\n // Cursor is managed by `useCursorController` via injected CSS so\n // it can flip between `pointer` / `grab` / `grabbing` without a\n // React re-render per hover.\n userSelect: \"none\",\n // Suppress the browser's default focus ring; the keyboard focus\n // indicator ships via `:focus-visible` (see `injectFocusRingStyles`).\n outline: \"none\",\n // Squares carry the container-query context so pieces inside can\n // size relative to this cell (85cqh glyph sizing).\n containerType: \"size\",\n }}\n >\n {renderSquare !== undefined ? renderSquare({ index, isLight, label }) : null}\n </div>\n );\n}\n\n/**\n * Memoised square. All props are primitives or stable callbacks — memo\n * skips re-render for every square whose `isFocused` flag didn't flip,\n * so arrow-key navigation re-renders exactly 2 squares (old + new).\n */\nexport const Square = memo(SquareImpl);\nSquare.displayName = \"Square\";\n","\"use client\";\n\n/**\n * The 8×8 grid of {@link Square} cells. Laid out with CSS Grid so browser\n * layout does all the work; we just emit the squares in the right order\n * based on orientation.\n *\n * The grid is static and never re-renders after mount. Dynamic content\n * (highlights, pieces, coordinates) lives on absolutely-positioned sibling\n * layers inside the board container.\n */\n\nimport { memo, type ReactNode, useMemo } from \"react\";\nimport type { BoardCell, BoardModel, SquareIndex } from \"../core/index.js\";\nimport type { Orientation, SquareContext } from \"../types.js\";\nimport { Square } from \"./square.js\";\n\n/** Build the order squares should appear in for a given orientation. */\nfunction buildSquareOrder(orientation: Orientation): SquareIndex[] {\n const squares: SquareIndex[] = [];\n if (orientation === \"white\") {\n // White at bottom: rank 7 (top) first, rank 0 (bottom) last.\n for (let rank = 7; rank >= 0; rank--) {\n for (let file = 0; file < 8; file++) {\n squares.push((rank * 8 + file) as SquareIndex);\n }\n }\n } else {\n // Black at bottom: rank 0 (top) first, rank 7 (bottom) last, files flipped.\n for (let rank = 0; rank < 8; rank++) {\n for (let file = 7; file >= 0; file--) {\n squares.push((rank * 8 + file) as SquareIndex);\n }\n }\n }\n return squares;\n}\n\n/** Props for {@link BoardGrid}. */\nexport interface BoardGridProps {\n readonly orientation: Orientation;\n readonly onSquareClick: (index: SquareIndex) => void;\n readonly renderSquare?: ((ctx: SquareContext) => ReactNode) | undefined;\n readonly ariaLabel?: string | undefined;\n /**\n * Index of the square that currently owns the roving `tabindex=0`.\n * `null` means no cell in the grid is focused — the user hasn't Tabbed\n * into the board yet.\n */\n readonly focusedSquare: SquareIndex | null;\n /**\n * Stable setter that receives each square's DOM node on mount /\n * unmount. The selection controller uses the resulting refs array to\n * paint highlights imperatively — no React state, no reconciliation.\n */\n readonly setSquareRef?: ((index: SquareIndex, el: HTMLElement | null) => void) | undefined;\n /**\n * Flip the grid into a declarative, non-interactive mode. Emits\n * `aria-readonly=\"true\"` for assistive tech and mirrors the shape of\n * the server-rendered `StaticChessboard` so a `viewOnly` client board\n * reads the same as an SSR'd one.\n */\n readonly readOnly?: boolean | undefined;\n readonly model?: BoardModel | null | undefined;\n readonly getSquareAriaLabel?: ((square: SquareIndex, cell: BoardCell) => string) | undefined;\n readonly onSquareFocus?: ((square: SquareIndex, cell: BoardCell) => void) | undefined;\n}\n\n/**\n * The static 8×8 grid. Re-renders only on orientation / focus changes.\n * When `focusedSquare` flips, only the two affected `Square` children\n * re-render (old + new) thanks to `React.memo` on `Square`.\n */\nexport const BoardGrid = memo(function BoardGrid({\n orientation,\n onSquareClick,\n renderSquare,\n ariaLabel,\n focusedSquare,\n setSquareRef,\n readOnly,\n model,\n getSquareAriaLabel,\n onSquareFocus,\n}: BoardGridProps) {\n const squares = useMemo(() => buildSquareOrder(orientation), [orientation]);\n\n return (\n <div\n role=\"grid\"\n aria-label={ariaLabel ?? \"Chess board\"}\n aria-rowcount={8}\n aria-colcount={8}\n {...(readOnly === true ? { \"aria-readonly\": true } : {})}\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"grid\",\n gridTemplateColumns: \"repeat(8, 1fr)\",\n gridTemplateRows: \"repeat(8, 1fr)\",\n }}\n >\n {squares.map((index) => (\n <Square\n key={index}\n index={index}\n onClick={onSquareClick}\n isFocused={focusedSquare === index}\n model={model}\n getSquareAriaLabel={getSquareAriaLabel}\n onFocus={onSquareFocus}\n {...(renderSquare !== undefined ? { renderSquare } : {})}\n {...(setSquareRef !== undefined ? { setSquareRef } : {})}\n />\n ))}\n </div>\n );\n});\n","\"use client\";\n\n/**\n * Red-glow highlight under the king when the side-to-move is in check.\n *\n * Subscribes to `inCheck`, `turn`, and `board` — when any of those change\n * (which is rare: only on moves that give or resolve check) we scan the\n * board for the side-to-move's king and position a radial-gradient tint\n * under its square. Pointer-events are `none` so the highlight never\n * intercepts clicks; the piece on top remains fully interactive.\n */\n\nimport type { BoardCell, BoardModel, SquareIndex } from \"../core/index.js\";\nimport { CSS_VARS } from \"../default-theme.js\";\nimport { useBoardSlice } from \"../hooks/use-board-subscription.js\";\nimport type { Orientation } from \"../types.js\";\n\n/** King cell value depending on colour. */\nconst WHITE_KING = 6 as BoardCell; // BOARD_CELL_WK\nconst BLACK_KING = 12 as BoardCell; // BOARD_CELL_BK\n\n/** Find the side-to-move's king index on the board, or `null` if missing. */\nfunction findKing(board: Readonly<Uint8Array>, turn: 0 | 1): SquareIndex | null {\n const code = turn === 0 ? WHITE_KING : BLACK_KING;\n for (let i = 0; i < 64; i++) {\n if (board[i] === code) return i as SquareIndex;\n }\n return null;\n}\n\n/** Pixel position of a square within the board, as `{ x%, y% }`. */\nfunction positionOf(\n index: SquareIndex,\n orientation: Orientation,\n): {\n x: number;\n y: number;\n} {\n const file = index & 7;\n const rank = index >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n return { x: col * 12.5, y: row * 12.5 };\n}\n\n/** Props for {@link CheckLayer}. */\nexport interface CheckLayerProps {\n readonly model: BoardModel;\n readonly orientation: Orientation;\n}\n\n/**\n * Renders nothing when the side-to-move is not in check. When it is, draws\n * a single absolute-positioned div with a radial-gradient background over\n * the king's square.\n *\n * Split into an outer shell that only subscribes to the cheap `inCheck`\n * primitive and an inner component that subscribes to `turn`/`board`. The\n * inner component only exists while the king IS in check, so the 64-byte\n * `board` slice is only observed during those commits — untouched during\n * the overwhelming majority of moves.\n */\nexport function CheckLayer({ model, orientation }: CheckLayerProps) {\n const inCheck = useBoardSlice(model, (s) => s.inCheck);\n if (!inCheck) return null;\n return <CheckLayerInner model={model} orientation={orientation} />;\n}\n\nfunction CheckLayerInner({ model, orientation }: CheckLayerProps) {\n const turn = useBoardSlice(model, (s) => s.turn) as 0 | 1;\n const board = useBoardSlice(model, (s) => s.board);\n const kingSquare = findKing(board, turn);\n if (kingSquare === null) return null;\n const { x, y } = positionOf(kingSquare, orientation);\n\n return (\n <div\n data-layer=\"check\"\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: `${x}%`,\n top: `${y}%`,\n width: \"12.5%\",\n height: \"12.5%\",\n background: `var(${CSS_VARS.CHECK})`,\n pointerEvents: \"none\",\n zIndex: 2,\n }}\n />\n );\n}\n","\"use client\";\n\n/**\n * Single floating-piece element that follows the pointer during a drag.\n *\n * ### Pre-mount, imperative show/hide\n *\n * Previously the layer conditionally rendered on a `dragActive` React\n * state flag — dragging started with a `flushSync(setState)`, which\n * synchronously re-rendered `<Chessboard/>` (and the entire layer\n * stack under it) during the first `pointermove` handler. Under CPU\n * throttle this showed up as a 25 ms peak frame at drag-start vs\n * chessground's 9 ms.\n *\n * The new model mounts all 12 possible drag ghosts **once** (hidden)\n * and exposes an imperative `DragLayerHandle`. `useDrag` calls\n * `handle.show(cell)` + `handle.setTransform(x, y)` from its pointer\n * handlers — no React state change, no reconciliation, compositor does\n * the work. `handle.hide()` on drag-end.\n */\n\nimport { forwardRef, useImperativeHandle, useMemo, useRef } from \"react\";\nimport type { BoardCell } from \"../core/index.js\";\nimport { CSS_VARS } from \"../default-theme.js\";\nimport type { PieceRenderer } from \"../types.js\";\n\n/**\n * Frozen style object for the wrapper. Always mounted, always visible\n * to the compositor — hidden via `opacity: 0` + `pointer-events: none`\n * rather than `display: none`. That keeps the GPU layer alive between\n * drags so the first pointer-move of a drag doesn't pay the cost of\n * allocating a fresh compositor layer (the previous design's 25 ms\n * peak frame in real Chromium was mostly that one-off).\n *\n * `transform: translate3d(0,0,0)` forces the browser to promote the\n * element to its own layer immediately at mount.\n */\nconst WRAPPER_STYLE = Object.freeze({\n position: \"absolute\" as const,\n top: 0,\n left: 0,\n width: \"12.5%\",\n height: \"12.5%\",\n pointerEvents: \"none\" as const,\n willChange: \"transform\",\n zIndex: 20,\n containerType: \"size\" as const,\n opacity: 0,\n transform: \"translate3d(0, 0, 0)\",\n});\n\n/**\n * Frozen style object shared across the 12 pre-materialised slot\n * wrappers. Kept always-laid-out (not `display: none`) so paint + layer\n * state is warm — opacity flips only on the selected one.\n */\nconst SLOT_STYLE = Object.freeze({\n position: \"absolute\" as const,\n inset: 0,\n opacity: 0,\n containerType: \"size\" as const,\n});\n\n/**\n * Imperative handle exposed by {@link DragLayer}. `useDrag` uses these\n * methods in its pointer handlers to show the ghost, move it, and hide\n * it — all without triggering a React render.\n */\nexport interface DragLayerHandle {\n /** Reveal the ghost for the given piece cell (1..12). */\n show(cell: BoardCell): void;\n /** Hide the ghost. Safe to call while already hidden. */\n hide(): void;\n /** Write the ghost's transform. Called every pointer-move during a drag. */\n setTransform(x: number, y: number): void;\n /** Raw wrapper element — kept for legacy callers that measure geometry. */\n element(): HTMLDivElement | null;\n}\n\n/** Props for {@link DragLayer}. */\nexport interface DragLayerProps {\n /**\n * The piece renderer to use — the same one `<PieceLayer/>` renders\n * with. The drag layer calls this once per piece code at mount and\n * stores the resulting elements in the DOM, so piece rendering never\n * happens on the hot path.\n */\n readonly pieces: PieceRenderer;\n}\n\n/**\n * Always-mounted, imperatively-controlled drag overlay. Always emits\n * the `data-layer=\"drag\"` attribute so existing CSS hooks keep working;\n * `data-active` toggles true during a drag so styling or tests can\n * key on that.\n */\nexport const DragLayer = forwardRef<DragLayerHandle, DragLayerProps>(function DragLayer(\n { pieces },\n ref,\n) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n // Refs to the 12 pre-materialised piece slots, keyed by cell code (1..12).\n // Index 0 is unused (empty cell has no drag ghost).\n const slotRefs = useRef<Array<HTMLDivElement | null>>(new Array(13).fill(null));\n\n // Pre-materialise the 13 (well, 12 — cell 0 is null) piece elements\n // once at mount. Rebuild only when the renderer identity changes.\n const slots = useMemo(() => {\n const nodes: Array<React.ReactNode> = [];\n for (let cell = 1; cell <= 12; cell++) {\n const child = pieces({ cell: cell as BoardCell, square: 0 as never });\n nodes.push(\n <div\n key={cell}\n ref={(el) => {\n slotRefs.current[cell] = el;\n }}\n data-drag-cell={cell}\n style={{\n ...SLOT_STYLE,\n filter: `var(${cell <= 6 ? CSS_VARS.PIECE_FILTER_WHITE : CSS_VARS.PIECE_FILTER_BLACK}, none)`,\n }}\n >\n {child}\n </div>,\n );\n }\n return nodes;\n }, [pieces]);\n\n useImperativeHandle(\n ref,\n () => ({\n show(cell): void {\n const wrapper = wrapperRef.current;\n if (wrapper === null) return;\n wrapper.style.opacity = \"1\";\n wrapper.dataset[\"active\"] = \"true\";\n // Show just the chosen piece slot; others stay at opacity 0.\n for (let c = 1; c <= 12; c++) {\n const el = slotRefs.current[c];\n if (el !== null && el !== undefined) {\n el.style.opacity = c === cell ? \"1\" : \"0\";\n }\n }\n },\n hide(): void {\n const wrapper = wrapperRef.current;\n if (wrapper === null) return;\n wrapper.style.opacity = \"0\";\n wrapper.dataset[\"active\"] = \"false\";\n },\n setTransform(x, y): void {\n const wrapper = wrapperRef.current;\n if (wrapper === null) return;\n wrapper.style.transform = `translate3d(${x}px, ${y}px, 0)`;\n },\n element(): HTMLDivElement | null {\n return wrapperRef.current;\n },\n }),\n [],\n );\n\n return (\n <div\n ref={wrapperRef}\n data-layer=\"drag\"\n data-active=\"false\"\n aria-hidden=\"true\"\n style={WRAPPER_STYLE}\n >\n {slots}\n </div>\n );\n});\n","\"use client\";\n\n/**\n * One-shot red flash on an origin square to announce a rejected move.\n *\n * Driven by a `flashAt` prop owned by `Chessboard`. When the prop changes\n * from `null` to a `SquareIndex`, a WAAPI animation fades a red tint in\n * and out once; the parent's timer nulls the prop afterwards.\n *\n * Honours `prefers-reduced-motion`: the flash renders briefly but the\n * opacity timeline collapses to zero so motion-sensitive users don't see\n * a pulse.\n */\n\nimport { useLayoutEffect, useRef } from \"react\";\nimport type { SquareIndex } from \"../core/index.js\";\nimport { DEFAULT_ILLEGAL_FLASH_TINT } from \"../default-theme.js\";\nimport type { Orientation } from \"../types.js\";\n\n/** CSS-percentage position of the square inside the board. */\nfunction positionOf(\n index: SquareIndex,\n orientation: Orientation,\n): {\n x: number;\n y: number;\n} {\n const file = index & 7;\n const rank = index >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n return { x: col * 12.5, y: row * 12.5 };\n}\n\nfunction prefersReducedMotion(): boolean {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return false;\n }\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\n/** Flash duration, in ms. Kept short so it doesn't interfere with UX. */\nconst FLASH_DURATION_MS = 280;\n\n/** Props for {@link IllegalFlashLayer}. */\nexport interface IllegalFlashLayerProps {\n readonly at: SquareIndex | null;\n readonly orientation: Orientation;\n}\n\n/**\n * Renders `null` when `at` is `null`. When `at` is a `SquareIndex`,\n * renders a tinted div and kicks off a one-shot opacity animation via\n * WAAPI. No setState / re-render during the fade.\n */\nexport function IllegalFlashLayer({ at, orientation }: IllegalFlashLayerProps) {\n const elRef = useRef<HTMLDivElement | null>(null);\n\n useLayoutEffect(() => {\n if (at === null) return;\n const el = elRef.current;\n if (el === null || typeof el.animate !== \"function\") return;\n const duration = prefersReducedMotion() ? 0 : FLASH_DURATION_MS;\n el.animate(\n [\n { opacity: 0, offset: 0 },\n { opacity: 1, offset: 0.15 },\n { opacity: 0, offset: 1 },\n ],\n { duration, easing: \"ease-out\", fill: \"forwards\" },\n );\n }, [at]);\n\n if (at === null) return null;\n const { x, y } = positionOf(at, orientation);\n return (\n <div\n ref={elRef}\n data-layer=\"illegal-flash\"\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: `${x}%`,\n top: `${y}%`,\n width: \"12.5%\",\n height: \"12.5%\",\n background: DEFAULT_ILLEGAL_FLASH_TINT,\n opacity: 0,\n pointerEvents: \"none\",\n zIndex: 5,\n }}\n />\n );\n}\n","\"use client\";\n\n/**\n * Visually-hidden screen-reader announcer.\n *\n * Subscribes to `snapshot.lastMove` and emits a concise, descriptive\n * announcement each time a move lands. Uses `aria-live=\"polite\"` so the\n * announcement is queued after any critical output the user is already\n * reading, not interrupted mid-word.\n *\n * ### Why descriptive text instead of SAN?\n *\n * SAN (\"Nf3\", \"exd5\", \"O-O\") is concise but not pronounceable by screen\n * readers in a way players recognise. \"Knight to f3\" reads out as\n * \"Knight to eff three\", which is what a chess commentator would say.\n * We compose the announcement from the packed move + the post-move board\n * snapshot so no extra engine call is required.\n */\n\nimport { useMemo } from \"react\";\nimport { type BoardModel, decodePackedMove, type PackedMove } from \"../core/index.js\";\nimport { useBoardSlice } from \"../hooks/use-board-subscription.js\";\n\n/** 0-indexed square → algebraic (`\"e4\"`). */\nfunction algebraicOf(index: number): string {\n const file = index & 7;\n const rank = index >> 3;\n return `${String.fromCharCode(0x61 + file)}${rank + 1}`;\n}\n\n/** Readable piece name for a board cell. Empty cell returns `\"piece\"`. */\nfunction pieceName(cell: number): string {\n if (cell === 0) return \"piece\";\n const color = cell > 6 ? \"black\" : \"white\";\n const type = (cell - 1) % 6;\n switch (type) {\n case 0:\n return `${color} pawn`;\n case 1:\n return `${color} knight`;\n case 2:\n return `${color} bishop`;\n case 3:\n return `${color} rook`;\n case 4:\n return `${color} queen`;\n case 5:\n return `${color} king`;\n default:\n return `${color} piece`;\n }\n}\n\n/** Build the announcement string from the last packed move + board state. */\nfunction announcementFor(\n lastMove: PackedMove,\n board: Readonly<Uint8Array>,\n wasCapture: boolean,\n): string {\n const { from, to, kind, promotion } = decodePackedMove(lastMove);\n\n // A pass moves no piece and has no from/to — announce the pass rather\n // than reading the sentinel as an h8→h8 move.\n if (kind === \"pass\") return \"Passes.\";\n\n if (kind === \"castle\") {\n const isKingside = (to & 7) > (from & 7);\n return isKingside ? \"Castles kingside.\" : \"Castles queenside.\";\n }\n\n // Post-move board[to] holds the piece that just moved (or promoted to).\n const landed = board[to] ?? 0;\n const name = pieceName(landed);\n const fromSq = algebraicOf(from);\n const toSq = algebraicOf(to);\n\n if (kind === \"promotion\" && promotion !== null) {\n const promoted =\n promotion === 1 ? \"knight\" : promotion === 2 ? \"bishop\" : promotion === 3 ? \"rook\" : \"queen\";\n const action = wasCapture ? \"captures and promotes\" : \"promotes\";\n return `Pawn ${fromSq} ${action} to ${promoted} on ${toSq}.`;\n }\n\n if (kind === \"en-passant\") {\n return `${capitalise(name)} ${fromSq} captures en passant on ${toSq}.`;\n }\n\n if (wasCapture) {\n return `${capitalise(name)} ${fromSq} captures on ${toSq}.`;\n }\n\n return `${capitalise(name)} ${fromSq} to ${toSq}.`;\n}\n\nfunction capitalise(s: string): string {\n return s.length === 0 ? s : s.charAt(0).toUpperCase() + s.slice(1);\n}\n\n/** Visually-hidden style block (the `sr-only` pattern). */\nconst srOnlyStyle = {\n position: \"absolute\" as const,\n width: \"1px\",\n height: \"1px\",\n padding: 0,\n margin: \"-1px\",\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\" as const,\n border: 0,\n};\n\n/** Props for {@link LiveRegion}. */\nexport interface LiveRegionProps {\n readonly model: BoardModel;\n}\n\n/**\n * Subscribes to `lastMove` + `board` + `lastAnimations` and renders a\n * visually-hidden `aria-live=\"polite\"` region with a human-readable\n * description of the most recent move.\n */\nexport function LiveRegion({ model }: LiveRegionProps) {\n // Subscribe to `lastMove` only. The board bytes relevant to the\n // announcement (the `to` square) are read lazily inside the memo via\n // `getSnapshot()`, so we never wake on unrelated commits (arrow draw,\n // selection change, etc.) and never subscribe to a Uint8Array whose\n // identity is kept across commits — both of those were quiet no-ops\n // before and are gone now, one less thing for React to schedule.\n const lastMove = useBoardSlice(model, (s) => s.lastMove);\n\n const message = useMemo(() => {\n if (lastMove === null) return \"\";\n // Capture detection: inspect the just-emitted animation descriptors.\n // `lastAnimations` isn't part of the snapshot object but is stable\n // across the same commit, so reading it here is safe.\n const wasCapture = model.lastAnimations.some(\n (d) => d.kind === \"capture\" || d.kind === \"en-passant\",\n );\n return announcementFor(lastMove, model.getSnapshot().board, wasCapture);\n }, [lastMove, model]);\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n data-layer=\"live-region\"\n style={srOnlyStyle}\n >\n {message}\n </div>\n );\n}\n","\"use client\";\n\n/**\n * Ghost-piece overlay for pending premoves.\n *\n * Subscribes to `snapshot.premoves`. If a premove is queued we render a\n * blue tint on its target square plus a translucent ghost of the moving\n * piece at that target. The ghost uses the caller's `pieces` renderer so\n * theme consistency is automatic.\n *\n * For M4 we only render the **first** queued premove. Chained premoves\n * would need to project the board state forward through every pending\n * move — tractable, but out of scope here. The engine still processes\n * every queued premove in order once the opponent plays; this is strictly\n * a visual simplification.\n */\n\nimport type { BoardCell, BoardModel, SquareIndex } from \"../core/index.js\";\nimport { DEFAULT_PREMOVE_TINT } from \"../default-theme.js\";\nimport { useBoardSlice, useSquareCell } from \"../hooks/use-board-subscription.js\";\nimport type { Orientation, PieceRenderer } from \"../types.js\";\n\n/** CSS-percentage position of the square inside the board. */\nfunction positionOf(\n index: SquareIndex,\n orientation: Orientation,\n): {\n x: number;\n y: number;\n} {\n const file = index & 7;\n const rank = index >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n return { x: col * 12.5, y: row * 12.5 };\n}\n\n/** Props for {@link PremoveLayer}. */\nexport interface PremoveLayerProps {\n readonly model: BoardModel;\n readonly orientation: Orientation;\n readonly pieces: PieceRenderer;\n}\n\n/**\n * Renders `null` when the premove queue is empty.\n *\n * Two-tier structure: the outer shell only subscribes to the `premoves`\n * slice (changes rarely). The inner component, which subscribes to the\n * specific from-square byte, is mounted only while a premove is queued —\n * so no `board` subscription is paid for during the bulk of the game.\n */\nexport function PremoveLayer({ model, orientation, pieces }: PremoveLayerProps) {\n const premoves = useBoardSlice(model, (s) => s.premoves);\n if (premoves.length === 0) return null;\n const head = premoves[0];\n if (head === undefined) return null;\n return (\n <PremoveLayerInner\n model={model}\n orientation={orientation}\n pieces={pieces}\n from={head.from}\n to={head.to}\n />\n );\n}\n\ninterface PremoveLayerInnerProps {\n readonly model: BoardModel;\n readonly orientation: Orientation;\n readonly pieces: PieceRenderer;\n readonly from: SquareIndex;\n readonly to: SquareIndex;\n}\n\nfunction PremoveLayerInner({ model, orientation, pieces, from, to }: PremoveLayerInnerProps) {\n const cell = useSquareCell(model, from) as BoardCell;\n if (cell === 0) return null;\n const origin = positionOf(from, orientation);\n const target = positionOf(to, orientation);\n\n return (\n <div\n data-layer=\"premove\"\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n pointerEvents: \"none\",\n zIndex: 4,\n }}\n >\n {/* Origin tint (faint, so the piece still reads through). */}\n <div\n style={{\n position: \"absolute\",\n left: `${origin.x}%`,\n top: `${origin.y}%`,\n width: \"12.5%\",\n height: \"12.5%\",\n background: DEFAULT_PREMOVE_TINT,\n opacity: 0.5,\n }}\n />\n {/* Target tint + ghost piece. */}\n <div\n style={{\n position: \"absolute\",\n left: `${target.x}%`,\n top: `${target.y}%`,\n width: \"12.5%\",\n height: \"12.5%\",\n background: DEFAULT_PREMOVE_TINT,\n }}\n />\n <div\n data-premove-ghost=\"true\"\n style={{\n position: \"absolute\",\n left: `${target.x}%`,\n top: `${target.y}%`,\n width: \"12.5%\",\n height: \"12.5%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: 0.55,\n containerType: \"size\",\n }}\n >\n {pieces({ cell, square: to })}\n </div>\n </div>\n );\n}\n","\"use client\";\n\n/**\n * Built-in promotion dialog.\n *\n * Rendered only while a promotion is pending. Shows the four promotion\n * options (Queen, Rook, Bishop, Knight) stacked on the target square,\n * with the queen on the promoting side.\n *\n * ### UX contract\n *\n * - Primary pointer click on a choice resolves the promotion.\n * - <kbd>Q</kbd>, <kbd>R</kbd>, <kbd>B</kbd>, <kbd>N</kbd> keyboard\n * shortcuts resolve without moving focus.\n * - <kbd>Escape</kbd> or a click outside the dialog cancels the move.\n * - `role=\"dialog\"` with `aria-modal=\"true\"` + labelled title, so screen\n * readers announce the choice prompt.\n *\n * Rendered inside the Chessboard container so theme CSS variables (for\n * piece glyphs) are in scope.\n */\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n type BoardCell,\n type Color,\n encodeBoardCell,\n PieceType,\n type SquareIndex,\n} from \"../core/index.js\";\nimport { CSS_VARS } from \"../default-theme.js\";\nimport type { Orientation, PieceRenderer } from \"../types.js\";\n\n/** Props for {@link PromotionOverlay}. */\nexport interface PromotionOverlayProps {\n readonly from: SquareIndex;\n readonly to: SquareIndex;\n readonly color: 0 | 1;\n readonly orientation: Orientation;\n readonly pieces: PieceRenderer;\n readonly onSelect: (piece: PieceType) => void;\n readonly onCancel: () => void;\n readonly getPromotionPieceAriaLabel?: ((piece: PieceType, color: Color) => string) | undefined;\n}\n\n/** Pixel position of a square within the board, as `{ x%, y% }`. */\nfunction positionOf(\n index: SquareIndex,\n orientation: Orientation,\n): {\n x: number;\n y: number;\n} {\n const file = index & 7;\n const rank = index >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n return { x: col * 12.5, y: row * 12.5 };\n}\n\n/** Order pieces offer (Chess.com order: Queen, Knight, Rook, Bishop). */\nconst CHOICE_ORDER: readonly PieceType[] = [\n PieceType.Queen,\n PieceType.Knight,\n PieceType.Rook,\n PieceType.Bishop,\n];\n\n/** Map from keyboard shortcut to piece type. */\nconst SHORTCUTS: Readonly<Record<string, PieceType>> = {\n q: PieceType.Queen,\n r: PieceType.Rook,\n b: PieceType.Bishop,\n n: PieceType.Knight,\n Q: PieceType.Queen,\n R: PieceType.Rook,\n B: PieceType.Bishop,\n N: PieceType.Knight,\n};\n\nexport function PromotionOverlay({\n from: _from,\n to,\n color,\n orientation,\n pieces,\n onSelect,\n onCancel,\n getPromotionPieceAriaLabel,\n}: PromotionOverlayProps) {\n const buttonRefs = useRef<(HTMLButtonElement | null)[]>([]);\n\n const getLabel = useCallback(\n (piece: PieceType): string =>\n getPromotionPieceAriaLabel\n ? getPromotionPieceAriaLabel(piece, color as Color)\n : pieceName(piece),\n [getPromotionPieceAriaLabel, color],\n );\n\n const [activeAnnouncement, setActiveAnnouncement] = useState<string>(() =>\n getLabel(CHOICE_ORDER[0] ?? PieceType.Queen),\n );\n\n // Auto-focus the primary promotion option on open\n useEffect(() => {\n buttonRefs.current[0]?.focus();\n }, []);\n\n // Keyboard navigation, shortcuts, Escape, and focus trapping\n useEffect(() => {\n const onKey = (e: KeyboardEvent): void => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onCancel();\n return;\n }\n\n if (e.key === \"Tab\") {\n e.preventDefault();\n const activeEl = document.activeElement as HTMLButtonElement | null;\n const currentIdx = buttonRefs.current.indexOf(activeEl);\n let nextIdx: number;\n if (e.shiftKey) {\n nextIdx = currentIdx <= 0 ? buttonRefs.current.length - 1 : currentIdx - 1;\n } else {\n nextIdx = currentIdx >= buttonRefs.current.length - 1 ? 0 : currentIdx + 1;\n }\n buttonRefs.current[nextIdx]?.focus();\n return;\n }\n\n if (e.key === \"ArrowDown\" || e.key === \"ArrowRight\") {\n e.preventDefault();\n const activeEl = document.activeElement as HTMLButtonElement | null;\n const currentIdx = buttonRefs.current.indexOf(activeEl);\n const nextIdx = currentIdx < 0 ? 0 : (currentIdx + 1) % CHOICE_ORDER.length;\n buttonRefs.current[nextIdx]?.focus();\n return;\n }\n\n if (e.key === \"ArrowUp\" || e.key === \"ArrowLeft\") {\n e.preventDefault();\n const activeEl = document.activeElement as HTMLButtonElement | null;\n const currentIdx = buttonRefs.current.indexOf(activeEl);\n const prevIdx = currentIdx <= 0 ? CHOICE_ORDER.length - 1 : currentIdx - 1;\n buttonRefs.current[prevIdx]?.focus();\n return;\n }\n\n if (e.key === \"Home\") {\n e.preventDefault();\n buttonRefs.current[0]?.focus();\n return;\n }\n\n if (e.key === \"End\") {\n e.preventDefault();\n buttonRefs.current[CHOICE_ORDER.length - 1]?.focus();\n return;\n }\n\n const choice = SHORTCUTS[e.key];\n if (choice !== undefined) {\n e.preventDefault();\n onSelect(choice);\n }\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [onSelect, onCancel]);\n\n const targetPos = positionOf(to, orientation);\n // Black-side promotion stacks upward; white-side stacks downward.\n // For a black pawn promoting on rank 0 in white orientation, the target\n // square visually sits at the bottom (row 7) — the dialog grows upward so\n // rook/bishop/knight don't fall off-board.\n const promotingColorIsBlack = color === 1;\n const stackUpward = orientation === \"white\" ? promotingColorIsBlack : !promotingColorIsBlack;\n\n return (\n <div\n role=\"presentation\"\n data-layer=\"promotion-overlay\"\n onClick={onCancel}\n style={{\n position: \"absolute\",\n inset: 0,\n background: \"rgba(0, 0, 0, 0.35)\",\n zIndex: 30,\n cursor: \"pointer\",\n }}\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={`Choose promotion piece at ${algebraicOf(to)}`}\n onClick={(e) => e.stopPropagation()}\n style={{\n position: \"absolute\",\n left: `${targetPos.x}%`,\n top: `${stackUpward ? targetPos.y - 12.5 * 3 : targetPos.y}%`,\n width: \"12.5%\",\n height: `${12.5 * 4}%`,\n display: \"flex\",\n flexDirection: stackUpward ? \"column-reverse\" : \"column\",\n background: \"#ffffff\",\n boxShadow: \"0 4px 16px rgba(0, 0, 0, 0.28)\",\n borderRadius: \"4px\",\n overflow: \"hidden\",\n }}\n >\n {CHOICE_ORDER.map((piece, index) => {\n const cell = encodeBoardCell(color as Color, piece) as BoardCell;\n const label = getLabel(piece);\n return (\n <button\n key={piece}\n ref={(el) => {\n buttonRefs.current[index] = el;\n }}\n type=\"button\"\n onClick={() => onSelect(piece)}\n onFocus={() => setActiveAnnouncement(label)}\n aria-label={label}\n style={{\n flex: 1,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n border: \"none\",\n background: \"transparent\",\n cursor: \"pointer\",\n padding: 0,\n margin: 0,\n font: \"inherit\",\n containerType: \"size\",\n }}\n data-promotion-piece={pieceName(piece)}\n >\n {pieces({ cell, square: to })}\n </button>\n );\n })}\n </div>\n <span className=\"sr-only\" aria-live=\"polite\" aria-atomic=\"true\" style={srOnlyStyle}>\n {activeAnnouncement}\n </span>\n <span className=\"sr-only\" style={srOnlyStyle}>\n Choose a promotion piece with Q, N, R, or B, or arrow keys. Press Escape to cancel.\n </span>\n </div>\n );\n}\n\n/** Ultra-minimal visually-hidden style for the sr-only announcement. */\nconst srOnlyStyle = {\n position: \"absolute\" as const,\n width: \"1px\",\n height: \"1px\",\n padding: 0,\n margin: \"-1px\",\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\" as const,\n border: 0,\n};\n\nfunction pieceName(t: PieceType): string {\n switch (t) {\n case PieceType.Queen:\n return \"Queen\";\n case PieceType.Rook:\n return \"Rook\";\n case PieceType.Bishop:\n return \"Bishop\";\n case PieceType.Knight:\n return \"Knight\";\n default:\n return \"Piece\";\n }\n}\n\nfunction algebraicOf(index: SquareIndex): string {\n const file = index & 7;\n const rank = index >> 3;\n return `${String.fromCharCode(0x61 + file)}${rank + 1}`;\n}\n\n// Prevent an unused-import warning when CSS_VARS is only referenced in docs.\nvoid CSS_VARS;\n","\"use client\";\n\n/**\n * FEN-only piece overlay — a pure, subscription-free twin of\n * `<PieceLayer/>` used before the engine has loaded.\n *\n * `<Chessboard/>` renders this layer when its `game` prop is `null`\n * **and** a `fallbackFen` has been supplied. The DOM it produces is\n * intentionally identical to `<PieceLayer/>`'s — same container tree,\n * same CSS-grid placement, same `data-piece-*` attributes — so when\n * the engine resolves and the interactive layer takes over, the\n * browser doesn't reflow or shift the pieces visibly.\n *\n * Because this component has no state and no effects it runs on the\n * very first commit, with no wait for `useEffect` to fire. Pieces are\n * painted inside the first frame the board DOM lays out — typically\n * under ~60 ms from navigation start on a cold mount, which is the\n * whole point of `fallbackFen`.\n *\n * Geometry helpers, slot style, and container style are imported\n * from `piece-layer.tsx` so the two layers really do produce the\n * same DOM and the shared constants dedupe in the minified bundle.\n */\n\nimport type { BoardCell, SquareIndex } from \"../core/index.js\";\nimport { CSS_VARS } from \"../default-theme.js\";\nimport type { Orientation, PieceRenderer } from \"../types.js\";\nimport { algebraicOf, CONTAINER_STYLE, gridCoord, SLOT_BASE_STYLE } from \"./piece-layer.js\";\n\n/** Props for {@link StaticPieceLayer}. */\nexport interface StaticPieceLayerProps {\n /** Parsed FEN placement, 64 bytes, LERF indexed. */\n readonly board: Uint8Array;\n readonly orientation: Orientation;\n readonly pieces: PieceRenderer;\n}\n\n/**\n * Render one slot per occupied square — empty squares are elided so\n * the commit doesn't allocate nodes it would just have to drop. Keys\n * match the square index (matching the interactive layer) so React's\n * diff is minimal if either side of the transition re-enters.\n */\nexport function StaticPieceLayer({ board, orientation, pieces }: StaticPieceLayerProps) {\n const slots: React.ReactNode[] = [];\n for (let i = 0; i < 64; i++) {\n const cell = board[i] ?? 0;\n if (cell === 0) continue;\n const index = i as SquareIndex;\n const { col, row } = gridCoord(index, orientation);\n slots.push(\n <div\n key={i}\n data-piece-square={algebraicOf(index)}\n data-piece-cell={cell}\n style={{\n ...SLOT_BASE_STYLE,\n gridColumnStart: col,\n gridRowStart: row,\n filter: `var(${cell <= 6 ? CSS_VARS.PIECE_FILTER_WHITE : CSS_VARS.PIECE_FILTER_BLACK}, none)`,\n }}\n >\n {pieces({ cell: cell as BoardCell, square: index })}\n </div>,\n );\n }\n return (\n <div aria-hidden=\"true\" style={CONTAINER_STYLE}>\n {slots}\n </div>\n );\n}\n","\"use client\";\n\n/**\n * WAAPI-driven FLIP animations for piece glides.\n *\n * ### Strategy\n *\n * After every model commit we know, via `model.lastAnimations`, what\n * visually changed: a set of {@link AnimDescriptor}s describing `move`,\n * `capture`, `en-passant`, `castle`, `promotion`, `appear`, or `disappear`.\n *\n * For each descriptor that has a source and a destination, we:\n *\n * 1. Compute the pixel displacement between the `from` and `to` squares.\n * 2. Locate the destination `PieceSlot` DOM node (by `data-piece-square`).\n * 3. Cancel any in-flight animation on that node.\n * 4. Kick off a WAAPI animation whose first keyframe translates it back\n * to the source and whose last keyframe returns to identity.\n *\n * The animation runs entirely on the compositor — React never re-renders\n * during the glide.\n *\n * ### FLIP invariants\n *\n * - Run inside `useLayoutEffect` so the transform is applied **before**\n * the browser paints, preventing a one-frame flash at the destination.\n * - Skip animation when `prefers-reduced-motion: reduce` is set, or when\n * the caller's duration is zero.\n * - Fall back silently if the destination DOM node is missing (e.g. the\n * piece-layer was reparented mid-animation) — never throw.\n */\n\nimport { type ReactNode, type RefObject, useLayoutEffect, useRef } from \"react\";\nimport type { AnimDescriptor, BoardModel, SquareIndex } from \"../core/index.js\";\nimport type { AnimationOptions, Orientation } from \"../types.js\";\nimport { useBoardSlice } from \"./use-board-subscription.js\";\n\nconst DEFAULT_DURATION_MS = 60;\nconst DEFAULT_EASING = \"cubic-bezier(0.22, 0.61, 0.36, 1)\";\n\n/** Algebraic name `\"e2\"` from a square index. */\nfunction algebraicOf(index: SquareIndex): string {\n const file = index & 7;\n const rank = index >> 3;\n return `${String.fromCharCode(0x61 + file)}${rank + 1}`;\n}\n\n/**\n * Compute the pixel delta from `to` back to `from` in board coordinates.\n * In an orientation-flipped board, the sign of both axes flips together so\n * the helper just needs to know the square size and the two raw indices.\n */\nfunction deltaFromTo(\n from: SquareIndex,\n to: SquareIndex,\n squareSize: number,\n orientation: Orientation,\n): { dx: number; dy: number } {\n const fromFile = from & 7;\n const fromRank = from >> 3;\n const toFile = to & 7;\n const toRank = to >> 3;\n const fromCol = orientation === \"white\" ? fromFile : 7 - fromFile;\n const fromRow = orientation === \"white\" ? 7 - fromRank : fromRank;\n const toCol = orientation === \"white\" ? toFile : 7 - toFile;\n const toRow = orientation === \"white\" ? 7 - toRank : toRank;\n return {\n dx: (fromCol - toCol) * squareSize,\n dy: (fromRow - toRow) * squareSize,\n };\n}\n\n/** Cancel any running WAAPI animation on `element`. */\nfunction cancelAnimations(element: Element): void {\n // `getAnimations` is standard but may be absent in reduced test envs.\n if (typeof element.getAnimations !== \"function\") return;\n for (const anim of element.getAnimations()) anim.cancel();\n}\n\n/**\n * Read `prefers-reduced-motion: reduce`. Returns `false` in non-browser\n * environments (e.g. during SSR).\n */\nfunction prefersReducedMotion(): boolean {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return false;\n }\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\n/**\n * Animate one piece glide from the source square back to identity at the\n * destination. `element` is the destination `PieceSlot` wrapper — the same\n * one the `PieceLayer` renders.\n */\nfunction animateGlide(\n element: HTMLElement,\n dx: number,\n dy: number,\n duration: number,\n easing: string,\n): void {\n cancelAnimations(element);\n if (duration <= 0 || typeof element.animate !== \"function\") return;\n element.animate(\n [{ transform: `translate(${dx}px, ${dy}px)` }, { transform: \"translate(0, 0)\" }],\n { duration, easing, fill: \"none\" },\n );\n}\n\n/** Runtime hooks exposed to {@link useAnimation}'s caller. */\nexport interface UseAnimationRuntime {\n /**\n * Ref to a boolean flag. If `true` at commit time the next animation is\n * skipped and the flag is reset to `false` automatically. Used by the\n * drag handler to suppress the FLIP glide — for a drag-initiated move,\n * the user has already placed the piece at the target, so animating\n * from source → target reverses their action and looks jarring.\n */\n readonly skipNextRef?: RefObject<boolean>;\n}\n\n/**\n * Subscribe to the model's commit stream and play a WAAPI animation for\n * every descriptor in `model.lastAnimations`.\n *\n * @param model The board model (or `null` during async init).\n * @param containerRef Ref to the outer board container — used for pixel\n * geometry.\n * @param orientation Current board orientation.\n * @param options Duration / easing overrides.\n * @param runtime Optional runtime hooks (e.g. a `skipNextRef` to bypass\n * the animation on the next commit).\n */\n/**\n * Drive FLIP animations off a cheap scalar slice subscription.\n *\n * Previously this hook ran a `setState` inside `<Chessboard/>` on every\n * model commit to make its `useLayoutEffect` re-fire. That worked, but it\n * forced `<Chessboard/>` (and the entire layer tree below it) to re-run\n * its function body every single move — the per-byte subscriptions saved\n * `<Square/>` / `<PieceSlot/>` from re-rendering, but the 11 layer\n * wrappers above them paid full price. See the M7 render-budget diagnosis\n * in BENCH.md's \"What's not measured yet\" section.\n *\n * The fix: expose `<AnimationRunner/>` as a sibling component that\n * subscribes to `historyPly` via `useBoardSlice`. When a move lands,\n * only `<AnimationRunner/>` re-renders (it produces `null`), its layout\n * effect fires, and it reads `model.lastAnimations` to run the WAAPI\n * glides. `<Chessboard/>` never re-renders on a move.\n */\nfunction runAnimations(\n descriptors: readonly AnimDescriptor[],\n container: HTMLElement,\n orientation: Orientation,\n duration: number,\n easing: string,\n): void {\n const rect = container.getBoundingClientRect();\n const sqSize = rect.width / 8;\n if (sqSize <= 0) return;\n\n for (const d of descriptors) {\n switch (d.kind) {\n case \"move\":\n case \"capture\":\n case \"en-passant\":\n case \"promotion\": {\n const toEl = container.querySelector<HTMLElement>(\n `[data-piece-square=\"${algebraicOf(d.to)}\"]`,\n );\n if (toEl === null) break;\n const { dx, dy } = deltaFromTo(d.from, d.to, sqSize, orientation);\n animateGlide(toEl, dx, dy, duration, easing);\n break;\n }\n case \"castle\": {\n const kingEl = container.querySelector<HTMLElement>(\n `[data-piece-square=\"${algebraicOf(d.kingTo)}\"]`,\n );\n const rookEl = container.querySelector<HTMLElement>(\n `[data-piece-square=\"${algebraicOf(d.rookTo)}\"]`,\n );\n if (kingEl !== null) {\n const { dx, dy } = deltaFromTo(d.kingFrom, d.kingTo, sqSize, orientation);\n animateGlide(kingEl, dx, dy, duration, easing);\n }\n if (rookEl !== null) {\n const { dx, dy } = deltaFromTo(d.rookFrom, d.rookTo, sqSize, orientation);\n animateGlide(rookEl, dx, dy, duration, easing);\n }\n break;\n }\n // `appear` / `disappear` deliberately not animated — they cover\n // edge cases like `load(fen)` where no \"glide\" is meaningful.\n case \"appear\":\n case \"disappear\":\n break;\n }\n }\n}\n\n/** Props for {@link AnimationRunner}. */\nexport interface AnimationRunnerProps {\n readonly model: BoardModel;\n readonly containerRef: RefObject<HTMLElement | null>;\n readonly orientation: Orientation;\n readonly options?: AnimationOptions;\n readonly runtime?: UseAnimationRuntime;\n}\n\n/**\n * Sibling component that owns the animation subscription. Renders `null`;\n * its only job is to translate a scalar slice change (`historyPly`) into\n * a `useLayoutEffect` firing with the descriptors from the just-committed\n * move. Because the subscription lives here — not in `<Chessboard/>` —\n * the root board component no longer re-renders once per move.\n */\nexport function AnimationRunner({\n model,\n containerRef,\n orientation,\n options,\n runtime,\n}: AnimationRunnerProps): ReactNode {\n const duration = options?.durationMs ?? DEFAULT_DURATION_MS;\n const easing = options?.easing ?? DEFAULT_EASING;\n const skipNextRef = runtime?.skipNextRef;\n\n // `historyPly` advances exactly once per committed move (including\n // undo / redo / goto). Subscribing to this single number — via React's\n // default `Object.is` bailout — wakes us exactly when we need to run\n // the post-commit glide. We include `historyPly` in the layout-effect\n // deps below so the effect re-fires on every move; without it, the\n // effect would run once on mount and sit there forever.\n const historyPly = useBoardSlice(model, (s) => s.historyPly);\n const lastAnimatedPlyRef = useRef<number | null>(null);\n\n useLayoutEffect(() => {\n if (lastAnimatedPlyRef.current === historyPly) return;\n lastAnimatedPlyRef.current = historyPly;\n const container = containerRef.current;\n if (container === null) return;\n const descriptors = model.lastAnimations;\n if (descriptors.length === 0) return;\n\n // Drag-initiated commits: consume the skip flag and bail out. The\n // user has already placed the piece at the target; replaying a glide\n // from the source looks like the move is being undone and redone.\n if (skipNextRef?.current) {\n skipNextRef.current = false;\n return;\n }\n\n const effectiveDuration = prefersReducedMotion() ? 0 : duration;\n if (effectiveDuration <= 0) return;\n\n runAnimations(descriptors, container, orientation, effectiveDuration, easing);\n }, [historyPly, model, containerRef, orientation, duration, easing, skipNextRef]);\n\n return null;\n}\n","\"use client\";\n\n/**\n * Right-click drawing gesture.\n *\n * Mirrors the left-click drag hook but listens only for the secondary\n * button. On `pointerdown` we record the origin square. Each `pointermove`\n * updates an in-flight preview arrow via `arrowsLayerRef.setPreview` —\n * **zero React re-renders** per frame, the canvas repaints imperatively.\n * On `pointerup` we commit the arrow through the board model's\n * `toggleArrow` (identical start/end toggles the same-square mark).\n *\n * Also intercepts the browser context menu so right-click doesn't pop the\n * OS menu.\n */\n\nimport { type RefObject, useEffect } from \"react\";\nimport type { ArrowsLayerHandle } from \"../components/arrows-layer.js\";\nimport type { BoardModel, SquareIndex } from \"../core/index.js\";\nimport { getSquareAtPoint } from \"../lib/geometry.js\";\nimport type { Orientation, ResolvedArrowPalette } from \"../types.js\";\n\n/** Resolve modifier keys to a colour channel. */\nfunction colorForModifiers(e: PointerEvent, palette: ResolvedArrowPalette): string {\n if (e.shiftKey) return palette.shift;\n if (e.altKey) return palette.alt;\n if (e.ctrlKey || e.metaKey) return palette.ctrl;\n return palette.default;\n}\n\nexport interface UseArrowGestureOptions {\n readonly game: BoardModel | null;\n readonly orientation: Orientation;\n readonly containerRef: RefObject<HTMLElement | null>;\n readonly arrowsLayerRef: RefObject<ArrowsLayerHandle | null>;\n readonly enabled: boolean;\n /** Fully-resolved colour palette (caller merges prop with defaults). */\n readonly palette: ResolvedArrowPalette;\n /**\n * When `true`, an arrow endpoint that lies on a legal move target\n * from the origin snaps to that target. Typical usage: analysis\n * boards where the user wants to draw future-move hints that align\n * with the rules. Default `false`.\n */\n readonly snapToValidMove?: boolean;\n}\n\n/**\n * Install right-click pointer listeners. Returns nothing — the side effect\n * is the listener registration. Gesture state lives entirely inside the\n * effect's closure and is torn down on unmount / dep change.\n */\nexport function useArrowGesture(options: UseArrowGestureOptions): void {\n const { game, orientation, containerRef, arrowsLayerRef, enabled, palette, snapToValidMove } =\n options;\n\n useEffect(() => {\n if (!enabled) return;\n const container = containerRef.current;\n if (container === null || game === null) return;\n\n let origin: SquareIndex | null = null;\n let activePointerId: number | null = null;\n\n const clearPreview = (): void => {\n arrowsLayerRef.current?.setPreview(null);\n };\n\n /**\n * Constrain a candidate endpoint to a legal target from `origin`\n * when `snapToValidMove` is enabled. Same-square (circle / mark)\n * is always preserved. When the caller hovers a non-legal square,\n * the arrow snaps to the nearest legal target — euclidean on square\n * indices (cheap; no allocations in the hot path because\n * `legalFrom` is already cached by position hash in the model).\n */\n const snap = (candidate: SquareIndex): SquareIndex => {\n if (!snapToValidMove) return candidate;\n if (origin === null) return candidate;\n if (candidate === origin) return candidate;\n const legals = game.legalFrom(origin);\n if (legals.size === 0 || legals.has(candidate)) return candidate;\n // File/rank diff to the candidate; square-index euclidean is a\n // fine proxy since we're comparing targets on an 8×8 grid.\n const cf = candidate & 7;\n const cr = candidate >> 3;\n let best = candidate;\n let bestDist = Infinity;\n for (const t of legals) {\n const df = (t & 7) - cf;\n const dr = (t >> 3) - cr;\n const d = df * df + dr * dr;\n if (d < bestDist) {\n bestDist = d;\n best = t;\n }\n }\n return best;\n };\n\n const setPreview = (to: SquareIndex, color: string): void => {\n if (origin === null) return;\n arrowsLayerRef.current?.setPreview({ from: origin, to: snap(to), color });\n };\n\n const onContextMenu = (e: MouseEvent): void => {\n // Suppress the browser menu whenever arrow drawing is armed — otherwise\n // the OS context menu steals the pointerup and leaves the preview ghost\n // on the board.\n e.preventDefault();\n };\n\n const onPointerDown = (e: PointerEvent): void => {\n if (e.button !== 2) return;\n const sq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (sq === null) return;\n origin = sq;\n activePointerId = e.pointerId;\n // Initial preview: a same-square \"mark\" at the origin.\n setPreview(sq, colorForModifiers(e, palette));\n try {\n container.setPointerCapture(e.pointerId);\n } catch {\n /* pointer capture not supported in this environment */\n }\n };\n\n const onPointerMove = (e: PointerEvent): void => {\n if (origin === null) return;\n if (activePointerId !== null && e.pointerId !== activePointerId) return;\n const sq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (sq === null) {\n // Pointer left the board — show the preview as a mark at origin.\n setPreview(origin, colorForModifiers(e, palette));\n return;\n }\n setPreview(sq, colorForModifiers(e, palette));\n };\n\n const onPointerUp = (e: PointerEvent): void => {\n if (origin === null) return;\n if (activePointerId !== null && e.pointerId !== activePointerId) return;\n const raw = getSquareAtPoint(container, e.clientX, e.clientY, orientation) ?? origin;\n const target = snap(raw);\n const color = colorForModifiers(e, palette);\n game.toggleArrow({ from: origin, to: target, color });\n origin = null;\n activePointerId = null;\n clearPreview();\n };\n\n const onPointerCancel = (e: PointerEvent): void => {\n if (origin === null) return;\n if (activePointerId !== null && e.pointerId !== activePointerId) return;\n origin = null;\n activePointerId = null;\n clearPreview();\n };\n\n container.addEventListener(\"contextmenu\", onContextMenu);\n container.addEventListener(\"pointerdown\", onPointerDown);\n container.addEventListener(\"pointermove\", onPointerMove, { passive: true });\n container.addEventListener(\"pointerup\", onPointerUp);\n container.addEventListener(\"pointercancel\", onPointerCancel);\n\n return (): void => {\n container.removeEventListener(\"contextmenu\", onContextMenu);\n container.removeEventListener(\"pointerdown\", onPointerDown);\n container.removeEventListener(\"pointermove\", onPointerMove);\n container.removeEventListener(\"pointerup\", onPointerUp);\n container.removeEventListener(\"pointercancel\", onPointerCancel);\n clearPreview();\n };\n }, [game, orientation, containerRef, arrowsLayerRef, enabled, palette, snapToValidMove]);\n}\n","\"use client\";\n\n/**\n * Click-to-move handler.\n *\n * Given a `BoardModel`, returns a stable `(index) => void` that implements\n * the standard chess-UI click semantics:\n *\n * | Prior state | Clicked square | Result |\n * |------------------|-------------------|-----------------------------------|\n * | nothing selected | own piece | select it |\n * | nothing selected | empty / opponent | no-op |\n * | piece selected | same square | deselect |\n * | piece selected | legal target | play (or defer to onPromotion) |\n * | piece selected | own piece | switch selection |\n * | piece selected | illegal square | deselect |\n *\n * The handler reads `model.getSnapshot()` at click time and does not\n * subscribe — the component wrapping this hook never re-renders because of\n * it.\n *\n * When a promotion is required:\n *\n * - If `onPromotionNeeded` is supplied, it's invoked with `(from, to)` and\n * `tryMove` is NOT called — the caller is responsible for resolving the\n * promotion and invoking `model.tryMove(from, to, chosenPiece)`.\n * - Otherwise we auto-promote to queen. This keeps the zero-config default\n * behaviour intact.\n */\n\nimport { useCallback } from \"react\";\nimport {\n type BoardModel,\n Color,\n type PackedMove,\n PieceType,\n type SquareIndex,\n} from \"../core/index.js\";\n\n/** Pawn = piece-type 0; rank 7 / rank 0 is the last rank for white / black. */\nfunction wouldPromote(fromCell: number, toIndex: SquareIndex): boolean {\n if (fromCell === 0) return false;\n const pieceType = (fromCell - 1) % 6;\n if (pieceType !== PieceType.Pawn) return false;\n const toRank = toIndex >> 3;\n return toRank === 0 || toRank === 7;\n}\n\n/**\n * @param model The board model, or `null` while the engine is loading.\n * @param onMove Optional callback fired on every successful move.\n * @param onPromotionNeeded Optional deferred-promotion handler. When\n * provided, `tryMove` is not called — the caller resolves the promotion\n * piece and invokes `model.tryMove` itself.\n * @param enabled Gate click-to-move. When `false` the returned callback\n * is a no-op — used by `viewOnly` boards and anywhere the caller needs\n * a stable identity while suppressing input. Defaults to `true`.\n */\nexport function useClickToMove(\n model: BoardModel | null,\n onMove?: (m: PackedMove) => void,\n onPromotionNeeded?: (from: SquareIndex, to: SquareIndex) => void,\n enabled = true,\n): (index: SquareIndex) => void {\n return useCallback(\n (index: SquareIndex) => {\n if (!enabled) return;\n if (model === null) return;\n const snap = model.getSnapshot();\n const cell = snap.board[index] ?? 0;\n const pieceColour = cell === 0 ? -1 : cell > 6 ? Color.Black : Color.White;\n\n if (snap.selected === null) {\n if (pieceColour === snap.turn) model.selectSquare(index);\n return;\n }\n\n if (snap.selected === index) {\n model.selectSquare(null);\n return;\n }\n\n if (snap.legalTargets.has(index)) {\n const fromCell = snap.board[snap.selected] ?? 0;\n if (wouldPromote(fromCell, index)) {\n if (onPromotionNeeded !== undefined) {\n onPromotionNeeded(snap.selected, index);\n return;\n }\n const played = model.tryMove(snap.selected, index, PieceType.Queen);\n if (played !== null && onMove !== undefined) onMove(played);\n return;\n }\n const played = model.tryMove(snap.selected, index);\n if (played !== null && onMove !== undefined) onMove(played);\n return;\n }\n\n if (pieceColour === snap.turn) {\n model.selectSquare(index);\n return;\n }\n\n model.selectSquare(null);\n },\n [model, onMove, onPromotionNeeded, enabled],\n );\n}\n","\"use client\";\n\n/**\n * `useCursorController` — cursor paint for grabbable pieces via a\n * single container-level attribute plus CSS matching.\n *\n * ### Why this exists\n *\n * The board's pointer cursor is a signal: hover a piece you can pick up,\n * see `grab`; drag it, see `grabbing`; hover an empty square or a piece\n * that isn't yours to move, see the normal `pointer`. That's how every\n * native chess UI (lichess / chess.com / chessground) behaves.\n *\n * ### Design — why not per-square data-attributes\n *\n * An earlier version of this controller imperatively wrote\n * `data-gb-grabbable=\"true\"` on every square that currently held a\n * pickup-eligible piece. The diff logic was correct, but every turn\n * flip changes grabbable status for 16 white + 16 black piece squares,\n * so a single move dispatched **32 DOM attribute mutations**. For a\n * 40-ply game that's 1 280 attribute writes — the library's largest\n * source of DOM churn per move, visible in the mutation-audit bench.\n *\n * The new design writes **one** container-level attribute per turn\n * flip and lets CSS express which pieces are grabbable based on data\n * already present on each piece slot:\n *\n * - `data-gb-turn=\"white\" | \"black\"` on the board container\n * — one attribute write per commit in which `turn` changes.\n * - `data-gb-premove=\"true\"` on the container when `allowPremove`\n * is on — one attribute write when premove availability changes.\n * - `[data-piece-cell]` is already set on every `PieceSlot`\n * (1..6 white, 7..12 black); see `piece-layer.tsx`.\n *\n * The injected CSS rules target piece slots directly, flipping\n * `pointer-events: auto` + `cursor: grab` on them. Because piece slots\n * render inside an overlay that normally has `pointer-events: none`,\n * this has the side-benefit of making ONLY grabbable pieces intercept\n * pointer events — click-to-move / drag initiation still fire via the\n * board's bubbling listener.\n *\n * Net effect:\n * Before: 32 attribute writes per turn flip (per-square)\n * After: 0-1 attribute write per turn flip (per-container)\n * ≈ 98 % reduction in cursor-system DOM mutations per move.\n */\n\nimport { type RefObject, useEffect } from \"react\";\nimport type { BoardModel } from \"../core/index.js\";\n\n/** Singleton id used to dedupe the injected `<style>` element. */\nconst STYLE_ID = \"gb-cursor-styles\";\n\n/**\n * Inject the cursor CSS once per document. SSR-safe (early-returns).\n *\n * Rule precedence (later rules win on ties):\n * 1. Every square defaults to `pointer`.\n * 2. Piece slots whose cell code belongs to the side-to-move get\n * `cursor: grab` and `pointer-events: auto` so the cursor on the\n * piece reads correctly and the piece intercepts the pointerdown.\n * 3. Same for `data-gb-premove=\"true\"` + opposite-colour pieces.\n * 4. While any descendant square is under an active drag (the board\n * container carries `data-gb-dragging=\"true\"`), every square\n * reads `grabbing`.\n */\nfunction injectCursorStyles(): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(STYLE_ID) !== null) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = `\n[data-gb-square] {\n cursor: pointer;\n}\n[data-gb-turn=\"white\"] [data-piece-cell=\"1\"],\n[data-gb-turn=\"white\"] [data-piece-cell=\"2\"],\n[data-gb-turn=\"white\"] [data-piece-cell=\"3\"],\n[data-gb-turn=\"white\"] [data-piece-cell=\"4\"],\n[data-gb-turn=\"white\"] [data-piece-cell=\"5\"],\n[data-gb-turn=\"white\"] [data-piece-cell=\"6\"],\n[data-gb-turn=\"black\"] [data-piece-cell=\"7\"],\n[data-gb-turn=\"black\"] [data-piece-cell=\"8\"],\n[data-gb-turn=\"black\"] [data-piece-cell=\"9\"],\n[data-gb-turn=\"black\"] [data-piece-cell=\"10\"],\n[data-gb-turn=\"black\"] [data-piece-cell=\"11\"],\n[data-gb-turn=\"black\"] [data-piece-cell=\"12\"] {\n pointer-events: auto;\n cursor: grab;\n}\n[data-gb-premove=\"true\"][data-gb-turn=\"white\"] [data-piece-cell=\"7\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"white\"] [data-piece-cell=\"8\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"white\"] [data-piece-cell=\"9\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"white\"] [data-piece-cell=\"10\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"white\"] [data-piece-cell=\"11\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"white\"] [data-piece-cell=\"12\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"black\"] [data-piece-cell=\"1\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"black\"] [data-piece-cell=\"2\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"black\"] [data-piece-cell=\"3\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"black\"] [data-piece-cell=\"4\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"black\"] [data-piece-cell=\"5\"],\n[data-gb-premove=\"true\"][data-gb-turn=\"black\"] [data-piece-cell=\"6\"] {\n pointer-events: auto;\n cursor: grab;\n}\n[data-gb-dragging=\"true\"] [data-gb-square],\n[data-gb-dragging=\"true\"] [data-piece-cell] {\n cursor: grabbing;\n}\n`;\n document.head.appendChild(style);\n}\n\n/**\n * Paint `data-gb-turn` (and, when applicable, `data-gb-premove`) on\n * the board container. One attribute write per turn flip, independent\n * of how many pieces are on the board.\n *\n * @param model The board model, or `null` while the engine is loading.\n * @param containerRef Ref to the board container — the root of the\n * ARIA grid and the element that carries every container-level\n * interaction attribute (dragging, turn, premove).\n * @param allowDrag When `false`, no piece is grabbable — the container\n * drops the `data-gb-turn` attribute entirely so the CSS rules no\n * longer match.\n * @param allowPremove When `true`, pieces of the colour that's **not**\n * to move are also grabbable (premove queueing).\n */\nexport function useCursorController(\n model: BoardModel | null,\n containerRef: RefObject<HTMLElement | null>,\n allowDrag: boolean,\n allowPremove: boolean,\n): void {\n useEffect(() => {\n injectCursorStyles();\n }, []);\n\n useEffect(() => {\n if (model === null) return;\n\n // Track the last value we wrote so we only touch the DOM on change.\n // DOMStringMap deletion on an already-absent key is a no-op, but the\n // browser still serialises the call — this guard keeps the observer\n // clean in test environments.\n let lastTurn: \"white\" | \"black\" | null = null;\n let lastPremove: boolean | null = null;\n\n const write = (): void => {\n const el = containerRef.current;\n if (el === null) return;\n if (!allowDrag) {\n // Drag is off — CSS rules won't match anything without the\n // attribute, so pull it cleanly if it was set.\n if (lastTurn !== null) {\n delete el.dataset[\"gbTurn\"];\n lastTurn = null;\n }\n if (lastPremove !== null) {\n delete el.dataset[\"gbPremove\"];\n lastPremove = null;\n }\n return;\n }\n const turn = model.getSnapshot().turn === 0 ? \"white\" : \"black\";\n if (turn !== lastTurn) {\n el.dataset[\"gbTurn\"] = turn;\n lastTurn = turn;\n }\n if (allowPremove !== lastPremove) {\n if (allowPremove) {\n el.dataset[\"gbPremove\"] = \"true\";\n } else {\n delete el.dataset[\"gbPremove\"];\n }\n lastPremove = allowPremove;\n }\n };\n\n write();\n const unsubscribe = model.subscribe(write);\n return () => {\n unsubscribe();\n const el = containerRef.current;\n if (el !== null) {\n delete el.dataset[\"gbTurn\"];\n delete el.dataset[\"gbPremove\"];\n }\n };\n }, [model, containerRef, allowDrag, allowPremove]);\n}\n","\"use client\";\n\n/**\n * Pointer-driven drag orchestration.\n *\n * The hook attaches `pointerdown`/`pointermove`/`pointerup`/`pointercancel`\n * listeners to a container ref and threads them through the drag state\n * machine from `gigaboard/core`.\n *\n * ### Why event listeners on the container (not per square)\n *\n * We need a single source of truth for every pointer sample during a drag:\n * the pointer naturally crosses square boundaries many times in a single\n * drag. Attaching per-square `onPointerMove` handlers would register 64\n * React listeners and re-subscribe every render. A single container\n * listener is one registration that never re-subscribes.\n *\n * ### Zero React renders per frame during drag\n *\n * During the `dragging` state we never call `setState`. Instead the hook\n * writes to `dragLayerRef.current.style.transform` in the pointer-move\n * handler. React sees nothing change until drag-end, at which point one\n * commit finishes the interaction (and the model's own commit renders the\n * new position).\n *\n * ### Contract with the caller\n *\n * - Provide a `containerRef` to the outermost board container (has 1:1\n * geometry with the 8×8 grid).\n * - Provide a `dragLayerRef` to the single absolutely-positioned element\n * that represents the floating piece; the hook writes its `transform`.\n * - `onDragStart(from, cell)` is called once when the drag crosses the\n * activation threshold. The caller should render the piece into the\n * drag layer (via React state) and imperatively hide the origin.\n * - `onDrop(from, to)` is called when a drop lands on a different square.\n * Illegal moves are the caller's problem — the hook merely reports the\n * user's intent.\n * - `onDragEnd()` is called on every terminal transition (drop, cancel,\n * same-square drop). The caller restores DOM opacity and clears the\n * drag-layer render state.\n */\n\nimport { type RefObject, useEffect, useRef } from \"react\";\nimport type { DragLayerHandle } from \"../components/drag-layer.js\";\nimport {\n type BoardCell,\n type BoardModel,\n createDragController,\n type SquareIndex,\n} from \"../core/index.js\";\nimport { CSS_VARS } from \"../default-theme.js\";\nimport { algebraicOf, getSquareAtPoint } from \"../lib/geometry.js\";\nimport type { Orientation } from \"../types.js\";\n\n/** CSS variable the theme uses to control drag-origin opacity. */\nconst GHOST_OPACITY_VAR = CSS_VARS.DRAG_GHOST_OPACITY;\n\n/** Options passed to {@link useDrag}. */\nexport interface UseDragOptions {\n readonly game: BoardModel | null;\n readonly orientation: Orientation;\n readonly containerRef: RefObject<HTMLElement | null>;\n /**\n * Imperative handle to the always-mounted drag overlay. `useDrag`\n * calls `show`, `setTransform`, and `hide` here from its pointer\n * handlers — zero React state changes during the drag loop (and\n * crucially, none at drag-start either).\n */\n readonly dragLayerRef: RefObject<DragLayerHandle | null>;\n readonly enabled: boolean;\n /** The activation distance (pixels) for `pending → dragging`. */\n readonly activationDistance?: number;\n /** Callbacks — see hook docs above. */\n readonly onDragStart: (from: SquareIndex, cell: BoardCell) => void;\n readonly onDragEnd: () => void;\n readonly onDrop: (from: SquareIndex, to: SquareIndex) => void;\n /**\n * Optional per-piece gate. If provided and it returns `false` for the\n * would-be drag source, pointer-down is silently ignored and no drag\n * initiates. Called once per attempt, never during a drag.\n */\n readonly canDragPiece?: (ctx: {\n readonly square: SquareIndex;\n readonly cell: BoardCell;\n }) => boolean;\n}\n\n/**\n * Install pointer listeners for drag-and-drop. Listeners stay registered for\n * the lifetime of the containing component.\n */\nexport function useDrag(options: UseDragOptions): void {\n const {\n game,\n orientation,\n containerRef,\n dragLayerRef,\n enabled,\n activationDistance,\n onDragStart,\n onDragEnd,\n onDrop,\n canDragPiece,\n } = options;\n\n // Latest-ref so the caller can pass a fresh predicate every render\n // without tearing down the pointer listeners. Absorbed here — not at\n // the call site — so consumers don't have to wrap every time.\n const canDragPieceRef = useRef(canDragPiece);\n useEffect(() => {\n canDragPieceRef.current = canDragPiece;\n });\n\n useEffect(() => {\n if (!enabled) return;\n const container = containerRef.current;\n if (container === null || game === null) return;\n\n const controller = createDragController(\n activationDistance === undefined ? {} : { activationDistance },\n );\n\n // Imperative drag internals. Mutating these does NOT re-render.\n let originEl: HTMLElement | null = null;\n let active = false;\n let activePointerId: number | null = null;\n\n const writeTransform = (clientX: number, clientY: number): void => {\n const layer = dragLayerRef.current;\n if (layer === null) return;\n const rect = container.getBoundingClientRect();\n const sqSize = rect.width / 8;\n // Centre the piece on the pointer.\n const x = clientX - rect.left - sqSize / 2;\n const y = clientY - rect.top - sqSize / 2;\n layer.setTransform(x, y);\n };\n\n const restoreOrigin = (): void => {\n if (originEl !== null) {\n originEl.style.opacity = \"\";\n originEl = null;\n }\n };\n\n const cleanup = (): void => {\n restoreOrigin();\n // Hide the ghost imperatively; no React state change.\n dragLayerRef.current?.hide();\n active = false;\n activePointerId = null;\n onDragEnd();\n };\n\n const onPointerDown = (e: PointerEvent): void => {\n // Primary button only. Right-clicks are reserved for arrows (M4).\n // Multi-touch is defended by drag-controller's pointerId tracking.\n if (e.button !== 0) return;\n const sq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (sq === null) return;\n const cell = game.getSnapshot().board[sq] ?? 0;\n if (cell === 0) return;\n // Caller-supplied gate. Fires on the cold activation path — never\n // during a drag — so the ref deref is free on the hot loop.\n const canDrag = canDragPieceRef.current;\n if (canDrag !== undefined && !canDrag({ square: sq, cell: cell as BoardCell })) {\n return;\n }\n const consumed = controller.pointerDown(sq, e.pointerId, e.clientX, e.clientY);\n if (consumed) activePointerId = e.pointerId;\n };\n\n const onPointerMove = (e: PointerEvent): void => {\n const evt = controller.pointerMove(e.pointerId, e.clientX, e.clientY);\n if (evt === null) return;\n\n if (evt.kind === \"drag-start\") {\n const cell = (game.getSnapshot().board[evt.from] ?? 0) as BoardCell;\n if (cell === 0) {\n // Piece disappeared between down and move — treat as cancel.\n controller.cancel();\n return;\n }\n // Fade the origin piece imperatively (no re-render). The target\n // opacity is sourced from `--gb-drag-ghost-opacity` on the board\n // container so themes control the look — `0` for chess.com's\n // vanish-on-drag, `0.35` for lichess-style translucent ghost.\n // Reading via `var(...)` inside the inline style keeps the value\n // live: users can toggle the CSS var and the next drag reflects\n // it without a remount.\n const originLabel = algebraicOf(evt.from);\n originEl = container.querySelector<HTMLElement>(`[data-piece-square=\"${originLabel}\"]`);\n if (originEl !== null) {\n // Fallback `0.35` matches the lichess convention and keeps the\n // behaviour correct when the caller swaps in a theme that\n // doesn't define the variable (theme records replace — not\n // merge with — the default theme).\n originEl.style.opacity = `var(${GHOST_OPACITY_VAR}, 0.35)`;\n }\n\n active = true;\n try {\n container.setPointerCapture(e.pointerId);\n } catch {\n // Some test environments don't support pointer capture; ignore.\n }\n\n // Show the ghost imperatively — no React state change, no\n // `flushSync`, no synchronous re-render of `<Chessboard/>`.\n // This is the fix that closes the 25 ms drag-peak gap with\n // chessground in real Chromium.\n dragLayerRef.current?.show(cell);\n writeTransform(e.clientX, e.clientY);\n\n // `onDragStart` still fires for callers that need to react\n // (clear arrows, set `selectSquare` to show legal targets,\n // analytics, haptic feedback, etc.) — but it no longer drives\n // the drag-layer visibility.\n onDragStart(evt.from, cell);\n return;\n }\n\n // drag-move: imperative only, no React involvement.\n writeTransform(e.clientX, e.clientY);\n };\n\n const onPointerUp = (e: PointerEvent): void => {\n const evt = controller.pointerUp(e.pointerId, e.clientX, e.clientY);\n if (evt === null) return;\n\n if (evt.kind === \"drop\") {\n const target = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (target !== null && target !== evt.from) {\n onDrop(evt.from, target);\n }\n }\n // \"click\" kind is ignored — Square.onClick handles simple clicks; the\n // browser only fires click if the pointer didn't move past threshold.\n\n if (active) cleanup();\n activePointerId = null;\n };\n\n const onPointerCancel = (e: PointerEvent): void => {\n if (activePointerId !== null && e.pointerId !== activePointerId) return;\n controller.cancel();\n if (active) cleanup();\n activePointerId = null;\n };\n\n // Passive listeners where possible; pointer-move gets `passive: true`\n // since we never call preventDefault inside.\n container.addEventListener(\"pointerdown\", onPointerDown);\n container.addEventListener(\"pointermove\", onPointerMove, { passive: true });\n container.addEventListener(\"pointerup\", onPointerUp);\n container.addEventListener(\"pointercancel\", onPointerCancel);\n\n return (): void => {\n container.removeEventListener(\"pointerdown\", onPointerDown);\n container.removeEventListener(\"pointermove\", onPointerMove);\n container.removeEventListener(\"pointerup\", onPointerUp);\n container.removeEventListener(\"pointercancel\", onPointerCancel);\n if (active) cleanup();\n };\n }, [\n game,\n orientation,\n containerRef,\n dragLayerRef,\n enabled,\n activationDistance,\n onDragStart,\n onDragEnd,\n onDrop,\n ]);\n}\n","\"use client\";\n\n/**\n * Per-square pointer-hover tracker.\n *\n * One `pointermove` + `pointerleave` listener on the container diffs the\n * current square against the previous, firing `onEnter`/`onLeave` once\n * per transition. Attaching handlers per-square would cost 64 React\n * listeners and break the \"0 re-renders per hover\" budget\n * (STANDARDS.md §4.2).\n *\n * Callbacks read through latest-refs so a fresh arrow function each\n * render doesn't re-install the effect.\n */\n\nimport { type RefObject, useEffect, useRef } from \"react\";\nimport type { BoardCell, BoardModel, SquareIndex } from \"../core/index.js\";\nimport { getSquareAtPoint } from \"../lib/geometry.js\";\nimport type { Orientation } from \"../types.js\";\n\n/** Context passed to hover callbacks. */\nexport interface HoverSquareContext {\n readonly square: SquareIndex;\n readonly cell: BoardCell;\n}\n\n/** Options for {@link useHoverSquare}. */\nexport interface UseHoverSquareOptions {\n readonly game: BoardModel | null;\n readonly orientation: Orientation;\n readonly containerRef: RefObject<HTMLElement | null>;\n readonly enabled: boolean;\n readonly onEnter?: (ctx: HoverSquareContext) => void;\n readonly onLeave?: (ctx: HoverSquareContext) => void;\n}\n\nexport function useHoverSquare(options: UseHoverSquareOptions): void {\n const { game, orientation, containerRef, enabled, onEnter, onLeave } = options;\n\n const onEnterRef = useRef(onEnter);\n const onLeaveRef = useRef(onLeave);\n useEffect(() => {\n onEnterRef.current = onEnter;\n onLeaveRef.current = onLeave;\n });\n\n useEffect(() => {\n if (!enabled) return;\n const container = containerRef.current;\n if (container === null) return;\n\n let current: SquareIndex | null = null;\n\n const cellAt = (sq: SquareIndex): BoardCell =>\n game === null ? (0 as BoardCell) : ((game.getSnapshot().board[sq] ?? 0) as BoardCell);\n\n const onPointerMove = (e: PointerEvent): void => {\n const sq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (sq === current) return;\n if (current !== null) onLeaveRef.current?.({ square: current, cell: cellAt(current) });\n if (sq !== null) onEnterRef.current?.({ square: sq, cell: cellAt(sq) });\n current = sq;\n };\n\n const onPointerLeave = (): void => {\n if (current === null) return;\n onLeaveRef.current?.({ square: current, cell: cellAt(current) });\n current = null;\n };\n\n container.addEventListener(\"pointermove\", onPointerMove, { passive: true });\n container.addEventListener(\"pointerleave\", onPointerLeave);\n\n return () => {\n container.removeEventListener(\"pointermove\", onPointerMove);\n container.removeEventListener(\"pointerleave\", onPointerLeave);\n if (current !== null) {\n onLeaveRef.current?.({ square: current, cell: cellAt(current) });\n current = null;\n }\n };\n }, [game, orientation, containerRef, enabled]);\n}\n","\"use client\";\n\n/**\n * Keyboard navigation for the 8×8 grid.\n *\n * Implements the WAI-ARIA \"Grid\" authoring pattern:\n *\n * - Tab brings focus to the board via a roving tabindex — only the\n * currently-focused square has `tabindex=0`; every other cell has\n * `tabindex=-1`, so Tab moves straight out of the grid once the user\n * is done.\n * - Arrow keys move the focus between squares (visual up/down/left/right,\n * orientation-aware).\n * - Enter / Space activate the focused square (same path as a mouse click).\n * - Escape clears the selection + any drawn arrows.\n * - Home / End jump to the first / last square in the focused rank.\n * - Ctrl+Home / Ctrl+End jump to the first / last square on the board.\n *\n * The hook is controlled: the caller owns `focusedSquare` state. This\n * lets {@link Chessboard} integrate the keyboard focus with other\n * board-level state (selection, drag, promotion dialog).\n */\n\nimport { type RefObject, useEffect } from \"react\";\nimport type { SquareIndex } from \"../core/index.js\";\nimport type { Orientation } from \"../types.js\";\n\n/**\n * Translate a visual direction into a new square index, honouring\n * orientation so arrow keys always move focus the way the user sees it.\n */\nfunction moveFocus(\n current: SquareIndex,\n direction: \"up\" | \"down\" | \"left\" | \"right\",\n orientation: Orientation,\n): SquareIndex {\n const file = current & 7;\n const rank = current >> 3;\n const col = orientation === \"white\" ? file : 7 - file;\n const row = orientation === \"white\" ? 7 - rank : rank;\n\n let newCol = col;\n let newRow = row;\n switch (direction) {\n case \"up\":\n newRow = Math.max(0, row - 1);\n break;\n case \"down\":\n newRow = Math.min(7, row + 1);\n break;\n case \"left\":\n newCol = Math.max(0, col - 1);\n break;\n case \"right\":\n newCol = Math.min(7, col + 1);\n break;\n }\n\n const newFile = orientation === \"white\" ? newCol : 7 - newCol;\n const newRank = orientation === \"white\" ? 7 - newRow : newRow;\n return (newRank * 8 + newFile) as SquareIndex;\n}\n\n/** Jump to the first / last file in the same rank as `current`, orientation-aware. */\nfunction rankEnd(\n current: SquareIndex,\n which: \"home\" | \"end\",\n orientation: Orientation,\n): SquareIndex {\n const rank = current >> 3;\n if (orientation === \"white\") {\n return ((rank << 3) | (which === \"home\" ? 0 : 7)) as SquareIndex;\n }\n return ((rank << 3) | (which === \"home\" ? 7 : 0)) as SquareIndex;\n}\n\n/** Jump to a board corner. */\nfunction boardCorner(which: \"home\" | \"end\", orientation: Orientation): SquareIndex {\n // \"home\" = visual top-left, \"end\" = visual bottom-right.\n if (orientation === \"white\") {\n return (which === \"home\" ? 56 : 7) as SquareIndex;\n }\n return (which === \"home\" ? 7 : 56) as SquareIndex;\n}\n\n/** Options accepted by {@link useKeyboardNav}. */\nexport interface UseKeyboardNavOptions {\n readonly containerRef: RefObject<HTMLElement | null>;\n readonly orientation: Orientation;\n readonly focusedSquare: SquareIndex | null;\n readonly setFocusedSquare: (square: SquareIndex) => void;\n readonly onActivate: (square: SquareIndex) => void;\n readonly onEscape: () => void;\n readonly enabled: boolean;\n}\n\n/**\n * Attach keyboard navigation listeners to the board container. All motion\n * is expressed via `setFocusedSquare` — the render layer is responsible\n * for applying `tabindex` and programmatic focus based on that state.\n */\nexport function useKeyboardNav(options: UseKeyboardNavOptions): void {\n const {\n containerRef,\n orientation,\n focusedSquare,\n setFocusedSquare,\n onActivate,\n onEscape,\n enabled,\n } = options;\n\n useEffect(() => {\n if (!enabled) return;\n const container = containerRef.current;\n if (container === null) return;\n\n const onKeyDown = (e: KeyboardEvent): void => {\n // Only consume keys if focus is somewhere inside our container —\n // otherwise a user typing in an unrelated input would have Tab or\n // Arrow keys hijacked.\n if (!container.contains(e.target as Node)) return;\n const current = focusedSquare;\n if (current === null) return;\n\n switch (e.key) {\n case \"ArrowUp\":\n e.preventDefault();\n setFocusedSquare(moveFocus(current, \"up\", orientation));\n return;\n case \"ArrowDown\":\n e.preventDefault();\n setFocusedSquare(moveFocus(current, \"down\", orientation));\n return;\n case \"ArrowLeft\":\n e.preventDefault();\n setFocusedSquare(moveFocus(current, \"left\", orientation));\n return;\n case \"ArrowRight\":\n e.preventDefault();\n setFocusedSquare(moveFocus(current, \"right\", orientation));\n return;\n case \"Home\":\n e.preventDefault();\n setFocusedSquare(\n e.ctrlKey || e.metaKey\n ? boardCorner(\"home\", orientation)\n : rankEnd(current, \"home\", orientation),\n );\n return;\n case \"End\":\n e.preventDefault();\n setFocusedSquare(\n e.ctrlKey || e.metaKey\n ? boardCorner(\"end\", orientation)\n : rankEnd(current, \"end\", orientation),\n );\n return;\n case \"Enter\":\n case \" \":\n e.preventDefault();\n onActivate(current);\n return;\n case \"Escape\":\n e.preventDefault();\n onEscape();\n return;\n default:\n return;\n }\n };\n\n container.addEventListener(\"keydown\", onKeyDown);\n return () => container.removeEventListener(\"keydown\", onKeyDown);\n }, [containerRef, orientation, focusedSquare, setFocusedSquare, onActivate, onEscape, enabled]);\n}\n","\"use client\";\n\n/**\n * `useLastMoveController` — imperative last-move tint paint.\n *\n * Mirror of `useSelectionController` for the from/to last-move\n * highlight. Previously rendered as `<LastMoveLayer/>`, a React\n * component that emitted two fresh `<div>` tints on every move\n * commit. Those two divs were real DOM + layout + paint work\n * inside the same commit as the move itself — which in Chromium\n * showed up as part of the \"drop frame\" peak during drag storms.\n *\n * The new controller:\n *\n * 1. Subscribes to the model via `model.subscribe` inside a\n * `useEffect`. Never calls `setState`, never triggers React.\n * 2. On each commit, derives `(from, to)` from `s.lastMove` and\n * diffs against the previously-painted pair.\n * 3. Writes `el.dataset.gbLastMove = \"from\" | \"to\"` on only the\n * changed squares — removing the attribute for squares that\n * are no longer either endpoint of the last move.\n * 4. CSS (injected once per document by `injectLastMoveStyles`)\n * paints a `::after` pseudo-element with the `--gb-last-move`\n * theme variable.\n *\n * Uses `::after` rather than `::before` because the selection\n * controller already owns `::before`. Paint order ends up\n * `background → selection tint (::before) → last-move tint\n * (::after)` — for the rare overlap where a square is both\n * selected AND one end of the last move, last-move paints on top.\n * That's a reversal of the old Chessboard JSX order, but the\n * visual difference between \"selection on top of last-move\" and\n * \"last-move on top of selection\" is imperceptible when both use\n * semi-transparent rgba tints.\n */\n\nimport { type RefObject, useEffect } from \"react\";\nimport { type BoardModel, isNullMove, type SquareIndex } from \"../core/index.js\";\n\n/** Values written to `data-gb-last-move`. */\ntype LastMoveState = \"from\" | \"to\";\n\n/** Singleton id used to dedupe the injected `<style>` element. */\nconst STYLE_ID = \"gb-last-move-styles\";\n\n/**\n * Inject the last-move CSS once per document. SSR-safe (early-returns).\n *\n * The `::after` pseudo-element is declared on EVERY square (with a\n * transparent background) rather than only when the attribute matches.\n * That pre-materialises 64 rendering nodes during mount — the same\n * trick used by the selection controller — so the user's first move\n * doesn't pay for first-match pseudo-element creation + first-paint of\n * the tint as an INP outlier. The `data-gb-last-move` attribute then\n * only changes `background`, which repaints an already-live node.\n */\nfunction injectLastMoveStyles(): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(STYLE_ID) !== null) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = `\n[data-gb-square]::after {\n content: \"\";\n position: absolute;\n inset: 0;\n background: transparent;\n pointer-events: none;\n}\n[data-gb-square][data-gb-last-move]::after {\n background: var(--gb-last-move);\n}\n`;\n document.head.appendChild(style);\n}\n\n/**\n * Imperatively paint the from/to tints of the most recent move.\n *\n * @param model The board model, or `null` while the engine is loading.\n * @param squareRefs 64-slot refs array from `<BoardGrid/>`. Each slot\n * is the DOM node of the square at that LERF index, or `null` if\n * unmounted.\n * @param enabled When `false`, the controller clears any existing\n * last-move tint and does nothing further. Matches the contract of\n * the old `highlightLastMove={false}` prop exactly.\n */\nexport function useLastMoveController(\n model: BoardModel | null,\n squareRefs: RefObject<Array<HTMLElement | null>>,\n enabled: boolean,\n): void {\n useEffect(() => {\n injectLastMoveStyles();\n }, []);\n\n useEffect(() => {\n if (model === null) return;\n\n // Track what we painted last so we diff-write only changes.\n let prevFrom: SquareIndex | null = null;\n let prevTo: SquareIndex | null = null;\n\n const write = (i: SquareIndex, val: LastMoveState | null): void => {\n const el = squareRefs.current?.[i];\n if (el === null || el === undefined) return;\n if (val === null) {\n delete el.dataset[\"gbLastMove\"];\n } else {\n el.dataset[\"gbLastMove\"] = val;\n }\n };\n\n const clearAll = (): void => {\n if (prevFrom !== null) write(prevFrom, null);\n if (prevTo !== null) write(prevTo, null);\n prevFrom = null;\n prevTo = null;\n };\n\n if (!enabled) {\n // Nothing to subscribe to — just make sure no stale tint remains.\n return clearAll;\n }\n\n const update = (): void => {\n const snap = model.getSnapshot();\n const lastMove = snap.lastMove;\n\n let from: SquareIndex | null = null;\n let to: SquareIndex | null = null;\n // A pass moves no piece, so it has no from/to to tint. Its sentinel\n // word would otherwise decode to h8→h8 and paint a highlight on a\n // square that never changed.\n if (lastMove !== null && !isNullMove(lastMove)) {\n from = (lastMove & 0x3f) as SquareIndex;\n to = ((lastMove >> 6) & 0x3f) as SquareIndex;\n }\n\n // Early exit when nothing changed.\n if (from === prevFrom && to === prevTo) return;\n\n // Clear any previous endpoint that isn't also one of the new\n // endpoints. (Castling / promotion can keep one endpoint and\n // change the other, so we can't wipe unconditionally.)\n if (prevFrom !== null && prevFrom !== from && prevFrom !== to) {\n write(prevFrom, null);\n }\n if (prevTo !== null && prevTo !== from && prevTo !== to) {\n write(prevTo, null);\n }\n\n // Paint current. If one square is both `from` and `to` (shouldn't\n // happen in normal play, but defensive), `to` wins — it's the\n // landing square.\n if (from !== null && from !== to) write(from, \"from\");\n if (to !== null) write(to, \"to\");\n\n prevFrom = from;\n prevTo = to;\n };\n\n update();\n const unsubscribe = model.subscribe(update);\n return () => {\n unsubscribe();\n clearAll();\n };\n }, [model, squareRefs, enabled]);\n}\n","\"use client\";\n\nimport type { HapticInput, TriggerOptions, WebHaptics } from \"web-haptics\";\n\nexport type { HapticInput, TriggerOptions };\n\nconst COARSE_POINTER_QUERY = \"(hover: none), (pointer: coarse)\";\n\nlet cached: WebHaptics | null | undefined;\nlet pending: Promise<WebHaptics | null> | null = null;\n\nfunction isCoarsePointer(): boolean {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return false;\n }\n return window.matchMedia(COARSE_POINTER_QUERY).matches;\n}\n\nfunction shouldRunHaptics(options: {\n readonly enabled?: boolean;\n readonly mobileOnly?: boolean;\n}): boolean {\n if (options.enabled === false) return false;\n if (options.mobileOnly === false) return true;\n return isCoarsePointer();\n}\n\nasync function getInstance(): Promise<WebHaptics | null> {\n if (cached !== undefined) {\n return cached;\n }\n if (pending !== null) {\n return pending;\n }\n if (typeof window === \"undefined\") {\n cached = null;\n return cached;\n }\n\n pending = import(\"web-haptics\")\n .then(({ WebHaptics }) => {\n try {\n cached = new WebHaptics();\n } catch {\n cached = null;\n }\n return cached;\n })\n .catch(() => {\n cached = null;\n return cached;\n })\n .finally(() => {\n pending = null;\n });\n\n return pending;\n}\n\nexport interface HapticFeedbackOptions extends TriggerOptions {\n /** Master switch. Default `true`. */\n readonly enabled?: boolean;\n /** Restrict haptics to coarse-pointer/mobile-like devices. Default `true`. */\n readonly mobileOnly?: boolean;\n}\n\nexport function triggerHaptic(input?: HapticInput, options: HapticFeedbackOptions = {}): void {\n if (!shouldRunHaptics(options)) {\n return;\n }\n const { enabled: _enabled, mobileOnly: _mobileOnly, ...triggerOptions } = options;\n void getInstance().then((instance) => {\n void instance?.trigger(input, triggerOptions);\n });\n}\n\nexport function warmupHaptics(options: HapticFeedbackOptions = {}): void {\n if (!shouldRunHaptics(options)) {\n return;\n }\n void getInstance();\n}\n","\"use client\";\n\nimport type { HapticInput } from \"web-haptics\";\n\n/** The shared move-feedback cue categories. */\nexport type MoveFeedbackKey =\n | \"moveSelf\"\n | \"moveOpponent\"\n | \"capture\"\n | \"castle\"\n | \"moveCheck\"\n | \"promote\"\n | \"gameEnd\";\n\n/** Default haptic pattern per move-feedback cue. */\nexport const DEFAULT_MOVE_HAPTIC_PATTERNS: Readonly<Record<MoveFeedbackKey, HapticInput>> =\n Object.freeze({\n moveSelf: \"selection\",\n moveOpponent: \"selection\",\n capture: \"medium\",\n castle: \"medium\",\n moveCheck: \"success\",\n promote: \"success\",\n gameEnd: \"success\",\n });\n\n/**\n * Classify the feedback cue that should fire for the given committed move.\n *\n * Priority (highest wins):\n * 1. `gameEnd` if the engine reports `isGameOver`.\n * 2. `promote` / `castle` because structural moves get their own cue.\n * 3. `moveCheck` if the side-to-move is now in check.\n * 4. `capture` if any descriptor is a capture.\n * 5. `moveSelf` / `moveOpponent` otherwise.\n */\nexport function classifyMoveFeedback(\n animations: ReadonlyArray<{ readonly kind: string }>,\n snapshot: { readonly isGameOver: boolean; readonly inCheck: boolean; readonly turn: 0 | 1 },\n perspective: 0 | 1 | undefined,\n): MoveFeedbackKey {\n if (snapshot.isGameOver) return \"gameEnd\";\n\n let sawPromotion = false;\n let sawCastle = false;\n let sawCapture = false;\n for (const d of animations) {\n if (d.kind === \"promotion\") sawPromotion = true;\n else if (d.kind === \"castle\") sawCastle = true;\n else if (d.kind === \"capture\" || d.kind === \"en-passant\") sawCapture = true;\n }\n\n if (sawPromotion) return \"promote\";\n if (sawCastle) return \"castle\";\n if (snapshot.inCheck) return \"moveCheck\";\n if (sawCapture) return \"capture\";\n\n // The side that just moved is the opposite of the new side-to-move.\n if (perspective !== undefined) {\n const moverWasMe = snapshot.turn !== perspective;\n return moverWasMe ? \"moveSelf\" : \"moveOpponent\";\n }\n return \"moveSelf\";\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef } from \"react\";\nimport type { BoardModel } from \"../core/index.js\";\nimport {\n type HapticFeedbackOptions,\n type HapticInput,\n triggerHaptic,\n warmupHaptics,\n} from \"../lib/haptics.js\";\nimport {\n classifyMoveFeedback,\n DEFAULT_MOVE_HAPTIC_PATTERNS,\n type MoveFeedbackKey,\n} from \"../lib/move-feedback.js\";\n\nexport type MoveHapticKey = MoveFeedbackKey;\nexport type MoveHapticPatterns = Partial<Readonly<Record<MoveHapticKey, HapticInput>>>;\nexport type TriggerMoveHaptic = (key: MoveHapticKey) => void;\n\nexport interface MoveHapticOptions {\n /** Master switch. Default `true`. */\n readonly enabled?: boolean;\n /** Per-key haptic overrides. Missing keys fall back to the built-in pattern map. */\n readonly patterns?: MoveHapticPatterns;\n /**\n * Viewer perspective. When set, moves played by this colour use `moveSelf`\n * and moves played by the opponent use `moveOpponent`.\n */\n readonly perspective?: 0 | 1;\n /** Restrict haptics to coarse-pointer/mobile-like devices. Default `true`. */\n readonly mobileOnly?: boolean;\n /** Minimum gap between emitted haptic events. Default `14ms`. */\n readonly minIntervalMs?: number;\n /** Warm the haptic backend on the first user gesture. Default `true`. */\n readonly warmupOnFirstInteraction?: boolean;\n /** Forwarded to `web-haptics` trigger intensity. */\n readonly intensity?: HapticFeedbackOptions[\"intensity\"];\n}\n\nconst DEFAULT_MIN_INTERVAL_MS = 14;\n\nexport function triggerMoveHaptic(\n key: MoveHapticKey,\n {\n enabled = true,\n patterns,\n mobileOnly = true,\n intensity,\n }: Pick<MoveHapticOptions, \"enabled\" | \"patterns\" | \"mobileOnly\" | \"intensity\"> = {},\n): void {\n if (!enabled) {\n return;\n }\n const input = patterns?.[key] ?? DEFAULT_MOVE_HAPTIC_PATTERNS[key];\n triggerHaptic(input, {\n enabled,\n mobileOnly,\n ...(intensity !== undefined ? { intensity } : {}),\n });\n}\n\nexport function useMoveHaptics(\n model: BoardModel | null,\n options: MoveHapticOptions = {},\n): TriggerMoveHaptic {\n const {\n enabled = true,\n patterns,\n perspective,\n mobileOnly = true,\n minIntervalMs = DEFAULT_MIN_INTERVAL_MS,\n warmupOnFirstInteraction = true,\n intensity,\n } = options;\n\n const patternsRef = useRef(patterns);\n useEffect(() => {\n patternsRef.current = patterns;\n });\n\n const perspectiveRef = useRef(perspective);\n useEffect(() => {\n perspectiveRef.current = perspective;\n });\n\n const mobileOnlyRef = useRef(mobileOnly);\n useEffect(() => {\n mobileOnlyRef.current = mobileOnly;\n });\n\n const intensityRef = useRef(intensity);\n useEffect(() => {\n intensityRef.current = intensity;\n });\n\n const lastTriggerAtRef = useRef(0);\n\n const trigger = useCallback<TriggerMoveHaptic>(\n (key) => {\n triggerMoveHaptic(key, {\n enabled,\n ...(patternsRef.current !== undefined ? { patterns: patternsRef.current } : {}),\n mobileOnly: mobileOnlyRef.current,\n ...(intensityRef.current !== undefined ? { intensity: intensityRef.current } : {}),\n });\n },\n [enabled],\n );\n\n useEffect(() => {\n if (!enabled || !warmupOnFirstInteraction) {\n return;\n }\n\n let warmed = false;\n const warmup = () => {\n if (warmed) {\n return;\n }\n warmed = true;\n warmupHaptics({ mobileOnly: mobileOnlyRef.current });\n window.removeEventListener(\"pointerdown\", warmup, true);\n window.removeEventListener(\"touchstart\", warmup, true);\n window.removeEventListener(\"keydown\", warmup, true);\n };\n\n window.addEventListener(\"pointerdown\", warmup, { capture: true, passive: true });\n window.addEventListener(\"touchstart\", warmup, { capture: true, passive: true });\n window.addEventListener(\"keydown\", warmup, { capture: true });\n\n return () => {\n window.removeEventListener(\"pointerdown\", warmup, true);\n window.removeEventListener(\"touchstart\", warmup, true);\n window.removeEventListener(\"keydown\", warmup, true);\n };\n }, [enabled, warmupOnFirstInteraction]);\n\n useEffect(() => {\n if (!enabled || model === null) return;\n\n let prevPly = model.getSnapshot().historyPly;\n\n return model.subscribe(() => {\n const snap = model.getSnapshot();\n if (snap.historyPly <= prevPly) {\n prevPly = snap.historyPly;\n return;\n }\n prevPly = snap.historyPly;\n\n const nowMs = performance.now();\n if (nowMs - lastTriggerAtRef.current < minIntervalMs) {\n return;\n }\n lastTriggerAtRef.current = nowMs;\n\n const key = classifyMoveFeedback(model.lastAnimations, snap, perspectiveRef.current);\n trigger(key);\n });\n }, [enabled, minIntervalMs, model, trigger]);\n\n return trigger;\n}\n","\"use client\";\n\n/**\n * `useMoveSound` — drop-in chess.com-style move-sound effects.\n *\n * Plays one short audio cue on every committed move. The sound is picked\n * from the just-emitted `lastAnimations` descriptors and the post-move\n * snapshot, not from SAN — so the same hook works for drag, click,\n * keyboard, and `tryMove` invocations without any integration boilerplate.\n *\n * ### Design choices\n *\n * 1. **Local assets by default.** The seven chess.com MP3s ship in-package\n * (see `src/sounds/`). Users may override any URL via the `sources`\n * option — set one, set all, or set none. No runtime CDN dependency.\n * 2. **One pool per sound.** Each sound gets a {@link POOL_SIZE}-element\n * pool of `HTMLAudioElement` so rapid-fire clicks don't cut each other\n * off (the browser serializes `.play()` on a single element).\n * 3. **One cue per committed move.** We only fire when `historyPly`\n * advances. Undo / redo-to-same-state is silent (matches chess.com).\n * 4. **SSR-safe.** `new Audio()` is guarded behind a `typeof window`\n * check; the hook does nothing on the server.\n * 5. **`enabled={false}` zeroes all work.** No pool, no subscription, no\n * allocation — pass `false` and the hook returns without side effects.\n *\n * The hook is self-contained: it does not call into the engine adapter,\n * it does not need `san()`, and it will not re-render the component.\n */\n\nimport { useCallback, useEffect, useRef } from \"react\";\nimport type { BoardModel } from \"../core/index.js\";\nimport { classifyMoveFeedback, type MoveFeedbackKey } from \"../lib/move-feedback.js\";\n\n/** The seven categories of move cue, mirroring chess.com's default set. */\nexport type MoveSoundKey = MoveFeedbackKey;\n\n/** Sparse URL map — any key omitted falls back to the built-in local asset. */\nexport type MoveSoundSources = Partial<Readonly<Record<MoveSoundKey, string>>>;\nexport type TriggerMoveSound = (key: MoveSoundKey) => void;\n\n/**\n * Default URL map. Points at the MP3 files shipped with this package; the\n * package build copies them next to the emitted JS under `dist/sounds/`.\n * Keeping these as static `new URL(..., import.meta.url)` expressions lets\n * consumer bundlers such as Vite and Next.js rebase/copy the files correctly.\n *\n * The `typeof import.meta.url` guard keeps the CommonJS build importable in\n * Node; browser ESM consumers get the fully resolved asset URLs.\n */\nexport const DEFAULT_MOVE_SOUND_SOURCES: Readonly<Record<MoveSoundKey, string>> = Object.freeze({\n moveSelf:\n typeof import.meta.url === \"string\"\n ? new URL(\"./sounds/move-self.mp3\", import.meta.url).href\n : \"./sounds/move-self.mp3\",\n moveOpponent:\n typeof import.meta.url === \"string\"\n ? new URL(\"./sounds/move-opponent.mp3\", import.meta.url).href\n : \"./sounds/move-opponent.mp3\",\n capture:\n typeof import.meta.url === \"string\"\n ? new URL(\"./sounds/capture.mp3\", import.meta.url).href\n : \"./sounds/capture.mp3\",\n castle:\n typeof import.meta.url === \"string\"\n ? new URL(\"./sounds/castle.mp3\", import.meta.url).href\n : \"./sounds/castle.mp3\",\n moveCheck:\n typeof import.meta.url === \"string\"\n ? new URL(\"./sounds/move-check.mp3\", import.meta.url).href\n : \"./sounds/move-check.mp3\",\n promote:\n typeof import.meta.url === \"string\"\n ? new URL(\"./sounds/promote.mp3\", import.meta.url).href\n : \"./sounds/promote.mp3\",\n gameEnd:\n typeof import.meta.url === \"string\"\n ? new URL(\"./sounds/game-end.mp3\", import.meta.url).href\n : \"./sounds/game-end.mp3\",\n});\n\n/** Public configuration for the hook (and the `<Chessboard sound/>` prop). */\nexport interface MoveSoundOptions {\n /** Master switch. Default `true`. */\n readonly enabled?: boolean;\n /** Output volume, `0`–`1`. Default `1`. */\n readonly volume?: number;\n /** Audio preload mode used when the lazy pool is first created. Default `\"none\"`. */\n readonly preload?: \"none\" | \"metadata\" | \"auto\";\n /** Per-key URL overrides. Missing keys fall back to {@link DEFAULT_MOVE_SOUND_SOURCES}. */\n readonly sources?: MoveSoundSources;\n /**\n * Viewer perspective. When set, moves played *by* this colour use the\n * `moveSelf` cue and moves played by the opponent use `moveOpponent`. When\n * omitted (the default), every non-special move uses `moveSelf`.\n */\n readonly perspective?: 0 | 1;\n}\n\n/** How many audio elements per category. Four is enough for spam-clicking. */\nconst POOL_SIZE = 4;\n\n/** Internal per-category pool record. */\ntype Pool = {\n readonly elements: HTMLAudioElement[];\n cursor: number;\n};\n\nfunction createPools(\n sources: Readonly<Record<MoveSoundKey, string>>,\n preload: MoveSoundOptions[\"preload\"],\n): Record<MoveSoundKey, Pool> {\n const pools = {} as Record<MoveSoundKey, Pool>;\n for (const key of Object.keys(sources) as MoveSoundKey[]) {\n const url = sources[key];\n const elements: HTMLAudioElement[] = [];\n for (let i = 0; i < POOL_SIZE; i++) {\n const audio = new Audio(url);\n audio.preload = preload ?? \"none\";\n elements.push(audio);\n }\n pools[key] = { elements, cursor: 0 };\n }\n return pools;\n}\n\n/**\n * Drop-in hook. Mount inside a React tree that has a `BoardModel`. Pass\n * `null` while the engine is still loading — the hook no-ops until the\n * model is available.\n *\n * @example\n * ```tsx\n * useMoveSound(game, { enabled: soundOn, volume: 0.6 });\n * ```\n */\nexport function useMoveSound(\n model: BoardModel | null,\n options: MoveSoundOptions = {},\n): TriggerMoveSound {\n const { enabled = true, volume = 1, preload = \"none\", sources, perspective } = options;\n\n const poolsRef = useRef<Record<MoveSoundKey, Pool> | null>(null);\n const sourcesRef = useRef<Readonly<Record<MoveSoundKey, string>>>(DEFAULT_MOVE_SOUND_SOURCES);\n const preloadRef = useRef(preload);\n\n // Keep a latest-value ref for volume so the pool doesn't tear down\n // every time the slider moves — we just update each element's volume\n // at play time.\n const volumeRef = useRef(volume);\n useEffect(() => {\n volumeRef.current = volume;\n });\n\n const perspectiveRef = useRef(perspective);\n useEffect(() => {\n perspectiveRef.current = perspective;\n });\n\n useEffect(() => {\n sourcesRef.current = {\n ...DEFAULT_MOVE_SOUND_SOURCES,\n ...(sources ?? {}),\n };\n poolsRef.current = null;\n }, [sources]);\n\n useEffect(() => {\n preloadRef.current = preload;\n poolsRef.current = null;\n }, [preload]);\n\n useEffect(() => {\n if (!enabled) {\n poolsRef.current = null;\n }\n }, [enabled]);\n\n const triggerMoveSound = useCallback<TriggerMoveSound>(\n (key) => {\n if (!enabled) return;\n if (typeof window === \"undefined\") return; // SSR guard.\n if (typeof Audio === \"undefined\") return; // happy-dom lacks Audio.\n\n const pools = poolsRef.current ?? createPools(sourcesRef.current, preloadRef.current);\n poolsRef.current = pools;\n\n const pool = pools[key];\n if (pool === undefined) return;\n\n pool.cursor = (pool.cursor + 1) % pool.elements.length;\n const el = pool.elements[pool.cursor];\n if (el === undefined) return;\n el.volume = Math.max(0, Math.min(1, volumeRef.current));\n el.currentTime = 0;\n // Some browsers reject autoplay before a user gesture. Swallow the\n // rejection — once the user interacts, subsequent plays succeed.\n void el.play().catch(() => {\n /* autoplay blocked — will resolve after the first user gesture. */\n });\n },\n [enabled],\n );\n\n // Subscribe to the model. Fire the chosen cue on every commit that\n // increments `historyPly` (forward moves only — undo is silent, matching\n // chess.com). The subscription is cheap: one `subscribe` per enabled\n // mount and zero re-renders.\n useEffect(() => {\n if (!enabled || model === null) return;\n\n let prevPly = model.getSnapshot().historyPly;\n\n return model.subscribe(() => {\n const snap = model.getSnapshot();\n if (snap.historyPly <= prevPly) {\n prevPly = snap.historyPly;\n return;\n }\n prevPly = snap.historyPly;\n\n const key = classifyMoveFeedback(model.lastAnimations, snap, perspectiveRef.current);\n triggerMoveSound(key);\n });\n }, [enabled, model, triggerMoveSound]);\n\n return triggerMoveSound;\n}\n","\"use client\";\n\n/**\n * `useSelectionController` — imperative selection + legal-target paint.\n *\n * ### Why this exists\n *\n * The prior `<SelectionLayer/>` React component rendered fresh DOM\n * nodes (one tint + N legal-target markers) every time `selected` or\n * `legalTargets` changed. That's cheap in isolation, but during the\n * drag-start frame — where the pointermove handler also calls\n * `game.selectSquare(from)` — it compounds with React reconciliation\n * and the browser's layout/paint for the new nodes. In real Chromium\n * under 4× CPU throttle, that frame was a 25 ms spike (vs chessground's\n * 9 ms).\n *\n * This controller replaces that entirely. It:\n *\n * 1. Subscribes to the model via `model.subscribe(...)` inside a\n * `useEffect` — never calls `setState`, never triggers React.\n * 2. On each commit, computes the diff between\n * `(prev.selected, prev.legalTargets)` and\n * `(next.selected, next.legalTargets)`.\n * 3. Writes `el.dataset.gbSelection = \"selected\" | \"legal-quiet\" |\n * \"legal-capture\" | \"none\"` on only the squares whose state\n * changed, using the 64-slot ref array from `<BoardGrid/>`.\n * 4. CSS (injected by `injectSelectionStyles` below) paints the\n * overlay on each square via a `::before` pseudo-element.\n *\n * Result: selection changes cost one or two data-attribute writes per\n * affected square — pure browser-level work, no React, no new DOM,\n * no layout. Matches chessground's class-toggle strategy.\n */\n\nimport { type RefObject, useEffect } from \"react\";\nimport type { BoardModel, SquareIndex } from \"../core/index.js\";\nimport type { LegalTargetStyle } from \"../types.js\";\n\n/**\n * Values written to `data-gb-selection`.\n *\n * - `selected` — the from-square of a pending move.\n * - `legal-quiet` — a legal target with no capture.\n * - `legal-capture` — a legal target on an occupied square.\n * - `none` — no highlight.\n */\ntype SelectionState = \"none\" | \"selected\" | \"legal-quiet\" | \"legal-capture\";\n\n/** Singleton id used to dedupe the injected `<style>` element. */\nconst STYLE_ID = \"gb-selection-styles\";\n\n/**\n * Inject the selection CSS once per document. SSR-safe (early-returns).\n *\n * ### First-click INP: why `::before` is declared on EVERY square\n *\n * The earlier design declared `::before` only on squares currently\n * carrying `data-gb-selection`. That saves 64 pseudo-element nodes\n * at mount but costs the browser a first-match materialisation pass\n * on the user's very first click: when the attribute appears on a\n * square for the first time, Chromium creates the ::before rendering\n * node AND does its first paint of the radial gradient. The cost\n * shows up as a 20-30 ms INP outlier — visible in the bench's p99\n * per-click number and a major share of Ultra's \"worst click\" INP\n * reading.\n *\n * We now declare a universal `::before` on every `[data-gb-square]`\n * with a transparent background; the selection attribute only\n * changes `background` / `background-image`. All 64 pseudo-element\n * rendering nodes are materialised during cold mount, where their\n * ~0.5 ms cost is invisible inside the larger first-paint work.\n * Subsequent clicks only repaint the already-materialised nodes —\n * eliminating the INP outlier without any per-move cost.\n */\nfunction injectSelectionStyles(): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(STYLE_ID) !== null) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = `\n[data-gb-square]::before {\n content: \"\";\n position: absolute;\n inset: 0;\n background: transparent;\n pointer-events: none;\n}\n[data-gb-square][data-gb-selection=\"selected\"]::before {\n background: var(--gb-selected);\n}\n[data-gb-square][data-gb-selection=\"legal-quiet\"]::before {\n background-image: radial-gradient(var(--gb-legal-target) 19%, transparent 21%);\n}\n[data-gb-square][data-gb-selection=\"legal-capture\"]::before {\n background-image: radial-gradient(transparent 0 78%, var(--gb-legal-target-capture) 80%);\n}\n[data-gb-target-style=\"rings\"] [data-gb-square][data-gb-selection=\"legal-capture\"]::before {\n background-image: radial-gradient(transparent 0 70%, var(--gb-legal-target-capture) 72% 84%, transparent 86%);\n}\n[data-gb-target-style=\"dots\"] [data-gb-square][data-gb-selection=\"legal-quiet\"]::before {\n background-image: radial-gradient(var(--gb-legal-target) 19%, transparent 21%);\n}\n[data-gb-target-style=\"dots\"] [data-gb-square][data-gb-selection=\"legal-capture\"]::before {\n background-image: radial-gradient(transparent 0 78%, var(--gb-legal-target-capture) 80%);\n}\n`;\n document.head.appendChild(style);\n}\n\n/**\n * Imperatively paint selection + legal-target highlights.\n *\n * @param model The board model, or `null` while the engine is loading.\n * @param squareRefs 64-slot refs array. Each slot is the DOM node of\n * the square at that LERF index, or `null` if unmounted.\n * @param style Rendering style for legal targets. `false` suppresses\n * the overlay entirely; `\"rings\"` (default) and `\"dots\"` are picked\n * up by the board container's `data-gb-target-style` attribute.\n */\nexport function useSelectionController(\n model: BoardModel | null,\n squareRefs: RefObject<Array<HTMLElement | null>>,\n style: LegalTargetStyle,\n): void {\n useEffect(() => {\n injectSelectionStyles();\n }, []);\n\n useEffect(() => {\n if (model === null) return;\n\n // Track what we painted last so we can diff-write only changes.\n let prevSelected: SquareIndex | null = null;\n let prevTargets: ReadonlySet<SquareIndex> = new Set();\n\n const write = (i: SquareIndex, val: SelectionState): void => {\n const el = squareRefs.current?.[i];\n if (el === null || el === undefined) return;\n if (val === \"none\") {\n delete el.dataset[\"gbSelection\"];\n } else {\n el.dataset[\"gbSelection\"] = val;\n }\n };\n\n const clear = (): void => {\n if (prevSelected !== null) write(prevSelected, \"none\");\n for (const sq of prevTargets) write(sq, \"none\");\n prevSelected = null;\n prevTargets = new Set();\n };\n\n const update = (): void => {\n const snap = model.getSnapshot();\n const { selected, legalTargets, board } = snap;\n\n // When the caller disables target rendering, keep the selected\n // tint but hide legal targets — same contract the old component\n // had with `style === false`.\n if (style === false) {\n // Clear any old targets.\n for (const sq of prevTargets) {\n if (sq !== selected) write(sq, \"none\");\n }\n // Adjust selected highlight.\n if (prevSelected !== null && prevSelected !== selected) {\n write(prevSelected, \"none\");\n }\n if (selected !== null) write(selected, \"selected\");\n prevSelected = selected;\n prevTargets = new Set();\n return;\n }\n\n // Identity-compare: the store guarantees stable `selected` and\n // `legalTargets` refs when nothing changed, so most commits land\n // here and return instantly.\n if (selected === prevSelected && legalTargets === prevTargets) return;\n\n // Clear squares that were previously highlighted but no longer are.\n if (prevSelected !== null && prevSelected !== selected && !legalTargets.has(prevSelected)) {\n write(prevSelected, \"none\");\n }\n for (const sq of prevTargets) {\n if (sq !== selected && !legalTargets.has(sq)) write(sq, \"none\");\n }\n\n // Paint current highlights.\n if (selected !== null) write(selected, \"selected\");\n for (const sq of legalTargets) {\n if (sq === selected) continue;\n const targetCell = board[sq] ?? 0;\n write(sq, targetCell === 0 ? \"legal-quiet\" : \"legal-capture\");\n }\n\n prevSelected = selected;\n prevTargets = legalTargets;\n };\n\n update();\n const unsubscribe = model.subscribe(update);\n return () => {\n unsubscribe();\n clear();\n };\n }, [model, squareRefs, style]);\n}\n","\"use client\";\n\n/**\n * The top-level interactive board.\n *\n * Composes the static grid, piece layer, highlight layers, coordinate\n * overlay, drag layer, arrow overlay, and promotion overlay into a single\n * `position: relative; aspect-ratio: 1/1` container. Theme variables are\n * written inline on the container so they land at first paint without\n * needing an effect — SSR-safe and hydration-clean.\n *\n * The board is a client component. For a server-rendered static board\n * (zero client JS), import from `gigaboard/server` (M5).\n */\n\nimport {\n type CSSProperties,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { ArrowsLayer, type ArrowsLayerHandle } from \"./components/arrows-layer.js\";\nimport { BoardGrid } from \"./components/board-grid.js\";\nimport { CheckLayer } from \"./components/check-layer.js\";\nimport { Coordinates } from \"./components/coordinates.js\";\nimport { DragLayer, type DragLayerHandle } from \"./components/drag-layer.js\";\nimport { IllegalFlashLayer } from \"./components/illegal-flash-layer.js\";\nimport { LiveRegion } from \"./components/live-region.js\";\nimport { PieceLayer } from \"./components/piece-layer.js\";\nimport { PremoveLayer } from \"./components/premove-layer.js\";\nimport { PromotionOverlay } from \"./components/promotion-overlay.js\";\nimport { StaticPieceLayer } from \"./components/static-piece-layer.js\";\nimport {\n type BoardCell,\n colorOf,\n isEmptyCell,\n isNullMoveUci,\n type PieceType,\n pieceTypeOf,\n type SquareIndex,\n} from \"./core/index.js\";\nimport { defaultArrowColors, defaultTheme } from \"./default-theme.js\";\nimport { parseFenPlacement } from \"./fen.js\";\nimport { AnimationRunner } from \"./hooks/use-animation.js\";\nimport { useArrowGesture } from \"./hooks/use-arrow-gesture.js\";\nimport { useClickToMove } from \"./hooks/use-click-to-move.js\";\nimport { useCursorController } from \"./hooks/use-cursor-controller.js\";\nimport { useDrag } from \"./hooks/use-drag.js\";\nimport { useHoverSquare } from \"./hooks/use-hover-square.js\";\nimport { useKeyboardNav } from \"./hooks/use-keyboard-nav.js\";\nimport { useLastMoveController } from \"./hooks/use-last-move-controller.js\";\nimport { type MoveHapticOptions, useMoveHaptics } from \"./hooks/use-move-haptics.js\";\nimport { type MoveSoundOptions, useMoveSound } from \"./hooks/use-move-sound.js\";\nimport { useSelectionController } from \"./hooks/use-selection-controller.js\";\nimport { getSquareAtPoint } from \"./lib/geometry.js\";\nimport { classifyMoveFeedback } from \"./lib/move-feedback.js\";\nimport { defaultPieces } from \"./pieces/default-pieces.js\";\nimport type {\n AnimationOptions,\n ArrowColors,\n ChessboardProps,\n Orientation,\n PositionTransition,\n ResolvedArrowPalette,\n} from \"./types.js\";\n\n/** Internal record describing a pending promotion. */\ninterface PendingPromotion {\n readonly from: SquareIndex;\n readonly to: SquareIndex;\n readonly color: 0 | 1;\n readonly resolve: (piece: PieceType) => void;\n readonly cancel: () => void;\n}\n\n/** Interior colour-of from a cell code. Empty cell returns `0` defensively. */\nfunction colorOfCell(cell: number): 0 | 1 {\n return (cell > 6 ? 1 : 0) as 0 | 1;\n}\n\n/** Is `(from → to)` a pawn promotion given the current position? */\nfunction movePromotesPawn(fromCell: number, to: SquareIndex): boolean {\n if (fromCell === 0) return false;\n const pieceType = (fromCell - 1) % 6;\n if (pieceType !== 0 /* Pawn */) return false;\n const toRank = to >> 3;\n return toRank === 0 || toRank === 7;\n}\n\n/** Flash duration — must outlive the WAAPI animation in IllegalFlashLayer. */\nconst ILLEGAL_FLASH_HOLD_MS = 320;\n\nconst DEFAULT_POSITION_SYNC_DURATION_MS = 60;\nconst DEFAULT_POSITION_SYNC_EASING = \"cubic-bezier(0.22, 0.61, 0.36, 1)\";\nconst UCI_TRANSITION_RE = /^([a-h][1-8])([a-h][1-8])([nbrq])?$/i;\n\n/**\n * A pass is spelled `\"0000\"` in UCI. It never matches {@link UCI_TRANSITION_RE}\n * — there is no square to glide between — so the transition contributes no\n * square animations and no feedback descriptor. Recognised explicitly rather\n * than left to fall through on the regex miss, so the intent is pinned.\n */\nfunction isNullTransition(transition: PositionTransition): boolean {\n return isNullMoveUci(transition.uci);\n}\n\ninterface SquareTransition {\n readonly from: string;\n readonly to: string;\n}\n\ninterface ParsedTransitionMove {\n readonly from: SquareIndex;\n readonly to: SquareIndex;\n readonly promotion: string | null;\n}\n\ninterface FeedbackDescriptor {\n readonly kind: string;\n}\n\nfunction prefersReducedMotion(): boolean {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return false;\n }\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\nfunction cancelElementAnimations(element: HTMLElement): void {\n if (typeof element.getAnimations !== \"function\") return;\n for (const anim of element.getAnimations()) anim.cancel();\n}\n\nfunction queryPieceAt(container: HTMLElement, square: string): HTMLElement | null {\n return container.querySelector<HTMLElement>(`[data-piece-square=\"${square}\"]`);\n}\n\nfunction squareIndexOfName(square: string): SquareIndex {\n const file = square.charCodeAt(0) - 0x61;\n const rank = Number(square[1]) - 1;\n return ((rank << 3) | file) as SquareIndex;\n}\n\nfunction deltaFromSquareNames(\n from: string,\n to: string,\n squareSize: number,\n orientation: Orientation,\n): { dx: number; dy: number } {\n const fromIndex = squareIndexOfName(from);\n const toIndex = squareIndexOfName(to);\n const fromFile = fromIndex & 7;\n const fromRank = fromIndex >> 3;\n const toFile = toIndex & 7;\n const toRank = toIndex >> 3;\n const fromCol = orientation === \"white\" ? fromFile : 7 - fromFile;\n const fromRow = orientation === \"white\" ? 7 - fromRank : fromRank;\n const toCol = orientation === \"white\" ? toFile : 7 - toFile;\n const toRow = orientation === \"white\" ? 7 - toRank : toRank;\n return {\n dx: (fromCol - toCol) * squareSize,\n dy: (fromRow - toRow) * squareSize,\n };\n}\n\nfunction castleRookTransition(from: string, to: string): SquareTransition | null {\n const fromFile = from.charCodeAt(0);\n const toFile = to.charCodeAt(0);\n if (fromFile !== 0x65 /* e */ || Math.abs(toFile - fromFile) !== 2) return null;\n const rank = from[1];\n if (rank !== \"1\" && rank !== \"8\") return null;\n const kingSide = toFile > fromFile;\n return {\n from: `${kingSide ? \"h\" : \"a\"}${rank}`,\n to: `${kingSide ? \"f\" : \"d\"}${rank}`,\n };\n}\n\nfunction transitionSquares(transition: PositionTransition): SquareTransition[] {\n // A pass moves nothing: no square animations.\n if (isNullTransition(transition)) return [];\n const parsed = UCI_TRANSITION_RE.exec(transition.uci.trim().toLowerCase());\n if (parsed === null) return [];\n\n const moveFrom = parsed[1] ?? \"\";\n const moveTo = parsed[2] ?? \"\";\n const forward: SquareTransition[] = [{ from: moveFrom, to: moveTo }];\n const rook = castleRookTransition(moveFrom, moveTo);\n if (rook !== null) forward.push(rook);\n\n return transition.direction === \"forward\"\n ? forward\n : forward.map((item) => ({ from: item.to, to: item.from }));\n}\n\nfunction parseTransitionMove(transition: PositionTransition): ParsedTransitionMove | null {\n // A pass has no from/to; reporting `null` keeps it out of capture /\n // promotion / castle classification.\n if (isNullTransition(transition)) return null;\n const parsed = UCI_TRANSITION_RE.exec(transition.uci.trim().toLowerCase());\n if (parsed === null) return null;\n const from = parsed[1];\n const to = parsed[2];\n if (from === undefined || to === undefined) return null;\n return {\n from: squareIndexOfName(from),\n to: squareIndexOfName(to),\n promotion: parsed[3] ?? null,\n };\n}\n\nfunction isPawn(cell: BoardCell): boolean {\n return !isEmptyCell(cell) && pieceTypeOf(cell) === 0;\n}\n\nfunction controlledFeedbackDescriptors(\n transition: PositionTransition | null | undefined,\n previousBoard: Readonly<Uint8Array>,\n nextBoard: Readonly<Uint8Array>,\n): FeedbackDescriptor[] | null {\n if (transition === null || transition === undefined) return null;\n\n const parsed = parseTransitionMove(transition);\n if (parsed === null) return null;\n\n // Classify the original chess move even while replaying backward. The\n // post-sync snapshot is \"before\" the move in that case, so swap the board\n // pair back into original move order before inspecting capture/promotion.\n const before = transition.direction === \"forward\" ? previousBoard : nextBoard;\n const after = transition.direction === \"forward\" ? nextBoard : previousBoard;\n const movingPiece = (before[parsed.from] ?? 0) as BoardCell;\n if (isEmptyCell(movingPiece)) return null;\n\n const fromFile = parsed.from & 7;\n const toFile = parsed.to & 7;\n const targetBefore = (before[parsed.to] ?? 0) as BoardCell;\n const targetAfter = (after[parsed.to] ?? 0) as BoardCell;\n\n if (pieceTypeOf(movingPiece) === 5 && Math.abs(toFile - fromFile) === 2) {\n return [{ kind: \"castle\" }];\n }\n\n if (\n parsed.promotion !== null ||\n (isPawn(movingPiece) &&\n (parsed.to >> 3 === 0 || parsed.to >> 3 === 7) &&\n !isEmptyCell(targetAfter) &&\n pieceTypeOf(targetAfter) !== 0)\n ) {\n return [{ kind: \"promotion\" }];\n }\n\n if (!isEmptyCell(targetBefore) && colorOf(targetBefore) !== colorOf(movingPiece)) {\n return [{ kind: \"capture\" }];\n }\n\n if (isPawn(movingPiece) && fromFile !== toFile && isEmptyCell(targetBefore)) {\n const capturedSquare = ((parsed.from & ~7) | toFile) as SquareIndex;\n const capturedBefore = (before[capturedSquare] ?? 0) as BoardCell;\n const capturedAfter = (after[capturedSquare] ?? 0) as BoardCell;\n if (\n !isEmptyCell(capturedBefore) &&\n colorOf(capturedBefore) !== colorOf(movingPiece) &&\n isEmptyCell(capturedAfter)\n ) {\n return [{ kind: \"en-passant\" }];\n }\n }\n\n return [{ kind: \"move\" }];\n}\n\nfunction schedulePositionAnimation(\n container: HTMLElement,\n transitions: readonly SquareTransition[],\n options: Required<AnimationOptions>,\n orientation: Orientation,\n): void {\n const animate = (): void => {\n const rect = container.getBoundingClientRect();\n const squareSize = rect.width / 8;\n if (squareSize <= 0) return;\n\n for (const item of transitions) {\n const piece = queryPieceAt(container, item.to);\n if (piece === null || typeof piece.animate !== \"function\") continue;\n const { dx, dy } = deltaFromSquareNames(item.from, item.to, squareSize, orientation);\n if (Math.abs(dx) < 0.5 && Math.abs(dy) < 0.5) continue;\n\n cancelElementAnimations(piece);\n piece.animate(\n [{ transform: `translate(${dx}px, ${dy}px)` }, { transform: \"translate(0, 0)\" }],\n { duration: options.durationMs, easing: options.easing, fill: \"none\" },\n );\n }\n };\n\n if (typeof window.requestAnimationFrame === \"function\") {\n window.requestAnimationFrame(animate);\n } else {\n window.setTimeout(animate, 0);\n }\n}\n\nfunction syncPositionFen(\n game: NonNullable<ChessboardProps[\"game\"]>,\n targetFen: string,\n transition: PositionTransition | null | undefined,\n managedArrows: ChessboardProps[\"managedArrows\"],\n preserveUserArrows: boolean | undefined,\n container: HTMLElement | null,\n animation: AnimationOptions | undefined,\n orientation: Orientation,\n): boolean {\n const positionChanged = game.engine.fen() !== targetFen;\n const durationMs = animation?.durationMs ?? DEFAULT_POSITION_SYNC_DURATION_MS;\n const easing = animation?.easing ?? DEFAULT_POSITION_SYNC_EASING;\n const shouldAnimate =\n positionChanged &&\n transition !== null &&\n transition !== undefined &&\n container !== null &&\n durationMs > 0 &&\n !prefersReducedMotion();\n\n const transitions: SquareTransition[] = [];\n if (shouldAnimate) {\n for (const item of transitionSquares(transition)) {\n if (queryPieceAt(container, item.from) !== null) transitions.push(item);\n }\n }\n\n try {\n if (managedArrows === undefined) {\n if (!positionChanged) return false;\n game.load(targetFen);\n } else {\n game.syncPosition({\n fen: targetFen,\n managedArrows,\n preserveUserArrows: preserveUserArrows === true,\n });\n }\n } catch {\n return false;\n }\n\n if (transitions.length > 0 && container !== null) {\n schedulePositionAnimation(container, transitions, { durationMs, easing }, orientation);\n }\n return positionChanged;\n}\n\n/**\n * Interactive chess board.\n *\n * @example\n * ```tsx\n * \"use client\";\n * import { Chessboard, useChessGame } from \"gigaboard\";\n *\n * export default function Board() {\n * const game = useChessGame();\n * return <Chessboard game={game} />;\n * }\n * ```\n */\nexport function Chessboard(props: ChessboardProps) {\n const {\n game,\n fallbackFen,\n positionFen,\n positionTransition = null,\n managedArrows,\n preserveUserArrowsOnPositionSync,\n orientation = \"white\",\n theme = defaultTheme,\n pieces = defaultPieces,\n showCoordinates = true,\n ranksPosition = \"left\",\n showLegalTargets = \"rings\",\n highlightLastMove = true,\n onMove,\n onPromote,\n renderSquare,\n style,\n className,\n ariaLabel,\n animation,\n allowDrag = true,\n allowDrawingArrows = true,\n clearArrowsOnMove = true,\n clearArrowsOnClick = true,\n arrowColors,\n snapArrowsToValidMove = false,\n allowPremove = false,\n showCheckHighlight = true,\n showIllegalFlash = true,\n sound = true,\n haptics = false,\n viewOnly = false,\n canDragPiece,\n onSquareMouseEnter,\n onSquareMouseLeave,\n disableContextMenu = true,\n getSquareAriaLabel,\n onSquareFocus,\n getPromotionPieceAriaLabel,\n } = props;\n\n // Every interactive subsystem consults these resolved flags. Keeping\n // the resolution here — rather than inlining `!viewOnly && …` at each\n // call site — makes the blast radius of `viewOnly` explicit, keeps\n // dependency arrays stable, and means the branch is evaluated once\n // per render instead of once per consumer.\n const dragEnabled = allowDrag && !viewOnly;\n const arrowGestureEnabled = allowDrawingArrows && !viewOnly;\n const clickToMoveEnabled = !viewOnly;\n const keyboardNavEnabled = !viewOnly;\n\n // Parse the fallback FEN at most once per distinct string. The 64-byte\n // output is passed into `<StaticPieceLayer/>` only while `game` is null;\n // once a real model arrives the interactive `<PieceLayer/>` takes over.\n // Parsing costs a few µs so the memoisation is about render-identity,\n // not speed — `StaticPieceLayer` memos on the array reference.\n const fallbackBoard = useMemo<Uint8Array | null>(() => {\n if (fallbackFen === undefined || fallbackFen === \"\") return null;\n try {\n return parseFenPlacement(fallbackFen);\n } catch {\n // Malformed FEN → fall back to a pieceless board rather than\n // throwing out of a render. The console warning would be noisy\n // in tests; silent no-op is the least-surprising behaviour.\n return null;\n }\n }, [fallbackFen]);\n\n // Normalise `sound` (boolean | options) into a concrete options object.\n // Memoised so `useMoveSound` doesn't rebuild its audio pool on every\n // render when the caller passes a raw object literal.\n const soundOptions = useMemo<MoveSoundOptions>(() => {\n if (sound === true) return { enabled: true };\n if (sound === false || sound === undefined) return { enabled: false };\n return sound;\n }, [sound]);\n\n const hapticOptions = useMemo<MoveHapticOptions>(() => {\n if (haptics === true) return { enabled: true };\n if (haptics === false || haptics === undefined) return { enabled: false };\n return haptics;\n }, [haptics]);\n\n const containerRef = useRef<HTMLDivElement | null>(null);\n const dragLayerRef = useRef<DragLayerHandle | null>(null);\n const arrowsLayerRef = useRef<ArrowsLayerHandle | null>(null);\n const lastControlledFeedbackFenRef = useRef<string | null>(null);\n\n // 64-slot refs array populated by each `<Square/>` on mount. The\n // selection controller reads this to paint highlights imperatively.\n const squareRefs = useRef<Array<HTMLElement | null>>(new Array(64).fill(null));\n const setSquareRef = useCallback((index: SquareIndex, el: HTMLElement | null) => {\n squareRefs.current[index] = el;\n }, []);\n\n // Set to `true` whenever the next model commit is the result of a drag\n // (or a promotion dialog opened by a drag). `<AnimationRunner/>` reads\n // this flag on each commit and skips the FLIP animation, because the\n // piece has already been positioned by the user's pointer. Reset to\n // `false` anywhere the move is abandoned (illegal drop, dialog cancel)\n // so the flag never leaks into a subsequent non-drag move.\n const skipNextAnimationRef = useRef(false);\n\n // Latest-ref pattern for user callbacks — keeps `useCallback`/`useEffect`\n // deps stable while still reading the newest prop values at call time.\n const onMoveRef = useRef(onMove);\n const onPromoteRef = useRef(onPromote);\n useEffect(() => {\n onMoveRef.current = onMove;\n onPromoteRef.current = onPromote;\n });\n\n // Move feedback effects. The hooks subscribe to normal model moves and\n // also expose direct triggers for controlled `positionFen` syncs below.\n const triggerMoveSound = useMoveSound(game, soundOptions);\n const triggerMoveHaptic = useMoveHaptics(game, hapticOptions);\n\n useLayoutEffect(() => {\n if (game === null || positionFen === undefined || positionFen === \"\") return;\n const previousFeedbackFen = lastControlledFeedbackFenRef.current;\n const previousSnapshot = game.getSnapshot();\n if (game.engine.fen() === positionFen && managedArrows === undefined) {\n lastControlledFeedbackFenRef.current = positionFen;\n return;\n }\n const positionChanged = syncPositionFen(\n game,\n positionFen,\n positionTransition,\n managedArrows,\n preserveUserArrowsOnPositionSync,\n containerRef.current,\n animation,\n orientation,\n );\n lastControlledFeedbackFenRef.current = positionFen;\n\n if (!positionChanged || previousFeedbackFen === null || previousFeedbackFen === positionFen) {\n return;\n }\n\n const snapshot = game.getSnapshot();\n const feedbackDescriptors =\n controlledFeedbackDescriptors(positionTransition, previousSnapshot.board, snapshot.board) ??\n game.lastAnimations;\n const feedbackSnapshot =\n positionTransition?.direction === \"backward\" ? previousSnapshot : snapshot;\n triggerMoveSound(\n classifyMoveFeedback(feedbackDescriptors, feedbackSnapshot, soundOptions.perspective),\n );\n triggerMoveHaptic(\n classifyMoveFeedback(feedbackDescriptors, feedbackSnapshot, hapticOptions.perspective),\n );\n }, [\n animation,\n game,\n hapticOptions.perspective,\n positionFen,\n positionTransition,\n managedArrows,\n preserveUserArrowsOnPositionSync,\n orientation,\n soundOptions.perspective,\n triggerMoveHaptic,\n triggerMoveSound,\n ]);\n\n // Merge user-provided arrow colours with defaults. Memoised against\n // the whole `arrowColors` reference so consumers who pass a stable\n // object literal don't thrash the gesture hook's deps; callers who\n // recreate it each render pay one shallow-copy per commit — cheap.\n // Extra user-defined brush keys flow through alongside the four\n // modifier channels that always get defaults applied.\n const palette = useMemo<ResolvedArrowPalette>(() => {\n const merged: { [k: string]: string } = {\n default: defaultArrowColors.default,\n shift: defaultArrowColors.shift,\n alt: defaultArrowColors.alt,\n ctrl: defaultArrowColors.ctrl,\n };\n if (arrowColors !== undefined) {\n for (const k in arrowColors) {\n const v = (arrowColors as ArrowColors)[k];\n if (v !== undefined) merged[k] = v;\n }\n }\n return merged as ResolvedArrowPalette;\n }, [arrowColors]);\n\n // Drag state used to live here as `useState` + `flushSync` on\n // drag-start. It's gone now: the `<DragLayer/>` below is always\n // mounted (hidden) and exposes an imperative handle that `useDrag`\n // drives from its pointer handlers. This keeps the drag-start\n // pointer-move handler off React's critical path entirely, closing\n // the drag-peak-frame gap with chessground.\n\n // Promotion dialog state — null when no promotion is pending.\n const [pendingPromotion, setPendingPromotion] = useState<PendingPromotion | null>(null);\n\n // Keyboard-focus state for the roving tabindex. `null` means the board\n // hasn't been focused yet — Tabbing into it takes the user to the\n // square picked by `initialKeyboardFocusSquare` (below), or e2 for\n // a white-oriented board.\n const [focusedSquare, setFocusedSquare] = useState<SquareIndex | null>(null);\n // Visual bottom-left square given the current orientation: e2-ish for\n // white (a good default landing spot near the kingside piece the user\n // most often moves first), a7-ish for black.\n const defaultKeyboardFocus = useCallback(\n (): SquareIndex => (orientation === \"white\" ? 12 : 52) as SquareIndex,\n [orientation],\n );\n\n // Illegal-flash state: the square to pulse red, cleared after a short hold.\n const [flashSquare, setFlashSquare] = useState<SquareIndex | null>(null);\n const flashTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const triggerIllegalFlash = useCallback(\n (square: SquareIndex): void => {\n if (!showIllegalFlash) return;\n setFlashSquare(square);\n if (flashTimerRef.current !== null) clearTimeout(flashTimerRef.current);\n flashTimerRef.current = setTimeout(() => {\n setFlashSquare(null);\n flashTimerRef.current = null;\n }, ILLEGAL_FLASH_HOLD_MS);\n },\n [showIllegalFlash],\n );\n // Cancel any pending flash when the component unmounts.\n useEffect(\n () => () => {\n if (flashTimerRef.current !== null) clearTimeout(flashTimerRef.current);\n },\n [],\n );\n\n /**\n * Auto-clear arrows when the game advances. Subscribes to `historyPly`\n * and wipes the *user-drawn* arrows on every increment. Arrows marked\n * `managed: true` (engine hints, programmatic annotations) survive so\n * an analysis board can keep its best-move arrow current across the\n * move that replaces it. Toggled off by `clearArrowsOnMove={false}`.\n */\n useEffect(() => {\n if (game === null || !clearArrowsOnMove) return;\n let prevPly = game.getSnapshot().historyPly;\n return game.subscribe(() => {\n const snap = game.getSnapshot();\n if (snap.historyPly > prevPly && snap.arrows.length > 0) {\n game.clearUserArrows();\n }\n prevPly = snap.historyPly;\n });\n }, [game, clearArrowsOnMove]);\n\n /**\n * Kick off promotion resolution. Uses the caller-provided `onPromote`\n * prop when present, otherwise opens the built-in overlay.\n */\n const requestPromotion = useCallback(\n (from: SquareIndex, to: SquareIndex): void => {\n if (game === null) return;\n const fromCell = game.getSnapshot().board[from] ?? 0;\n const color = colorOfCell(fromCell);\n\n const completeMove = (piece: PieceType): void => {\n const played = game.tryMove(from, to, piece);\n const cb = onMoveRef.current;\n if (played !== null && cb !== undefined) cb(played);\n };\n\n const promoteHandler = onPromoteRef.current;\n if (promoteHandler !== undefined) {\n // Caller owns the UI. Resolve through their promise.\n Promise.resolve(promoteHandler({ from, to, color })).then(completeMove, () => {\n // Rejected → abandon the move. Board remains in its pre-move state.\n // A drag-initiated promotion that rejects must clear the skip\n // flag so the next non-drag move animates normally.\n skipNextAnimationRef.current = false;\n });\n return;\n }\n\n // Built-in overlay: rendered below via `pendingPromotion`.\n setPendingPromotion({\n from,\n to,\n color,\n resolve: (piece) => {\n setPendingPromotion(null);\n completeMove(piece);\n },\n cancel: () => {\n // A drag-initiated promotion that's cancelled must reset the\n // skip flag — otherwise the *next* legitimate move would be\n // silently de-animated.\n skipNextAnimationRef.current = false;\n setPendingPromotion(null);\n },\n });\n },\n [game],\n );\n\n const clickToMove = useClickToMove(game, onMove, requestPromotion, clickToMoveEnabled);\n\n /**\n * Clear any drawn arrows if `clearArrowsOnClick` is enabled. Called at\n * the start of every left-button interaction — click or drag-start —\n * and on Escape.\n */\n const maybeClearArrows = useCallback((): void => {\n if (!clearArrowsOnClick || game === null) return;\n // Managed arrows (engine hints) are deliberately preserved — the\n // user's left-click should dismiss their own annotations only, not\n // the app's.\n if (game.getSnapshot().arrows.length > 0) game.clearUserArrows();\n }, [clearArrowsOnClick, game]);\n\n /** Click-to-move with the arrow-clearing side effect woven in. */\n const handleSquareClick = useCallback(\n (index: SquareIndex): void => {\n // `viewOnly` keeps clicks from perturbing any board state — including\n // user-drawn or programmatic arrows. `clickToMove` is already a no-op\n // when disabled; guarding the arrow-clear here keeps the click path\n // purely declarative.\n if (viewOnly) return;\n maybeClearArrows();\n clickToMove(index);\n },\n [viewOnly, maybeClearArrows, clickToMove],\n );\n\n /** Escape clears arrows (and is a natural analogue for \"cancel\"). */\n useEffect(() => {\n if (!clearArrowsOnClick || game === null || viewOnly) return;\n const onKey = (e: KeyboardEvent): void => {\n if (e.key === \"Escape\") maybeClearArrows();\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [clearArrowsOnClick, game, maybeClearArrows, viewOnly]);\n\n // Piece slots carry `pointer-events: auto` (see `useCursorController`)\n // so the `grab` cursor renders correctly on pickable pieces. A native\n // click landing on a piece slot does NOT fire the underlying\n // `<Square/>`'s React `onClick`: the square is not an ancestor of the\n // slot in the React tree. Forward those clicks to click-to-move via\n // coordinate resolution — same geometry path `useDrag` / `useHoverSquare`\n // already use.\n useEffect(() => {\n if (viewOnly || clickToMoveEnabled === false || game === null) return;\n const container = containerRef.current;\n if (container === null) return;\n const onContainerClick = (e: MouseEvent): void => {\n if (e.button !== 0) return;\n const target = e.target as Element | null;\n if (target === null) return;\n // Only handle clicks that landed on the piece overlay — clicks\n // on squares already route through `Square.onClick`, and double\n // dispatch would fire click-to-move twice.\n if (target.closest(\"[data-piece-square]\") === null) return;\n const sq = getSquareAtPoint(container, e.clientX, e.clientY, orientation);\n if (sq === null) return;\n handleSquareClick(sq);\n };\n container.addEventListener(\"click\", onContainerClick);\n return () => container.removeEventListener(\"click\", onContainerClick);\n }, [viewOnly, clickToMoveEnabled, game, orientation, handleSquareClick]);\n\n /**\n * Suppress the browser context menu on the board container. Works\n * independently of `allowDrawingArrows` so consumers can have the OS\n * menu blocked even in view-only / no-arrow configurations. When\n * arrows are enabled, `useArrowGesture` installs its own identical\n * listener too — both call `preventDefault` on the same event, which\n * is idempotent.\n */\n useEffect(() => {\n if (!disableContextMenu) return;\n const container = containerRef.current;\n if (container === null) return;\n const onContextMenu = (e: MouseEvent): void => {\n e.preventDefault();\n };\n container.addEventListener(\"contextmenu\", onContextMenu);\n return () => container.removeEventListener(\"contextmenu\", onContextMenu);\n }, [disableContextMenu]);\n\n // Drag callbacks — each is stable across renders so `useDrag` doesn't\n // re-install its pointer listeners on every commit. The drag-layer\n // visibility is managed imperatively by `useDrag` itself via the\n // `DragLayerHandle`; these callbacks only carry out the React-state\n // side effects (arrow clear, selection update) that a drag implies.\n const onDragStart = useCallback(\n (from: SquareIndex, _cell: BoardCell): void => {\n maybeClearArrows();\n // Flip the container into \"grabbing\" cursor mode. See\n // `useCursorController` for the CSS rule that consumes this.\n const container = containerRef.current;\n if (container !== null) container.dataset[\"gbDragging\"] = \"true\";\n // Calling `game.selectSquare(from)` propagates the drag-source\n // into the model so the selection controller shows legal targets\n // while the piece is in flight — the same visual affordance\n // click-to-move gets.\n game?.selectSquare(from);\n },\n [game, maybeClearArrows],\n );\n const onDragEnd = useCallback((): void => {\n // Reset the cursor. We clear unconditionally because React may have\n // skipped a render cycle between drop and the next pointer event.\n const container = containerRef.current;\n if (container !== null) delete container.dataset[\"gbDragging\"];\n // Note: Selection on the origin square is retained on drag release/abort\n // so the user can seamlessly execute click-to-move. On a successful move,\n // tryMove already cleared the selection.\n }, []);\n\n const onDrop = useCallback(\n (from: SquareIndex, to: SquareIndex): void => {\n if (game === null) return;\n const snap = game.getSnapshot();\n const fromCell = snap.board[from] ?? 0;\n const pieceColour = colorOfCell(fromCell);\n\n // Not our turn? Queue as a premove if allowed; otherwise reject with\n // the same red flash any other illegal move gets. Silently dropping\n // the attempt was the default-true M4 behaviour but left users\n // confused (\"a blue ghost appeared from nowhere\").\n if (fromCell !== 0 && pieceColour !== snap.turn) {\n if (!allowPremove) {\n triggerIllegalFlash(from);\n return;\n }\n // Premove promotion auto-queens (lichess convention) — the user\n // isn't given a dialog here because it's not their turn yet.\n const promotion = movePromotesPawn(fromCell, to) ? (4 as PieceType) /* Queen */ : undefined;\n game.queuePremove(promotion === undefined ? { from, to } : { from, to, promotion });\n return;\n }\n\n // Drag-initiated → skip the next FLIP animation. The promotion and\n // happy paths both consume this flag; on failure we reset it so it\n // doesn't leak into a later, unrelated move.\n skipNextAnimationRef.current = true;\n\n if (movePromotesPawn(fromCell, to) && game.isLegal(from, to, 4 /* Queen */)) {\n requestPromotion(from, to);\n return;\n }\n\n const played = game.tryMove(from, to);\n const cb = onMoveRef.current;\n if (played !== null) {\n if (cb !== undefined) cb(played);\n } else {\n skipNextAnimationRef.current = false;\n triggerIllegalFlash(from);\n game.selectSquare(from);\n }\n },\n [game, requestPromotion, allowPremove, triggerIllegalFlash],\n );\n\n useDrag({\n game,\n orientation,\n containerRef,\n dragLayerRef,\n enabled: dragEnabled && game !== null,\n onDragStart,\n onDragEnd,\n onDrop,\n ...(canDragPiece !== undefined ? { canDragPiece } : {}),\n });\n\n // Initialise keyboard focus once per orientation so Tab lands on a\n // sensible square. We deliberately do NOT auto-focus on mount — the\n // board stays dormant until the user Tabs into it. Suppressed in\n // `viewOnly` mode so the grid stays out of the tab order entirely.\n useEffect(() => {\n if (!keyboardNavEnabled) {\n setFocusedSquare(null);\n return;\n }\n setFocusedSquare((current) => current ?? defaultKeyboardFocus());\n }, [defaultKeyboardFocus, keyboardNavEnabled]);\n\n const onKeyboardActivate = useCallback(\n (index: SquareIndex): void => {\n maybeClearArrows();\n clickToMove(index);\n },\n [maybeClearArrows, clickToMove],\n );\n const onKeyboardEscape = useCallback((): void => {\n maybeClearArrows();\n game?.selectSquare(null);\n }, [maybeClearArrows, game]);\n\n useKeyboardNav({\n containerRef,\n orientation,\n focusedSquare,\n setFocusedSquare,\n onActivate: onKeyboardActivate,\n onEscape: onKeyboardEscape,\n enabled: game !== null && keyboardNavEnabled,\n });\n\n // Per-square hover notification — only armed when the caller supplies\n // at least one of the two callbacks, so no container listener is\n // installed on the default play path. Pointer events not mouse events,\n // so touch drags through a square pair the same as pointer drags.\n useHoverSquare({\n game,\n orientation,\n containerRef,\n enabled: onSquareMouseEnter !== undefined || onSquareMouseLeave !== undefined,\n ...(onSquareMouseEnter !== undefined ? { onEnter: onSquareMouseEnter } : {}),\n ...(onSquareMouseLeave !== undefined ? { onLeave: onSquareMouseLeave } : {}),\n });\n\n useArrowGesture({\n game,\n orientation,\n containerRef,\n arrowsLayerRef,\n enabled: arrowGestureEnabled && game !== null,\n palette,\n snapToValidMove: snapArrowsToValidMove,\n });\n\n // Imperative selection + legal-target highlighter. Writes\n // `data-gb-selection` on the 64 square refs above; no React state,\n // no per-commit reconciliation. This is what closes the drag-start\n // peak-frame gap with chessground — a selectSquare call no longer\n // triggers a React render at all.\n useSelectionController(game, squareRefs, showLegalTargets);\n\n // Imperative last-move tint. Same pattern as the selection\n // controller — paints `data-gb-last-move` on the two endpoint\n // squares via a CSS `::after` pseudo-element. Removes the\n // `<LastMoveLayer/>` React component from the drop-frame commit,\n // eliminating two DOM creates + layout + paint per move.\n useLastMoveController(game, squareRefs, highlightLastMove);\n\n // Container-level cursor paint. Writes `data-gb-turn` (and\n // optionally `data-gb-premove`) on the board container — a CSS rule\n // chain keyed to `[data-piece-cell]` values picks out grabbable\n // pieces without touching any square. That takes per-move cursor\n // DOM churn from 32 attribute writes down to 0-1; the grabbing\n // cursor (`grabbing`) is applied by the sibling `data-gb-dragging`\n // attribute toggled from `onDragStart` / `onDragEnd`.\n useCursorController(game, containerRef, dragEnabled, allowPremove);\n\n // Memoised runtime so `<AnimationRunner/>`'s effect-deps stay stable\n // across `<Chessboard/>` prop changes unrelated to animation.\n const animationRuntime = useMemo(() => ({ skipNextRef: skipNextAnimationRef }), []);\n\n // Inline theme variables → available at first paint.\n const containerStyle: CSSProperties = {\n position: \"relative\",\n aspectRatio: \"1 / 1\",\n width: \"100%\",\n touchAction: \"none\", // let the drag layer own pan gestures\n ...(theme as CSSProperties),\n ...style,\n };\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={containerStyle}\n data-gb-orientation={orientation}\n data-gb-target-style={showLegalTargets === false ? \"off\" : showLegalTargets}\n {...(viewOnly ? { \"data-gb-view-only\": \"true\" } : {})}\n >\n <BoardGrid\n orientation={orientation}\n onSquareClick={handleSquareClick}\n focusedSquare={focusedSquare}\n setSquareRef={setSquareRef}\n readOnly={viewOnly}\n model={game}\n getSquareAriaLabel={getSquareAriaLabel}\n onSquareFocus={onSquareFocus}\n {...(renderSquare !== undefined ? { renderSquare } : {})}\n {...(ariaLabel !== undefined ? { ariaLabel } : {})}\n />\n {game !== null && showCheckHighlight ? (\n <CheckLayer model={game} orientation={orientation} />\n ) : null}\n {game !== null ? (\n <PremoveLayer model={game} orientation={orientation} pieces={pieces} />\n ) : null}\n {/*\n * \"Below\" arrows — arrows marked `below: true` render beneath the\n * piece layer by DOM order (positioned elements without z-index\n * paint in tree order). Fresh subset per commit filters server\n * annotations / heatmap tints away from the top overlay.\n */}\n {game !== null ? (\n <ArrowsLayer model={game} orientation={orientation} palette={palette} below />\n ) : null}\n {game !== null ? (\n <PieceLayer model={game} orientation={orientation} pieces={pieces} />\n ) : fallbackBoard !== null ? (\n <StaticPieceLayer board={fallbackBoard} orientation={orientation} pieces={pieces} />\n ) : null}\n {game !== null ? (\n <AnimationRunner\n model={game}\n containerRef={containerRef}\n orientation={orientation}\n {...(animation !== undefined ? { options: animation } : {})}\n runtime={animationRuntime}\n />\n ) : null}\n <DragLayer ref={dragLayerRef} pieces={pieces} />\n {game !== null ? (\n <ArrowsLayer\n ref={arrowsLayerRef}\n model={game}\n orientation={orientation}\n palette={palette}\n />\n ) : null}\n {showCoordinates ? (\n <Coordinates orientation={orientation} ranksPosition={ranksPosition} />\n ) : null}\n <IllegalFlashLayer at={flashSquare} orientation={orientation} />\n {game !== null ? <LiveRegion model={game} /> : null}\n {pendingPromotion !== null ? (\n <PromotionOverlay\n from={pendingPromotion.from}\n to={pendingPromotion.to}\n color={pendingPromotion.color}\n orientation={orientation}\n pieces={pieces}\n onSelect={pendingPromotion.resolve}\n onCancel={pendingPromotion.cancel}\n getPromotionPieceAriaLabel={getPromotionPieceAriaLabel}\n />\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\n/**\n * Own a `BoardModel` across the lifetime of a component.\n *\n * The engine (`gigachess`) initializes synchronously (<0.5 ms), so the model\n * is active and non-null immediately on frame 0. Pieces are grabbable and\n * responsive to pointer events on the initial render commit without an\n * intermediate async gap.\n */\n\nimport { useEffect, useRef, useState } from \"react\";\nimport {\n type BoardModel,\n type BoardModelOptions,\n createBoardModel,\n createGigachessAdapter,\n} from \"../core/index.js\";\nimport type { UseChessGameOptions } from \"../types.js\";\n\n/**\n * Allocate a board model bound to a fresh `gigachess` engine. The model\n * is created synchronously on the initial render, lives for the lifetime of\n * the calling component, and is disposed on unmount.\n *\n * @remarks\n * Synchronous initialization on frame 0 ensures zero layout shift and 0 ms\n * long tasks during mount. Changing `options.fen` disposes the current model\n * and allocates a fresh one.\n */\nexport function useChessGame(options: UseChessGameOptions & BoardModelOptions = {}): BoardModel {\n const { fen, ...modelOptions } = options;\n const [initialModelOptions] = useState<BoardModelOptions>(() => modelOptions);\n\n // Synchronous initialization on frame 0 via createGigachessAdapter (<0.5 ms)\n const [model, setModel] = useState<BoardModel>(() => {\n const adapter = createGigachessAdapter(fen);\n return createBoardModel(adapter, modelOptions);\n });\n\n // Track FEN changes: reallocate model if lifecycle FEN input changes\n const prevFenRef = useRef<string | undefined>(fen);\n useEffect(() => {\n if (prevFenRef.current !== fen) {\n prevFenRef.current = fen;\n const adapter = createGigachessAdapter(fen);\n const nextModel = createBoardModel(adapter, initialModelOptions);\n setModel((prev) => {\n prev.dispose();\n return nextModel;\n });\n }\n }, [fen, initialModelOptions]);\n\n // Clean up on component unmount\n useEffect(() => {\n return () => {\n model.dispose();\n };\n }, [model]);\n\n return model;\n}\n","/**\n * `gigaboard` — ultra-fast interactive React chessboard.\n *\n * Hand-curated barrel; sub-modules are never re-exported wholesale so\n * consumers can tree-shake aggressively.\n *\n * Server-only entry (static SSR board, zero client JS): `gigaboard/server`.\n */\n\nexport { BoardEditor, type BoardEditorProps, formatFenPlacement } from \"./board-editor.js\";\n// ---- Components ----\nexport { Chessboard } from \"./chessboard.js\";\nexport type {\n BoardCell,\n BoardModel,\n BoardSnapshot,\n EngineAdapter,\n PackedMove,\n SquareIndex,\n ZobristKey,\n} from \"./core/index.js\";\n// ---- Core engine & models ----\nexport {\n Color,\n createBoardModel,\n createGigachessAdapter,\n isNullMove,\n isNullMoveSan,\n isNullMoveUci,\n NULL_MOVE_SAN,\n NULL_MOVE_SANS,\n NULL_MOVE_UCI,\n NULL_MOVE_WORD,\n PieceType,\n packMove,\n preloadGigachessAdapter,\n unpackMove,\n} from \"./core/index.js\";\nexport {\n CSS_VARS,\n DEFAULT_ILLEGAL_FLASH_TINT,\n DEFAULT_PREMOVE_TINT,\n defaultArrowColors,\n defaultTheme,\n} from \"./default-theme.js\";\nexport { AnimationRunner } from \"./hooks/use-animation.js\";\nexport { useArrowGesture } from \"./hooks/use-arrow-gesture.js\";\nexport {\n useBoardSlice,\n useBoardSnapshot,\n useSquareCell,\n} from \"./hooks/use-board-subscription.js\";\n// ---- Hooks ----\nexport { useChessGame } from \"./hooks/use-chess-game.js\";\nexport { useClickToMove } from \"./hooks/use-click-to-move.js\";\nexport { useDrag } from \"./hooks/use-drag.js\";\nexport { type HoverSquareContext, useHoverSquare } from \"./hooks/use-hover-square.js\";\nexport { useKeyboardNav } from \"./hooks/use-keyboard-nav.js\";\nexport type {\n MoveHapticKey,\n MoveHapticOptions,\n MoveHapticPatterns,\n TriggerMoveHaptic,\n} from \"./hooks/use-move-haptics.js\";\nexport { triggerMoveHaptic, useMoveHaptics } from \"./hooks/use-move-haptics.js\";\nexport type {\n MoveSoundKey,\n MoveSoundOptions,\n MoveSoundSources,\n TriggerMoveSound,\n} from \"./hooks/use-move-sound.js\";\nexport {\n DEFAULT_MOVE_SOUND_SOURCES,\n useMoveSound,\n} from \"./hooks/use-move-sound.js\";\n// ---- Geometry helpers ----\nexport { algebraicOf, getPointAtSquareCentre, getSquareAtPoint, squareOf } from \"./lib/geometry.js\";\nexport type { HapticFeedbackOptions, HapticInput, TriggerOptions } from \"./lib/haptics.js\";\nexport { triggerHaptic, warmupHaptics } from \"./lib/haptics.js\";\nexport type { MoveFeedbackKey } from \"./lib/move-feedback.js\";\nexport { classifyMoveFeedback, DEFAULT_MOVE_HAPTIC_PATTERNS } from \"./lib/move-feedback.js\";\n// ---- Defaults ----\nexport { defaultPieces } from \"./pieces/default-pieces.js\";\n\n// ---- Types ----\nexport type {\n AnimationOptions,\n ArrowColors,\n ChessboardProps,\n LegalTargetStyle,\n Orientation,\n PieceRenderer,\n PositionTransition,\n PromotionContext,\n RanksPosition,\n ResolvedArrowPalette,\n SquareContext,\n Theme,\n UseChessGameOptions,\n} from \"./types.js\";\n\n/** Package version — keep in sync with `package.json`. */\nexport const PACKAGE_VERSION = \"1.5.0\";\n"]}