ui: sort and group TS imports on format

This commit is contained in:
Simek
2026-03-06 11:33:08 +01:00
parent 34c65b8296
commit 3fde57e7fe
551 changed files with 2640 additions and 1905 deletions
+17 -1
View File
@@ -5,5 +5,21 @@
"arrowParens": "avoid",
"endOfLine": "lf",
"ignorePatterns": ["**/public", "COPYING.md", "README.md"],
"experimentalSortPackageJson": false
"sortPackageJson": false,
"sortImports": {
"customGroups": [
{
"groupName": "libs",
"elementNamePattern": ["lib", "lib/**"]
}
],
"groups": [
["builtin", "external"],
["libs"],
["internal", "subpath"],
["parent", "sibling", "index"],
"style",
"unknown"
]
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
import { XMLParser } from 'fast-xml-parser';
import { readdirSync, readFileSync, writeFileSync } from 'fs';
import path from 'path';
import { XMLParser } from 'fast-xml-parser';
import { fileURLToPath } from 'url';
interface TranslationXml {
+2 -2
View File
@@ -1,9 +1,9 @@
#!/usr/bin/env node
import { MongoClient } from 'mongodb';
import { setTimeout as sleep } from 'node:timers/promises';
import fs from 'node:fs';
import crypto from 'node:crypto';
import fs from 'node:fs';
import { setTimeout as sleep } from 'node:timers/promises';
// consider a wrapper script to provide common options (like the together.ai api key).
// bin/ublog-automod (with no extension) is .gitignored for this purpose.
+12 -11
View File
@@ -1,19 +1,20 @@
import { execSync } from 'node:child_process';
import fs from 'node:fs';
import { relative, join } from 'node:path';
import { execSync } from 'node:child_process';
import { chdir } from 'node:process';
import { parsePackages } from './parse.ts';
import { makeTask, stopTask } from './task.ts';
import { tsc, stopTsc } from './tsc.ts';
import { sass, stopSass } from './sass.ts';
import { esbuild, stopEsbuild } from './esbuild.ts';
import { sync } from './sync.ts';
import { hash } from './hash.ts';
import { stopManifest } from './manifest.ts';
import { env, errorMark, c } from './env.ts';
import { i18n } from './i18n.ts';
import { definedUnique } from './algo.ts';
import { clean } from './clean.ts';
import { env, errorMark, c } from './env.ts';
import { esbuild, stopEsbuild } from './esbuild.ts';
import { hash } from './hash.ts';
import { i18n } from './i18n.ts';
import { stopManifest } from './manifest.ts';
import { parsePackages } from './parse.ts';
import { sass, stopSass } from './sass.ts';
import { sync } from './sync.ts';
import { makeTask, stopTask } from './task.ts';
import { tsc, stopTsc } from './tsc.ts';
export async function build(pkgs: string[]): Promise<void> {
env.startTime = Date.now();
+2 -1
View File
@@ -1,5 +1,6 @@
import { promises as fs } from 'node:fs';
import fg from 'fast-glob';
import { promises as fs } from 'node:fs';
import { env, c } from './env.ts';
const globOpts: fg.Options = {
+3 -2
View File
@@ -1,7 +1,8 @@
import { createServer, IncomingMessage, ServerResponse } from 'node:http';
import { env, errorMark, warnMark, c } from './env.ts';
import { transform } from 'esbuild';
import stringify from 'json-stringify-pretty-compact';
import { createServer, IncomingMessage, ServerResponse } from 'node:http';
import { env, errorMark, warnMark, c } from './env.ts';
export async function startConsole() {
if (!env.remoteLog || !env.watch) return;
+3 -2
View File
@@ -1,9 +1,10 @@
import type { Package } from './parse.ts';
import fs from 'node:fs';
import ps from 'node:process';
import { join, resolve, dirname } from 'node:path';
import ps from 'node:process';
import { definedUnique, isEquivalent } from './algo.ts';
import { updateManifest } from './manifest.ts';
import type { Package } from './parse.ts';
import { taskOk } from './task.ts';
// state, logging, status
+2 -1
View File
@@ -1,10 +1,11 @@
import es from 'esbuild';
import fs from 'node:fs';
import { join, basename } from 'node:path';
import { definedMap } from './algo.ts';
import { env, errorMark, warnMark, c } from './env.ts';
import { type Manifest, updateManifest } from './manifest.ts';
import { makeTask, stopTask } from './task.ts';
import { definedMap } from './algo.ts';
let esbuildCtx: es.BuildContext | undefined;
+6 -5
View File
@@ -1,11 +1,12 @@
import fs from 'node:fs';
import crypto from 'node:crypto';
import fs from 'node:fs';
import { relative, join, resolve } from 'node:path';
import { makeTask } from './task.ts';
import { type Manifest, updateManifest } from './manifest.ts';
import { env, c } from './env.ts';
import { type Package, isClose } from './parse.ts';
import { isEquivalent } from './algo.ts';
import { env, c } from './env.ts';
import { type Manifest, updateManifest } from './manifest.ts';
import { type Package, isClose } from './parse.ts';
import { makeTask } from './task.ts';
export async function hash(): Promise<void> {
if (!env.begin('hash')) return;
+6 -5
View File
@@ -1,14 +1,15 @@
import { transform } from 'esbuild';
import fg from 'fast-glob';
import { XMLParser } from 'fast-xml-parser';
import crypto from 'node:crypto';
import fs from 'node:fs';
import fg from 'fast-glob';
import { join, basename } from 'node:path';
import { XMLParser } from 'fast-xml-parser';
import { zip } from './algo.ts';
import { env } from './env.ts';
import { type Manifest, updateManifest } from './manifest.ts';
import { readable, isClose } from './parse.ts';
import { makeTask } from './task.ts';
import { type Manifest, updateManifest } from './manifest.ts';
import { zip } from './algo.ts';
import { transform } from 'esbuild';
type PluralMode = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';
type Plural = Record<PluralMode, string>;
+2 -1
View File
@@ -1,6 +1,7 @@
import ps from 'node:process';
import { deepClean, clean } from './clean.ts';
import { build, stopBuild } from './build.ts';
import { deepClean, clean } from './clean.ts';
import { startConsole } from './console.ts';
import { env, errorMark } from './env.ts';
import { tasksIdle } from './task.ts';
+5 -4
View File
@@ -1,11 +1,12 @@
import cps from 'node:child_process';
import fs from 'node:fs';
import crypto from 'node:crypto';
import fs from 'node:fs';
import { join } from 'node:path';
import { env, c } from './env.ts';
import { jsLogger } from './console.ts';
import { taskOk } from './task.ts';
import { shallowSort, isContained } from './algo.ts';
import { jsLogger } from './console.ts';
import { env, c } from './env.ts';
import { taskOk } from './task.ts';
const manifest = {
i18n: {} as Manifest,
+2 -1
View File
@@ -1,6 +1,7 @@
import fg from 'fast-glob';
import fs from 'node:fs';
import { dirname, join, basename } from 'node:path';
import fg from 'fast-glob';
import { env } from './env.ts';
export interface Package {
+1
View File
@@ -4,6 +4,7 @@ import fs from 'node:fs';
import { basename, dirname, join, relative, resolve } from 'node:path';
import ps from 'node:process';
import clr from 'tinycolor2';
import { clamp, isEquivalent } from './algo.ts';
import { c, env, errorMark, trimLines } from './env.ts';
import { hashedBasename, symlinkTargetHashes } from './hash.ts';
+3 -2
View File
@@ -1,9 +1,10 @@
import fs from 'node:fs';
import { join, dirname } from 'node:path';
import { makeTask } from './task.ts';
import { isEquivalent } from './algo.ts';
import { env, c } from './env.ts';
import { isGlob, isFolder, isClose } from './parse.ts';
import { isEquivalent } from './algo.ts';
import { makeTask } from './task.ts';
export async function sync(): Promise<void[] | undefined> {
if (!env.begin('sync')) return;
+2 -1
View File
@@ -2,9 +2,10 @@ import fg from 'fast-glob';
import mm from 'micromatch';
import fs from 'node:fs';
import { join, relative, basename } from 'node:path';
import { type Package, glob, isFolder, subfolders, isClose } from './parse.ts';
import { randomToken, definedUnique } from './algo.ts';
import { type Context, env, c, errorMark } from './env.ts';
import { type Package, glob, isFolder, subfolders, isClose } from './parse.ts';
const fsWatches = new Map<AbsPath, FSWatch>();
const tasks = new Map<TaskKey, Task>();
+4 -3
View File
@@ -1,12 +1,13 @@
import fg from 'fast-glob';
import fs from 'node:fs';
import os from 'node:os';
import { join, resolve, dirname, basename, relative } from 'node:path';
import ts from 'typescript';
import fg from 'fast-glob';
import { Worker } from 'node:worker_threads';
import ts from 'typescript';
import { clamp } from './algo.ts';
import { env, c, errorMark } from './env.ts';
import { folderSize } from './parse.ts';
import { clamp } from './algo.ts';
import type { WorkerData, Message, ErrorMessage } from './tscWorker.ts';
const workers: Worker[] = [];
+1 -1
View File
@@ -1,5 +1,5 @@
import { parentPort, workerData } from 'worker_threads';
import ts from 'typescript';
import { parentPort, workerData } from 'worker_threads';
export interface WorkerData {
projects: string[];
+2 -2
View File
@@ -1,9 +1,9 @@
#!/usr/bin/env node
import { readdirSync } from 'node:fs';
import { spawn } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import { readdirSync } from 'node:fs';
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
process.chdir(dirname(dirname(fileURLToPath(import.meta.url))));
+7 -5
View File
@@ -1,10 +1,12 @@
import { storedBooleanProp } from 'lib/storage';
import { url as xhrUrl } from 'lib/xhr';
import * as licon from 'lib/licon';
import type AnalyseCtrl from './ctrl';
import { domDialog, type Dialog } from 'lib/view';
import { opposite } from 'chessops';
import * as licon from 'lib/licon';
import { storedBooleanProp } from 'lib/storage';
import { domDialog, type Dialog } from 'lib/view';
import { url as xhrUrl } from 'lib/xhr';
import type AnalyseCtrl from './ctrl';
export function initModule(ctrl: AnalyseCtrl): void {
let gifOrientation: Color = ctrl.bottomColor();
+3 -2
View File
@@ -1,9 +1,10 @@
import { type Prop, prop } from 'lib';
import { type NvuiContext, makeContext } from 'lib/nvui/chess';
import type AnalyseCtrl from './ctrl';
import type { NvuiPlugin } from './interfaces';
import { type NvuiContext, makeContext } from 'lib/nvui/chess';
import type * as studyDeps from './study/studyDeps';
import { renderNvui, initNvui } from './view/nvuiView';
import { type Prop, prop } from 'lib';
export type AnalyseNvuiContext = NvuiContext &
Readonly<{
+3 -2
View File
@@ -1,7 +1,8 @@
import { patch } from './view/util';
import { wsConnect } from 'lib/socket';
import makeBoot from './boot';
import makeStart from './start';
import { wsConnect } from 'lib/socket';
import { patch } from './view/util';
export { patch };
+1 -1
View File
@@ -1,5 +1,5 @@
import AnalyseCtrl from './ctrl';
import * as control from './control';
import AnalyseCtrl from './ctrl';
export default function (ctrl: AnalyseCtrl) {
return {
+11 -9
View File
@@ -1,14 +1,16 @@
import { parseUci, makeSquare } from 'chessops/util';
import { isDrop, type Square } from 'chessops/types';
import { winningChances } from 'lib/ceval';
import { opposite } from '@lichess-org/chessground/util';
import type { DrawModifiers, DrawShape } from '@lichess-org/chessground/draw';
import { annotationShapes, analysisGlyphs } from 'lib/game/glyphs';
import type AnalyseCtrl from './ctrl';
import { isUci } from 'lib/game/chess';
import { parseFen } from 'chessops/fen';
import type { ServerEval } from 'lib/tree/types';
import { opposite } from '@lichess-org/chessground/util';
import { between, ray, knightAttacks } from 'chessops/attacks';
import { parseFen } from 'chessops/fen';
import { isDrop, type Square } from 'chessops/types';
import { parseUci, makeSquare } from 'chessops/util';
import { winningChances } from 'lib/ceval';
import { isUci } from 'lib/game/chess';
import { annotationShapes, analysisGlyphs } from 'lib/game/glyphs';
import type { ServerEval } from 'lib/tree/types';
import type AnalyseCtrl from './ctrl';
const pieceDrop = (key: Key, role: Role, color: Color): DrawShape => ({
orig: key,
+1
View File
@@ -1,4 +1,5 @@
import type { TreeNode } from 'lib/tree/types';
import type AnalyseCtrl from './ctrl';
export type AutoplayDelay = number | 'realtime' | 'cpl';
+2 -1
View File
@@ -1,5 +1,6 @@
import type { AnalyseApi, AnalyseOpts } from './interfaces';
import { wsConnect } from 'lib/socket';
import type { AnalyseApi, AnalyseOpts } from './interfaces';
import type { AnalyseSocketSend } from './socket';
export default function (start: (opts: AnalyseOpts) => AnalyseApi) {
+3 -3
View File
@@ -1,7 +1,7 @@
import type { TreeNode } from 'lib/tree/types';
import type AnalyseCtrl from './ctrl';
import { path as treePath } from 'lib/tree/tree';
import type { TreeNode } from 'lib/tree/types';
import type AnalyseCtrl from './ctrl';
export function next(ctrl: AnalyseCtrl): void {
if (ctrl.retro?.preventGoingToNextMove()) return;
+2 -1
View File
@@ -1,7 +1,8 @@
import { dragNewPiece } from '@lichess-org/chessground/drag';
import type AnalyseCtrl from '../ctrl';
import type { MouchEvent } from '@lichess-org/chessground/types';
import type AnalyseCtrl from '../ctrl';
export function drag(ctrl: AnalyseCtrl, color: Color, e: MouchEvent): void {
if (e.button !== undefined && e.button !== 0) return; // only touch or left click
if (ctrl.chessground.state.movable.color !== color) return;
+3 -1
View File
@@ -1,7 +1,9 @@
import { drag } from './crazyCtrl';
import { h } from 'snabbdom';
import { onInsert } from 'lib/view';
import type AnalyseCtrl from '../ctrl';
import { drag } from './crazyCtrl';
const eventNames = ['mousedown', 'touchstart'] as const;
const oKeys = ['pawn', 'knight', 'bishop', 'rook', 'queen'] as const;
+47 -45
View File
@@ -1,24 +1,16 @@
import { playable, playedTurns, fenToEpd, validUci } from 'lib/game';
import * as keyboard from './keyboard';
import { treeReconstruct, addCrazyData } from './util';
import { plural } from './view/util';
import type GamebookPlayCtrl from './study/gamebook/gamebookPlayCtrl';
import type StudyCtrl from './study/studyCtrl';
import type { AnalyseOpts, AnalyseData, ServerEvalData, JustCaptured, NvuiPlugin } from './interfaces';
import { Result } from '@badrap/result';
import type { Api as ChessgroundApi } from '@lichess-org/chessground/api';
import { Autoplay, type AutoplayDelay } from './autoplay';
import { makeTree, treePath, treeOps, type TreeWrapper } from 'lib/tree';
import { compute as computeAutoShapes } from './autoShape';
import type { Config as ChessgroundConfig } from '@lichess-org/chessground/config';
import {
CevalCtrl,
isEvalBetter,
sanIrreversible,
type CevalHandler,
type EvalMeta,
type CevalOpts,
} from 'lib/ceval';
import { TreeView } from './treeView/treeView';
import type { DrawShape } from '@lichess-org/chessground/draw';
import { uciToMove } from '@lichess-org/chessground/util';
import { makeFen } from 'chessops/fen';
import type { PgnError } from 'chessops/pgn';
import { makeSanAndPlay } from 'chessops/san';
import { isNormal, type Move } from 'chessops/types';
import { opposite, parseUci, makeSquare, roleToChar, makeUci, parseSquare } from 'chessops/util';
import { normalizeMove } from 'chessops/variant';
import { type ArrowKey, type KeyboardMove, ctrl as makeKeyboardMove } from 'keyboardMove';
import {
defined,
prop,
@@ -30,40 +22,50 @@ import {
type Prop,
type Toggle,
} from 'lib';
import {
CevalCtrl,
isEvalBetter,
sanIrreversible,
type CevalHandler,
type EvalMeta,
type CevalOpts,
} from 'lib/ceval';
import { ChatCtrl } from 'lib/chat/chatCtrl';
import { displayColumns } from 'lib/device';
import { playable, playedTurns, fenToEpd, validUci } from 'lib/game';
import { PromotionCtrl } from 'lib/game/promotion';
import { pubsub } from 'lib/pubsub';
import type { DrawShape } from '@lichess-org/chessground/draw';
import { storedBooleanProp, storedBooleanPropWithEffect } from 'lib/storage';
import { makeTree, treePath, treeOps, type TreeWrapper } from 'lib/tree';
import { completeNode } from 'lib/tree/node';
import type { ClientEval, LocalEval, ServerEval, TreeNode, TreePath } from 'lib/tree/types';
import { confirm } from 'lib/view';
import api from './api';
import { Autoplay, type AutoplayDelay } from './autoplay';
import { compute as computeAutoShapes } from './autoShape';
import * as control from './control';
import { valid as crazyValid } from './crazy/crazyCtrl';
import EvalCache from './evalCache';
import ExplorerCtrl from './explorer/explorerCtrl';
import ForecastCtrl from './forecast/forecastCtrl';
import { ForkCtrl } from './fork';
import { IdbTree } from './idbTree';
import type { AnalyseOpts, AnalyseData, ServerEvalData, JustCaptured, NvuiPlugin } from './interfaces';
import * as keyboard from './keyboard';
import MotifCtrl from './motif/motifCtrl';
import { nextGlyphSymbol, add3or5FoldGlyphs } from './nodeFinder';
import pgnImport from './pgnImport';
import { make as makePractice, type PracticeCtrl } from './practice/practiceCtrl';
import { make as makeRetro, type RetroCtrl } from './retrospect/retroCtrl';
import { make as makeSocket, type Socket } from './socket';
import { nextGlyphSymbol, add3or5FoldGlyphs } from './nodeFinder';
import { opposite, parseUci, makeSquare, roleToChar, makeUci, parseSquare } from 'chessops/util';
import { isNormal, type Move } from 'chessops/types';
import { makeFen } from 'chessops/fen';
import { normalizeMove } from 'chessops/variant';
import { storedBooleanProp, storedBooleanPropWithEffect } from 'lib/storage';
import type GamebookPlayCtrl from './study/gamebook/gamebookPlayCtrl';
import type { AnaMove } from './study/interfaces';
import { valid as crazyValid } from './crazy/crazyCtrl';
import { PromotionCtrl } from 'lib/game/promotion';
import type StudyCtrl from './study/studyCtrl';
import { TreeView } from './treeView/treeView';
import { treeReconstruct, addCrazyData } from './util';
import { plural } from './view/util';
import wikiTheory, { wikiClear, type WikiTheory } from './wiki';
import ExplorerCtrl from './explorer/explorerCtrl';
import { uciToMove } from '@lichess-org/chessground/util';
import { IdbTree } from './idbTree';
import pgnImport from './pgnImport';
import ForecastCtrl from './forecast/forecastCtrl';
import { type ArrowKey, type KeyboardMove, ctrl as makeKeyboardMove } from 'keyboardMove';
import * as control from './control';
import type { PgnError } from 'chessops/pgn';
import { ChatCtrl } from 'lib/chat/chatCtrl';
import { confirm } from 'lib/view';
import api from './api';
import { displayColumns } from 'lib/device';
import MotifCtrl from './motif/motifCtrl';
import { makeSanAndPlay } from 'chessops/san';
import type { ClientEval, LocalEval, ServerEval, TreeNode, TreePath } from 'lib/tree/types';
import { completeNode } from 'lib/tree/node';
import { Result } from '@badrap/result';
export default class AnalyseCtrl implements CevalHandler {
data: AnalyseData;
+3 -2
View File
@@ -1,10 +1,11 @@
import { defined, prop } from 'lib';
import { throttle } from 'lib/async';
import type { EvalHit, EvalGetData, EvalPutData } from './interfaces';
import type { AnalyseSocketSend } from './socket';
import { pubsub } from 'lib/pubsub';
import type { ClientEval, PvData, ServerEval, TreeNode, TreePath } from 'lib/tree/types';
import type { EvalHit, EvalGetData, EvalPutData } from './interfaces';
import type { AnalyseSocketSend } from './socket';
export interface EvalCacheOpts {
variant: VariantKey;
receive(ev: ClientEval, path: TreePath): void;
+11 -9
View File
@@ -1,15 +1,17 @@
import { h, type VNode } from 'snabbdom';
import { myUsername, type Prop, prop } from 'lib';
import * as licon from 'lib/licon';
import { type Dialog, snabDialog, bind, dataIcon, iconTag, onInsert } from 'lib/view';
import { storedProp, storedJsonProp, type StoredProp, storedStringProp } from 'lib/storage';
import type { ExplorerDb, ExplorerSpeed, ExplorerMode } from './interfaces';
import AnalyseCtrl from '../ctrl';
import perfIcons from 'lib/game/perfIcons';
import { ucfirst } from './explorerUtil';
import { opposite } from '@lichess-org/chessground/util';
import { h, type VNode } from 'snabbdom';
import { myUsername, type Prop, prop } from 'lib';
import perfIcons from 'lib/game/perfIcons';
import * as licon from 'lib/licon';
import { storedProp, storedJsonProp, type StoredProp, storedStringProp } from 'lib/storage';
import { type Dialog, snabDialog, bind, dataIcon, iconTag, onInsert } from 'lib/view';
import { userComplete } from 'lib/view/userComplete';
import AnalyseCtrl from '../ctrl';
import { ucfirst } from './explorerUtil';
import type { ExplorerDb, ExplorerSpeed, ExplorerMode } from './interfaces';
const allSpeeds: ExplorerSpeed[] = ['ultraBullet', 'bullet', 'blitz', 'rapid', 'classical', 'correspondence'];
const allModes: ExplorerMode[] = ['casual', 'rated'];
const allRatings = [400, 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2500];
+9 -7
View File
@@ -1,15 +1,17 @@
import { type Prop, prop, defined, myUserId } from 'lib';
import { storedBooleanProp } from 'lib/storage';
import { pieceCount, fenColor } from 'lib/game/chess';
import { debounce, defer, sync, type Sync } from 'lib/async';
import { opposite } from '@lichess-org/chessground/util';
import * as xhr from './explorerXhr';
import { winnerOf } from './explorerUtil';
import { type Prop, prop, defined, myUserId } from 'lib';
import { debounce, defer, sync, type Sync } from 'lib/async';
import { replayable } from 'lib/game';
import { pieceCount, fenColor } from 'lib/game/chess';
import { storedBooleanProp } from 'lib/storage';
import type AnalyseCtrl from '../ctrl';
import type { Hovering, ExplorerData, OpeningData, SimpleTablebaseHit, ExplorerOpts } from './interfaces';
import { ExplorerConfigCtrl } from './explorerConfig';
import { winnerOf } from './explorerUtil';
import { clearLastShow } from './explorerView';
import * as xhr from './explorerXhr';
import type { Hovering, ExplorerData, OpeningData, SimpleTablebaseHit, ExplorerOpts } from './interfaces';
export const MAX_DEPTH = 50;
+4 -2
View File
@@ -1,8 +1,10 @@
import type { TablebaseMoveStats } from './interfaces';
import { opposite } from 'chessops/util';
import { fenColor } from 'lib/game/chess';
import type { VNode } from 'snabbdom';
import { fenColor } from 'lib/game/chess';
import type AnalyseCtrl from '../ctrl';
import type { TablebaseMoveStats } from './interfaces';
export function winnerOf(fen: FEN, move: TablebaseMoveStats): Color | undefined {
const stm = fenColor(fen);
+7 -5
View File
@@ -1,11 +1,14 @@
import type { VNode } from 'snabbdom';
import * as licon from 'lib/licon';
import { displayLocale, numberFormat } from 'lib/i18n';
import perfIcons from 'lib/game/perfIcons';
import { displayLocale, numberFormat } from 'lib/i18n';
import * as licon from 'lib/licon';
import { bind, dataIcon, type MaybeVNode, type LooseVNodes, hl } from 'lib/view';
import { view as renderConfig } from './explorerConfig';
import { moveArrowAttributes, ucfirst } from './explorerUtil';
import type AnalyseCtrl from '../ctrl';
import { view as renderConfig } from './explorerConfig';
import ExplorerCtrl, { MAX_DEPTH } from './explorerCtrl';
import { moveArrowAttributes, ucfirst } from './explorerUtil';
import {
isOpening,
isTablebase,
@@ -15,7 +18,6 @@ import {
type OpeningGame,
type ExplorerDb,
} from './interfaces';
import ExplorerCtrl, { MAX_DEPTH } from './explorerCtrl';
import { showTablebase } from './tablebaseView';
function resultBar(move: OpeningMoveStats): VNode {
+2 -1
View File
@@ -1,7 +1,8 @@
import type { ExplorerDb, OpeningData, TablebaseData } from './interfaces';
import * as xhr from 'lib/xhr';
import { readNdJson } from 'lib/xhr';
import type { ExplorerConfigData } from './explorerConfig';
import type { ExplorerDb, OpeningData, TablebaseData } from './interfaces';
interface OpeningXhrOpts {
endpoint: string;
+1
View File
@@ -1,4 +1,5 @@
import { h, type VNode } from 'snabbdom';
import type AnalyseCtrl from '../ctrl';
import { moveArrowAttributes, winnerOf } from './explorerUtil';
import type { TablebaseMoveStats } from './interfaces';
+5 -4
View File
@@ -1,10 +1,11 @@
import { prop, notEmpty, type Prop } from 'lib';
import { json as xhrJson } from 'lib/xhr';
import type { ForecastData, ForecastList, ForecastStep } from './interfaces';
import type { AnalyseData } from '../interfaces';
import type { TreeWrapper } from 'lib/tree/tree';
import { completeNode } from 'lib/tree/node';
import type { TreeWrapper } from 'lib/tree/tree';
import type { TreePath } from 'lib/tree/types';
import { json as xhrJson } from 'lib/xhr';
import type { AnalyseData } from '../interfaces';
import type { ForecastData, ForecastList, ForecastStep } from './interfaces';
export default class ForecastCtrl {
forecasts: Prop<ForecastList> = prop<ForecastList>([]);
+5 -3
View File
@@ -1,12 +1,14 @@
import { h, type VNode } from 'snabbdom';
import { playable } from 'lib/game';
import { fixCrazySan } from 'lib/game/chess';
import * as licon from 'lib/licon';
import { bind, dataIcon, spinnerVdom as spinner } from 'lib/view';
import type { ForecastStep } from './interfaces';
import type AnalyseCtrl from '../ctrl';
import { renderNodesHtml } from '../pgnExport';
import { fixCrazySan } from 'lib/game/chess';
import type ForecastCtrl from './forecastCtrl';
import { playable } from 'lib/game';
import type { ForecastStep } from './interfaces';
function onMyTurn(fctrl: ForecastCtrl, cNodes: ForecastStep[]): VNode | undefined {
const firstNode = cNodes[0];
+5 -4
View File
@@ -1,11 +1,12 @@
import { defined } from 'lib';
import { onInsert, hl } from 'lib/view';
import type AnalyseCtrl from './ctrl';
import type { ConcealOf } from './interfaces';
import { renderIndexAndMove } from './view/components';
import { isTouchDevice } from 'lib/device';
import { addPointerListeners } from 'lib/pointer';
import type { TreeNode } from 'lib/tree/types';
import { onInsert, hl } from 'lib/view';
import type AnalyseCtrl from './ctrl';
import type { ConcealOf } from './interfaces';
import { renderIndexAndMove } from './view/components';
export class ForkCtrl {
selectedIndex = 0;
+8 -6
View File
@@ -1,10 +1,12 @@
import { h, type VNode } from 'snabbdom';
import type { Elements } from '@lichess-org/chessground/types';
import resizeHandle from 'lib/chessgroundResize';
import { storage } from 'lib/storage';
import type AnalyseCtrl from './ctrl';
import * as Prefs from 'lib/prefs';
import { Chessground as makeChessground } from '@lichess-org/chessground';
import type { Elements } from '@lichess-org/chessground/types';
import { h, type VNode } from 'snabbdom';
import resizeHandle from 'lib/chessgroundResize';
import * as Prefs from 'lib/prefs';
import { storage } from 'lib/storage';
import type AnalyseCtrl from './ctrl';
export const render = (ctrl: AnalyseCtrl): VNode =>
h('div.cg-wrap.cgv' + ctrl.cgVersion.js, {
+4 -3
View File
@@ -1,8 +1,9 @@
import type { TreeNode, TreeNodeIncomplete, TreePath } from 'lib/tree/types';
import type AnalyseCtrl from './ctrl';
import { objectStorage, type ObjectStorage } from 'lib/objectStorage';
import * as treeOps from 'lib/tree/ops';
import { completeNode } from 'lib/tree/node';
import * as treeOps from 'lib/tree/ops';
import type { TreeNode, TreeNodeIncomplete, TreePath } from 'lib/tree/types';
import type AnalyseCtrl from './ctrl';
export type DiscloseState = undefined | 'expanded' | 'collapsed';
+11 -10
View File
@@ -1,19 +1,20 @@
import type { VNode } from 'snabbdom';
import type { Player, Status, Source, Clock } from 'lib/game';
import type { ForecastData } from './forecast/interfaces';
import type { StudyPracticeData, Goal as PracticeGoal } from './study/practice/interfaces';
import type { RelayData } from './study/relay/interfaces';
import type { ChatCtrl, ChatPlugin, ChatOpts } from 'lib/chat/interfaces';
import type { ExplorerOpts } from './explorer/interfaces';
import type { StudyDataFromServer } from './study/interfaces';
import type { AnalyseSocketSend } from './socket';
import type { ExternalEngineInfo } from 'lib/ceval';
import type { ChatCtrl, ChatPlugin, ChatOpts } from 'lib/chat/interfaces';
import type { Player, Status, Source, Clock } from 'lib/game';
import type { Coords, MoveEvent } from 'lib/prefs';
import type { EnhanceOpts } from 'lib/richText';
import type * as studyDeps from './study/studyDeps';
import type { PvDataServer, ServerEval, TreeNode, TreeNodeIncomplete, TreePath } from 'lib/tree/types';
import type { ExplorerOpts } from './explorer/interfaces';
import type { ForecastData } from './forecast/interfaces';
import type { AnalyseSocketSend } from './socket';
import type { StudyDataFromServer } from './study/interfaces';
import type { StudyPracticeData, Goal as PracticeGoal } from './study/practice/interfaces';
import type { RelayData } from './study/relay/interfaces';
import type * as studyDeps from './study/studyDeps';
export interface NvuiPlugin {
render(deps?: typeof studyDeps): VNode;
}
+6 -4
View File
@@ -1,9 +1,11 @@
import type { VNode } from 'snabbdom';
import { pubsub } from 'lib/pubsub';
import { snabDialog } from 'lib/view';
import * as xhr from 'lib/xhr';
import * as control from './control';
import type AnalyseCtrl from './ctrl';
import * as xhr from 'lib/xhr';
import { snabDialog } from 'lib/view';
import type { VNode } from 'snabbdom';
import { pubsub } from 'lib/pubsub';
export const keyToMouseEvent = (key: string, eventName: string, selector: string) =>
window.site.mousetrap.bind(key, () =>
+3 -2
View File
@@ -1,5 +1,3 @@
import { parseSquare, opposite, squareRank, squareFile, squareFromCoords } from 'chessops/util';
import { SquareSet } from 'chessops/squareSet';
import {
attacks,
ray,
@@ -13,7 +11,10 @@ import {
import { Board } from 'chessops/board';
import { Chess } from 'chessops/chess';
import { chessgroundDests } from 'chessops/compat';
import { SquareSet } from 'chessops/squareSet';
import { type Role, type Color, type Piece, type NormalMove, COLORS, type Square } from 'chessops/types';
import { parseSquare, opposite, squareRank, squareFile, squareFromCoords } from 'chessops/util';
import type { Pin, Undefended, Checkable } from './interfaces';
export const boardAnalysisVariants = [
+5 -4
View File
@@ -1,8 +1,9 @@
import type { Prop } from 'lib';
import { storedBooleanPropWithEffect } from 'lib/storage';
import { boardAnalysisVariants, detectCheckable, detectPins, detectUndefended } from './boardAnalysis';
import type { Board, Square, SquareSet } from 'chessops';
import type { Prop } from 'lib';
import { storedBooleanPropWithEffect } from 'lib/storage';
import { boardAnalysisVariants, detectCheckable, detectPins, detectUndefended } from './boardAnalysis';
import type { Checkable, Pin, Undefended } from './interfaces';
export default class MotifCtrl {
+2 -1
View File
@@ -1,8 +1,9 @@
import type AnalyseCtrl from '@/ctrl';
import { displayColumns } from 'lib/device';
import { hl, type LooseVNodes } from 'lib/view';
import { cmnToggleWrap } from 'lib/view/cmn-toggle';
import type AnalyseCtrl from '@/ctrl';
export const config = (ctrl: AnalyseCtrl): LooseVNodes => [
displayColumns() > 1 && hl('h2', i18n.site.visualMotifs),
cmnToggleWrap({
+2 -2
View File
@@ -1,7 +1,7 @@
import { winningChances } from 'lib/ceval';
import { fenToEpd } from 'lib/game/chess';
import { defined } from 'lib';
import { zip } from 'lib/algo';
import { winningChances } from 'lib/ceval';
import { fenToEpd } from 'lib/game/chess';
import type { TreeNode } from 'lib/tree/types';
const hasCompChild = (node: TreeNode): boolean => node.children.some(c => !!c.comp);
+7 -5
View File
@@ -1,10 +1,12 @@
import type AnalyseCtrl from './ctrl';
import { h } from 'snabbdom';
import { fixCrazySan, plyToTurn } from 'lib/game/chess';
import { type MaybeVNodes } from 'lib/view';
import { INITIAL_FEN } from 'chessops/fen';
import type { Game } from './interfaces';
import { h } from 'snabbdom';
import { fixCrazySan, plyToTurn } from 'lib/game/chess';
import type { TreeNode } from 'lib/tree/types';
import { type MaybeVNodes } from 'lib/view';
import type AnalyseCtrl from './ctrl';
import type { Game } from './interfaces';
interface PgnNode {
ply: Ply;
+7 -5
View File
@@ -1,12 +1,14 @@
import type { AnalyseData, Game } from './interfaces';
import { makeFen } from 'chessops/fen';
import { makeSanAndPlay, parseSan } from 'chessops/san';
import { makeUci } from 'chessops';
import { makeVariant, parsePgn, startingPosition, type ChildNode, type PgnNodeData } from 'chessops/pgn';
import { IllegalSetup, type Position } from 'chessops/chess';
import { makeFen } from 'chessops/fen';
import { makeVariant, parsePgn, startingPosition, type ChildNode, type PgnNodeData } from 'chessops/pgn';
import { makeSanAndPlay, parseSan } from 'chessops/san';
import type { Player } from 'lib/game';
import type { TreeNode } from 'lib/tree/types';
import { completeNode } from 'lib/tree/node';
import type { TreeNode } from 'lib/tree/types';
import type { AnalyseData, Game } from './interfaces';
const readNode = (
variant: VariantKey,
+10 -8
View File
@@ -1,15 +1,17 @@
import { winningChances, type CustomCeval } from 'lib/ceval';
import { path as treePath } from 'lib/tree/tree';
import { detectThreefold } from '../nodeFinder';
import { tablebaseGuaranteed } from '../explorer/explorerCtrl';
import type AnalyseCtrl from '../ctrl';
import { defined, prop, type Prop, requestIdleCallback } from 'lib';
import { parseUci } from 'chessops/util';
import { makeSan } from 'chessops/san';
import { parseUci } from 'chessops/util';
import { defined, prop, type Prop, requestIdleCallback } from 'lib';
import { winningChances, type CustomCeval } from 'lib/ceval';
import { storedBooleanPropWithEffect } from 'lib/storage';
import { renderCustomPearl, renderCustomStatus } from './practiceView';
import { path as treePath } from 'lib/tree/tree';
import type { TablebaseHit, TreeNode, TreePath } from 'lib/tree/types';
import type AnalyseCtrl from '../ctrl';
import { tablebaseGuaranteed } from '../explorer/explorerCtrl';
import { detectThreefold } from '../nodeFinder';
import { renderCustomPearl, renderCustomStatus } from './practiceView';
declare type Verdict = 'goodMove' | 'inaccuracy' | 'mistake' | 'blunder';
export interface Comment {
+5 -3
View File
@@ -1,10 +1,12 @@
import type { Outcome } from 'chessops/types';
import type { Prop } from 'lib';
import { fixCrazySan } from 'lib/game/chess';
import { hl, type VNode, bind, type MaybeVNodes } from 'lib/view';
import type { PracticeCtrl, Comment } from './practiceCtrl';
import type AnalyseCtrl from '../ctrl';
import { renderNextChapter } from '../study/nextChapter';
import { fixCrazySan } from 'lib/game/chess';
import type { Prop } from 'lib';
import type { PracticeCtrl, Comment } from './practiceCtrl';
const commentBest = (c: Comment, ctrl: PracticeCtrl): MaybeVNodes =>
c.best
+6 -4
View File
@@ -1,10 +1,12 @@
import type { AnalyseNvuiContext } from '../analyse.nvui';
import { type LooseVNodes, hl } from 'lib/view';
import { type VNodeData } from 'snabbdom';
import type AnalyseCtrl from '../ctrl';
import type { RetroCtrl } from '../retrospect/retroCtrl';
import { renderSan } from 'lib/nvui/chess';
import { liveText } from 'lib/nvui/notify';
import { type LooseVNodes, hl } from 'lib/view';
import type { AnalyseNvuiContext } from '../analyse.nvui';
import type AnalyseCtrl from '../ctrl';
import type { RetroCtrl } from '../retrospect/retroCtrl';
import { clickHook, renderCurrentNode } from '../view/nvuiView';
export function renderRetro(nvuiCtx: AnalyseNvuiContext): LooseVNodes {
+6 -4
View File
@@ -1,12 +1,14 @@
import { opposite } from '@lichess-org/chessground/util';
import { evalSwings } from '../nodeFinder';
import { isEmpty, type Prop, prop } from 'lib';
import { winningChances } from 'lib/ceval';
import { path as treePath } from 'lib/tree/tree';
import { isEmpty, type Prop, prop } from 'lib';
import type { OpeningData } from '../explorer/interfaces';
import type AnalyseCtrl from '../ctrl';
import type { TreeNode } from 'lib/tree/types';
import type AnalyseCtrl from '../ctrl';
import type { OpeningData } from '../explorer/interfaces';
import { evalSwings } from '../nodeFinder';
export interface RetroCtrl {
isSolving(): boolean;
current: Prop<Retrospection | null>;
+5 -4
View File
@@ -1,9 +1,10 @@
import * as licon from 'lib/licon';
import type { TreeNode } from 'lib/tree/types';
import { bind, dataIcon, hl, type VNode, spinnerVdom as spinner } from 'lib/view';
import type AnalyseCtrl from '../ctrl';
import { renderIndexAndMove } from '../view/components';
import type { RetroCtrl } from './retroCtrl';
import type AnalyseCtrl from '../ctrl';
import * as licon from 'lib/licon';
import { bind, dataIcon, hl, type VNode, spinnerVdom as spinner } from 'lib/view';
import type { TreeNode } from 'lib/tree/types';
const skipOrViewSolution = (ctrl: RetroCtrl): VNode =>
hl('div.choices', [
+9 -7
View File
@@ -1,13 +1,15 @@
import type AnalyseCtrl from './ctrl';
import { baseUrl } from './view/util';
import * as licon from 'lib/licon';
import { url as xhrUrl, textRaw as xhrTextRaw } from 'lib/xhr';
import type { AnalyseData } from './interfaces';
import type { ChartGame, AcplChart } from 'chart';
import { spinnerHtml, domDialog, alert, confirm } from 'lib/view';
import { escapeHtml } from 'lib';
import { storage } from 'lib/storage';
import * as licon from 'lib/licon';
import { pubsub } from 'lib/pubsub';
import { storage } from 'lib/storage';
import { spinnerHtml, domDialog, alert, confirm } from 'lib/view';
import { url as xhrUrl, textRaw as xhrTextRaw } from 'lib/xhr';
import type AnalyseCtrl from './ctrl';
import type { AnalyseData } from './interfaces';
import { baseUrl } from './view/util';
export const stockfishName = 'Stockfish 18';
+2 -1
View File
@@ -1,9 +1,10 @@
import { ops as treeOps } from 'lib/tree/tree';
import type { Shape } from 'lib/tree/types';
import type AnalyseCtrl from './ctrl';
import type { EvalGetData, EvalPutData, Opening, ServerEvalData } from './interfaces';
import type { AnaDrop, AnaMove, ChapterData, EditChapterData } from './study/interfaces';
import type { FormData as StudyFormData } from './study/studyForm';
import type { Shape } from 'lib/tree/types';
interface MoveOpts {
write?: false;
+6 -4
View File
@@ -1,9 +1,11 @@
import makeCtrl from './ctrl';
import menuHover from 'lib/menuHover';
import makeView from './view/main';
import type { AnalyseApi, AnalyseOpts } from './interfaces';
import type { VNode } from 'snabbdom';
import menuHover from 'lib/menuHover';
import makeCtrl from './ctrl';
import type { AnalyseApi, AnalyseOpts } from './interfaces';
import type * as studyDeps from './study/studyDeps';
import makeView from './view/main';
export default function (
patch: (oldVnode: VNode | Element | DocumentFragment, vnode: VNode) => VNode,
@@ -1,8 +1,9 @@
import debounce from 'debounce-promise';
import { json as xhrJson, url as xhrUrl } from 'lib/xhr';
import Tagify from '@yaireo/tagify';
import debounce from 'debounce-promise';
import Sortable from 'sortablejs';
import { json as xhrJson, url as xhrUrl } from 'lib/xhr';
site.load.then(() => {
const input = document.getElementById('form3-topics') as HTMLInputElement;
const tagify = new Tagify(input, {
+5 -3
View File
@@ -1,8 +1,10 @@
import type AnalyseCtrl from '../ctrl';
import Shepherd from 'shepherd.js';
import type { ChapterTab, StudyTour, Tab } from './interfaces';
import { pubsub } from 'lib/pubsub';
import * as licon from 'lib/licon';
import { pubsub } from 'lib/pubsub';
import type AnalyseCtrl from '../ctrl';
import type { ChapterTab, StudyTour, Tab } from './interfaces';
export function initModule(): StudyTour {
return {
+4 -3
View File
@@ -1,9 +1,10 @@
import { patch } from '../view/util';
import makeStart from '../start';
import { wsConnect } from 'lib/socket';
import type { AnalyseOpts } from '../interfaces';
import type { AnalyseSocketSend } from '../socket';
import makeStart from '../start';
import { patch } from '../view/util';
import * as studyDeps from './studyDeps';
import { wsConnect } from 'lib/socket';
export { patch };
+7 -5
View File
@@ -1,6 +1,12 @@
import { fieldValue, modeChoices } from './chapterNewForm';
import { COLORS } from 'chessops';
import { h, type VNode } from 'snabbdom';
import { defined, prop } from 'lib';
import { bind, bindSubmit, onInsert, spinnerVdom as spinner, snabDialog, confirm } from 'lib/view';
import type { StudySocketSend } from '../socket';
import { option, emptyRedButton } from '../view/util';
import { fieldValue, modeChoices } from './chapterNewForm';
import type {
ChapterMode,
EditChapterData,
@@ -8,10 +14,6 @@ import type {
StudyChapterConfig,
ChapterPreview,
} from './interfaces';
import { defined, prop } from 'lib';
import { h, type VNode } from 'snabbdom';
import type { StudySocketSend } from '../socket';
import { COLORS } from 'chessops';
export class StudyChapterEditForm {
current = prop<ChapterPreview | StudyChapterConfig | null>(null);
+7 -5
View File
@@ -1,5 +1,10 @@
import { parseFen } from 'chessops/fen';
import type { LichessEditor } from 'editor';
import { defined, prop, type Prop, toggle } from 'lib';
import * as licon from 'lib/licon';
import { pubsub } from 'lib/pubsub';
import { storedProp } from 'lib/storage';
import {
snabDialog,
alert,
@@ -12,17 +17,14 @@ import {
type Dialog,
type VNode,
} from 'lib/view';
import * as licon from 'lib/licon';
import { storedProp } from 'lib/storage';
import { json as xhrJson, text as xhrText } from 'lib/xhr';
import type AnalyseCtrl from '../ctrl';
import type { StudySocketSend } from '../socket';
import { option } from '../view/util';
import type { ChapterData, ChapterMode, ChapterTab, Orientation, StudyTour } from './interfaces';
import { importPgn, variants as xhrVariants } from './studyXhr';
import type { StudyChapters } from './studyChapters';
import type { LichessEditor } from 'editor';
import { pubsub } from 'lib/pubsub';
import { importPgn, variants as xhrVariants } from './studyXhr';
export const modeChoices = [
['normal', i18n.study.normalAnalysis],
+7 -5
View File
@@ -1,12 +1,14 @@
import { prop } from 'lib';
import { onInsert } from 'lib/view';
import { throttle } from 'lib/async';
import { h, type VNode } from 'snabbdom';
import type AnalyseCtrl from '../ctrl';
import { currentComments, isAuthorObj } from './studyComments';
import { prop } from 'lib';
import { throttle } from 'lib/async';
import { storage } from 'lib/storage';
import type { TreeNode, TreePath } from 'lib/tree/types';
import { onInsert } from 'lib/view';
import type AnalyseCtrl from '../ctrl';
import type { ChapterId } from './interfaces';
import { currentComments, isAuthorObj } from './studyComments';
interface Current {
chapterId: ChapterId;
+2 -1
View File
@@ -1,6 +1,7 @@
import * as licon from 'lib/licon';
import { type VNode, bind, onInsert, hl, confirm } from 'lib/view';
import { richHTML } from 'lib/richText';
import { type VNode, bind, onInsert, hl, confirm } from 'lib/view';
import type StudyCtrl from './studyCtrl';
export type Save = (t: string) => void;
@@ -1,6 +1,8 @@
import * as licon from 'lib/licon';
import { bind, dataIcon, type VNode, hl } from 'lib/view';
import type AnalyseCtrl from '@/ctrl';
import type StudyCtrl from '../studyCtrl';
export function playButtons(root: AnalyseCtrl): VNode | undefined {
@@ -1,11 +1,13 @@
import { h, type Hooks, type VNode } from 'snabbdom';
import { requestIdleCallback } from 'lib';
import { throttle } from 'lib/async';
import * as licon from 'lib/licon';
import type { Gamebook, TreeNode } from 'lib/tree/types';
import { iconTag, bind, type MaybeVNodes } from 'lib/view';
import { prev } from '@/control';
import type AnalyseCtrl from '@/ctrl';
import { requestIdleCallback } from 'lib';
import * as licon from 'lib/licon';
import { throttle } from 'lib/async';
import { iconTag, bind, type MaybeVNodes } from 'lib/view';
import { h, type Hooks, type VNode } from 'snabbdom';
import type { Gamebook, TreeNode } from 'lib/tree/types';
export const running = (ctrl: AnalyseCtrl): boolean =>
!!ctrl.study &&
@@ -1,8 +1,9 @@
import type AnalyseCtrl from '@/ctrl';
import { path as treePath } from 'lib/tree/tree';
import { makeShapesFromUci } from '@/autoShape';
import type { Shape, TreePath } from 'lib/tree/types';
import { makeShapesFromUci } from '@/autoShape';
import type AnalyseCtrl from '@/ctrl';
export type Feedback = 'play' | 'good' | 'bad' | 'end';
export interface State {
@@ -1,7 +1,8 @@
import GamebookPlayCtrl, { type State } from './gamebookPlayCtrl';
import * as licon from 'lib/licon';
import { type VNode, iconTag, bind, dataIcon, hl, requiresI18n } from 'lib/view';
import { richHTML } from 'lib/richText';
import { type VNode, iconTag, bind, dataIcon, hl, requiresI18n } from 'lib/view';
import GamebookPlayCtrl, { type State } from './gamebookPlayCtrl';
export function render(ctrl: GamebookPlayCtrl): VNode {
const state = ctrl.state;
+4 -3
View File
@@ -1,9 +1,10 @@
import type { Prop } from 'lib';
import type { TreeNodeIncomplete, TreePath } from 'lib/tree/types';
import type AnalyseCtrl from '../ctrl';
import type { Opening } from '../explorer/interfaces';
import type { AnalyseData } from '../interfaces';
import type { GamebookOverride } from './gamebook/interfaces';
import type { Opening } from '../explorer/interfaces';
import type AnalyseCtrl from '../ctrl';
import type { TreeNodeIncomplete, TreePath } from 'lib/tree/types';
export type Tab = 'intro' | 'members' | 'chapters';
export type ChapterTab = 'init' | 'edit' | 'game' | 'fen' | 'pgn';
+9 -7
View File
@@ -1,13 +1,15 @@
import * as licon from 'lib/licon';
import { bind, onInsert, snabDialog } from 'lib/view';
import { titleNameToId } from '../view/util';
import { h, type VNode } from 'snabbdom';
import { prop, type Prop } from 'lib';
import type { StudyMemberMap } from './interfaces';
import type { AnalyseSocketSend } from '../socket';
import { storedSet, type StoredSet } from 'lib/storage';
import { userComplete } from 'lib/view/userComplete';
import * as licon from 'lib/licon';
import { pubsub } from 'lib/pubsub';
import { storedSet, type StoredSet } from 'lib/storage';
import { bind, onInsert, snabDialog } from 'lib/view';
import { userComplete } from 'lib/view/userComplete';
import type { AnalyseSocketSend } from '../socket';
import { titleNameToId } from '../view/util';
import type { StudyMemberMap } from './interfaces';
export interface StudyInviteFormCtrl {
open: Prop<boolean>;
+16 -14
View File
@@ -1,23 +1,25 @@
import * as licon from 'lib/licon';
import { otbClockIsRunning, formatMs } from 'lib/game/clock/clockWidget';
import { Chessground as makeChessground } from '@lichess-org/chessground';
import { opposite as cgOpposite, uciToMove } from '@lichess-org/chessground/util';
import type { Color } from 'chessops';
import { EMPTY_BOARD_FEN } from 'chessops/fen';
import { h } from 'snabbdom';
import { type Prop, type Toggle, defined, notNull, prop, toggle } from 'lib';
import { fenColor } from 'lib/game/chess';
import { otbClockIsRunning, formatMs } from 'lib/game/clock/clockWidget';
import * as licon from 'lib/licon';
import { storage, storedBooleanProp } from 'lib/storage';
import { type MaybeVNode, type VNode, bind, dataIcon, onInsert, hl } from 'lib/view';
import { cmnToggleWrapProp } from 'lib/view/cmn-toggle';
import { opposite as cgOpposite, uciToMove } from '@lichess-org/chessground/util';
import type { ChapterId, ChapterPreview, StudyPlayer } from './interfaces';
import type StudyCtrl from './studyCtrl';
import { type CloudEval, type MultiCloudEval, renderScore } from './multiCloudEval';
import { type Prop, type Toggle, defined, notNull, prop, toggle } from 'lib';
import type { Color } from 'chessops';
import { type StudyChapters, gameLinkAttrs, gameLinksListener } from './studyChapters';
import { playerFedFlag } from './playerBars';
import { userTitle } from 'lib/view/userLink';
import { h } from 'snabbdom';
import { storage, storedBooleanProp } from 'lib/storage';
import { Chessground as makeChessground } from '@lichess-org/chessground';
import { EMPTY_BOARD_FEN } from 'chessops/fen';
import type { ChapterId, ChapterPreview, StudyPlayer } from './interfaces';
import { type CloudEval, type MultiCloudEval, renderScore } from './multiCloudEval';
import { playerFedFlag } from './playerBars';
import { playerColoredResult } from './relay/customScoreStatus';
import type { RelayRound } from './relay/interfaces';
import { type StudyChapters, gameLinkAttrs, gameLinksListener } from './studyChapters';
import type StudyCtrl from './studyCtrl';
export class MultiBoardCtrl {
playing: Toggle = toggle(false);
+6 -5
View File
@@ -1,12 +1,13 @@
import { type Prop, defined } from 'lib';
import type { EvalHitMulti } from '../interfaces';
import { storedBooleanPropWithEffect } from 'lib/storage';
import { povChances } from 'lib/ceval/winningChances';
import type { StudyChapters } from './studyChapters';
import { debounce } from 'lib/async';
import type { ServerNodeMsg } from './interfaces';
import { povChances } from 'lib/ceval/winningChances';
import { storedBooleanPropWithEffect } from 'lib/storage';
import type { ClientEval, TreeNode } from 'lib/tree/types';
import type { EvalHitMulti } from '../interfaces';
import type { ServerNodeMsg } from './interfaces';
import type { StudyChapters } from './studyChapters';
export interface CloudEval extends EvalHitMulti {
chances: number;
}
+4 -2
View File
@@ -1,8 +1,10 @@
import { h } from 'snabbdom';
import * as licon from 'lib/licon';
import { bind } from 'lib/view';
import type AnalyseCtrl from '../ctrl';
import { ops as treeOps } from 'lib/tree/tree';
import { bind } from 'lib/view';
import type AnalyseCtrl from '../ctrl';
export const renderNextChapter = (ctrl: AnalyseCtrl) =>
!ctrl.opts.relay && ctrl.study?.hasNextChapter()
+14 -12
View File
@@ -1,22 +1,24 @@
import { COLORS } from 'chessops';
import type { VNode } from 'snabbdom';
import { defined } from 'lib';
import { intersection } from 'lib/tree/path';
import type { TreePath } from 'lib/tree/types';
import { hl } from 'lib/view';
import renderClocks from '../view/clocks';
import { userTitle } from 'lib/view/userLink';
import type AnalyseCtrl from '../ctrl';
import renderClocks from '../view/clocks';
import { renderMaterialDiffs } from '../view/components';
import type { StudyPlayers, Federation, StudyPlayer, StatusStr, TagMap } from './interfaces';
import { looksLikeLichessGame } from './studyChapters';
import { userTitle } from 'lib/view/userLink';
import RelayPlayers, { fidePageLinkAttrs, playerId, playerPhotoOrFallback } from './relay/relayPlayers';
import { StudyCtrl } from './studyDeps';
import { intersection } from 'lib/tree/path';
import { defined } from 'lib';
import { resultTag } from './studyView';
import type { RelayRound } from './relay/interfaces';
import { playerColoredResult } from './relay/customScoreStatus';
import type { TreePath } from 'lib/tree/types';
import { tagsToMap } from './studyTags';
import { COLORS } from 'chessops';
import type { RelayRound } from './relay/interfaces';
import RelayPlayers, { fidePageLinkAttrs, playerId, playerPhotoOrFallback } from './relay/relayPlayers';
import RelayTeamLeaderboard from './relay/relayTeamLeaderboard';
import { looksLikeLichessGame } from './studyChapters';
import { StudyCtrl } from './studyDeps';
import { tagsToMap } from './studyTags';
import { resultTag } from './studyView';
export default function (ctrl: AnalyseCtrl): VNode[] | undefined {
const study = ctrl.study;
@@ -1,11 +1,13 @@
import { practiceComplete } from '../studyXhr';
import { type Prop, prop } from 'lib';
import { storedBooleanProp } from 'lib/storage';
import makeSuccess from './studyPracticeSuccess';
import { readOnlyProp } from '@/util';
import type { StudyPracticeData, Goal } from './interfaces';
import type { StudyData } from '../interfaces';
import type AnalyseCtrl from '@/ctrl';
import { readOnlyProp } from '@/util';
import type { StudyData } from '../interfaces';
import { practiceComplete } from '../studyXhr';
import type { StudyPracticeData, Goal } from './interfaces';
import makeSuccess from './studyPracticeSuccess';
export default class StudyPracticeCtrl {
goal: Prop<Goal>;
@@ -1,8 +1,10 @@
import type AnalyseCtrl from '@/ctrl';
import type { Goal } from './interfaces';
import type { Comment } from '@/practice/practiceCtrl';
import type { TreeNode } from 'lib/tree/types';
import type AnalyseCtrl from '@/ctrl';
import type { Comment } from '@/practice/practiceCtrl';
import type { Goal } from './interfaces';
// returns null if not deep enough to know
const isDrawish = (node: TreeNode): boolean | null =>
hasSolidEval(node) ? !node.ceval!.mate && Math.abs(node.ceval!.cp!) < 150 : null;
@@ -1,12 +1,15 @@
import { h, thunk, type VNode } from 'snabbdom';
import * as licon from 'lib/licon';
import { richHTML } from 'lib/richText';
import { bind, bindNonPassive, type MaybeVNodes, spinnerVdom as spinner } from 'lib/view';
import { cmnToggleWrapProp } from 'lib/view/cmn-toggle';
import { h, thunk, type VNode } from 'snabbdom';
import { richHTML } from 'lib/richText';
import { option, plural } from '@/view/util';
import { view as descView } from '../description';
import type { StudyPracticeData } from './interfaces';
import type StudyCtrl from '../studyCtrl';
import type { StudyPracticeData } from './interfaces';
import type StudyPracticeCtrl from './studyPracticeCtrl';
const selector = (data: StudyPracticeData) =>
@@ -1,7 +1,9 @@
import { opposite } from 'chessops/util';
import { hl, type LooseVNodes, type VNodeChildElement } from 'lib/view';
import type { GamePointsStr } from '../interfaces';
import type { CustomScoring, RelayRound } from './interfaces';
import { opposite } from 'chessops/util';
type ServerPoint = '1' | '0' | '½';
const points = (point: ServerPoint) => parseFloat(point.replace('½', '.5'));
@@ -1,8 +1,10 @@
import { hl, type VNode, getChessground, initMiniBoardWith, spinnerVdom } from 'lib/view';
import { fenColor, uciToMove } from 'lib/game/chess';
import { type ChatPlugin } from 'lib/chat/interfaces';
import type AnalyseCtrl from '@/ctrl';
import { fenColor, uciToMove } from 'lib/game/chess';
import { mainlineNodeList } from 'lib/tree/ops';
import { hl, type VNode, getChessground, initMiniBoardWith, spinnerVdom } from 'lib/view';
import type AnalyseCtrl from '@/ctrl';
import { type ChapterId } from '../interfaces';
type BoardConfig = CgConfig & { lastUci?: Uci };
+13 -10
View File
@@ -1,15 +1,18 @@
import type { RelayData, LogEvent, RelaySync, RelayRound } from './interfaces';
import type { BothClocks, ChapterId, ServerClockMsg } from '@/study/interfaces';
import { type Prop, type Toggle, myUserId, notNull, prop, toggle } from 'lib';
import RelayTeams from './relayTeams';
import RelayPlayers from './relayPlayers';
import type StudyCtrl from '@/study/studyCtrl';
import { VideoPlayer } from './videoPlayer';
import RelayStats from './relayStats';
import { LiveboardPlugin } from './liveboardPlugin';
import { pubsub } from 'lib/pubsub';
import { COLORS } from 'chessops';
import { type Prop, type Toggle, myUserId, notNull, prop, toggle } from 'lib';
import { pubsub } from 'lib/pubsub';
import type { BothClocks, ChapterId, ServerClockMsg } from '@/study/interfaces';
import type StudyCtrl from '@/study/studyCtrl';
import type { RelayData, LogEvent, RelaySync, RelayRound } from './interfaces';
import { LiveboardPlugin } from './liveboardPlugin';
import RelayPlayers from './relayPlayers';
import RelayStats from './relayStats';
import RelayTeamLeaderboard from './relayTeamLeaderboard';
import RelayTeams from './relayTeams';
import { VideoPlayer } from './videoPlayer';
export const relayTabs = ['overview', 'boards', 'teams', 'players', 'stats', 'team-results'] as const;
export type RelayTab = (typeof relayTabs)[number];
+12 -10
View File
@@ -1,15 +1,17 @@
import type { StudyCtrl } from '../studyDeps';
import type RelayCtrl from './relayCtrl';
import { userTitle } from 'lib/view/userLink';
import { defined, scrollToInnerSelector } from 'lib';
import { renderClock, verticalEvalGauge } from '../multiBoard';
import type { ChapterPreview } from '../interfaces';
import { gameLinkAttrs } from '../studyChapters';
import { playerFedFlag } from '../playerBars';
import { hl } from 'lib/view';
import { playerColoredResult } from './customScoreStatus';
import { COLORS } from 'chessops';
import { defined, scrollToInnerSelector } from 'lib';
import { hl } from 'lib/view';
import { userTitle } from 'lib/view/userLink';
import type { ChapterPreview } from '../interfaces';
import { renderClock, verticalEvalGauge } from '../multiBoard';
import { playerFedFlag } from '../playerBars';
import { gameLinkAttrs } from '../studyChapters';
import type { StudyCtrl } from '../studyDeps';
import { playerColoredResult } from './customScoreStatus';
import type RelayCtrl from './relayCtrl';
export const gamesList = (study: StudyCtrl, relay: RelayCtrl) => {
const chapters = study.chapters.list.all();
const cloudEval = study.multiCloudEval?.thisIfShowEval();
@@ -1,11 +1,12 @@
import { memoize } from 'lib';
import * as licon from 'lib/licon';
import { hl, bind, onInsert, dataIcon, type MaybeVNode } from 'lib/view';
import type StudyCtrl from '../studyCtrl';
import { studySideNodes } from '../studyView';
import { broadcasterDeepLink } from './deepLink';
import type { LogEvent } from './interfaces';
import type RelayCtrl from './relayCtrl';
import { memoize } from 'lib';
import { studySideNodes } from '../studyView';
import type StudyCtrl from '../studyCtrl';
import { broadcasterDeepLink } from './deepLink';
export default function (ctrl: RelayCtrl, study: StudyCtrl): MaybeVNode {
const contributor = study.members.canContribute(),
+16 -14
View File
@@ -1,6 +1,20 @@
import { type VNode, dataIcon, hl, onInsert, spinnerVdom as spinner, type LooseVNodes } from 'lib/view';
import { json as xhrJson } from 'lib/xhr';
import { type Attrs, type Hooks, init as initSnabbdom, attributesModule, type VNodeData } from 'snabbdom';
import type { Tablesort } from 'tablesort';
import { defined } from 'lib';
import { isTouchDevice } from 'lib/device';
import perfIcons from 'lib/game/perfIcons';
import * as licon from 'lib/licon';
import { pubsub } from 'lib/pubsub';
import { sortTable, extendTablesortNumber } from 'lib/tablesort';
import { type VNode, dataIcon, hl, onInsert, spinnerVdom as spinner, type LooseVNodes } from 'lib/view';
import { userLink, userTitle } from 'lib/view/userLink';
import { json as xhrJson } from 'lib/xhr';
import type { ChapterId, FideId, PointsStr, StudyPlayer, StudyPlayerFromServer } from '../interfaces';
import { playerFedFlag } from '../playerBars';
import { convertPlayerFromServer } from '../studyChapters';
import { playerColoredResult } from './customScoreStatus';
import type {
FideTC,
Photo,
@@ -10,19 +24,7 @@ import type {
RoundId,
StatByFideTC,
} from './interfaces';
import { playerColoredResult } from './customScoreStatus';
import { playerFedFlag } from '../playerBars';
import { userLink, userTitle } from 'lib/view/userLink';
import type { ChapterId, FideId, PointsStr, StudyPlayer, StudyPlayerFromServer } from '../interfaces';
import { sortTable, extendTablesortNumber } from 'lib/tablesort';
import { defined } from 'lib';
import { type Attrs, type Hooks, init as initSnabbdom, attributesModule, type VNodeData } from 'snabbdom';
import { convertPlayerFromServer } from '../studyChapters';
import { isTouchDevice } from 'lib/device';
import { pubsub } from 'lib/pubsub';
import { teamLinkData } from './relayTeamLeaderboard';
import perfIcons from 'lib/game/perfIcons';
import type { Tablesort } from 'tablesort';
export type RelayPlayerId = FideId | string;
+5 -3
View File
@@ -1,8 +1,10 @@
import { spinnerVdom as spinner } from 'lib/view';
import type { RelayRound } from './interfaces';
import { json as xhrJson } from 'lib/xhr';
import { h } from 'snabbdom';
import { numberFormat } from 'lib/i18n';
import { spinnerVdom as spinner } from 'lib/view';
import { json as xhrJson } from 'lib/xhr';
import type { RelayRound } from './interfaces';
type Data = {
viewers: any;
@@ -1,12 +1,14 @@
import { dataIcon, hl, onInsert, requiresI18n, spinnerVdom, type VNode, type VNodeData } from 'lib/view';
import { Group, StudyBoard } from 'lib/licon';
import { json as xhrJson } from 'lib/xhr';
import type { RelayTeamName, RelayTeamStandings, TourId } from './interfaces';
import RelayPlayers, { renderPlayers, tableAugment, type RelayPlayer } from './relayPlayers';
import type { Tablesort } from 'tablesort';
import { throttle } from 'lib';
import { Group, StudyBoard } from 'lib/licon';
import { dataIcon, hl, onInsert, requiresI18n, spinnerVdom, type VNode, type VNodeData } from 'lib/view';
import { json as xhrJson } from 'lib/xhr';
import type { StudyPlayerFromServer } from '../interfaces';
import { convertPlayerFromServer } from '../studyChapters';
import type { Tablesort } from 'tablesort';
import type { RelayTeamName, RelayTeamStandings, TourId } from './interfaces';
import RelayPlayers, { renderPlayers, tableAugment, type RelayPlayer } from './relayPlayers';
export default class RelayTeamLeaderboard {
standings: RelayTeamStandings | undefined;
+4 -3
View File
@@ -1,13 +1,14 @@
import { type MaybeVNodes, type VNode, onInsert, hl, spinnerVdom as spinner } from 'lib/view';
import { userTitle } from 'lib/view/userLink';
import { json as xhrJson } from 'lib/xhr';
import type { RelayRound, RelayTour } from './interfaces';
import type { ChapterId, ChapterPreview, StudyPlayer, ChapterSelect } from '../interfaces';
import { type MultiCloudEval, renderScore } from '../multiCloudEval';
import { playerFedFlag } from '../playerBars';
import { gameLinkAttrs, gameLinksListener, StudyChapters } from '../studyChapters';
import { userTitle } from 'lib/view/userLink';
import type RelayPlayers from './relayPlayers';
import { coloredStatusStr } from './customScoreStatus';
import type { RelayRound, RelayTour } from './interfaces';
import type RelayPlayers from './relayPlayers';
import { teamLinkData } from './relayTeamLeaderboard';
interface TeamWithPoints {
+24 -21
View File
@@ -1,10 +1,26 @@
import type AnalyseCtrl from '@/ctrl';
import RelayCtrl, { type RelayTab } from './relayCtrl';
import type { VNode } from 'snabbdom';
import { defined, memoize } from 'lib';
import { renderChat } from 'lib/chat/renderChat';
import { displayColumns } from 'lib/device';
import { commonDateFormat, timeago } from 'lib/i18n';
import * as licon from 'lib/licon';
import { pubsub } from 'lib/pubsub';
import { innerHTML, richHTML } from 'lib/richText';
import { bind, dataIcon, onInsert, hl, type LooseVNode, copyMeInput } from 'lib/view';
import { cmnToggleWrap } from 'lib/view/cmn-toggle';
import type { VNode } from 'snabbdom';
import { innerHTML, richHTML } from 'lib/richText';
import { userLink } from 'lib/view/userLink';
import { verticalResize } from 'lib/view/verticalResize';
import { watchers } from 'lib/view/watchers';
import { text as xhrText } from 'lib/xhr';
import type AnalyseCtrl from '@/ctrl';
import { type RelayViewContext } from '@/view/components';
import { baseUrl } from '@/view/util';
import { view as multiBoardView } from '../multiBoard';
import { gameLinksListener } from '../studyChapters';
import type StudyCtrl from '../studyCtrl';
import type {
RelayData,
RelayGroup,
@@ -13,25 +29,12 @@ import type {
RelayTourInfo,
RelayTourPreview,
} from './interfaces';
import { view as multiBoardView } from '../multiBoard';
import { defined, memoize } from 'lib';
import type StudyCtrl from '../studyCtrl';
import { text as xhrText } from 'lib/xhr';
import { teamsView } from './relayTeams';
import { statsView } from './relayStats';
import { type RelayViewContext } from '@/view/components';
import RelayCtrl, { type RelayTab } from './relayCtrl';
import { gamesList } from './relayGames';
import { renderStreamerMenu } from './relayView';
import { playersView } from './relayPlayers';
import { gameLinksListener } from '../studyChapters';
import { baseUrl } from '@/view/util';
import { commonDateFormat, timeago } from 'lib/i18n';
import { renderChat } from 'lib/chat/renderChat';
import { displayColumns } from 'lib/device';
import { verticalResize } from 'lib/view/verticalResize';
import { watchers } from 'lib/view/watchers';
import { userLink } from 'lib/view/userLink';
import { pubsub } from 'lib/pubsub';
import { statsView } from './relayStats';
import { teamsView } from './relayTeams';
import { renderStreamerMenu } from './relayView';
export function renderRelayTour(ctx: RelayViewContext): VNode | undefined {
const tab = ctx.relay.tab();
+8 -6
View File
@@ -1,11 +1,11 @@
import { view as cevalView } from 'lib/ceval';
import { onClickAway } from 'lib';
import { bind, dataIcon, hl, onInsert, type VNode } from 'lib/view';
import { view as cevalView } from 'lib/ceval';
import { displayColumns, isTouchDevice } from 'lib/device';
import * as licon from 'lib/licon';
import { bind, dataIcon, hl, onInsert, type VNode } from 'lib/view';
import type AnalyseCtrl from '@/ctrl';
import { view as keyboardView } from '@/keyboard';
import type * as studyDeps from '../studyDeps';
import { tourSide, renderRelayTour } from './relayTourView';
import {
type RelayViewContext,
viewContext,
@@ -14,10 +14,12 @@ import {
renderTools,
renderUnderboard,
} from '@/view/components';
import { displayColumns, isTouchDevice } from 'lib/device';
import type RelayCtrl from './relayCtrl';
import { renderControls } from '@/view/controls';
import type * as studyDeps from '../studyDeps';
import type RelayCtrl from './relayCtrl';
import { tourSide, renderRelayTour } from './relayTourView';
export function relayView(
ctrl: AnalyseCtrl,
study: studyDeps.StudyCtrl,
@@ -1,4 +1,5 @@
import { hl, type VNode, onInsert } from 'lib/view';
import { allowVideo } from './relayView';
export class VideoPlayer {
+9 -7
View File
@@ -1,13 +1,15 @@
import * as licon from 'lib/licon';
import { bind, onInsert, spinnerVdom } from 'lib/view';
import { requestIdleCallback } from 'lib';
import { h, type VNode } from 'snabbdom';
import type AnalyseCtrl from '../ctrl';
import type { ChartGame, AcplChart } from 'chart';
import type { AnalyseData } from '../interfaces';
import { h, type VNode } from 'snabbdom';
import { requestIdleCallback } from 'lib';
import * as licon from 'lib/licon';
import { pubsub } from 'lib/pubsub';
import { stockfishName } from '../serverSideUnderboard';
import type { TreeNode } from 'lib/tree/types';
import { bind, onInsert, spinnerVdom } from 'lib/view';
import type AnalyseCtrl from '../ctrl';
import type { AnalyseData } from '../interfaces';
import { stockfishName } from '../serverSideUnderboard';
export const chartSpinner = (): VNode =>
h('div#acpl-chart-container-loader', [
+7 -5
View File
@@ -1,10 +1,17 @@
import { INITIAL_FEN } from 'chessops/fen';
import { opposite } from 'chessops/util';
import type Sortable from 'sortablejs';
import { blurIfPrimaryClick, defined, prop, type Prop, scrollToInnerSelector } from 'lib';
import { fenColor } from 'lib/game/chess';
import * as licon from 'lib/licon';
import { type VNode, bind, dataIcon, iconTag, hl, alert } from 'lib/view';
import type AnalyseCtrl from '../ctrl';
import type { StudySocketSend } from '../socket';
import { StudyChapterEditForm } from './chapterEditForm';
import { StudyChapterNewForm } from './chapterNewForm';
import { federations, localizedName } from './fideFeds';
import type {
LocalPaths,
StudyChapter,
@@ -20,11 +27,6 @@ import type {
StatusStr,
} from './interfaces';
import type StudyCtrl from './studyCtrl';
import { opposite } from 'chessops/util';
import { fenColor } from 'lib/game/chess';
import type Sortable from 'sortablejs';
import { INITIAL_FEN } from 'chessops/fen';
import { federations, localizedName } from './fideFeds';
/* read-only interface for external use */
export class StudyChapters {
+3 -1
View File
@@ -1,7 +1,9 @@
import { h, type VNode } from 'snabbdom';
import * as licon from 'lib/licon';
import { bind, confirm } from 'lib/view';
import { richHTML } from 'lib/richText';
import { bind, confirm } from 'lib/view';
import type AnalyseCtrl from '../ctrl';
import { nodeFullName } from '../view/util';
import type StudyCtrl from './studyCtrl';
+31 -29
View File
@@ -1,20 +1,23 @@
import type { DrawShape } from '@lichess-org/chessground/draw';
import { opposite } from 'chessops/util';
import { prop, defined } from 'lib';
import { debounce, throttle, throttlePromiseDelay } from 'lib/async';
import type AnalyseCtrl from '../ctrl';
import { StudyMemberCtrl } from './studyMembers';
import StudyPracticeCtrl from './practice/studyPracticeCtrl';
import type { StudyPracticeData } from './practice/interfaces';
import { CommentForm } from './commentForm';
import { GlyphForm } from './studyGlyph';
import { StudyForm } from './studyForm';
import TopicsCtrl from './topics';
import { NotifCtrl } from './notif';
import { StudyShare } from './studyShare';
import { TagsForm } from './studyTags';
import ServerEval from './serverEval';
import * as xhr from './studyXhr';
import { displayColumns } from 'lib/device';
import { pubsub } from 'lib/pubsub';
import { storedMap } from 'lib/storage';
import { completeNode } from 'lib/tree/node';
import { path as treePath, ops as treeOps } from 'lib/tree/tree';
import type { Glyph, Shape, TreeComment, TreeNode, TreePath } from 'lib/tree/types';
import { alert } from 'lib/view';
import type AnalyseCtrl from '../ctrl';
import type { EvalHitMulti, EvalHitMultiArray } from '../interfaces';
import type { StudySocketSendParams } from '../socket';
import { CommentForm } from './commentForm';
import { DescriptionCtrl } from './description';
import GamebookPlayCtrl from './gamebook/gamebookPlayCtrl';
import type { GamebookOverride } from './gamebook/interfaces';
import type {
StudyVm,
Tab,
@@ -36,25 +39,24 @@ import type {
ChapterPreviewFromServer,
ChapterSelect,
} from './interfaces';
import GamebookPlayCtrl from './gamebook/gamebookPlayCtrl';
import { DescriptionCtrl } from './description';
import RelayCtrl from './relay/relayCtrl';
import type { RelayData } from './relay/interfaces';
import { MultiBoardCtrl } from './multiBoard';
import type { StudySocketSendParams } from '../socket';
import { storedMap } from 'lib/storage';
import { opposite } from 'chessops/util';
import StudyChaptersCtrl, { isFinished } from './studyChapters';
import { SearchCtrl } from './studySearch';
import type { GamebookOverride } from './gamebook/interfaces';
import type { EvalHitMulti, EvalHitMultiArray } from '../interfaces';
import { MultiCloudEval } from './multiCloudEval';
import { pubsub } from 'lib/pubsub';
import { alert } from 'lib/view';
import { displayColumns } from 'lib/device';
import type { Glyph, Shape, TreeComment, TreeNode, TreePath } from 'lib/tree/types';
import { completeNode } from 'lib/tree/node';
import { NotifCtrl } from './notif';
import type { StudyPracticeData } from './practice/interfaces';
import StudyPracticeCtrl from './practice/studyPracticeCtrl';
import type { RelayData } from './relay/interfaces';
import RelayCtrl from './relay/relayCtrl';
import ServerEval from './serverEval';
import StudyChaptersCtrl, { isFinished } from './studyChapters';
import { StudyForm } from './studyForm';
import { GlyphForm } from './studyGlyph';
import studyKeyboard from './studyKeyboard';
import { StudyMemberCtrl } from './studyMembers';
import { SearchCtrl } from './studySearch';
import { StudyShare } from './studyShare';
import { TagsForm } from './studyTags';
import * as xhr from './studyXhr';
import TopicsCtrl from './topics';
interface Handlers {
path(d: WithWhoAndPos): void;
+1 -1
View File
@@ -1,5 +1,5 @@
import relayManager from './relay/relayManagerView';
import renderPlayerBars from './playerBars';
import relayManager from './relay/relayManagerView';
import StudyCtrl from './studyCtrl';
export { relayManager, renderPlayerBars, StudyCtrl };
+5 -3
View File
@@ -1,7 +1,9 @@
import * as licon from 'lib/licon';
import { toggle } from 'lib';
import { snabDialog, confirm, prompt, type VNode, bindSubmit, bindNonPassive, onInsert, hl } from 'lib/view';
import flairPickerLoader from 'bits/flairPicker';
import { toggle } from 'lib';
import * as licon from 'lib/licon';
import { snabDialog, confirm, prompt, type VNode, bindSubmit, bindNonPassive, onInsert, hl } from 'lib/view';
import { emptyRedButton } from '../view/util';
import type { StudyData } from './interfaces';
import type RelayCtrl from './relay/relayCtrl';
+6 -4
View File
@@ -1,10 +1,12 @@
import { blurIfPrimaryClick, prop } from 'lib';
import { bind, spinnerVdom } from 'lib/view';
import { throttle } from 'lib/async';
import { h, type VNode } from 'snabbdom';
import { blurIfPrimaryClick, prop } from 'lib';
import { throttle } from 'lib/async';
import type { Glyph, GlyphId, TreeNode } from 'lib/tree/types';
import { bind, spinnerVdom } from 'lib/view';
import type AnalyseCtrl from '../ctrl';
import { glyphs as xhrGlyphs } from './studyXhr';
import type { Glyph, GlyphId, TreeNode } from 'lib/tree/types';
interface AllGlyphs {
move: Glyph[];
+1
View File
@@ -1,4 +1,5 @@
import { keyToMouseEvent } from '@/keyboard';
import type StudyCtrl from './studyCtrl';
export default function studyKeyboard(ctrl: StudyCtrl) {
+11 -10
View File
@@ -1,17 +1,18 @@
import type { AnalyseSocketSend } from '../socket';
import * as licon from 'lib/licon';
import { type VNode, iconTag, bind, onInsert, dataIcon, bindNonPassive, hl } from 'lib/view';
import { makeCtrl as inviteFormCtrl, type StudyInviteFormCtrl } from './inviteForm';
import type { NotifCtrl } from './notif';
import { prop, type Prop, scrollTo } from 'lib';
import * as licon from 'lib/licon';
import { pubsub } from 'lib/pubsub';
import { once } from 'lib/storage';
import { type VNode, iconTag, bind, onInsert, dataIcon, bindNonPassive, hl } from 'lib/view';
import { cmnToggleWrap } from 'lib/view/cmn-toggle';
import { userLink } from 'lib/view/userLink';
import { textRaw as xhrTextRaw } from 'lib/xhr';
import type { AnalyseSocketSend } from '../socket';
import { titleNameToId } from '../view/util';
import type { StudyMember, StudyMemberMap, Tab } from './interfaces';
import { textRaw as xhrTextRaw } from 'lib/xhr';
import { userLink } from 'lib/view/userLink';
import { makeCtrl as inviteFormCtrl, type StudyInviteFormCtrl } from './inviteForm';
import type { NotifCtrl } from './notif';
import type StudyCtrl from './studyCtrl';
import { once } from 'lib/storage';
import { pubsub } from 'lib/pubsub';
import { cmnToggleWrap } from 'lib/view/cmn-toggle';
interface Opts {
initDict: StudyMemberMap;
+3 -1
View File
@@ -1,7 +1,9 @@
import { h, type VNode } from 'snabbdom';
import { type Prop, type Toggle, propWithEffect, toggle } from 'lib';
import * as licon from 'lib/licon';
import { bind, dataIcon, enter, onInsert, snabDialog } from 'lib/view';
import { h, type VNode } from 'snabbdom';
import type { ChapterPreview } from './interfaces';
import type { StudyChapters } from './studyChapters';

Some files were not shown because too many files have changed in this diff Show More