import * as _angular_core from '@angular/core'; import { ElementRef, AfterViewInit, OnDestroy, InjectionToken } from '@angular/core'; import { Api } from 'chessground/api'; import { Config } from 'chessground/config'; import { Key, Color } from 'chessground/types'; export { Key } from 'chessground/types'; import { MatDialogRef } from '@angular/material/dialog'; import { Chess } from 'chess.js'; /** * Core chessboard component wrapping the chessground library via snabbdom. * * Accepts a `runFunction` signal-model input that receives the mounted DOM element * and must return a chessground `Api` instance. The component manages lifecycle: * - Uses an Angular `afterRenderEffect()` to watch both `runFunction` changes * and `viewChild` population, redrawing the board after Angular finishes DOM * rendering. This is the recommended approach for third-party library integration. * - When the `runFunction` identity changes, the previous Chessground instance * is destroyed before the new one is created. * - Provides an optional `config` input: when its identity changes, the config * is applied to the **existing** instance in place via `Api.set()`. This keeps * animations and drag & drop state intact and is far cheaper than recreating * the instance — the preferred way to update positions/moves. * - Provides a `toggleOrientation()` method to flip the board. * * Uses {@link NgxChessgroundService} (provided at component level) for snabbdom patching * and chessground instance management. * * @example * ```html * * ``` * * @example * ```typescript * myRunFn = signal<(el: HTMLElement) => Api>((el) => { * return Chessground(el, { fen: 'start' }); * }); * ``` */ declare class NgxChessgroundComponent { /** * Signal-based view query for the board container element. * * References the DOM element with template variable `#chessboard`. * Tracked by `afterRenderEffect` to pass the native element to chessground. */ readonly elementView: _angular_core.Signal>; /** * Function that constructs the chessground instance on a given element. * * This is the primary input mechanism of the component, and it is * **required** — omitting it is a compile-time error rather than a silently * blank board. Changes to the function's identity trigger a board redraw * via `afterRenderEffect()`; the previous instance is destroyed first. * * A plain `input()` (not a `model()`) because a callback is never written * back to by the component — there is no two-way binding to expose. * * @param el — The board container `HTMLElement` mounted in the DOM. * @returns A chessground `Api` instance configured as desired. */ readonly runFunction: _angular_core.InputSignal<(el: HTMLElement) => Api>; /** * Optional partial Chessground config applied to the live instance via * `Api.set()` whenever its identity changes. * * Prefer updating the board through this input instead of changing * `runFunction`: the instance is reconfigured in place, preserving * animations, drag & drop state and avoiding recreation costs. */ readonly config: _angular_core.InputSignal | null>; /** Service managing the chessground instance and snabbdom patching lifecycle. */ private readonly ngxChessgroundService; /** Last run function applied, used to skip redundant instance recreation. */ private lastFn; /** Last config applied, used to skip redundant set() calls. */ private lastConfig; /** * Sets up an `afterRenderEffect` that redraws the chessboard after Angular * finishes rendering the DOM. * * Uses the recommended phase separation: * - **earlyRead** — reads signals to establish reactive tracking * - **write** — performs DOM manipulation (snabbdom patching) with the * guarantee that Angular's rendering is complete * * `afterRenderEffect` is the correct API for third-party library * integration per Angular's guidance. Standard `effect` runs before * Angular updates the DOM, which can cause timing issues with * `viewChild` signals and DOM-dependent libraries. */ constructor(); /** * Flips the board orientation (white ↔ black). * * Delegates to {@link NgxChessgroundService.toggleOrientation}. */ toggleOrientation(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } /** * A table-style chessboard demo component. * * Displays a single chessboard initialized with the "Play legal moves from initial position" * unit preset, enhanced with dialog-based pawn promotion via {@link PromotionService}. * * The run function is exposed as a `computed`, so the child board receives it * directly through its required `runFunction` input — no view-child query, no * imperative `effect()`, and no `initialized` guard flag. * * @example * ```html * * ``` */ declare class NgxChessgroundTableComponent { /** Injected promotion dialog service for pawn promotion UX. */ private readonly promotionService; /** * Board factory for the "play from the initial position" preset, wired to * the promotion dialog. * * The identity is stable: `createPlayUnitsWithDialog` returns fresh unit * objects only when re-evaluated, and a `computed` caches its result until a * dependency changes. The board therefore is not torn down and recreated. */ protected readonly runFunction: _angular_core.Signal<(el: HTMLElement) => Api>; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } /** * A single segment of highlighted text — either a matching portion or * non-matching surrounding text. */ interface TextSegment { /** The substring of the original text. */ text: string; /** Whether this segment matched the search query. */ match: boolean; } /** * Splits `text` into match / non-match segments for typeahead highlighting. * * Performs a case-insensitive substring match of `query` within `text`. * Returns an array of {@link TextSegment} objects that can be rendered * with conditional styling (e.g. bold for matching segments). * * @param text — Full text to segment (e.g. a player name). * @param query — Search query string to match against. * @returns Array of `{ text, match }` objects for template rendering. * * @example * ```typescript * const segments = highlightMatch('GM Magnus Carlsen (2850)', 'carl'); * // [ * // { text: 'GM Magnus ', match: false }, * // { text: 'Carl', match: true }, * // { text: 'sen (2850)', match: false }, * // ] * ``` */ declare function highlightMatch(text: string, query: string): TextSegment[]; /** * Types for the PGN viewer component and its sub-components. */ /** Collapsible section identifier for the left panel. */ type LeftPanelSection = 'players' | 'gameDetails' | 'upsets' | 'rating' | 'position'; /** Collapsible section identifier for the right panel. */ type RightPanelSection = 'moves' | 'replay' | 'loadCache'; /** Replay timing mode. */ type ReplayMode = 'realtime' | 'proportional' | 'fixed' | 'fast'; /** Which side's errors should trigger "stop on error" during replay. */ type StopOnErrorSide = 'both' | 'white' | 'black'; /** Player name with optional selection state for typeahead. */ interface PlayerSuggestion { /** Display name of the player. */ name: string; /** Whether this suggestion is the highlighted one in the dropdown. */ active: boolean; } /** A single evaluation change representing a "stop on error" event. */ interface EvaluationChange { /** Zero-based index of the move that caused the change. */ moveIndex: number; /** Size of the evaluation swing, in pawns. */ diff: number; /** The configured `stopOnErrorThreshold` this `diff` exceeded. */ threshold: number; /** Side whose move caused the evaluation change. */ side: 'white' | 'black'; } /** Clock state at a given half-move. */ interface ClockState { /** Remaining time for White, in seconds. */ white: number; /** Remaining time for Black, in seconds. */ black: number; } /** Stockfish analysis result. */ interface BestMoveInfo { /** Best move found, in SAN. */ move: string; /** Principal variation, as SAN plus the FEN reached after each move. */ pv: { san: string; fen: string; }[]; /** * Engine evaluation of the position, from White's perspective * (e.g. `'+0.32'`, `'#-2'`). */ score?: string; } /** A single move played during practice mode. */ interface PracticeMove { /** Move in standard algebraic notation (SAN). */ san: string; /** * Stockfish evaluation of the position after this move, from White's * perspective (e.g. `'+0.32'`, `'#-2'`), or null while pending/unknown. */ evaluation: string | null; } /** Complete export payload for a practice session. */ interface PracticeExport { /** FEN of the position where the practice session started. */ startFen: string; /** FEN of the current practice position. */ fen: string; /** SAN moves played during the practice session. */ moves: string[]; /** Formatted move text (e.g. `"1. e4 e5 2. Nf3"`). */ moveText: string; /** Full PGN of the practice session, including evaluation comments. */ pgn: string; } /** Game metadata for the filter panel's game list. */ interface FilterGameInfo { /** One-based game number as shown in the list. */ number: number; /** Player with the white pieces. */ white: string; /** Player with the black pieces. */ black: string; /** Result string: `'1-0'`, `'0-1'`, `'1/2-1/2'` or `'*'`. */ result: string; } /** Typeahead keyboard navigation handler. */ interface TypeaheadKeyboardEvent { /** The `KeyboardEvent.key` value that was pressed. */ key: string; /** Suppresses the browser's default handling of the key. */ preventDefault(): void; } /** Input/output contract for the player typeahead component. */ interface PlayerTypeaheadState { /** Current text in the typeahead field. */ value: string; /** Player names matching the current query. */ suggestions: string[]; /** Whether the suggestion dropdown is showing. */ isOpen: boolean; /** Index of the highlighted suggestion, or `-1` when none is highlighted. */ activeIndex: number; } /** * A PGN data source the viewer can load. * * A discriminated union rather than a set of boolean flags, so an invalid * combination ("load a URL and also this file") is unrepresentable. */ type PgnSource = /** A remote archive or PGN file. `.zst` is decompressed automatically. */ { readonly kind: 'url'; /** Absolute or app-relative URL. */ readonly url: string; /** * Remember this URL alongside the content hash so a later session * can restore it from cache without downloading. Defaults to the * URL itself, or `false` to opt out of bookmarking. */ readonly cacheAs?: string | false; } /** Raw PGN text already held by the host. */ | { readonly kind: 'pgn'; readonly text: string; /** Optional origin, used for cache bookmarking. */ readonly sourceUrl?: string; } /** A `File` from an `` or drag & drop. */ | { readonly kind: 'file'; readonly file: File; }; /** Optional per-call overrides for {@link PgnSource} loading. */ interface LoadOptions { /** * Build a position index for the loaded games. Defaults to the viewer's * current `indexStartPositions` setting. */ readonly indexStartPositions?: boolean; /** Max half-moves replayed per game when indexing. Defaults to `maxFenPlies`. */ readonly maxFenPlies?: number; } /** Machine-readable failure categories reported through `loadFailed`. */ type PgnViewerErrorCode = /** The source could not be fetched (network, HTTP status, CORS). */ 'DOWNLOAD_FAILED' /** The archive or PGN text could not be parsed into games. */ | 'PARSE_FAILED' /** The local cache could not be read or written. */ | 'CACHE_FAILED' /** The Stockfish worker could not be started. */ | 'ENGINE_FAILED' /** The source was rejected before any work started (missing/empty input). */ | 'INVALID_SOURCE'; /** * A failure the host can observe and react to. * * Every load path reports exactly one of these on failure, so a host needs a * single handler rather than sniffing console output. */ interface PgnViewerError { /** Stable category for programmatic branching. */ readonly code: PgnViewerErrorCode; /** Human-readable description, safe to display. */ readonly message: string; /** The originating error, when there was one. */ readonly cause?: unknown; } /** * Board display panel for the PGN viewer — center panel. * * Shows the chessboard with player names, clocks, turn indicators, * evaluation bar, board control buttons (flip, 3D toggle), * Stockfish analysis controls, and move navigation buttons. * * All state is owned by the parent container and passed via inputs. * The component emits events for user interactions. */ declare class BoardDisplayComponent { /** * Chessground run function for rendering the board. * * Required and never `undefined`: the wrapper's `runFunction` input is * required, so a missing factory is a compile-time error rather than a * silently empty board. */ readonly runFunction: _angular_core.InputSignal<(el: HTMLElement) => Api>; /** * Partial Chessground config applied to the live board instance via * `Api.set()` on every change (position, orientation, movable pieces). */ readonly config: _angular_core.InputSignal | null>; /** Whether the board is flipped (black at bottom). */ readonly flipped: _angular_core.ModelSignal; /** Whether to render 3D Staunton pieces. */ readonly in3d: _angular_core.ModelSignal; /** Player shown above the board (Black when unflipped). */ readonly topPlayerName: _angular_core.InputSignal; /** Player shown below the board (White when unflipped). */ readonly bottomPlayerName: _angular_core.InputSignal; /** Extra CSS class for the top player row, e.g. a turn indicator. */ readonly topPlayerTurnClass: _angular_core.InputSignal; /** Extra CSS class for the bottom player row, e.g. a turn indicator. */ readonly bottomPlayerTurnClass: _angular_core.InputSignal; /** Side to move, as used by chessground's piece theming. */ readonly activeColor: _angular_core.InputSignal; /** Colour of the top player's piece icon. */ readonly topPlayerActiveColor: _angular_core.InputSignal; /** Colour of the bottom player's piece icon. */ readonly bottomPlayerActiveColor: _angular_core.InputSignal; /** Title (GM/IM/…) prefix for the top player, or `''`. */ readonly topPlayerTitle: _angular_core.InputSignal; /** Title (GM/IM/…) prefix for the bottom player, or `''`. */ readonly bottomPlayerTitle: _angular_core.InputSignal; /** Formatted remaining time for the top player, or `''` when unknown. */ readonly topTimeRemaining: _angular_core.InputSignal; /** Formatted remaining time for the bottom player, or `''` when unknown. */ readonly bottomTimeRemaining: _angular_core.InputSignal; /** Result of the loaded game: `'1-0'`, `'0-1'`, `'1/2-1/2'` or `'*'`. */ readonly gameResult: _angular_core.InputSignal; /** Whether the board shows the final position of the game. */ readonly isEndOfReplay: _angular_core.InputSignalWithTransform; /** Evaluation to display, in the viewer's display format, or `null`. */ readonly evaluation: _angular_core.InputSignal; /** Zero-based index of the displayed move; `-1` is the start position. */ readonly currentMoveIndex: _angular_core.InputSignal; /** Total number of moves in the loaded game. */ readonly movesCount: _angular_core.InputSignal; /** Whether the "jump to start" control is enabled. */ readonly canGoFirst: _angular_core.Signal; /** Whether the "previous move" control is enabled. */ readonly canGoPrev: _angular_core.Signal; /** Whether the "next move" control is enabled. */ readonly canGoNext: _angular_core.Signal; /** Whether the "jump to end" control is enabled. */ readonly canGoLast: _angular_core.Signal; /** Whether Stockfish is analyzing the displayed position. */ readonly isAnalyzing: _angular_core.InputSignalWithTransform; /** Engine best move and principal variation, or `null`. */ readonly bestMoveInfo: _angular_core.InputSignal; /** Whether the analysis panel is expanded. */ readonly analysisVisible: _angular_core.InputSignalWithTransform; /** Whether the "show better move" button should be offered. */ readonly showBetterMoveBtn: _angular_core.InputSignalWithTransform; /** Stockfish search depth (two-way). */ readonly stockfishDepth: _angular_core.ModelSignal; /** Whether there is a next alternative move to cycle to. */ readonly hasNextAlternative: _angular_core.InputSignalWithTransform; /** Whether there is a previous alternative to cycle back to. */ readonly hasPrevAlternative: _angular_core.InputSignalWithTransform; /** Label showing current alternative position (e.g. "2/3"). */ readonly alternativeLabel: _angular_core.InputSignal; /** Whether autoplay of the best line has completed (enables re-evaluate). */ readonly autoplayCompleted: _angular_core.InputSignalWithTransform; /** Whether the "Analyze practice" button should be offered (game not replaying). */ readonly practiceAvailable: _angular_core.InputSignalWithTransform; /** Whether practice mode is currently active. */ readonly practiceActive: _angular_core.InputSignalWithTransform; /** The user asked to flip the board orientation. */ readonly flipBoard: _angular_core.OutputEmitterRef; /** The user asked to toggle 3D pieces. */ readonly toggle3d: _angular_core.OutputEmitterRef; /** The user asked to jump to the start of the game. */ readonly goToStart: _angular_core.OutputEmitterRef; /** The user asked to step back one move. */ readonly prev: _angular_core.OutputEmitterRef; /** The user asked to step forward one move. */ readonly next: _angular_core.OutputEmitterRef; /** The user asked to jump to the end of the game. */ readonly end: _angular_core.OutputEmitterRef; /** The user asked to analyze a position; emits its FEN. */ readonly analyzePosition: _angular_core.OutputEmitterRef; /** The user asked to autoplay the engine's best line. */ readonly autoplayBestLine: _angular_core.OutputEmitterRef; /** The user asked to preview a principal-variation move; emits its FEN. */ readonly previewPvMove: _angular_core.OutputEmitterRef; /** The user asked to show or hide the analysis panel. */ readonly toggleAnalysis: _angular_core.OutputEmitterRef; /** Cycle to the next-best engine move. */ readonly nextBestMove: _angular_core.OutputEmitterRef; /** Cycle to the previous engine move. */ readonly prevBestMove: _angular_core.OutputEmitterRef; /** Re-evaluate the position currently displayed on the board. */ readonly reevaluate: _angular_core.OutputEmitterRef; /** Start practice mode from the current board position. */ readonly startPractice: _angular_core.OutputEmitterRef; /** Applies the Stockfish depth chosen in the number input. */ onStockfishDepthChange(event: Event): void; /** Forwards an analyze request for the given position. */ onAnalyzePosition(fen: string): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } /** * Vertical evaluation bar showing the current position evaluation. * * Displays a white/black gradient bar with a centered divider and * a floating text badge showing the current centipawn/mate score. * Supports flipping via CSS scaleY when the board orientation is flipped. * * @example * ```html * * ``` */ declare class EvaluationBarComponent { /** Raw evaluation string (e.g. `"+1.23"`, `"#3"`, `"-M2"`) or null. */ readonly evaluation: _angular_core.InputSignal; /** Whether the board is flipped (black at bottom). Flips the bar. */ readonly flipped: _angular_core.InputSignalWithTransform; /** Height percentage for the fill (0 = all black, 100 = all white, 50 = equal). */ readonly barHeight: _angular_core.Signal; /** Formatted evaluation string for the text badge (e.g. `"+1.23"`, `"M3"`, `"-M2"`). */ readonly formattedEval: _angular_core.Signal; /** CSS class for the evaluation fill based on advantage. */ readonly evalClass: _angular_core.Signal<"eval-equal" | "eval-white" | "eval-black">; /** Dynamic fill color using CSS variables for theme support. */ readonly evalFillColor: _angular_core.Signal<"var(--eval-fill-white, #ffffff)" | "var(--eval-fill-black, #ffffff)" | "var(--eval-fill-equal, #ffffff)">; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } /** * Desktop (Deno) runtime detection. * * The packaged desktop app serves the same Angular bundle as the web app, but * `desktop/server.ts` injects `desktop/desktop-adapter.js` into the page, which * exposes a `window.__desktop__` marker before the bundle runs. * * This matters for persistence: Deno Desktop points the webview at a random * localhost port on every launch, so the webview origin — and with it * `localStorage` and `IndexedDB` — is new each time. Only in the desktop * runtime do the viewer's settings and its parsed-game cache therefore go * through the local server's on-disk `/api/state` and `/api/cache` endpoints. * In a regular browser everything keeps using web storage. */ /** Shape of the marker object injected by the desktop adapter. */ interface DesktopMarker { /** * Opens the host's native file picker. * * @param extensions — Allowed file extensions, e.g. `['.pgn', '.zip']`. * @returns The chosen path, or `null` when the user cancelled. */ openFileDialog?(extensions: string[]): Promise; } /** Returns `true` when running inside the Deno Desktop webview. */ declare function isDesktopRuntime(): boolean; /** * Filter panel for the PGN viewer — left sidebar. * * Contains collapsible sections for: * - Player name typeahead filters (white/black) * - Game details (result, ECO, time control, event) * - Rating range filters with presets * - Position/FEN and opening-move filters * * All state is managed by the parent container and passed via inputs/outputs. * This component is purely presentational. */ declare class GameFilterPanelComponent { /** White-player name filter (two-way). */ readonly filterWhite: _angular_core.ModelSignal; /** Black-player name filter (two-way). */ readonly filterBlack: _angular_core.ModelSignal; /** When `true`, a name matches either colour instead of its own field only (two-way). */ readonly ignoreColor: _angular_core.ModelSignal; /** All distinct White player names, for the typeahead. */ readonly uniqueWhitePlayers: _angular_core.InputSignal; /** All distinct Black player names, for the typeahead. */ readonly uniqueBlackPlayers: _angular_core.InputSignal; /** Selected results; an empty array means "no result filter" (two-way). */ readonly filterResult: _angular_core.ModelSignal; /** Selected ECO code, or `''` for none (two-way). */ readonly filterEco: _angular_core.ModelSignal; /** Selected time-control keys, e.g. `['180+2']` (two-way). */ readonly filterTimeControl: _angular_core.ModelSignal; /** Selected event name, or `''` for none (two-way). */ readonly filterEvent: _angular_core.ModelSignal; /** Selected broadcast name, or `''` for none (two-way). */ readonly filterBroadcastName: _angular_core.ModelSignal; /** Distinct ECO codes with game counts, for the dropdown. */ readonly sortedEcoCodes: _angular_core.InputSignal<{ code: string; count: number; }[]>; /** Distinct time controls with counts and a human-readable label/originals summary. */ readonly sortedTimeControls: _angular_core.InputSignal<{ key: string; count: number; label: string; originalsSummary: string; }[]>; /** Distinct event names with game counts, for the dropdown. */ readonly sortedEvents: _angular_core.InputSignal<{ event: string; count: number; }[]>; /** Distinct broadcast names with game counts, for the dropdown. */ readonly sortedBroadcastNames: _angular_core.InputSignal<{ broadcastName: string; count: number; }[]>; /** Whether upset filtering is enabled (two-way). */ readonly filterUpsetEnabled: _angular_core.ModelSignal; /** Include upsets won by the lower-rated player (two-way). */ readonly filterUpsetWin: _angular_core.ModelSignal; /** Include upsets drawn by the lower-rated player (two-way). */ readonly filterUpsetDraw: _angular_core.ModelSignal; /** Minimum Elo gap between players for a game to count as an upset. */ readonly filterUpsetMinDiff: _angular_core.ModelSignal; /** Whether rating-range filtering is enabled (two-way). */ readonly filterRatingEnabled: _angular_core.ModelSignal; /** Lower bound of the White rating range, as entered (two-way). */ readonly filterWhiteRating: _angular_core.ModelSignal; /** Lower bound of the Black rating range, as entered (two-way). */ readonly filterBlackRating: _angular_core.ModelSignal; /** Upper bound of the White rating range, as entered (two-way). */ readonly filterWhiteRatingMax: _angular_core.ModelSignal; /** Upper bound of the Black rating range, as entered (two-way). */ readonly filterBlackRatingMax: _angular_core.ModelSignal; /** Whether the opening-move prefix filter is active (two-way). */ readonly filterMoves: _angular_core.ModelSignal; /** Whether position (FEN) filtering is active (two-way). */ readonly filterByFenEnabled: _angular_core.ModelSignal; /** Target position for FEN filtering, as entered (two-way). */ readonly filterFen: _angular_core.ModelSignal; /** Whether the game list is sorted oldest-first (two-way). */ readonly sortAscending: _angular_core.ModelSignal; /** Which left-panel sections are expanded, keyed by section id. */ readonly leftPanelSections: _angular_core.ModelSignal>; /** Parsed metadata for every game; drives the game-list navigator. */ readonly gamesMetadata: _angular_core.InputSignal; /** Metadata of the games matching the active filters. */ readonly filteredGameInfos: _angular_core.InputSignal; /** Number of games matching the active filters. */ readonly totalFilteredCount: _angular_core.InputSignal; /** Whether a filter request is in flight. */ readonly isFiltering: _angular_core.InputSignalWithTransform; /** Index of the game currently loaded in the board. */ readonly currentGameIndex: _angular_core.InputSignal; /** How many games are selected for batch operations. */ readonly selectedGamesCount: _angular_core.InputSignal; /** Whether a previous game exists in the current navigation order. */ readonly canGoPrev: _angular_core.InputSignalWithTransform; /** Whether a next game exists in the current navigation order. */ readonly canGoNext: _angular_core.InputSignalWithTransform; /** White player of the loaded game, for the game-list header. */ readonly currentWhitePlayer: _angular_core.InputSignal; /** Black player of the loaded game, for the game-list header. */ readonly currentBlackPlayer: _angular_core.InputSignal; /** Result of the loaded game, for the game-list header. */ readonly currentGameResult: _angular_core.InputSignal; /** The user asked to apply the current filter selection. */ readonly applyFilter: _angular_core.OutputEmitterRef; /** The user asked to reset all filters. */ readonly clearFilters: _angular_core.OutputEmitterRef; /** A game was picked from the list; emits its index. */ readonly loadGame: _angular_core.OutputEmitterRef; /** A game's selection checkbox was toggled; emits its index. */ readonly toggleGameSelection: _angular_core.OutputEmitterRef; /** Navigate to the previous game in the filtered order. */ readonly prevGame: _angular_core.OutputEmitterRef; /** Navigate to the next game in the filtered order. */ readonly nextGame: _angular_core.OutputEmitterRef; /** Reverse the game-list sort direction. */ readonly toggleSortDirection: _angular_core.OutputEmitterRef; /** A collapsible section was toggled; emits the section id. */ readonly toggleLeftSection: _angular_core.OutputEmitterRef; /** Show every filtered game instead of the limited page. */ readonly showAllFilteredGames: _angular_core.OutputEmitterRef; /** Return to the limited game page. */ readonly showLimitedGames: _angular_core.OutputEmitterRef; /** Capture the board's current position as the FEN filter value. */ readonly snapshotCurrentPosition: _angular_core.OutputEmitterRef; /** Resolves an ECO code to its opening move sequence, supplied by the container. */ readonly getOpeningMoves: _angular_core.InputSignal<((code: string) => string) | undefined>; /** Safe wrapper for invoking getOpeningMoves in templates. */ getOpeningMovesSafe(code: string): string; /** Selected Lichess archive year (two-way). */ readonly lichessYear: _angular_core.ModelSignal; /** Selected Lichess archive month, 1-12 (two-way). */ readonly lichessMonth: _angular_core.ModelSignal; /** Supplies the selectable years; provided by the container. */ readonly getLichessYears: _angular_core.InputSignal<(() => number[]) | undefined>; /** Supplies the selectable months; provided by the container. */ readonly getLichessMonths: _angular_core.InputSignal<(() => number[]) | undefined>; /** Expands or collapses one left-panel section. */ toggleSection(section: string): void; /** Applies the ECO code chosen in the dropdown. */ updateFilterEco(event: Event): void; /** Adds or removes one time-control key from the selection. */ toggleTimeControl(value: string, event: Event): void; /** Selects every time control present in the loaded collection. */ selectAllTimeControls(): void; /** Clears the time-control selection. */ clearTimeControls(): void; /** Applies the event chosen in the dropdown. */ updateFilterEvent(event: Event): void; /** Applies the broadcast chosen in the dropdown. */ updateFilterBroadcastName(event: Event): void; /** * Applies a rating-range preset. * * Accepts either an explicit `min-max` value or a single lower bound * (`'3000'` opens the range to `4000`, anything else up to `3000`). */ applyRatingPreset(event: Event): void; /** Toggles inclusion of upsets won by the lower-rated player. */ toggleUpsetWin(event: Event): void; /** Toggles inclusion of upsets drawn by the lower-rated player. */ toggleUpsetDraw(event: Event): void; /** Applies the minimum Elo gap for the upset filter. */ updateUpsetMinDiff(value: string): void; /** Adds or removes one result from the result filter. */ toggleResult(value: string, event: Event): void; /** Applies the FEN typed into the position filter. */ updateFilterFen(value: string): void; /** Applies the lower bound of the White rating range. */ updateWhiteRating(value: string): void; /** Applies the upper bound of the White rating range. */ updateWhiteRatingMax(value: string): void; /** Applies the lower bound of the Black rating range. */ updateBlackRating(value: string): void; /** Applies the upper bound of the Black rating range. */ updateBlackRatingMax(value: string): void; /** Requests loading of the game at `index`. */ onGameClick(index: number): void; /** Requests navigation to the previous game. */ onPrevGame(): void; /** Requests navigation to the next game. */ onNextGame(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } /** Inline styles applied to the dropdown when anchored to the viewer container. */ interface DropdownPosition { /** Always `fixed`: the dropdown is anchored to the viewer, not the panel. */ position: 'fixed'; /** Viewport x-offset, as a CSS length. */ left: string; /** Viewport y-offset, as a CSS length. */ top: string; /** Dropdown width, matched to the input element. */ width: string; /** Max height before the list scrolls internally. */ maxHeight: string; /** Set to `hidden` while measuring, so the pre-position paint is skipped. */ visibility?: 'hidden'; } /** * Reusable typeahead input for filtering by player name. * * Provides an autocomplete dropdown with keyboard navigation, * text highlighting of matched portions, and support for * closing via blur (with configurable delay) or Escape. * * @example * ```html * * ``` */ declare class PlayerTypeaheadComponent implements AfterViewInit, OnDestroy { /** Placeholder text for the input field. */ readonly label: _angular_core.InputSignal; /** Full list of player name suggestions. */ readonly suggestions: _angular_core.InputSignal; /** Two-way bound current filter value. */ readonly value: _angular_core.ModelSignal; /** Emitted when a suggestion is selected from the dropdown. */ readonly optionSelected: _angular_core.OutputEmitterRef; /** Whether the dropdown is open. */ readonly isOpen: _angular_core.WritableSignal; /** Currently highlighted index in the dropdown. */ readonly activeIndex: _angular_core.WritableSignal; /** Close timeout handle for delayed blur. */ private closeTimeout; /** The text input element. */ readonly inputEl: _angular_core.Signal | undefined>; /** The suggestion list element. */ readonly dropdownEl: _angular_core.Signal | undefined>; /** Inline styles anchoring the dropdown; null keeps the CSS fallback. */ readonly dropdownPosition: _angular_core.WritableSignal; /** Whether the dropdown opens above the input. */ readonly openUp: _angular_core.WritableSignal; /** * The viewer container that anchors the fixed-position dropdown. * It establishes the containing block via layout containment * (`container-type: inline-size`), letting the dropdown escape the * left panel's scroll/clip context entirely. */ private containerEl; /** Watches the viewer container so the dropdown follows panel resizes. */ private resizeObserver; /** Detaches the capture-phase scroll listener added in `ngAfterViewInit`. */ private scrollCleanup; /** Coalesces reposition work into one animation frame. */ private rafId; /** Filtered suggestions based on current input value. */ readonly filteredSuggestions: _angular_core.Signal; /** * Resets the highlighted suggestion whenever the dropdown (re)opens, so a * stale index from a previous query can never point past the new list. */ constructor(); /** * Handles input events, updating the value and keeping the dropdown open. */ onInput(event: Event): void; /** Opens the dropdown and resets selection index. */ open(): void; /** * Closes the dropdown after a delay to allow mousedown on items to fire first. */ close(): void; /** Selects a player suggestion, updates the value, and closes the dropdown. */ select(player: string): void; /** * Handles keyboard navigation in the dropdown. * Arrow keys navigate, Enter selects, Escape closes. */ onKeydown(event: KeyboardEvent): void; /** * Splits text into match/non-match segments for highlighting. * Delegates to the standalone {@link highlightMatch} utility. */ highlightText(text: string, query: string): TextSegment[]; /** Cancels any pending close timeout. */ private cancelClose; /** * Finds the viewer container to anchor the dropdown against and starts * observing the layout, so the fixed-position dropdown tracks the input * while ancestor scroll or panel-resize changes the input's position. */ ngAfterViewInit(): void; /** Detaches the scroll and resize listeners set up in `ngAfterViewInit`. */ ngOnDestroy(): void; /** * Clears the anchored dropdown styles, restoring the CSS fallback * (only relevant when the dropdown is closed). */ private resetPosition; /** Coalesces repositioning work into a single animation frame. */ private schedulePosition; /** * Anchors the dropdown to the input using fixed positioning relative to the * viewer container, so it escapes the left panel's scroll/clip context. * Opens upward when there is not enough room below the input. */ private positionDropdown; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } /** * Lichess broadcast archive URL helpers. * * Extracted from the viewer component so the derivation rule is unit-testable * on its own — it is the one piece of non-obvious behaviour behind the URL * field (generated URLs follow the picker, hand-entered ones do not). */ /** * Path of the Lichess monthly broadcast archive for a year/month pair. * * @param year — Four-digit year. * @param month — Month number (1-12); zero-padded to two digits. */ declare function lichessBroadcastUrl(year: number, month: number): string; /** * Whether `url` is a URL this library generated from the year/month picker, * as opposed to one the user typed or restored from a previous session. */ declare function isLichessBroadcastUrl(url: string): boolean; /** * Resolves the PGN source URL shown in the load panel. * * The URL follows the Lichess year/month picker, but a value the user chose — * a hand-entered URL, or one restored from storage that is unrelated to the * picker — is preserved across later picker changes. * * @param next — The year/month the picker currently shows. * @param previousUrl — The URL currently in the field, if any. * @returns The URL the field should show. */ declare function resolveBroadcastUrl(next: { year: number; month: number; }, previousUrl: string | undefined): string; /** * Load & Cache panel for the PGN viewer — right sidebar bottom section. * * Provides: * - PGN text input textarea with clipboard buttons * - FEN indexing options (start positions, max plies) * - Cache management (clear, info) * - File-based loading (ZIP, PGN file picker) * - Lichess database date picker (year/month) * - URL-based loading with support for .zst compressed files * - Loading progress bar with status message * * @example * ```html * * ``` */ declare class LoadCachePanelComponent { /** Whether a load is in progress. */ readonly isLoading: _angular_core.InputSignalWithTransform; /** Load progress, 0-100. */ readonly loadingProgress: _angular_core.InputSignal; /** Human-readable description of the current load step. */ readonly loadingStatus: _angular_core.InputSignal; /** Cached-entry count and estimated size, or `null` while unknown. */ readonly cacheInfo: _angular_core.InputSignal<{ count: number; estimatedBytes: number; } | null>; /** PGN text typed or pasted into the panel (two-way). */ readonly pgnInput: _angular_core.ModelSignal; /** PGN source URL typed into the panel (two-way). */ readonly urlInput: _angular_core.ModelSignal; /** Whether to build a starting-position FEN index (two-way). */ readonly indexStartPositions: _angular_core.ModelSignal; /** Max half-moves replayed per game when indexing (two-way). */ readonly maxFenPlies: _angular_core.ModelSignal; /** Selected Lichess archive year (two-way). */ readonly lichessYear: _angular_core.ModelSignal; /** Selected Lichess archive month, 1-12 (two-way). */ readonly lichessMonth: _angular_core.ModelSignal; /** PGN text is ready to be parsed; emits the text. */ readonly loadPgnString: _angular_core.OutputEmitterRef; /** The user asked to clear the PGN cache. */ readonly clearPgnCache: _angular_core.OutputEmitterRef; /** The user asked to refresh the cache statistics. */ readonly refreshCacheInfo: _angular_core.OutputEmitterRef; /** The user asked to load the selected Lichess month. */ readonly loadFromLichess: _angular_core.OutputEmitterRef; /** The user asked to load the URL in the input. */ readonly loadFromUrl: _angular_core.OutputEmitterRef; /** The user asked to load PGN text from the clipboard. */ readonly loadFromClipboardEvent: _angular_core.OutputEmitterRef; /** The user asked to copy the PGN text to the clipboard. */ readonly copyToClipboardEvent: _angular_core.OutputEmitterRef; /** * A local file could not be read or contained no PGN entry. * * The panel is presentational and has no access to user-facing * notification, so the container turns this into a message. */ readonly fileLoadFailed: _angular_core.OutputEmitterRef; /** * Selectable archive years, oldest first. * * The lower bound matches the earliest Lichess monthly broadcast archive; * the upper bound is the current year. */ get years(): number[]; /** * Selectable months for the selected year. * * A past year offers all twelve; the current year offers only the months * that have already ended, because a broadcast archive is published after * the month closes. */ get months(): number[]; /** Applies the selected year and clamps the month to an available one. */ onLichessYearChange(event: Event): void; /** Applies the selected month. */ onLichessMonthChange(event: Event): void; /** Applies the edited PGN text. */ onPgnInputChange(event: Event): void; /** Applies the edited source URL. */ onUrlInputChange(event: Event): void; /** Applies the starting-position indexing checkbox. */ onIndexStartPositionsChange(event: Event): void; /** Applies the indexing replay window, ignoring values below 1. */ onMaxFenPliesChange(event: Event): void; /** Extracts the first `.pgn` entry from a chosen zip archive and emits it. */ onPgnZipSelected(event: Event): Promise; /** Emits the text of a chosen `.pgn` file. */ onPgnFileSelected(event: Event): void; /** Reads a file as UTF-8 text and emits it, or reports the failure. */ private handleFileRead; /** Whether the load & cache panel is expanded (two-way). */ readonly expanded: _angular_core.ModelSignal; /** Expands or collapses the load & cache panel. */ toggleExpanded(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } /** * Displays the move list for the current game as clickable buttons. * * Each move is rendered in chess notation with move numbers (1., 2., etc.). * Active and last-move buttons are highlighted. Move clocks are shown * alongside moves when available. The list auto-scrolls to keep the * active move visible when the current move index changes. * * @example * ```html * * ``` */ declare class MoveListComponent { /** SAN move strings for the current game. */ readonly moves: _angular_core.InputSignal; /** Per-move clock strings (empty string if no clock data). */ readonly moveClocks: _angular_core.InputSignal; /** Current zero-based move index (-1 = start position). */ readonly currentMoveIndex: _angular_core.InputSignal; /** Whether to highlight the last move in the game. */ readonly highlightLastMove: _angular_core.InputSignalWithTransform; /** Whether the moves section is expanded/collapsed. */ readonly expanded: _angular_core.ModelSignal; /** Emitted when the user clicks a move to jump to it. */ readonly jumpToMove: _angular_core.OutputEmitterRef; /** View query for the move list container (for auto-scroll). */ readonly moveListRef: _angular_core.Signal | undefined>; /** * Keeps the active move visible: scrolls it into the nearest edge of the * list whenever the current move index changes. */ constructor(); /** Expands or collapses the move-list panel (two-way bound). */ toggleExpanded(): void; /** Returns the move number for a given half-move index (0-indexed). */ moveNumber(index: number): number; /** Whether a given index starts a new move pair (white's move). */ isWhiteMove(index: number): boolean; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } /** * Criteria for filtering a parsed game collection in the PGN processor worker. * * All string fields are matched case-insensitively as substrings. * Rating fields default to 0 (no lower bound) or Infinity (no upper bound) when unset. * * @example * ```typescript * const criteria: FilterCriteria = { * white: 'carlsen', * black: '', * result: '1-0', * moves: true, * ignoreColor: false, * targetMoves: ['e4', 'e5', 'Nf3'], * minWhiteRating: 2500, * minBlackRating: 2400, * maxWhiteRating: Infinity, * maxBlackRating: Infinity, * eco: 'B33', * timeControl: ['180+2', '300+0'], * event: '', * filterByFen: false, * targetFen: '', * sortAscending: false, * }; * ``` */ interface FilterCriteria { /** Filter by white player name (case-insensitive substring match). */ white: string; /** Filter by black player name (case-insensitive substring match). */ black: string; /** Comma-separated result strings: `"1-0"`, `"0-1"`, `"draw"`, or `"*"` for unfinished. */ result: string; /** When `true`, filter games by the {@link targetMoves} opening sequence. */ moves: boolean; /** When `true`, treat {@link white} and {@link black} fields as matching either color. */ ignoreColor: boolean; /** SAN move sequence the game must be prefixed with (only used when {@link moves} is `true`). */ targetMoves: string[]; /** When `true`, filter games by the {@link targetFen} position. * Games that reach the target board position at any point are included. */ filterByFen: boolean; /** Target FEN string (piece placement + active color + castling + * en passant) for position-based filtering. Only used when * {@link filterByFen} is `true`. */ targetFen: string; /** Minimum white Elo rating (inclusive). Default 0. */ minWhiteRating: number; /** Minimum black Elo rating (inclusive). Default 0. */ minBlackRating: number; /** Maximum white Elo rating (inclusive). Use `Infinity` for no upper bound. */ maxWhiteRating: number; /** Maximum black Elo rating (inclusive). Use `Infinity` for no upper bound. */ maxBlackRating: number; /** ECO code filter (case-insensitive substring, e.g. `"B33"`). */ eco: string; /** * Time control filter — normalized time controls to keep * (e.g. `["180+2", "60+0"]`). A game matches when its normalized * time control equals any entry. Empty array means no filter. */ timeControl: string[]; /** Event/tournament name filter (case-insensitive substring). */ event: string; /** Broadcast name filter (case-insensitive substring). */ broadcastName: string; /** * Sort direction for filtered results. * `false` = descending (highest Elo first, default). * `true` = ascending (lowest Elo first). */ sortAscending: boolean; /** * When `true`, keep only upset games: the weaker-rated player * (by Elo) either beats or draws the stronger-rated player. * Requires both players to have a known Elo and the rating gap to * be at least {@link minUpsetEloDiff}. When enabled, results are * sorted by upset size (rating gap) instead of Elo sum. */ upsetEnabled: boolean; /** When `true` and {@link upsetEnabled}, include upsets where the weaker player wins. */ upsetWin: boolean; /** When `true` and {@link upsetEnabled}, include upsets where the weaker player draws. */ upsetDraw: boolean; /** Minimum Elo gap between the players for a game to count as an upset. Default 0. */ minUpsetEloDiff: number; } /** * Discriminated union of responses sent from the PGN processor worker to the main thread. * * The `id` field matches the correlation ID from the originating {@link WorkerMessage}. */ type WorkerResponse = /** Response to a `'load'` message with game count and metadata. */ { type: 'load'; payload: { count: number; metadata: GameMetadata[]; }; id: number; } /** Response to a `'filter'` message with matching game indices. */ | { type: 'filter'; payload: number[]; id: number; } /** Response to a `'loadGame'` message with moves, cleaned PGN, evaluations, and optional error. */ | { type: 'loadGame'; payload: { moves: string[]; pgn: string; evaluations: (string | null)[]; error?: string; }; id: number; } /** Progress update during long-running operations (load, filter). */ | { type: 'progress'; payload: { percent: number; status: string; }; id: number; } /** * Response to `'loadFromCache'` when no usable IndexedDB entry exists. The * main thread should fall back to downloading and parsing the source. */ | { type: 'cacheMiss'; payload?: undefined; id: number; } /** Error response for any message type. */ | { type: 'error'; payload: string; id: number; }; /** * Metadata extracted from a single PGN game header. * * Used for displaying game lists, filtering, and sorting without parsing full move data. * The `timeControlNormalized` field converts human-readable time controls * (e.g. `"90+30"`, `"3:0"`) into a uniform `"baseSeconds+incrementSeconds"` format. */ interface GameMetadata { /** 1-based game number within the loaded PGN collection. */ number: number; /** White player display name (includes title and Elo if present, e.g. `"GM Carlsen (2850)"`). */ white: string; /** Black player display name (includes title and Elo if present). */ black: string; /** Normalized result: `"1-0"`, `"0-1"`, `"½-½"`, or `"*"`. */ result: string; /** White player Elo rating (0 if missing). */ whiteElo: number; /** Black player Elo rating (0 if missing). */ blackElo: number; /** ECO (Encyclopedia of Chess Openings) code (e.g. `"B33"`). */ eco?: string; /** Raw time control string from the PGN header. */ timeControl?: string; /** Normalized time control in `"seconds+increment"` format, or `undefined` if unparseable. */ timeControlNormalized?: string; /** Event/tournament name from the PGN header. */ event?: string; /** Broadcast name from the PGN header (e.g. Lichess broadcast name). */ broadcastName?: string; } /** * Serialized form of the worker's cached state for IndexedDB persistence. * * The FEN cache is stored as `[gameIndex, normalizedFen[]][]` (serialized * from `Map>`) so it survives structured clone. */ interface CachedPgnData { /** Raw PGN text for each game, split by `[Event ...]` header. */ games: string[]; /** Parsed metadata for each game (headers only, no move data). */ gameMetadata: GameMetadata[]; /** * Serialized FEN position cache. * Each entry: `[gameIndex, normalizedFenString[]]`. * The FEN strings are normalized (4-field: piece placement, active color, * castling, en passant) and deduplicated per game. */ fenCache: [number, string[]][]; /** When this cache entry was created (epoch ms). */ createdAt: number; /** * Whether the FEN index was actually built for this entry. `false`/absent * means {@link fenCache} holds empty sets (indexing was disabled), so * position filters cannot be served from this entry. */ indexed?: boolean; /** Max half-moves replayed per game when the FEN index was built. */ maxFenPlies?: number; } /** * Maps a PGN source (URL) to the content hash under which its parsed games and * FEN index are stored in IndexedDB. * * The content hash alone cannot be computed without first downloading and * decompressing the archive, so this bookmark lets the application detect a * usable cache entry at startup and skip the download entirely. */ interface PgnSourceCacheEntry { /** SHA-256 hash of the decompressed PGN content. */ pgnHash: string; /** Whether the cached entry contains a built FEN index. */ indexed: boolean; /** Max half-moves replayed per game for the cached FEN index. */ maxFenPlies: number; /** When this mapping was recorded (epoch ms). */ createdAt: number; } /** * Service for caching parsed PGN data (games, metadata, FEN positions) in * IndexedDB. Allows re-opening a previously loaded PGN without re-parsing * the entire file. * * Uses raw IndexedDB (no external dependency). Provided at root level so a * single database connection is shared across the application. */ declare class PgnCacheService { /** Durable store used for the URL → content-hash bookmark map. */ private readonly store; /** Cached open handle, so the database is opened at most once. */ private dbPromise; /** * Opens (or creates) the IndexedDB database and returns a handle. */ private getDb; /** * Computes a SHA-256 hex digest of the given string using the * SubtleCrypto API. */ hashPgn(pgn: string): Promise; /** * Retrieves cached PGN data by hash, or `null` if not found or expired. * * @param pgnHash — SHA-256 hash of the original PGN string. * @param ttlMs — Time-to-live in milliseconds (default 7 days). */ getCached(pgnHash: string, ttlMs?: number): Promise; /** * Stores parsed PGN data in the cache, keyed by the PGN content hash. * * Automatically evicts the oldest entries when the cache exceeds * {@link MAX_ENTRIES}. */ setCache(pgnHash: string, data: CachedPgnData): Promise; /** * Deletes a single cache entry by hash. */ private deleteEntry; /** * Evicts the oldest entries when the store exceeds {@link MAX_ENTRIES}. */ private evictIfNeeded; /** * Removes all cached PGN data from IndexedDB. */ clearCache(): Promise; /** * Returns the number of cached entries and their total estimated size. * * On desktop the parsed archives live on disk behind the local server, so * the figures come from `/api/cache-info` instead of IndexedDB. */ getCacheInfo(): Promise<{ count: number; estimatedBytes: number; }>; /** * Looks up the cached content hash for a PGN source without touching the * content. Used to detect a cache hit before downloading the archive. * * @param source — Source identifier (typically the PGN URL). * @returns The bookmark entry, or `null` when the source is not remembered. */ getSourceEntry(source: string): PgnSourceCacheEntry | null; /** * Remembers which content hash backs a PGN source, so a later session can * restore it from the cache without downloading and decompressing it again. */ setSourceEntry(source: string, entry: PgnSourceCacheEntry): void; /** Removes all source bookmarks (used when the PGN cache is cleared). */ clearSourceEntries(): void; /** * Fills the desktop snapshot with the source bookmarks from disk. * * A no-op in the browser. Hosts should await this before reading * {@link getSourceEntry} at startup on desktop. */ hydrateSourceEntries(): Promise; /** Reads the URL → hash map, tolerating absent or corrupt payloads. */ private readSourceMap; /** Keeps only the {@link MAX_SOURCE_ENTRIES} most recently recorded sources. */ private pruneSourceMap; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } /** * Container for the full-featured PGN viewer application. * * Owns all state signals and business logic, delegating rendering to * focused presentational sub-components: * - {@link GameFilterPanelComponent} — left sidebar filters * - {@link BoardDisplayComponent} — center board area * - {@link MoveListComponent} — right panel move list * - {@link ReplayPanelComponent} — right panel replay controls * - {@link LoadCachePanelComponent} — right panel load & cache * * @example * ```html * * ``` */ declare class NgxPgnViewerComponent implements OnDestroy { /** Owns the PGN worker and the Stockfish worker. */ private readonly pgnViewerEngine; /** Sink for user-facing messages; defaults to the console. */ private readonly notifier; /** Parsed-game cache and URL → hash bookmarks. */ private readonly pgnCacheService; /** Opens the pawn-promotion dialog during interactive play. */ private readonly promotionService; /** Persists and restores the filter selection and data source. */ private readonly pgnViewerSettings; /** PGN text to load. Changing it (non-empty) starts a load. */ pgn: _angular_core.InputSignal; /** Whether to highlight the origin and destination of the last move. */ highlightLastMove: _angular_core.InputSignalWithTransform; /** Board orientation; `true` puts Black at the bottom (two-way). */ flipped: _angular_core.ModelSignal; /** Whether to render 3D Staunton pieces (two-way). */ in3d: _angular_core.ModelSignal; /** Width of the left filter panel in pixels (two-way). */ leftPanelWidth: _angular_core.ModelSignal; /** Width of the right panel in pixels (two-way). */ rightPanelWidth: _angular_core.ModelSignal; /** Whether the move-list panel is expanded (two-way). */ movesExpanded: _angular_core.ModelSignal; /** * Emitted once when durable state has been restored. * * Hosts that need to read `urlInput`/`restoredStateFromStorage` at startup * can `await whenStateReady()` instead; this output exists for hosts that * prefer the reactive form. */ readonly stateRestored: _angular_core.OutputEmitterRef; /** * Emitted when a load starts, carrying the initial status text. * * Load progress afterwards is reported through `loadProgress`. */ readonly loadStarted: _angular_core.OutputEmitterRef<{ status: string; }>; /** Emitted whenever load progress advances. */ readonly loadProgress: _angular_core.OutputEmitterRef<{ percent: number; status: string; }>; /** * Emitted for every load failure, in addition to the user-facing notice. * * This is the single place a host needs to handle to surface load errors * programmatically (telemetry, retry UI, a custom banner). */ readonly loadFailed: _angular_core.OutputEmitterRef; /** Parsed metadata for every game in the loaded collection. */ gamesMetadata: _angular_core.WritableSignal; /** Index of the game currently loaded into the board. */ currentGameIndex: _angular_core.WritableSignal; /** SAN moves of the loaded game. */ moves: _angular_core.WritableSignal; /** Zero-based index of the displayed move; `-1` is the start position. */ currentMoveIndex: _angular_core.WritableSignal; /** FEN of the position currently displayed on the board. */ currentFen: _angular_core.WritableSignal; /** Whether a load or parse is in progress. */ isLoading: _angular_core.WritableSignal; /** Load progress, 0-100. */ loadingProgress: _angular_core.WritableSignal; /** Human-readable description of the current load step. */ loadingStatus: _angular_core.WritableSignal; /** Content hash of the PGN being loaded, used for cache bookkeeping. */ lastPgnHash: string | null; /** Indices of the games selected for batch operations. */ selectedGames: _angular_core.WritableSignal>; /** White-player name filter. */ filterWhite: _angular_core.WritableSignal; /** Black-player name filter. */ filterBlack: _angular_core.WritableSignal; /** Selected results; empty means no result filter. */ filterResult: _angular_core.WritableSignal; /** Whether the opening-move prefix filter is active. */ filterMoves: _angular_core.WritableSignal; /** Whether player names match either colour. */ ignoreColor: _angular_core.WritableSignal; /** Whether upset filtering is enabled. */ filterUpsetEnabled: _angular_core.WritableSignal; /** Include upsets won by the lower-rated player. */ filterUpsetWin: _angular_core.WritableSignal; /** Include upsets drawn by the lower-rated player. */ filterUpsetDraw: _angular_core.WritableSignal; /** Minimum Elo gap between players for a game to count as an upset. */ filterUpsetMinDiff: _angular_core.WritableSignal; /** Whether rating-range filtering is enabled. */ filterRatingEnabled: _angular_core.WritableSignal; /** Lower bound of the White rating range, as entered. */ filterWhiteRating: _angular_core.WritableSignal; /** Lower bound of the Black rating range, as entered. */ filterBlackRating: _angular_core.WritableSignal; /** Upper bound of the White rating range, as entered. */ filterWhiteRatingMax: _angular_core.WritableSignal; /** Upper bound of the Black rating range, as entered. */ filterBlackRatingMax: _angular_core.WritableSignal; /** Selected ECO code, or `''`. */ filterEco: _angular_core.WritableSignal; /** Selected time-control keys; empty means no filter. */ filterTimeControl: _angular_core.WritableSignal; /** Selected event name, or `''`. */ filterEvent: _angular_core.WritableSignal; /** Selected broadcast name, or `''`. */ filterBroadcastName: _angular_core.WritableSignal; /** Target position for FEN filtering. */ filterFen: _angular_core.WritableSignal; /** Whether position (FEN) filtering is active. */ filterByFenEnabled: _angular_core.WritableSignal; /** * Whether to build a starting-position FEN index. * * Defaults to `true` in the packaged desktop app, which has the resources * to index every game, and `false` on the web unless the user opts in. */ indexStartPositions: _angular_core.WritableSignal; /** Max half-moves replayed per game when building the FEN index. */ maxFenPlies: _angular_core.WritableSignal; /** Whether the game list is sorted oldest-first. */ sortAscending: _angular_core.WritableSignal; /** Distinct White player names in the loaded collection. */ uniqueWhitePlayers: _angular_core.WritableSignal; /** Distinct Black player names in the loaded collection. */ uniqueBlackPlayers: _angular_core.WritableSignal; /** ECO code → game count, for the ECO dropdown. */ uniqueEcoCodes: _angular_core.WritableSignal>; /** Time-control key → game count and original time-control strings. */ uniqueTimeControls: _angular_core.WritableSignal; }>>; /** Event name → game count. */ uniqueEvents: _angular_core.WritableSignal>; /** Broadcast name → game count. */ uniqueBroadcastNames: _angular_core.WritableSignal>; /** Indices of the games matching the active filters. */ filteredGamesIndices: _angular_core.WritableSignal; /** Whether a filter request is in flight. */ isFiltering: _angular_core.WritableSignal; /** Whether the full filtered list is shown instead of the limited page. */ showAllGames: _angular_core.WritableSignal; /** ECO codes with counts, most frequent first. */ sortedEcoCodes: _angular_core.Signal<{ code: string; count: number; }[]>; /** Time controls with counts and display labels, most frequent first. */ sortedTimeControls: _angular_core.Signal<{ key: string; count: number; label: string; originalsSummary: string; }[]>; /** Event names with counts, most frequent first. */ sortedEvents: _angular_core.Signal<{ event: string; count: number; }[]>; /** Broadcast names with counts, most frequent first. */ sortedBroadcastNames: _angular_core.Signal<{ broadcastName: string; count: number; }[]>; /** * Metadata rows the filter panel's game list should show. * * While games are explicitly selected the list collapses to the current * game only, so the selection stays stable; otherwise it shows the first * match, or every match once `showAllGames` is set. */ filteredGameInfos: _angular_core.Signal; /** Number of games matching the active filters. */ totalFilteredCount: _angular_core.Signal; /** Number of games explicitly selected. */ selectedGamesCount: _angular_core.Signal; /** Whether batch replay should be offered: several games, some selected. */ canShowReplayAll: _angular_core.Signal; /** Position of the loaded game within the collection, e.g. `"Game 2 of 40"`. */ currentGameInfo: _angular_core.Signal; /** White player of the loaded game, or `'Unknown'` when unavailable. */ currentWhitePlayer: _angular_core.Signal; /** Black player of the loaded game, or `'Unknown'` when unavailable. */ currentBlackPlayer: _angular_core.Signal; /** Result of the loaded game, or `'*'` when unavailable. */ currentGameResult: _angular_core.Signal; /** Player name for the row above the board, honouring orientation. */ topPlayerName: _angular_core.Signal; /** Player name for the row below the board, honouring orientation. */ bottomPlayerName: _angular_core.Signal; /** Turn-indicator CSS class for the top row. */ topPlayerTurnClass: _angular_core.Signal<"white-turn" | "black-turn">; /** Turn-indicator CSS class for the bottom row. */ bottomPlayerTurnClass: _angular_core.Signal<"white-turn" | "black-turn">; /** Piece colour for the top row, honouring orientation. */ topPlayerActiveColor: _angular_core.Signal<"b" | "w">; /** Piece colour for the bottom row, honouring orientation. */ bottomPlayerActiveColor: _angular_core.Signal<"b" | "w">; /** Tooltip for the top row, naming the side that moves next. */ topPlayerTitle: _angular_core.Signal<"White to move" | "Black to move">; /** Tooltip for the bottom row, naming the side that moves next. */ bottomPlayerTitle: _angular_core.Signal<"White to move" | "Black to move">; /** Remaining time shown beside the top player. */ topTimeRemaining: _angular_core.Signal; /** Remaining time shown beside the bottom player. */ bottomTimeRemaining: _angular_core.Signal; /** * Origin and destination of the move to highlight, or `undefined`. * * Reads `currentMoveIndex`/`currentFen` so the highlight is recomputed on * every position change even though it is derived from chess.js history. */ lastMoveSquares: _angular_core.Signal<[Key, Key] | undefined>; /** Side to move, parsed from the displayed FEN. */ activeColor: _angular_core.Signal; /** Active replay timing mode. */ replayMode: _angular_core.WritableSignal<"realtime" | "proportional" | "fixed" | "fast">; /** Target duration in seconds for `proportional` replay. */ proportionalDuration: _angular_core.WritableSignal; /** Minimum seconds between moves in `realtime` replay. */ minSecondsBetweenMoves: _angular_core.WritableSignal; /** Seconds per move in `fixed` replay. */ fixedTime: _angular_core.WritableSignal; /** Seconds per move in `fast` replay. */ fastTime: _angular_core.WritableSignal; /** Whether replay halts on a significant evaluation drop. */ stopOnError: _angular_core.WritableSignal; /** Evaluation drop, in pawns, that counts as an error. */ stopOnErrorThreshold: _angular_core.WritableSignal; /** Which side's errors trigger "stop on error": 'both' | 'white' | 'black'. */ stopOnErrorSide: _angular_core.WritableSignal; /** Whether an auto-replay is currently running. */ isReplaying: _angular_core.WritableSignal; /** Whether a paused replay can be resumed from the current position. */ canContinueReplay: _angular_core.Signal; /** Whether the replay has reached the final move of the game. */ isEndOfReplay: _angular_core.Signal; /** Formatted remaining time for White, or `''` when the PGN has no clocks. */ whiteTimeRemaining: _angular_core.WritableSignal; /** Formatted remaining time for Black, or `''` when the PGN has no clocks. */ blackTimeRemaining: _angular_core.WritableSignal; /** Clock string per half-move, aligned with `moves`. */ moveClocks: _angular_core.WritableSignal; /** Whether the PGN carried clock data, so clock UI should be shown. */ showClocks: _angular_core.Signal; /** Whether Stockfish is analyzing the displayed position. */ isAnalyzing: _angular_core.WritableSignal; /** All PV lines collected from the current analysis (sorted by MultiPV rank). */ allAlternatives: _angular_core.WritableSignal; /** Index into allAlternatives indicating which line is currently displayed. */ currentAlternativeIndex: _angular_core.WritableSignal; /** Computed: currently displayed best move info (cycles through alternatives). */ readonly bestMoveInfo: _angular_core.Signal; /** Whether the "show better move" button should be offered. */ showBetterMoveBtn: _angular_core.WritableSignal; /** Whether the analysis panel is expanded. */ analysisVisible: _angular_core.WritableSignal; /** Stockfish search depth requested for the next analysis. */ stockfishDepth: _angular_core.WritableSignal; /** True after autoplayBestLine completes — enables the re-evaluate button. */ autoplayCompleted: _angular_core.WritableSignal; /** Whether practice mode (turn-based play + continuous analysis) is active. */ practiceMode: _angular_core.WritableSignal; /** FEN of the position where the current practice session started. */ practiceStartFen: _angular_core.WritableSignal; /** Moves played during the practice session, with engine evaluations. */ practiceMoves: _angular_core.WritableSignal; /** Stockfish evaluation of the current practice position (White's perspective). */ practiceEvaluation: _angular_core.WritableSignal; /** FEN currently being analyzed by Stockfish in practice mode (guards stale results). */ private practiceAnalysisFen; /** * Live chessground API of the mounted board, captured by {@link runFunction}. * Used to push the committed position (FEN + legal move destinations) to the * board synchronously after a user move, so drag & drop stays responsive * even while Angular change detection has not flushed yet. */ private boardApi; /** * Incremented whenever the board must be force-synchronized to the internal * chess.js position, even when the FEN string itself did not change (e.g. * after a rejected move that chessground already rendered). Tracked by * {@link boardConfig} to guarantee a fresh config is always pushed. */ private boardSyncTick; /** Whether the "Analyze practice" button should be offered (game not replaying). */ practiceAvailable: _angular_core.Signal; /** Evaluation shown on the evaluation bar: practice eval while practicing. */ boardEvaluation: _angular_core.Signal; /** Game result of the current practice position, or null while ongoing. */ practiceResult: _angular_core.Signal; /** Game result displayed under the board (practice result while practicing). */ displayGameResult: _angular_core.Signal; /** Evaluation string per half-move, aligned with `moves`; `null` when unknown. */ evaluations: _angular_core.WritableSignal<(string | null)[]>; /** Evaluation of the displayed move, or `null` before the first move. */ currentEvaluation: _angular_core.Signal; /** Cached-entry count and estimated size, or `null` while unknown. */ cacheInfo: _angular_core.WritableSignal<{ count: number; estimatedBytes: number; } | null>; /** PGN text shown in the load panel's textarea. */ pgnInput: _angular_core.WritableSignal; /** Lichess archive year selected in the load panel (two-way). */ lichessYear: _angular_core.ModelSignal; /** Lichess archive month selected in the load panel (two-way). */ lichessMonth: _angular_core.ModelSignal; /** * PGN source URL shown in the load panel. * * Derived from the Lichess year/month picker, but writable so a user can * type or restore a custom URL — which is then preserved across later * picker changes. A `linkedSignal` (rather than an `effect` + flag) keeps * the derivation declarative and drops the mutable "already synced" * bookkeeping. */ urlInput: _angular_core.WritableSignal; /** Panel currently being dragged, or `null` when no drag is in progress. */ private resizing; /** Pending animation frame for a panel drag, so moves are coalesced. */ private resizeRafId; /** The element that establishes the panel widths; used to clamp resizing. */ private readonly mainContentRef; /** Authoritative game state; the board is rendered from this instance. */ private chess; /** Timers scheduled for the current replay sequence, cleared on stop. */ private replayTimeouts; /** Resolver of the promise a batch replay is awaiting, or `null`. */ private replayResolve; /** Whether a multi-game (batch) replay is in progress. */ private isReplayingSequence; /** Correlation id of the newest filter request; stale replies are dropped. */ private currentFilterId; /** Correlation id of the newest `loadGame` request; stale replies are dropped. */ private currentLoadGameId; /** Whether the next filter result should replace the game selection. */ private autoSelectOnFinish; /** Move prefix the active filter was applied with, replayed after a load. */ private activeFilterMoves; /** Move index to restore when a position filter is cleared, or `null`. */ private savedGameMoveIndex; /** Moves the user played on the board while composing a position filter. */ private interactiveMoves; /** Pending request to turn off the opening-move filter after a load. */ private shouldUncheckFilterMoves; /** Clock readings parsed from the PGN, one entry per half-move. */ private clockHistory; /** Every timer this component owns, drained on destroy. */ private readonly pendingTimeouts; /** * Handle of an in-flight `requestIdleCallback` (filter-list aggregation), * cancelled on destroy so it cannot write to signals of a dead component. */ private pendingIdleCallback; /** State restored from a previous session, or `null` for a fresh session. */ private persistedState; /** * `false` until the durable state has been read. While it is `false` the * persist effect stays quiet, so the defaults cannot overwrite the saved * state before the desktop store has been hydrated. */ private readonly stateHydrated; /** Resolves once the durable state has been loaded. */ private stateReady; /** * Resolves once the persisted filter selection, Lichess source and cache * bookmarks are available. * * In the browser this is already the case when the component is created. * In the packaged desktop app the state is fetched from the local server, * so hosts should await this before loading data — otherwise the restored * archive URL is not known yet. */ whenStateReady(): Promise; /** * Source URL whose `loadFromCache` request is in flight. When the worker * answers `'cacheMiss'`, the download is started for this URL. */ private pendingCacheSourceUrl; /** Correlation id of the in-flight `loadFromCache` request. */ private currentCacheLoadId; /** * `true` when a previous session's viewer state was restored on startup. * Hosts can use this to reload the same data source before the persisted * filters are applied. */ get restoredStateFromStorage(): boolean; /** * Stable board factory: created once and never re-created afterwards, so the * Chessground instance is never torn down on position changes. All state * updates (fen, orientation, movable pieces, highlights) flow through the * {@link boardConfig} input instead, which reconfigures the live instance * in place — keeping drag & drop responsive and animations intact. */ runFunction: _angular_core.Signal<(el: HTMLElement) => Api>; /** * Complete board state passed to the board component and applied to the * live Chessground instance via `Api.set()` on every change. */ boardConfig: _angular_core.Signal>; /** * Wires the engine callbacks, restores the persisted session, and keeps the * URL field and durable state in sync with the filters. */ constructor(); /** Releases timers, workers and DOM state owned by the viewer. */ ngOnDestroy(): void; /** Flips the board orientation. */ protected flipBoard(): void; /** Toggles between flat SVG pieces and 3D Staunton pieces. */ protected toggle3d(): void; /** Begins a panel drag, locking the cursor for its duration. */ protected startResize(side: 'left' | 'right', event: MouseEvent): void; /** Applies a panel drag, clamped to 200px minimum and 45% of the container. */ protected onResizeMove(event: MouseEvent): void; /** Ends a panel drag and restores the cursor and text selection. */ protected stopResize(): void; /** Requests the full move data for the game at `index` from the worker. */ protected loadGame(index: number): void; /** Moves to the next game in the current navigation order. */ protected nextGame(): void; /** Moves to the previous game in the current navigation order. */ protected prevGame(): void; /** Game indices the prev/next controls step through (selection-aware). */ private navigationIndices; /** Whether a previous game exists in the current navigation order. */ canGoPrev: _angular_core.Signal; /** Whether a next game exists in the current navigation order. */ canGoNext: _angular_core.Signal; /** Replays the game from the start up to `index`; `-1` is the start position. */ protected jumpToMove(index: number): void; /** Advances one move, no-op in practice mode. */ protected next(): void; /** Steps back one move, no-op in practice mode. */ protected prev(): void; /** Jumps to the start position of the loaded game. */ protected start(): void; /** Jumps to the final position of the loaded game. */ protected end(): void; /** Sends the current filter selection to the worker. */ protected applyFilter(): void; /** Resets every filter to its default and re-applies them. */ protected clearFilters(): void; /** Reverses the game-list sort direction. */ protected toggleSortDirection(): void; /** Adds or removes one game from the batch-operation selection. */ protected toggleGameSelection(index: number): void; /** Starts auto-replay of the loaded game from its first move. */ protected replayGame(): void; /** Resumes a paused replay from the displayed position. */ protected continueReplay(): void; /** Cancels a batch replay across multiple games. */ protected stopSequence(): void; /** * Stops the active replay and cancels its pending move timers. * * @param resolvePromise — When `true`, resolves the promise a caller may be * awaiting from `replayAllSelectedGames`. */ stopReplay(resolvePromise?: boolean): void; /** Replays each selected game in turn, stopping early if the user cancels. */ replayAllSelectedGames(): Promise; /** Sends `fen` to Stockfish at the configured depth. */ protected analyzePosition(fen: string): void; /** Plays out the engine's principal variation on the board. */ protected autoplayBestLine(): void; /** Cycle to the next-best engine move in the current analysis. */ protected nextBestMove(): void; /** Cycle to the previous engine move in the current analysis. */ protected prevBestMove(): void; /** Re-analyze the board position currently displayed. */ protected reevaluatePosition(): void; /** Shows a principal-variation position without committing a move. */ protected previewPvMove(fen: string): void; /** Shows or hides the analysis panel, starting analysis on first open. */ protected toggleAnalysis(): void; /** * Enters practice mode: turn-based play starting from the currently * displayed position, with continuous Stockfish analysis. */ protected startPractice(): void; /** Leaves practice mode and restores the loaded game position. */ protected exitPractice(): void; /** Takes back the last practice move and re-analyzes the resulting position. */ protected undoPracticeMove(): void; /** Restarts the practice session from the position where it started. */ protected restartPractice(): void; /** Re-analyzes the current practice position (e.g. after a depth change). */ protected reanalyzePracticePosition(): void; /** Copies the current practice position as a FEN string. */ copyPracticeFen(): Promise; /** Copies the practice move list as SAN text. */ copyPracticeMoves(): Promise; /** Copies the practice session as PGN, including evaluation comments. */ copyPracticePgn(): Promise; /** Downloads the practice session as a PGN file. */ protected downloadPracticePgn(): void; /** * Parses raw PGN text in the worker. * * @param pgn — Raw PGN text. * @param sourceUrl — When the text came from a URL, the URL is remembered * alongside the content hash so the next session can restore it from * IndexedDB without downloading and decompressing it again. */ loadPgnString(pgn: string, sourceUrl?: string): Promise; /** Resets per-collection state and marks a new load as in progress. */ private beginLoad; /** Loads PGN text from the system clipboard. */ loadFromClipboard(): Promise; /** Copies the PGN text currently in the load panel. */ copyToClipboard(): Promise; /** Loads the Lichess broadcast archive for the selected year and month. */ loadFromLichess(): Promise; /** * Loads a PGN source into the viewer. * * The single entry point for getting data in — it replaces the pattern of * writing to `urlInput`/`pgnInput` and then calling a no-argument loader. * The source is explicit at the call site, so a misconfigured load is a * type error rather than a silently ignored click. * * Awaits durable-state hydration internally, so hosts do not need to * sequence `whenStateReady()` before their first load. Failures are * reported through {@link loadFailed} and a user-facing notice; this method * does not reject. * * @example * ```typescript * await viewer.load({ kind: 'url', url: 'lichess/broadcast/…pgn.zst' }); * await viewer.load({ kind: 'pgn', text: pgnString }); * await viewer.load({ kind: 'file', file: input.files[0] }); * ``` */ load(source: PgnSource, options?: LoadOptions): Promise; /** * Whether a PGN source can be restored from the IndexedDB cache with the * current indexing options, without downloading it. * * Hosts can use this to skip network probes at startup before calling * {@link load}. */ canLoadFromCache(url: string): boolean; /** * Loads the URL currently in the URL field, preferring the parsed-game * cache over a fresh download. Prefer {@link load} at call sites. */ loadFromUrl(): Promise; /** * Whether a remembered source entry can satisfy the current indexing * options. A caller that needs a FEN index cannot use an entry cached * without one (or with a shorter replay window). */ private isSourceCacheUsable; /** Downloads, decompresses and parses a PGN archive from a URL. */ private downloadFromUrl; /** Clears the worker's parsed-game cache and the URL bookmarks. */ protected clearPgnCache(): void; /** Refreshes the cached-entry count and size shown in the load panel. */ refreshCacheInfo(): Promise; /** Surfaces a file-read failure reported by the load panel. */ protected onFileLoadFailed(message: string): void; /** Handles a `.zip` chosen in the file picker. */ protected onPgnZipSelected(event: Event): void; /** * Parses a user-selected `.pgn` or `.zip` file into the viewer. * * Shared by the file inputs and by {@link load}, so both paths report * failures identically instead of one of them silently resetting the * spinner. */ loadFile(file: File): Promise; /** Extracts the first `.pgn` entry from a zip archive, if any. */ private readPgnFromZip; /** Handles a `.pgn` chosen in the file picker. */ protected onPgnFileSelected(event: Event): void; /** Copies the displayed position into the FEN filter and enables it. */ protected snapshotCurrentPosition(): void; /** Safe text highlighting for typeahead. */ protected highlightText(text: string, query: string): TextSegment[]; /** Lookup ECO opening moves from the ECO_MOVES map. */ protected getOpeningMoves(code: string): string; /** Year/month of the most recent Lichess archive that may already exist. */ private previousMonthDefaults; /** * Loads the durable state and applies it. * * In the browser this only marks the state as hydrated (localStorage was * already read synchronously in the constructor). On desktop it waits for * the local server snapshot, then restores the saved source and filters. */ private hydratePersistedState; /** Applies a state restored from storage to the filter and source signals. */ private applyPersistedState; /** Snapshots the current filter selection and data source for persistence. */ private buildPersistedState; /** * Builds the distinct-value lists behind the filter dropdowns (players, * ECO, events, time controls, broadcasts) from freshly loaded metadata. */ private buildFilterLists; /** * Legal destination map for the board's editable pieces. * * The map contains legal moves for the **side to move** only, so the user * can move whichever color the position dictates and never the other side. */ private getMovableDests; /** * Applies a move made on the board while composing a position filter. * * Every path ends either committed or with the board re-synchronized to * chess.js, because chessground renders the drop before the app validates it. */ private handleBoardMove; /** * Applies a move played on the board during practice mode. * * Practice is turn-based: only the side to move may move, and only legal * moves are accepted. The move is applied directly to the internal chess.js * instance, which enforces both legality and turn alternation. * * Every path ends in exactly one of two states: the move is committed * (FEN update + re-analysis + immediate board push), or it is rejected and * the board is force-synchronized back to the chess.js position. The board * can therefore never stay desynchronized from chess.js — a desync makes * subsequent drag & drop moves silently fail. */ private handlePracticeMove; /** * Commits an applied practice move: updates the FEN, appends the move to * the session list and triggers re-analysis of the new position. */ private commitPracticeMove; /** * Force-pushes the chess.js position to the board, even when the FEN string * did not change, healing any desync between chessground's rendered state * and chess.js (chessground applies a drop to its own state before the app * validates it — a rejected drop must be explicitly reverted). */ private forceBoardSync; /** * Synchronously pushes the current chess.js position and legal move * destinations to the live chessground instance. * * chessground clears `movable.dests` after every user drop and only * re-receives them once the `after` callback plus Angular change detection * have run. This immediate push closes that window, so rapid consecutive * drag & drop moves are never rejected. */ private pushBoardNow; /** * Applies a practice move for the side to move: rejects moves by the other * side, then lets chess.js validate legality and turn alternation in place. * Returns the made move, or null when the move is not allowed. */ private applyPracticeMove; /** Starts Stockfish analysis of the current practice position. */ private analyzePracticePosition; /** Clears practice state without touching the chess instance. */ private clearPracticeState; /** Rebuilds the chess instance and FEN from the loaded game's current move index. */ private restoreGamePosition; /** * Publishes a completed Stockfish analysis result to the practice state, * ignoring results that do not belong to the currently displayed position. */ private applyPracticeAnalysisResult; /** Formats practice moves as a single text line, e.g. `"1. e4 e5 2. Nf3"`. */ private buildPracticeMoveText; /** * Builds a full PGN for the practice session, including evaluation * comments for analyzed moves. */ private buildPracticePgn; /** Formats today's date as a PGN header value, e.g. `2026.08.24`. */ private formatPgnDate; /** Copies text to the clipboard with user feedback. */ private copyTextToClipboard; /** Routes one PGN-worker response to the matching request handler. */ private handleWorkerMessage; /** Multi-PV lines buffered until `bestmove` closes the search. */ private readonly pendingAlternatives; /** Parses UCI output from Stockfish into evaluations and PV lines. */ private handleStockfishMessage; /** Position the in-flight analysis was started for, used to drop stale results. */ private analyzedFen; /** * Converts a UCI principal variation into SAN plus the FEN after each move. * * @returns One entry per convertible move; returns `[]` for an invalid FEN. */ private uciToSan; /** Chooses and runs the replay strategy for the current timing mode. */ private runReplayLogic; /** Replays the loaded game move by move, awaiting each scheduled delay. */ private replayGameAsync; /** * Derives per-move delays from the clock data already parsed by chess.js. * * Used for `realtime` replay; falls back to the fixed interval when the PGN * carries no clock annotations. */ private calculateReplayTimeouts; /** * Derives per-move delays by parsing clock comments with chessops. * * Fallback for PGNs whose clock data chess.js cannot expose. */ private calculateReplayTimeoutsChessops; /** Queues one replay step, tracking its timer so it can be cancelled. */ private scheduleReplay; /** Renders a time-control key such as `'180+2'` as a readable label. */ private formatTimeControlKey; /** Summarizes the distinct original time-control strings behind a key. */ private formatOriginalsSummary; /** Formats a duration in seconds as `H:MM:SS` or `M:SS`. */ private formatTime; /** Parses an evaluation string into pawns, from White's perspective. */ private parseEval; /** * Whether the move that just played was made by White. * * Uses the FEN of the position AFTER the move: its active color is the * side to move next, so the mover is the opposite color. This stays * correct for games that start from a custom FEN position. */ private isWhiteMove; /** * Recovers `[%eval …]` annotations from raw PGN when the worker reported none. * * @returns One evaluation per move, `null` where the PGN has no annotation. */ private extractEvalsFromPgn; /** Parses `[%clk …]` annotations into {@link clockHistory}. */ private extractClockHistory; /** Builds the formatted per-move clock strings from `clockHistory`. */ private buildMoveClocks; /** * Finds the first move index whose position matches `targetFen`. * * @returns The zero-based index, or `-1` when the position never occurs. */ private findMoveIndexForFen; /** Trims a FEN to its first four fields for comparison. */ private normalizeFen; /** FEN of the position immediately before `moveIndex`, or `null`. */ private getFenBeforeMove; /** * Schedules a callback and tracks its timer so `ngOnDestroy` can cancel it. * * @returns The timer handle, for callers that need to cancel it early. */ private setDeferredTimeout; /** Sends a user-facing message to the configured notifier. */ private showMessage; /** * Reports a load failure on every channel at once. * * The three consumers of a failure — the host (`loadFailed`), the user * (notice) and a developer (console) — are served from one place, so a new * error path cannot accidentally reach only some of them. */ private reportLoadFailure; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } /** * Callback interface for PGN viewer engine events. * Consumer components implement these handlers to react to worker messages. */ interface PgnViewerEngineCallbacks { /** Called when the PGN processor worker sends a response (parse, filter, load results). */ onPgnMessage: (data: WorkerResponse) => void; /** Called when the Stockfish worker sends analysis output (UCI protocol messages). */ onStockfishMessage: (event: MessageEvent) => void; /** Optional error handler for worker initialization failures. */ onError?: (message: string, error?: unknown) => void; } /** * Service that manages Web Workers for background PGN processing and Stockfish analysis. * * Maintains two workers: * - **PGN processor** — parses/filters PGN data off the main thread using `pgn-processor.worker`. * - **Stockfish** — runs the Stockfish chess engine for position analysis via UCI protocol. * * Provided at root level so a single instance is shared across the application. * Callers must call {@link initialize} before using the service and {@link dispose} when done. */ declare class PgnViewerEngineService { /** Web Worker for PGN parsing and filtering. */ private pgnWorker; /** Web Worker running the Stockfish chess engine. */ private stockfishWorker; /** True once Stockfish completes its UCI handshake (uciok → isready → readyok). */ private stockfishReady; /** True while a `go` command is running and its `bestmove` has not arrived yet. */ private searching; /** * When true, drop engine output until the next `bestmove`. This swallows the * trailing info + bestmove of a search that was aborted by `stop`, so it * cannot be mistaken for the result of the search that replaced it. */ private ignoreUntilBestmove; /** Analysis request made while the engine was still booting; flushed once ready. */ private pendingAnalysis; /** * Creates and initializes both Web Workers. * * Disposes any existing workers first, then spawns new ones. * The Stockfish worker is started in UCI mode immediately. * * @param callbacks — Event handlers for worker messages and errors. * @returns `true` if workers were created successfully, `false` if Web Workers are unsupported. */ initialize(callbacks: PgnViewerEngineCallbacks): boolean; /** * Sends raw PGN text and indexing options to the parser worker for processing. * * Supports caching via `pgnHash`. When provided, the worker checks its cache * first and skips re-parsing if a valid entry exists. In the browser the * cache is IndexedDB; in the packaged desktop app it is a file on disk behind * the local server, because the webview origin (and therefore IndexedDB) is * new on every launch there. * * @param pgn — Raw PGN string (supports multi-game, compressed formats). * @param id — Correlation ID echoed back in the worker response for matching requests. * @param pgnHash — Optional SHA-256 hash for cache restore. * @param indexStartPositions — Whether to include the starting position FEN in the index. * @param maxFenPlies — Max half-moves to replay when building the FEN cache. */ loadPgn(pgn: string, id: number, pgnHash?: string, indexStartPositions?: boolean, maxFenPlies?: number): void; /** * Restores a previously parsed game collection from the cache without * sending the PGN text again. * * The worker answers with a `'load'` response on a cache hit, or a * `'cacheMiss'` response when no usable entry exists (in which case the * caller must fall back to {@link loadPgn} with the downloaded text). * * @param pgnHash — SHA-256 hash of the decompressed PGN content. * @param id — Correlation ID echoed back in the worker response. * @param indexStartPositions — Whether a built FEN index is required. * @param maxFenPlies — Max half-moves the caller expects to be indexed. */ loadFromCache(pgnHash: string, id: number, indexStartPositions?: boolean, maxFenPlies?: number): void; /** * Filters the parsed game list by the given criteria. * * @param payload — Filter criteria (player names, ECO, draw inclusion, opening moves, ratings). * @param id — Correlation ID echoed back in the worker response. */ filterGames(payload: FilterCriteria, id: number): void; /** * Loads the full move data for a specific game by its index in the parsed list. * * @param index — Zero-based index of the game to load. * @param id — Correlation ID echoed back in the worker response. */ loadGame(index: number, id: number): void; /** * Sends a FEN position to Stockfish for analysis at the given search depth. * * Stops any in-progress analysis before starting the new one. If the engine * has not finished booting yet, the request is queued and issued once the * UCI handshake completes. * * @param fen — FEN string of the position to analyze. * @param depth — Search depth in plies. * @returns `false` if the Stockfish worker is not available, `true` otherwise. */ analyzePosition(fen: string, depth: number): boolean; /** * Aborts any in-flight search and starts a new one for `fen`. */ private sendAnalysis; /** Runs the queued analysis request once the engine reports ready. */ private flushPendingAnalysis; /** * Sends a message to the PGN worker to clear all cached data — IndexedDB in * the browser, the on-disk cache files in the desktop app. */ clearCache(id: number): void; /** * Terminates both workers and releases resources. * * Sends a 'quit' command to Stockfish before terminating to allow * the engine to shut down gracefully. */ dispose(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } /** * Severity of a viewer notification. * * `'error'` is used for failures the user must know about (a download that * failed, a clipboard that could not be read); `'info'` covers confirmations * such as "PGN cache cleared." */ type PgnViewerNoticeLevel = 'info' | 'error'; /** A message the viewer wants to surface to the user. */ interface PgnViewerNotice { /** Human-readable text, already localized by the viewer. */ readonly message: string; /** How prominently the host should present it. */ readonly level: PgnViewerNoticeLevel; /** * Suggested display duration in milliseconds. `0` means "until dismissed". * Hosts are free to ignore this. */ readonly durationMs: number; } /** * Host-provided sink for user-facing viewer notifications. * * The viewer deliberately does not depend on a UI toolkit: without a provider * it falls back to {@link consolePgnViewerNotifier}, and applications that want * snackbars, toasts or a live region provide {@link PGN_VIEWER_NOTIFIER} * themselves. * * @example * ```typescript * // Bridge to Angular Material, if the host already uses it. * export const appConfig: ApplicationConfig = { * providers: [ * { * provide: PGN_VIEWER_NOTIFIER, * useFactory: () => { * const snackBar = inject(MatSnackBar); * return { * notify: ({ message, durationMs }) => * void snackBar.open(message, 'Dismiss', { duration: durationMs }), * }; * }, * }, * ], * }; * ``` */ interface PgnViewerNotifier { /** Presents a message to the user. Must not throw. */ notify(notice: PgnViewerNotice): void; } /** * Default notifier used when the host provides none. * * Writes errors to `console.error` and informational messages to * `console.info`, so nothing is silently swallowed even in a host that never * wired up {@link PGN_VIEWER_NOTIFIER}. */ declare const consolePgnViewerNotifier: PgnViewerNotifier; /** * Injection token for the viewer's notification sink. * * Defaults to {@link consolePgnViewerNotifier}. Provide your own to route * viewer messages into the host's notification system. */ declare const PGN_VIEWER_NOTIFIER: InjectionToken; /** * Filter selections persisted across application sessions. * * Mirrors the filter state owned by `NgxPgnViewerComponent`. Every field is * serialized as plain JSON so the stored blob stays human-readable and can be * migrated in future versions. */ interface PersistedFilterState { /** White-player name filter; `''` means unset. */ white: string; /** Black-player name filter; `''` means unset. */ black: string; /** Selected results, any of `'1-0'`, `'0-1'`, `'draw'`, `'*'`; empty means no result filter. */ result: string[]; /** Whether the opening-move prefix filter was active. */ moves: boolean; /** Whether player names were matched against either colour. */ ignoreColor: boolean; /** Whether upset filtering was enabled. */ upsetEnabled: boolean; /** Whether upsets won by the lower-rated player were included. */ upsetWin: boolean; /** Whether upsets drawn by the lower-rated player were included. */ upsetDraw: boolean; /** Minimum Elo gap for a game to count as an upset, as entered (string form field). */ upsetMinDiff: string; /** Whether rating-range filtering was enabled. */ ratingEnabled: boolean; /** Lower bound of the White rating range, as entered. */ whiteRating: string; /** Lower bound of the Black rating range, as entered. */ blackRating: string; /** Upper bound of the White rating range, as entered. */ whiteRatingMax: string; /** Upper bound of the Black rating range, as entered. */ blackRatingMax: string; /** Selected ECO code, or `''` for none. */ eco: string; /** Selected time-control keys, e.g. `['180+2', '300+0']`; empty means no filter. */ timeControl: string[]; /** Selected event name, or `''` for none. */ event: string; /** Selected broadcast name, or `''` for none. */ broadcastName: string; /** Position (FEN) filter value, or `''` for none. */ fen: string; /** Whether position filtering was enabled. */ byFenEnabled: boolean; /** Whether the game list was sorted ascending. */ sortAscending: boolean; } /** * Complete PGN viewer state persisted to `localStorage`. * * Besides the filters this keeps the data source the user last worked with — * the URL and the Lichess year/month picker — so a fresh session can reload * the same database and re-apply the same filter selection. */ interface PersistedViewerState { /** Schema version, used to discard incompatible payloads. */ version: number; /** Last PGN URL (Lichess broadcast archive or custom URL). */ url: string; /** Last selected Lichess archive year. */ lichessYear: number; /** Last selected Lichess archive month (1-12). */ lichessMonth: number; /** Filter selection carried over from the previous session. */ filters: PersistedFilterState; } /** Current persisted schema version. */ declare const PGN_VIEWER_STATE_VERSION = 1; /** `localStorage` key holding the serialized {@link PersistedViewerState}. */ declare const PGN_VIEWER_STATE_STORAGE_KEY = "ngx-chessground-pgn-viewer-state"; /** Filter defaults, used both for a fresh session and to fill gaps. */ declare const DEFAULT_PERSISTED_FILTER_STATE: PersistedFilterState; /** * Persists the PGN viewer's filter selection and data-source picker so they * survive an application restart. * * Storage is delegated to {@link PgnViewerStoreService}: `localStorage` in the * browser, the desktop server's on-disk store inside the packaged app (where * the webview origin changes on every launch and web storage is not durable). * * Stored values are validated and merged with {@link DEFAULT_PERSISTED_FILTER_STATE} * on load, so a corrupt, partial or older payload degrades gracefully instead * of throwing. * * Provided at root level so the viewer component and its host share one * instance and one storage key. */ declare class PgnViewerSettingsService { /** Durable key/value store backing {@link load} and {@link save}. */ private readonly store; /** * Reads the persisted viewer state. * * @returns The normalized state, or `null` when nothing valid is stored. */ load(): PersistedViewerState | null; /** * Writes the viewer state, overwriting any previously stored payload. * * @param state — Complete state snapshot to persist. */ save(state: PersistedViewerState): void; /** Removes the persisted viewer state. */ clear(): void; /** * Fills the desktop snapshot from disk. * * A no-op in the browser (localStorage is synchronous). Hosts should await * this before reading {@link load} at startup on desktop. */ hydrate(): Promise; /** * Validates an arbitrary parsed payload and fills missing fields with * defaults. Returns `null` for payloads that are not objects or carry an * incompatible schema version. */ private normalize; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } /** * Durable JSON key/value store for the PGN viewer. * * - **Browser** — `localStorage`, synchronous and unchanged. * - **Desktop** — the local app server's `/api/state/` endpoints, because * the Deno Desktop webview is served from a random localhost port on every * launch and therefore gets a fresh `localStorage`/`IndexedDB` each time. * * Reads are synchronous through an in-memory snapshot. In the browser the * snapshot is filled on demand from `localStorage`; on desktop it is filled by * {@link hydrate}, which the viewer awaits before loading games. */ declare class PgnViewerStoreService { /** Whether the durable backend is the desktop app's on-disk API. */ private readonly desktop; /** Synchronous snapshot of every key read or written this session. */ private readonly memory; /** Serializes writes per key so an earlier value can never land last. */ private readonly writeQueue; /** In-flight (or completed) {@link hydrate} call; `null` until first use. */ private hydration; /** `true` when this store is backed by the desktop app's on-disk API. */ get isDesktop(): boolean; /** * Reads a previously stored value. * * @returns The parsed value, or `null` when the key is unknown. */ get(key: string): T | null; /** Stores a value, writing through to the active backend. */ set(key: string, value: unknown): void; /** Removes a value from both the snapshot and the active backend. */ remove(key: string): void; /** * Fills the in-memory snapshot from the active backend. * * A no-op in the browser (localStorage is synchronous) and idempotent on * desktop. Resolve {@link whenReady} before reading values that must be * available at startup. */ hydrate(keys: readonly string[]): Promise; /** Resolves once {@link hydrate} has completed (immediately if not called). */ whenReady(): Promise; /** Loads one key from the desktop server into the snapshot. */ private fetchServer; /** Enqueues a JSON write so writes for one key stay ordered. */ private queueServerWrite; /** * Enqueues a request for a key after any request already in flight for it. */ private queueServerRequest; /** Builds the desktop endpoint URL for one state key. */ private serverUrl; /** Reads and parses one key from `localStorage`, tolerating corruption. */ private readLocal; /** Serializes and writes one key to `localStorage`; failures are ignored. */ private writeLocal; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } /** * Replay control panel for the PGN viewer. * * Provides timing mode selection (realtime, proportional, fixed), * replay options (stop on error with threshold), and action buttons * (replay, continue, stop, replay selected games). * * @example * ```html * * ``` */ declare class ReplayPanelComponent { /** Active replay timing mode (two-way). */ readonly replayMode: _angular_core.ModelSignal; /** Target duration in seconds for `proportional` mode (two-way). */ readonly proportionalDuration: _angular_core.ModelSignal; /** Minimum seconds between moves in `realtime` mode (two-way). */ readonly minSecondsBetweenMoves: _angular_core.ModelSignal; /** Seconds per move in `fixed` mode (two-way). */ readonly fixedTime: _angular_core.ModelSignal; /** Seconds per move in `fast` mode (two-way). */ readonly fastTime: _angular_core.ModelSignal; /** Whether replay halts on a significant evaluation drop (two-way). */ readonly stopOnError: _angular_core.ModelSignal; /** Evaluation drop, in pawns, that counts as an error (two-way). */ readonly stopOnErrorThreshold: _angular_core.ModelSignal; /** Which side's errors should trigger the stop: 'both' | 'white' | 'black'. */ readonly stopOnErrorSide: _angular_core.ModelSignal; /** Whether an auto-replay is currently running. */ readonly isReplaying: _angular_core.InputSignalWithTransform; /** Whether a paused replay can be resumed. */ readonly canContinueReplay: _angular_core.InputSignalWithTransform; /** Whether the "replay all selected games" action should be offered. */ readonly canShowReplayAll: _angular_core.InputSignalWithTransform; /** How many games are selected for batch replay. */ readonly selectedGamesCount: _angular_core.InputSignal; /** Start replaying the loaded game from the beginning. */ readonly replayGame: _angular_core.OutputEmitterRef; /** Resume the paused replay. */ readonly continueReplay: _angular_core.OutputEmitterRef; /** Stop a batch replay across multiple games. */ readonly stopSequence: _angular_core.OutputEmitterRef; /** Replay every selected game in turn. */ readonly replayAllSelectedGames: _angular_core.OutputEmitterRef; /** A collapsible section was toggled; emits the section id. */ readonly toggleSection: _angular_core.OutputEmitterRef; /** Whether the replay panel is expanded (two-way). */ readonly expanded: _angular_core.ModelSignal; /** Applies the proportional-replay target duration. */ onProportionalDurationChange(event: Event): void; /** Applies the minimum seconds between moves. */ onMinSecondsChange(event: Event): void; /** Applies the fixed per-move duration. */ onFixedTimeChange(event: Event): void; /** Applies the fast-mode per-move duration. */ onFastTimeChange(event: Event): void; /** Toggles stop-on-error. */ onStopOnErrorChange(event: Event): void; /** Applies the evaluation-drop threshold for stop-on-error. */ onStopOnErrorThresholdChange(event: Event): void; /** Applies the side whose errors trigger stop-on-error. */ onStopOnErrorSideChange(event: Event): void; /** Expands or collapses the replay panel. */ toggleExpanded(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } /** * Data passed to the promotion dialog. */ interface PromotionDialogData { /** The color of the promoting pawn — determines piece set rendering. */ color: 'white' | 'black'; } /** * Legal promotion piece choices. * - `'q'` — Queen * - `'r'` — Rook * - `'b'` — Bishop * - `'n'` — Knight */ type PromotionPiece = 'q' | 'r' | 'b' | 'n'; /** * A Material dialog that lets the user choose a piece for pawn promotion. * * Displays four buttons (Queen, Rook, Bishop, Knight) styled with Unicode * chess piece characters. On selection, the dialog closes with the chosen * {@link PromotionPiece} string. If dismissed without selection, defaults to `'q'`. * * The application is running in zoneless mode via {@link provideZonelessChangeDetection}. * The component is fully signal-driven — all template bindings are signal reads, * making `ChangeDetectionStrategy` a no-op in this configuration. */ declare class PromotionDialogComponent { /** Reference to this dialog instance, used to close it with the selection result. */ readonly dialogRef: MatDialogRef; /** Dialog input data (reactive signal) containing the promoting pawn's color. */ readonly data: _angular_core.WritableSignal; /** * Closes the dialog with the user's chosen promotion piece. * * @param piece — The selected piece: `'q'`, `'r'`, `'b'`, or `'n'`. */ selectPiece(piece: PromotionPiece): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } /** * Service that opens a Material dialog for pawn promotion selection. * * Used by chess units and components when a pawn reaches the eighth rank. * The dialog presents Queen, Rook, Bishop, and Knight options. * * Provided at root level so any component can inject it. * * @example * ```typescript * const promotionService = inject(PromotionService); * const piece = await promotionService.showPromotionDialog('white'); * // piece is 'q', 'r', 'b', or 'n' * ``` */ declare class PromotionService { /** Material dialog service used to open the promotion dialog. */ private readonly dialog; /** * Opens the promotion dialog and returns the user's selection. * * The dialog is modal (disableClose) with a backdrop. * Defaults to Queen ('q') if the dialog is dismissed without selection. * * @param color — The color of the promoting pawn ('white' or 'black'). * @returns A Promise resolving to the chosen piece: `'q'` (Queen), `'r'` (Rook), * `'b'` (Bishop), or `'n'` (Knight). */ showPromotionDialog(color: 'white' | 'black'): Promise; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } /** * Represents a unit with a name and a run method. */ interface Unit { /** * The name of the unit. */ name: string; /** * Executes the unit's functionality. * * @param el - The HTML element to run the unit on. * @returns An instance of Api. */ run: (el: HTMLElement) => Api; } /** * Represents a unit of animation for a chess conflict scenario. * * @constant * @type {Unit} * @name conflictingAnim * * @property {string} name - The name of the animation unit. * @property {Function} run - The function to execute the animation. * @param {HTMLElement} el - The HTML element to attach the Chessground instance to. * @returns {Chessground} The Chessground instance with the specified configuration. * * The animation runs with the following configuration: * - Duration: 500ms * - Initial FEN: "8/8/5p2/4P3/4K3/8/8/8" * - Turn color: Black * - Movable color: White * - Movable pieces are not free to move initially * * After 2 seconds, the black pawn on f6 moves to e5, and the turn color changes to white. * The white king on e4 can then move to e5, d5, or f5. */ declare const conflictingAnim: Unit; /** * Represents a unit test for animating chess moves with the same role. * * This unit test initializes a Chessground instance with a specific FEN position * and animates two moves sequentially with a delay between them. * * @constant * @type {Unit} * @name withSameRole * @property {string} name - The name of the unit test. * @property {function} run - The function that runs the unit test. * @param {HTMLElement} el - The HTML element to initialize the Chessground instance on. * @returns {Chessground} The initialized Chessground instance. */ declare const withSameRole: Unit; /** * Represents a unit test for an animation where pieces of different roles are moved. * * @constant * @type {Unit} * @name notSameRole * @property {string} name - The name of the unit test. * @property {function} run - The function that runs the unit test. * @param {HTMLElement} el - The HTML element where the Chessground instance will be initialized. * @returns {Chessground} - The Chessground instance after performing the moves. * * The test initializes a Chessground instance with a specific FEN position and turn color. * It then performs a sequence of moves with a delay to test the animation of pieces with different roles. */ declare const notSameRole: Unit; /** * Represents a unit that performs an animation while holding a piece on a chessboard. * * @constant * @type {Unit} * @name whileHolding * * @property {string} name - The name of the unit. * @property {Function} run - The function that executes the animation. * * @param {HTMLElement} el - The HTML element where the chessboard will be rendered. * * @returns {Chessground} - The Chessground instance with the specified configuration. * * The `run` function initializes a Chessground instance with a specific FEN position and configuration. * It sets the turn color to black and specifies an animation duration of 5000 milliseconds. * After a timeout of 3000 milliseconds, it moves a piece from f6 to e5, changes the turn color to white, * and sets the movable destinations for the white piece on e4. Finally, it plays any premoves. */ declare const whileHolding: Unit; /** * Default configuration for a unit. * * @constant * @type {Unit} * @property {string} name - The name of the configuration. * @property {function} run - Function to initialize Chessground with the given element. * @param {HTMLElement} el - The HTML element to initialize Chessground on. * @returns {Chessground} - The initialized Chessground instance. */ declare const defaults: Unit; /** * Represents a unit that initializes a chessboard from a FEN string with the black player's perspective. * * @constant * @type {Unit} * @name fromFen * * @property {string} name - The name of the unit. * @property {function} run - The function that initializes the chessboard. * @param {HTMLElement} el - The HTML element where the chessboard will be rendered. * @returns {Chessground} - The initialized Chessground instance. */ declare const fromFen: Unit; /** * Represents a unit that simulates the last move in a Crazyhouse chess game. * * @constant * @type {Unit} * @name lastMoveCrazyhouse * * @property {string} name - The name of the unit. * @property {Function} run - The function that initializes the Chessground instance and sets the last moves. * @param {HTMLElement} el - The HTML element to initialize the Chessground on. * @returns {Chessground} The initialized Chessground instance with the last moves set. */ declare const lastMoveCrazyhouse: Unit; /** * Represents a unit that highlights the king in check on a chessboard. * * @constant * @type {Unit} * @name checkHighlight * * @property {string} name - The name of the unit. * @property {Function} run - The function that initializes the chessboard with the specified FEN and highlights the king in check. * @param {HTMLElement} el - The HTML element where the chessboard will be rendered. * @returns {Chessground} - The initialized Chessground instance with the king in check highlighted. */ declare const checkHighlight: Unit; /** * Represents a unit that automatically switches between different FEN configurations * to demonstrate a puzzle bug in a chess game. * * @constant * @type {Unit} * @name autoSwitch * * @property {string} name - The name of the unit. * @property {function} run - The function that runs the unit. * * @param {HTMLElement} cont - The container element where the chessboard will be rendered. * @returns {Chessground} - The Chessground instance. * * The `run` function initializes a Chessground instance with the first configuration * and then switches between the configurations every 2000 milliseconds. * * The configurations are defined as an array of functions, each returning an object * with the following properties: * - `orientation`: The orientation of the board ("black" or "white"). * - `fen`: The FEN string representing the board position. * - `lastMove`: An array of keys representing the last move made. */ declare const autoSwitch: Unit; /** * Default configuration for the 3D theme unit. * * @constant * @type {Unit} * @name in3dDefaults * * @property {string} name - The name of the unit. * @property {function} run - The function to initialize and run the 3D theme. * * @param {HTMLElement} cont - The container element where the chessboard will be rendered. * @returns {Chessground} - The initialized Chessground instance with 3D theme settings. */ declare const in3dDefaults: Unit; /** * Represents a unit for a 3D chess theme where the player plays against a random AI. * * @constant * @type {Unit} * @name vsRandom * * @property {string} name - The name of the unit. * @property {Function} run - The function to initialize and run the unit. * @param {HTMLElement} cont - The container element where the chessboard will be rendered. * @returns {Chessground} - The initialized Chessground instance. */ declare const vsRandom: Unit; /** * Represents a 3D theme where two random AIs play against each other. * * @constant * @type {Unit} * @name fullRandom * * @property {string} name - The name of the unit. * @property {function} run - The function to execute the unit. * * @param {HTMLElement} cont - The container element where the chessboard will be rendered. * @returns {Chessground} - The Chessground instance. * * The `run` function initializes a Chessground instance with a 3D theme and sets up a game * where two random AIs play against each other. Moves are made at a fixed delay interval. */ declare const fullRandom: Unit; /** * Represents a unit test for the performance of a piece move in a chess game. * * @constant * @type {Unit} * @name move * * @property {string} name - The name of the performance test. * @property {function} run - The function that runs the performance test. * * @param {HTMLElement} cont - The container element where the chessboard will be rendered. * * @returns {Chessground} - The Chessground instance used for the performance test. * * The `run` function initializes a Chessground instance with a specified animation duration. * It then defines a recursive function `run` that moves a piece from "e2" to "a8" and back * to "e2" with a delay between moves. The recursive function continues to run as long as * the chessboard is visible. */ declare const move: Unit; /** * Represents a unit test for the performance of square selection in a chessboard. * * @constant * @type {Unit} * @name select * @property {string} name - The name of the performance test. * @property {function} run - The function that runs the performance test. * @param {HTMLElement} cont - The container element for the chessboard. * @returns {Chessground} - The Chessground instance. * * The `run` function initializes a Chessground instance with specific movable * destinations for the square "e2". It then repeatedly selects the square "e2" * and "d4" with a delay of 500 milliseconds between each selection. */ declare const select: Unit; /** * Unit to replay a PGN (Portable Game Notation) game in real time. * * @constant * @type {Unit} * @name loadPgnRealTime * @property {string} name - The name of the unit. * @property {Function} run - Function to execute the replay of the PGN game. * @param {HTMLElement} el - The HTML element where the chessboard will be rendered. * @returns {Chessground} - The Chessground instance used to render the chessboard and replay the game. * * The function performs the following steps: * 1. Initializes a new Chess instance and loads the PGN data. * 2. Creates a new Chessground instance with specific animation and movement settings. * 3. Retrieves the move history and comments from the PGN. * 4. Calculates the time control and think times for each move. * 5. Sets timeouts to replay each move on the chessboard in real time. */ declare const loadPgnRealTime: Unit; /** * Represents a unit that replays a PGN (Portable Game Notation) game with one second per move. * * @constant * @type {Unit} * @name loadPgnOneSecondPerMove * * @property {string} name - The name of the unit. * @property {Function} run - The function that executes the unit. * * @param {HTMLElement} el - The HTML element where the chessboard will be rendered. * @returns {Chessground} - The Chessground instance with the replayed game. * * The `run` function performs the following steps: * 1. Initializes a new Chess instance and loads the PGN. * 2. Creates a new Chessground instance with specific animation and movement settings. * 3. Retrieves the move history and comments from the Chess instance. * 4. Iterates through the move history and replays each move on the Chessground board with a one-second interval. */ declare const loadPgnOneSecondPerMove: Unit; /** * Unit to replay a PGN game in proportional time of 1 minute. * * @constant * @type {Unit} * @name loadPgnProportionalTime * * @property {string} name - The name of the unit. * @property {Function} run - The function to execute the unit. * * @param {HTMLElement} el - The HTML element to attach the chessboard to. * * @returns {Chessground} - The Chessground instance with the replayed game. * * The `run` function performs the following steps: * 1. Initializes a new Chess instance and loads the PGN. * 2. Creates a new Chessground instance with specific animation and movement settings. * 3. Retrieves the move history and comments from the chess instance. * 4. Calculates the think time for each move based on the comments. * 5. Sets timeouts to replay each move on the Chessground instance in proportional time. */ declare const loadPgnProportionalTime: Unit; /** * Factory function to create units that use dialog-based promotion. * This allows the components to pass in the PromotionService dependency. */ declare function createPlayUnitsWithDialog(promotionService?: PromotionService): { initial: Unit; castling: Unit; playVsRandom: Unit; playFullRandom: Unit; slowAnim: Unit; conflictingHold: Unit; }; /** * The `initial` constant represents a unit that sets up a chessboard with the initial position * and allows playing legal moves from that position. * * @constant * @type {Unit} * * @property {string} name - The name of the unit. * @property {Function} run - The function that initializes the chessboard and sets up the game. * @param {HTMLElement} el - The HTML element where the chessboard will be rendered. * @returns {Chessground} - The initialized Chessground instance. * * The `run` function performs the following tasks: * - Creates a new instance of the Chess game. * - Initializes the Chessground with the given HTML element and configuration options. * - Sets up the chessboard to allow only legal moves for the white player. * - Enables draggable pieces with ghost images. * - Defines an event handler for the move event. * - Updates the Chessground configuration to handle moves for the other side after a move is made. */ declare const initial: Unit; /** * Represents the castling unit in a chess game. * * @constant * @type {Unit} * @name castling * * @property {string} name - The name of the unit. * @property {Function} run - The function to execute the castling logic. * * @param {HTMLElement} el - The HTML element where the chessboard will be rendered. * @returns {Chessground} - The Chessground instance with the castling configuration. * * The `run` function initializes a chessboard with a given FEN string representing the board state. * It sets up the Chessground instance with the appropriate configuration for castling moves. * The function also sets up an event to handle moves after the current move. */ declare const castling: Unit; /** * Represents a unit that allows playing against a random AI. * * @constant * @type {Unit} * @name playVsRandom * * @property {string} name - The name of the unit. * @property {Function} run - The function to initialize the chess game against the random AI. * @param {HTMLElement} el - The HTML element where the chessboard will be rendered. * @returns {Chessground} - The initialized Chessground instance. */ declare const playVsRandom: Unit; /** * Represents a unit that simulates a chess game between two random AIs. * The game is displayed on a Chessground board with animations. * * @constant * @type {Unit} * @name playFullRandom * * @property {string} name - The name of the unit. * @property {Function} run - The function that initializes and runs the unit. * @param {HTMLElement} el - The HTML element where the Chessground board will be rendered. * @returns {Chessground} - The Chessground instance displaying the game. */ declare const playFullRandom: Unit; /** * Represents a unit configuration for playing against a random AI with slow animations. * * @constant * @type {Unit} * @name slowAnim * * @property {string} name - The name of the unit configuration. * @property {Function} run - The function to execute the unit configuration. * * @param {HTMLElement} el - The HTML element to initialize the chessground on. * * @returns {Chessground} - The initialized chessground instance. */ declare const slowAnim: Unit; /** * Represents a unit that demonstrates a conflicting hold/premove scenario in a chess game. * * This unit sets up a chessboard with a specific FEN position and simulates a move conflict * where a black pawn moves to a square that a white pawn is attempting to move to. * * @constant * @type {Unit} * @property {string} name - The name of the unit. * @property {Function} run - The function that initializes the chessboard and runs the scenario. * @param {HTMLElement} el - The HTML element where the chessboard will be rendered. * @returns {Chessground} The Chessground instance representing the chessboard. */ declare const conflictingHold: Unit; /** * Represents a unit test case for preset user shapes in Chessground. * This unit initializes a Chessground instance with predefined drawable shapes. * * @type {Unit} * @property {string} name - The name of the unit test case * @property {(el: HTMLElement) => Api} run - Function that initializes Chessground with preset shapes */ declare const presetUserShapes: Unit; /** * Unit test for automatically changing shapes with high difference between states * Creates a Chessground instance that cycles through different shape sets at regular intervals * * @property {string} name - The name of the unit test * @property {function} run - Function that executes the shape changing logic * @param {HTMLElement} el - The DOM element where Chessground will be mounted * @returns {Api} The Chessground API instance * * @remarks * The function cycles through three predefined shape sets (shapeSet1, shapeSet2, shapeSet3) * with a delay of 1000ms between changes. The cycling continues until the board * is no longer in the DOM (checked via offsetParent). */ declare const changingShapesHigh: Unit; /** * Represents a unit that automatically changes shapes with a low difficulty level. * * @constant * @type {Unit} * @name changingShapesLow * * @property {string} name - The name of the unit. * @property {function} run - The function that initializes the Chessground instance and starts the automatic shape changing. * * @param {HTMLElement} el - The HTML element where the Chessground instance will be initialized. * * @returns {Chessground} The initialized Chessground instance. */ declare const changingShapesLow: Unit; /** * Represents a unit that applies brush modifiers to drawable shapes on a chessboard. * * @constant * @type {Unit} * @name brushModifiers * * @property {string} name - The name of the unit. * @property {Function} run - The function that initializes the brush modifiers on the given element. * * @param {HTMLElement} el - The HTML element to which the brush modifiers will be applied. * * @returns {Chessground} - The Chessground instance with the applied brush modifiers. * * The `run` function: * - Generates sets of drawable shapes with random brush modifiers. * - Initializes a Chessground instance with the first set of shapes. * - Continuously updates the shapes on the chessboard at a specified interval. */ declare const brushModifiers: Unit; /** * Represents a unit that automatically generates and sets shapes on a chessboard. * * @constant * @type {Unit} * @name autoShapes * * @property {string} name - The name of the unit. * @property {function} run - The function that initializes and runs the auto shape generation. * * @param {HTMLElement} el - The HTML element where the chessboard will be rendered. * * @returns {Chessground} - The Chessground instance with auto shapes functionality. */ declare const autoShapes: Unit; /** * A unit configuration for creating a Chessground instance with shapes not visible. * * @constant * @type {Unit} * @name visibleFalse * * @property {string} name - The name of the unit. * @property {Function} run - A function that initializes a Chessground instance with the specified element. * @param {HTMLElement} el - The HTML element to initialize the Chessground instance on. * * @example * // Usage example: * visibleFalse.run(document.getElementById('chessboard')); */ declare const visibleFalse: Unit; /** * A unit configuration object for a chessboard with shapes that are not enabled but still visible. * * @constant * @type {Unit} * @property {string} name - The name of the unit. * @property {function} run - A function that initializes a Chessground instance with the given element. * @param {HTMLElement} el - The HTML element to initialize the Chessground instance on. * @returns {void} */ declare const enabledFalse: Unit; /** * Generates a map of possible destination squares for each piece on the board. * * @param chess - An instance of the Chess game. * @returns A map where the keys are the squares with pieces that have legal moves, * and the values are arrays of destination squares for those pieces. */ declare function toDests(chess: Chess): Map; /** * Converts the current turn of a chess game to a color string. * * @param chess - An instance of a chess game. * @returns The color string "white" if it's white's turn, otherwise "black". */ declare function toColor(chess: Chess): Color; /** * Converts chess.js promotion character to chessground piece role. * * @param promotion - The chess.js promotion character ('q', 'r', 'b', 'n') * @returns The corresponding chessground piece role ('queen', 'rook', 'bishop', 'knight') */ declare function promotionToRole(promotion: string): 'queen' | 'rook' | 'bishop' | 'knight'; /** * Creates a function that makes a move on the chessboard and updates the state of the chess game. * Uses window.prompt for pawn promotion (legacy method). * * @param cg - The chessground API instance. * @param chess - The chess.js instance representing the current state of the chess game. * @returns A function that takes the origin and destination squares of a move, makes the move on the chessboard, * and updates the turn color and movable destinations in the chessground instance. */ declare function playOtherSide(cg: Api, chess: Chess): (orig: Key, dest: Key) => void; /** * Creates an async function that makes a move on the chessboard and updates the state of the chess game. * Uses a promotion service for pawn promotion (modern method with dialog). * * @param cg - The chessground API instance. * @param chess - The chess.js instance representing the current state of the chess game. * @param promotionService - The promotion service to handle pawn promotion dialog. * @returns A function that takes the origin and destination squares of a move, makes the move on the chessboard, * and updates the turn color and movable destinations in the chessground instance. */ declare function playOtherSideWithDialog(cg: Api, chess: Chess, promotionService: PromotionService): (orig: Key, dest: Key) => Promise; /** * Executes an AI move in a chess game after a specified delay. * * @param cg - The chessground API instance. * @param chess - The chess.js instance. * @param delay - The delay in milliseconds before the AI makes a move. * @param firstMove - A boolean indicating if this is the first move of the game. * @returns A function that takes the origin and destination squares of the player's move. */ declare function aiPlay(cg: Api, chess: Chess, delay: number, firstMove: boolean): (orig: Key, dest: Key) => void; /** * Represents a unit configuration for a chessboard that is view-only and * features two random AIs making moves. * * @constant * @type {Unit} * @name viewOnlyFullRandom * * @property {string} name - The name of the unit. * @property {Function} run - The function that initializes the chessboard * and starts the random AI moves. * * @param {HTMLElement} el - The HTML element where the chessboard will be rendered. * * @returns {Chessground} - The initialized Chessground instance. */ declare const viewOnlyFullRandom: Unit; /** * Represents a unit for the Crazyhouse variant where the last move is a drop. * This unit runs a sequence of configurations on a chessboard, each with a specific FEN and last move. * The configurations are cycled through with a delay between each change. * * @constant * @type {Unit} * @name lastMoveDrop * * @property {string} name - The name of the unit. * @property {function} run - The function that runs the unit. * @param {HTMLElement} cont - The container element where the chessboard will be rendered. * @returns {Chessground} - The Chessground instance. */ declare const lastMoveDrop: Unit; export { BoardDisplayComponent, DEFAULT_PERSISTED_FILTER_STATE, EvaluationBarComponent, GameFilterPanelComponent, LoadCachePanelComponent, MoveListComponent, NgxChessgroundComponent, NgxChessgroundTableComponent, NgxPgnViewerComponent, PGN_VIEWER_NOTIFIER, PGN_VIEWER_STATE_STORAGE_KEY, PGN_VIEWER_STATE_VERSION, PgnCacheService, PgnViewerEngineService, PgnViewerSettingsService, PgnViewerStoreService, PlayerTypeaheadComponent, PromotionDialogComponent, PromotionService, ReplayPanelComponent, aiPlay, autoShapes, autoSwitch, brushModifiers, castling, changingShapesHigh, changingShapesLow, checkHighlight, conflictingAnim, conflictingHold, consolePgnViewerNotifier, createPlayUnitsWithDialog, defaults, enabledFalse, fromFen, fullRandom, highlightMatch, in3dDefaults, initial, isDesktopRuntime, isLichessBroadcastUrl, lastMoveCrazyhouse, lastMoveDrop, lichessBroadcastUrl, loadPgnOneSecondPerMove, loadPgnProportionalTime, loadPgnRealTime, move, notSameRole, playFullRandom, playOtherSide, playOtherSideWithDialog, playVsRandom, presetUserShapes, promotionToRole, resolveBroadcastUrl, select, slowAnim, toColor, toDests, viewOnlyFullRandom, visibleFalse, vsRandom, whileHolding, withSameRole }; export type { BestMoveInfo, CachedPgnData, ClockState, DesktopMarker, EvaluationChange, FilterGameInfo, LeftPanelSection, LoadOptions, PersistedFilterState, PersistedViewerState, PgnSource, PgnSourceCacheEntry, PgnViewerError, PgnViewerErrorCode, PgnViewerNotice, PgnViewerNoticeLevel, PgnViewerNotifier, PlayerSuggestion, PlayerTypeaheadState, PracticeExport, PracticeMove, PromotionDialogData, PromotionPiece, ReplayMode, RightPanelSection, StopOnErrorSide, TextSegment, TypeaheadKeyboardEvent, Unit };