├── .yarnrc.yml
├── src
├── assets
│ ├── img
│ │ ├── logo.png
│ │ ├── tfcc.png
│ │ ├── webapp.png
│ │ ├── favicon.ico
│ │ ├── mobileapp.png
│ │ └── tfcc-small.png
│ ├── data
│ │ └── gm2600.bin
│ ├── js
│ │ └── stockfish.wasm
│ └── css
│ │ ├── themes
│ │ ├── ic.css
│ │ ├── gray.css
│ │ ├── purple.css
│ │ ├── red.css
│ │ ├── brown.css
│ │ ├── default.css
│ │ ├── newspaper.css
│ │ ├── yellow.css
│ │ └── green.css
│ │ ├── images
│ │ ├── board
│ │ │ ├── 3d
│ │ │ │ └── woodi.1024.png
│ │ │ ├── red.svg
│ │ │ ├── brown.svg
│ │ │ ├── ic.svg
│ │ │ ├── blue.svg
│ │ │ ├── gray.svg
│ │ │ ├── green.svg
│ │ │ ├── purple.svg
│ │ │ ├── yellow.svg
│ │ │ └── newspaper.svg
│ │ └── pieces
│ │ │ ├── staunton
│ │ │ └── basic
│ │ │ │ ├── Black-King.png
│ │ │ │ ├── Black-Pawn.png
│ │ │ │ ├── Black-Rook.png
│ │ │ │ ├── White-King.png
│ │ │ │ ├── White-Pawn.png
│ │ │ │ ├── White-Rook.png
│ │ │ │ ├── Black-Bishop.png
│ │ │ │ ├── Black-Knight.png
│ │ │ │ ├── Black-Queen.png
│ │ │ │ ├── White-Bishop.png
│ │ │ │ ├── White-Knight.png
│ │ │ │ ├── White-Queen.png
│ │ │ │ ├── Black-Bishop-Flipped.png
│ │ │ │ ├── Black-Knight-Flipped.png
│ │ │ │ ├── White-Bishop-Flipped.png
│ │ │ │ └── White-Knight-Flipped.png
│ │ │ ├── alpha
│ │ │ ├── bP.svg
│ │ │ ├── bR.svg
│ │ │ ├── wR.svg
│ │ │ ├── bB.svg
│ │ │ ├── bN.svg
│ │ │ ├── bQ.svg
│ │ │ ├── wP.svg
│ │ │ ├── wK.svg
│ │ │ ├── bK.svg
│ │ │ ├── wB.svg
│ │ │ ├── wQ.svg
│ │ │ └── wN.svg
│ │ │ ├── pirouetti
│ │ │ ├── bR.svg
│ │ │ ├── wR.svg
│ │ │ ├── wB.svg
│ │ │ ├── bB.svg
│ │ │ ├── bP.svg
│ │ │ ├── wP.svg
│ │ │ ├── wN.svg
│ │ │ ├── bN.svg
│ │ │ ├── bQ.svg
│ │ │ ├── wQ.svg
│ │ │ ├── bK.svg
│ │ │ └── wK.svg
│ │ │ ├── cburnett
│ │ │ ├── bP.svg
│ │ │ ├── wP.svg
│ │ │ ├── wQ.svg
│ │ │ ├── wR.svg
│ │ │ ├── bB.svg
│ │ │ ├── wB.svg
│ │ │ ├── wN.svg
│ │ │ ├── wK.svg
│ │ │ ├── bK.svg
│ │ │ ├── bQ.svg
│ │ │ ├── bN.svg
│ │ │ └── bR.svg
│ │ │ ├── leipzig
│ │ │ ├── bP.svg
│ │ │ └── wP.svg
│ │ │ ├── merida
│ │ │ ├── wR.svg
│ │ │ ├── bP.svg
│ │ │ ├── bR.svg
│ │ │ ├── wP.svg
│ │ │ ├── bQ.svg
│ │ │ ├── bN.svg
│ │ │ ├── bB.svg
│ │ │ ├── wK.svg
│ │ │ ├── wN.svg
│ │ │ ├── wQ.svg
│ │ │ ├── wB.svg
│ │ │ └── bK.svg
│ │ │ ├── cardinal
│ │ │ ├── bR.svg
│ │ │ ├── wR.svg
│ │ │ ├── bP.svg
│ │ │ ├── wP.svg
│ │ │ ├── wK.svg
│ │ │ ├── bK.svg
│ │ │ ├── wB.svg
│ │ │ ├── bB.svg
│ │ │ ├── wN.svg
│ │ │ ├── bN.svg
│ │ │ ├── bQ.svg
│ │ │ └── wQ.svg
│ │ │ ├── spatial
│ │ │ ├── bP.svg
│ │ │ ├── wP.svg
│ │ │ ├── bN.svg
│ │ │ ├── wN.svg
│ │ │ ├── wQ.svg
│ │ │ ├── bQ.svg
│ │ │ ├── bK.svg
│ │ │ ├── wK.svg
│ │ │ ├── wR.svg
│ │ │ ├── bR.svg
│ │ │ ├── wB.svg
│ │ │ └── bB.svg
│ │ │ └── maestro
│ │ │ ├── wR.svg
│ │ │ ├── wP.svg
│ │ │ ├── bP.svg
│ │ │ └── bR.svg
│ │ ├── pieces
│ │ ├── alpha.css
│ │ ├── default.css
│ │ ├── leipzig.css
│ │ ├── maestro.css
│ │ ├── spatial.css
│ │ ├── cardinal.css
│ │ ├── cburnett.css
│ │ └── pirouetti.css
│ │ ├── 3d.css
│ │ └── chessground.css
├── icons
│ ├── icon-128.webp
│ ├── icon-192.webp
│ ├── icon-256.webp
│ ├── icon-48.webp
│ ├── icon-512.webp
│ ├── icon-72.webp
│ └── icon-96.webp
├── js
│ ├── globals.d.ts
│ ├── preload.js
│ ├── android
│ │ └── MainActivity.java
│ ├── settings.ts
│ └── service-worker.js
├── sitemap.xml
└── manifest.json
├── .gitattributes
├── .gitignore
├── .editorconfig
├── capacitor.config.ts
├── scripts
├── inject-sw-manifest.js
└── copy-app-files.js
├── .vscode
└── launch.json
├── tsconfig.json
├── README.md
├── electron.webpack.js
├── manifest.json
├── .github
└── workflows
│ └── codeql-analysis.yml
├── package.json
└── webpack.config.js
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
3 | yarnPath: .yarn/releases/yarn-4.9.4.cjs
4 |
--------------------------------------------------------------------------------
/src/assets/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/img/logo.png
--------------------------------------------------------------------------------
/src/assets/img/tfcc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/img/tfcc.png
--------------------------------------------------------------------------------
/src/icons/icon-128.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/icons/icon-128.webp
--------------------------------------------------------------------------------
/src/icons/icon-192.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/icons/icon-192.webp
--------------------------------------------------------------------------------
/src/icons/icon-256.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/icons/icon-256.webp
--------------------------------------------------------------------------------
/src/icons/icon-48.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/icons/icon-48.webp
--------------------------------------------------------------------------------
/src/icons/icon-512.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/icons/icon-512.webp
--------------------------------------------------------------------------------
/src/icons/icon-72.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/icons/icon-72.webp
--------------------------------------------------------------------------------
/src/icons/icon-96.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/icons/icon-96.webp
--------------------------------------------------------------------------------
/src/assets/img/webapp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/img/webapp.png
--------------------------------------------------------------------------------
/src/assets/data/gm2600.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/data/gm2600.bin
--------------------------------------------------------------------------------
/src/assets/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/img/favicon.ico
--------------------------------------------------------------------------------
/src/assets/img/mobileapp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/img/mobileapp.png
--------------------------------------------------------------------------------
/src/assets/js/stockfish.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/js/stockfish.wasm
--------------------------------------------------------------------------------
/src/assets/img/tfcc-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/img/tfcc-small.png
--------------------------------------------------------------------------------
/src/assets/css/themes/ic.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --bg-color: #ececec;
3 | }
4 |
5 | cg-board {
6 | background-image: url('../images/board/ic.svg');
7 | }
--------------------------------------------------------------------------------
/src/assets/css/images/board/3d/woodi.1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/board/3d/woodi.1024.png
--------------------------------------------------------------------------------
/src/assets/css/themes/gray.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --bg-color: #424242;
3 | }
4 |
5 | cg-board {
6 | background-image: url('../images/board/gray.svg');
7 | }
8 |
--------------------------------------------------------------------------------
/src/assets/css/themes/purple.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --bg-color: #decfef;
3 | }
4 |
5 | cg-board {
6 | background-image: url('../images/board/purple.svg');
7 | }
--------------------------------------------------------------------------------
/src/assets/css/themes/red.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --bg-color: #ffc8c8;
3 | }
4 |
5 | cg-board {
6 | background-image: url('../images/board/red.svg');
7 | }
8 |
--------------------------------------------------------------------------------
/src/assets/css/themes/brown.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --bg-color: #f0d9b5;
3 | }
4 |
5 | cg-board {
6 | background-image: url('../images/board/brown.svg');
7 | }
8 |
--------------------------------------------------------------------------------
/src/assets/css/themes/default.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --bg-color: #dee3e6;
3 | }
4 |
5 | cg-board {
6 | background-image: url('../images/board/blue.svg');
7 | }
8 |
--------------------------------------------------------------------------------
/src/assets/css/themes/newspaper.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --bg-color: #dcdcdc;
3 | }
4 |
5 | cg-board {
6 | background-image: url('../images/board/newspaper.svg');
7 | }
--------------------------------------------------------------------------------
/src/assets/css/themes/yellow.css:
--------------------------------------------------------------------------------
1 | .feature3 {
2 | background-color: #f4ede1;
3 | }
4 | cg-board {
5 | background-image: url('../images/board/yellow.svg');
6 | }
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | /.yarn/** linguist-vendored
2 | /.yarn/releases/* binary
3 | /.yarn/plugins/**/* binary
4 | /.pnp.* binary linguist-generated
5 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/Black-King.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/Black-King.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/Black-Pawn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/Black-Pawn.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/Black-Rook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/Black-Rook.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/White-King.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/White-King.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/White-Pawn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/White-Pawn.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/White-Rook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/White-Rook.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/Black-Bishop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/Black-Bishop.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/Black-Knight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/Black-Knight.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/Black-Queen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/Black-Queen.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/White-Bishop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/White-Bishop.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/White-Knight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/White-Knight.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/White-Queen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/White-Queen.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/Black-Bishop-Flipped.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/Black-Bishop-Flipped.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/Black-Knight-Flipped.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/Black-Knight-Flipped.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/White-Bishop-Flipped.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/White-Bishop-Flipped.png
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/staunton/basic/White-Knight-Flipped.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freechessclub/freechessclub-app/HEAD/src/assets/css/images/pieces/staunton/basic/White-Knight-Flipped.png
--------------------------------------------------------------------------------
/src/assets/css/themes/green.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --bg-color: #eaffea;
3 | }
4 |
5 | cg-board {
6 | background-image: url('../images/board/green.svg');
7 | }
8 |
9 | #chat-info {
10 | background-color: rgba(0, 0, 0, 0.025);
11 | }
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | /src/js/app.js
3 | /www
4 | /dev
5 | /app
6 | /dist
7 | platforms
8 | plugins
9 | package-lock.json
10 | yarn-error.log
11 | .idea
12 | /android
13 | /ios
14 | .DS_Store
15 | .pnp.*
16 | .yarn/*
17 | !.yarn/patches
18 | !.yarn/plugins
19 | !.yarn/releases
20 | !.yarn/sdks
21 | !.yarn/versions
22 |
--------------------------------------------------------------------------------
/src/js/globals.d.ts:
--------------------------------------------------------------------------------
1 | interface Window {
2 | bootstrap: any;
3 | Popper: any;
4 | d3: any;
5 | Capacitor: any;
6 | electron: any;
7 | }
8 |
9 | declare const bootstrap: any;
10 | declare const Popper: any;
11 | declare const d3: any;
12 | declare const Capacitor: any;
13 | declare const electron: any;
14 | declare module '*.css';
15 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | indent_style = space
9 | tab_width = 2
10 | end_of_line = lf
11 | charset = utf-8
12 | trim_trailing_whitespace = true
13 | insert_final_newline = true
14 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/alpha/bP.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/capacitor.config.ts:
--------------------------------------------------------------------------------
1 | import { CapacitorConfig } from '@capacitor/cli';
2 |
3 | const config: CapacitorConfig = {
4 | appId: 'club.freechess.FreeChessClub',
5 | appName: 'Free Chess Club',
6 | webDir: 'app',
7 | cordova: {
8 | preferences: {
9 | AppendUserAgent: 'Free Chess Club Mobile'
10 | }
11 | }
12 | };
13 |
14 | export default config;
15 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/alpha/bR.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/js/preload.js:
--------------------------------------------------------------------------------
1 | // Copyright 2024 Free Chess Club.
2 | // Use of this source code is governed by a GPL-style
3 | // license that can be found in the LICENSE file.
4 |
5 | const { contextBridge, ipcRenderer } = require('electron');
6 | contextBridge.exposeInMainWorld('electron', {
7 | encrypt: (value) => ipcRenderer.invoke('encrypt', value),
8 | decrypt: (value) => ipcRenderer.invoke('decrypt', value),
9 | });
10 |
--------------------------------------------------------------------------------
/scripts/inject-sw-manifest.js:
--------------------------------------------------------------------------------
1 | const workboxBuild = require("workbox-build");
2 | const path = require('path');
3 |
4 | workboxBuild.injectManifest({
5 | swSrc: "./www/service-worker.js",
6 | swDest: "./www/service-worker.js",
7 | globDirectory: path.resolve(process.cwd(), 'www'),
8 | globPatterns: [
9 | "play.html",
10 | "assets/**/*.{html,js,wasm,css,png,jpg,svg,json,bin,tsv,ico}",
11 | ],
12 | });
13 |
--------------------------------------------------------------------------------
/scripts/copy-app-files.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs').promises;
2 |
3 | async function copyFiles() {
4 | try {
5 | await fs.mkdir('./app', { recursive: true });
6 | await fs.copyFile('./www/play.html', './app/index.html');
7 | await fs.copyFile('./www/service-worker.js', './app/service-worker.js');
8 | await fs.cp('./www/assets', './app/assets', { recursive: true, force: true });
9 | await fs.copyFile('./src/js/android/MainActivity.java', './android/app/src/main/java/club/freechess/FreeChessClub/MainActivity.java');
10 | } catch (err) {
11 | console.error("Error during copy:", err.message);
12 | }
13 | }
14 |
15 | copyFiles();
16 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible Node.js debug attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "type": "node",
9 | "request": "launch",
10 | "name": "Launch Program",
11 | "program": "${file}"
12 | },
13 | {
14 | "type": "node",
15 | "request": "attach",
16 | "name": "Attach to Port",
17 | "address": "localhost",
18 | "port": 5858
19 | }
20 | ]
21 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | // "noImplicitAny": true,
4 | // "strictNullChecks": true,
5 | "removeComments": false, // Don't enable this, we need webpack magic comments and comments are later removed by the minimizer
6 | "preserveConstEnums": true,
7 | "sourceMap": true,
8 | "esModuleInterop": true,
9 | "resolveJsonModule": true,
10 | "allowSyntheticDefaultImports": true,
11 | "module": "es2022",
12 | "target": "es2022",
13 | "moduleResolution": "node"
14 | },
15 | "include": [
16 | "src/**/*"
17 | ],
18 | "exclude": [
19 | "node_modules",
20 | "assets",
21 | "app"
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/src/assets/css/images/board/red.svg:
--------------------------------------------------------------------------------
1 |
2 |
20 |
--------------------------------------------------------------------------------
/src/assets/css/images/board/brown.svg:
--------------------------------------------------------------------------------
1 |
2 |
20 |
--------------------------------------------------------------------------------
/src/assets/css/images/board/ic.svg:
--------------------------------------------------------------------------------
1 |
2 |
21 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/pirouetti/bR.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/pirouetti/wR.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/board/blue.svg:
--------------------------------------------------------------------------------
1 |
2 |
21 |
--------------------------------------------------------------------------------
/src/assets/css/images/board/gray.svg:
--------------------------------------------------------------------------------
1 |
2 |
21 |
--------------------------------------------------------------------------------
/src/assets/css/images/board/green.svg:
--------------------------------------------------------------------------------
1 |
2 |
21 |
--------------------------------------------------------------------------------
/src/assets/css/images/board/purple.svg:
--------------------------------------------------------------------------------
1 |
2 |
21 |
--------------------------------------------------------------------------------
/src/assets/css/images/board/yellow.svg:
--------------------------------------------------------------------------------
1 |
2 |
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Free Chess Club: A modern web client for FICS.
2 |
3 | Free Chess Club is a modern interface for the [Free Internet Chess Server (FICS)](https://freechess.org/) — one of the oldest internet chess servers with over 800,000 registered accounts.
4 |
5 | You can try out the interface here: [Free Chess Club](http://www.freechess.club/play).
6 |
7 | In addition to the hosted web interface, there are cross-platform [Electron](https://www.electronjs.org/)-based desktop apps (under [Releases](https://github.com/freechessclub/freechessclub-app/releases)) and [Capacitor](https://capacitorjs.com/)-based mobile apps that you can access from the mobile app stores.
8 |
9 | To get started locally, just type:
10 | ```bash
11 | $ yarn start
12 | ```
13 | and point your browser to http://localhost:8080
14 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cburnett/bP.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cburnett/wP.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/alpha/wR.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/alpha/bB.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/leipzig/bP.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/alpha/bN.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/alpha/bQ.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/merida/wR.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/merida/bP.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/pirouetti/wB.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/merida/bR.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/pirouetti/bB.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/pirouetti/bP.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/pirouetti/wP.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/pirouetti/wN.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/alpha/wP.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/pirouetti/bN.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | http://www.freechess.club/
11 | 2017-08-12T19:42:12+00:00
12 | monthly
13 |
14 |
15 | http://www.freechess.club/play
16 | 2017-08-12T19:42:12+00:00
17 | monthly
18 |
19 |
20 | http://www.freechess.club/contact
21 | 2017-08-12T19:42:12+00:00
22 | yearly
23 |
24 |
25 | http://www.freechess.club/privacy
26 | 2017-08-12T19:42:12+00:00
27 | yearly
28 |
29 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/pirouetti/bQ.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/pirouetti/wQ.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/js/android/MainActivity.java:
--------------------------------------------------------------------------------
1 | // Custom MainActivity.java for Capacitor Android builds. Allows service worker to work with Android WebView
2 |
3 | package club.freechess.FreeChessClub;
4 |
5 | import android.os.Bundle;
6 | import android.os.Build;
7 | import android.webkit.WebResourceRequest;
8 | import android.webkit.WebResourceResponse;
9 | import android.webkit.ServiceWorkerClient;
10 | import android.webkit.ServiceWorkerController;
11 | import com.getcapacitor.BridgeActivity;
12 |
13 | public class MainActivity extends BridgeActivity {
14 | @Override
15 | public void onCreate(Bundle savedInstanceState) {
16 | super.onCreate(savedInstanceState);
17 |
18 | if(Build.VERSION.SDK_INT >= 24 ){
19 | ServiceWorkerController swController = ServiceWorkerController.getInstance();
20 |
21 | swController.setServiceWorkerClient(new ServiceWorkerClient() {
22 | @Override
23 | public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
24 | return bridge.getLocalServer().shouldInterceptRequest(request);
25 | }
26 | });
27 | }
28 | }
29 | }
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cburnett/wQ.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/electron.webpack.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const path = require('path');
3 |
4 | const inputDir = 'src';
5 | const outputDir = 'dist';
6 |
7 | const electronPreload = {
8 | name: 'electron-preload',
9 | target: 'electron-preload',
10 | mode: 'production',
11 | entry: path.resolve(__dirname, inputDir, 'js/preload.js'),
12 | output: {
13 | filename: 'preload.js',
14 | path: path.resolve(__dirname, outputDir, 'js'),
15 | },
16 | node: {
17 | __dirname: false,
18 | __filename: false,
19 | },
20 | }
21 |
22 | const electronApp = {
23 | name: 'electron-app',
24 | target: 'electron-main',
25 | mode: 'production',
26 | entry: path.resolve(__dirname, inputDir, 'js/app.ts'),
27 | output: {
28 | path: path.resolve(__dirname, outputDir, 'js'),
29 | filename: 'app.js',
30 | },
31 | resolve: {
32 | extensions: ['.ts', '.js'],
33 | },
34 | module: {
35 | rules: [
36 | { test: /\.ts$/, exclude: /node_modules/, use: 'ts-loader', },
37 | ],
38 | },
39 | node: {
40 | __dirname: false,
41 | __filename: false,
42 | },
43 | }
44 |
45 | module.exports = [electronPreload, electronApp];
46 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/alpha/wK.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/pieces/alpha.css:
--------------------------------------------------------------------------------
1 | .cg-wrap piece.pawn.white {
2 | background-image: url('../images/pieces/alpha/wP.svg');
3 | }
4 | .cg-wrap piece.bishop.white {
5 | background-image: url('../images/pieces/alpha/wB.svg');
6 | }
7 | .cg-wrap piece.knight.white {
8 | background-image: url('../images/pieces/alpha/wN.svg');
9 | }
10 | .cg-wrap piece.rook.white {
11 | background-image: url('../images/pieces/alpha/wR.svg');
12 | }
13 | .cg-wrap piece.queen.white {
14 | background-image: url('../images/pieces/alpha/wQ.svg');
15 | }
16 | .cg-wrap piece.king.white {
17 | background-image: url('../images/pieces/alpha/wK.svg');
18 | }
19 | .cg-wrap piece.pawn.black {
20 | background-image: url('../images/pieces/alpha/bP.svg');
21 | }
22 | .cg-wrap piece.bishop.black {
23 | background-image: url('../images/pieces/alpha/bB.svg');
24 | }
25 | .cg-wrap piece.knight.black {
26 | background-image: url('../images/pieces/alpha/bN.svg');
27 | }
28 | .cg-wrap piece.rook.black {
29 | background-image: url('../images/pieces/alpha/bR.svg');
30 | }
31 | .cg-wrap piece.queen.black {
32 | background-image: url('../images/pieces/alpha/bQ.svg');
33 | }
34 | .cg-wrap piece.king.black {
35 | background-image: url('../images/pieces/alpha/bK.svg');
36 | }
37 |
--------------------------------------------------------------------------------
/src/assets/css/pieces/default.css:
--------------------------------------------------------------------------------
1 | .cg-wrap piece.pawn.white {
2 | background-image: url('../images/pieces/merida/wP.svg');
3 | }
4 | .cg-wrap piece.bishop.white {
5 | background-image: url('../images/pieces/merida/wB.svg');
6 | }
7 | .cg-wrap piece.knight.white {
8 | background-image: url('../images/pieces/merida/wN.svg');
9 | }
10 | .cg-wrap piece.rook.white {
11 | background-image: url('../images/pieces/merida/wR.svg');
12 | }
13 | .cg-wrap piece.queen.white {
14 | background-image: url('../images/pieces/merida/wQ.svg');
15 | }
16 | .cg-wrap piece.king.white {
17 | background-image: url('../images/pieces/merida/wK.svg');
18 | }
19 | .cg-wrap piece.pawn.black {
20 | background-image: url('../images/pieces/merida/bP.svg');
21 | }
22 | .cg-wrap piece.bishop.black {
23 | background-image: url('../images/pieces/merida/bB.svg');
24 | }
25 | .cg-wrap piece.knight.black {
26 | background-image: url('../images/pieces/merida/bN.svg');
27 | }
28 | .cg-wrap piece.rook.black {
29 | background-image: url('../images/pieces/merida/bR.svg');
30 | }
31 | .cg-wrap piece.queen.black {
32 | background-image: url('../images/pieces/merida/bQ.svg');
33 | }
34 | .cg-wrap piece.king.black {
35 | background-image: url('../images/pieces/merida/bK.svg');
36 | }
37 |
--------------------------------------------------------------------------------
/src/assets/css/pieces/leipzig.css:
--------------------------------------------------------------------------------
1 | .cg-wrap piece.pawn.white {
2 | background-image: url('../images/pieces/leipzig/wP.svg');
3 | }
4 | .cg-wrap piece.bishop.white {
5 | background-image: url('../images/pieces/leipzig/wB.svg');
6 | }
7 | .cg-wrap piece.knight.white {
8 | background-image: url('../images/pieces/leipzig/wN.svg');
9 | }
10 | .cg-wrap piece.rook.white {
11 | background-image: url('../images/pieces/leipzig/wR.svg');
12 | }
13 | .cg-wrap piece.queen.white {
14 | background-image: url('../images/pieces/leipzig/wQ.svg');
15 | }
16 | .cg-wrap piece.king.white {
17 | background-image: url('../images/pieces/leipzig/wK.svg');
18 | }
19 | .cg-wrap piece.pawn.black {
20 | background-image: url('../images/pieces/leipzig/bP.svg');
21 | }
22 | .cg-wrap piece.bishop.black {
23 | background-image: url('../images/pieces/leipzig/bB.svg');
24 | }
25 | .cg-wrap piece.knight.black {
26 | background-image: url('../images/pieces/leipzig/bN.svg');
27 | }
28 | .cg-wrap piece.rook.black {
29 | background-image: url('../images/pieces/leipzig/bR.svg');
30 | }
31 | .cg-wrap piece.queen.black {
32 | background-image: url('../images/pieces/leipzig/bQ.svg');
33 | }
34 | .cg-wrap piece.king.black {
35 | background-image: url('../images/pieces/leipzig/bK.svg');
36 | }
37 |
--------------------------------------------------------------------------------
/src/assets/css/pieces/maestro.css:
--------------------------------------------------------------------------------
1 | .cg-wrap piece.pawn.white {
2 | background-image: url('../images/pieces/maestro/wP.svg');
3 | }
4 | .cg-wrap piece.bishop.white {
5 | background-image: url('../images/pieces/maestro/wB.svg');
6 | }
7 | .cg-wrap piece.knight.white {
8 | background-image: url('../images/pieces/maestro/wN.svg');
9 | }
10 | .cg-wrap piece.rook.white {
11 | background-image: url('../images/pieces/maestro/wR.svg');
12 | }
13 | .cg-wrap piece.queen.white {
14 | background-image: url('../images/pieces/maestro/wQ.svg');
15 | }
16 | .cg-wrap piece.king.white {
17 | background-image: url('../images/pieces/maestro/wK.svg');
18 | }
19 | .cg-wrap piece.pawn.black {
20 | background-image: url('../images/pieces/maestro/bP.svg');
21 | }
22 | .cg-wrap piece.bishop.black {
23 | background-image: url('../images/pieces/maestro/bB.svg');
24 | }
25 | .cg-wrap piece.knight.black {
26 | background-image: url('../images/pieces/maestro/bN.svg');
27 | }
28 | .cg-wrap piece.rook.black {
29 | background-image: url('../images/pieces/maestro/bR.svg');
30 | }
31 | .cg-wrap piece.queen.black {
32 | background-image: url('../images/pieces/maestro/bQ.svg');
33 | }
34 | .cg-wrap piece.king.black {
35 | background-image: url('../images/pieces/maestro/bK.svg');
36 | }
37 |
--------------------------------------------------------------------------------
/src/assets/css/pieces/spatial.css:
--------------------------------------------------------------------------------
1 | .cg-wrap piece.pawn.white {
2 | background-image: url('../images/pieces/spatial/wP.svg');
3 | }
4 | .cg-wrap piece.bishop.white {
5 | background-image: url('../images/pieces/spatial/wB.svg');
6 | }
7 | .cg-wrap piece.knight.white {
8 | background-image: url('../images/pieces/spatial/wN.svg');
9 | }
10 | .cg-wrap piece.rook.white {
11 | background-image: url('../images/pieces/spatial/wR.svg');
12 | }
13 | .cg-wrap piece.queen.white {
14 | background-image: url('../images/pieces/spatial/wQ.svg');
15 | }
16 | .cg-wrap piece.king.white {
17 | background-image: url('../images/pieces/spatial/wK.svg');
18 | }
19 | .cg-wrap piece.pawn.black {
20 | background-image: url('../images/pieces/spatial/bP.svg');
21 | }
22 | .cg-wrap piece.bishop.black {
23 | background-image: url('../images/pieces/spatial/bB.svg');
24 | }
25 | .cg-wrap piece.knight.black {
26 | background-image: url('../images/pieces/spatial/bN.svg');
27 | }
28 | .cg-wrap piece.rook.black {
29 | background-image: url('../images/pieces/spatial/bR.svg');
30 | }
31 | .cg-wrap piece.queen.black {
32 | background-image: url('../images/pieces/spatial/bQ.svg');
33 | }
34 | .cg-wrap piece.king.black {
35 | background-image: url('../images/pieces/spatial/bK.svg');
36 | }
37 |
--------------------------------------------------------------------------------
/src/assets/css/pieces/cardinal.css:
--------------------------------------------------------------------------------
1 | .cg-wrap piece.pawn.white {
2 | background-image: url('../images/pieces/cardinal/wP.svg');
3 | }
4 | .cg-wrap piece.bishop.white {
5 | background-image: url('../images/pieces/cardinal/wB.svg');
6 | }
7 | .cg-wrap piece.knight.white {
8 | background-image: url('../images/pieces/cardinal/wN.svg');
9 | }
10 | .cg-wrap piece.rook.white {
11 | background-image: url('../images/pieces/cardinal/wR.svg');
12 | }
13 | .cg-wrap piece.queen.white {
14 | background-image: url('../images/pieces/cardinal/wQ.svg');
15 | }
16 | .cg-wrap piece.king.white {
17 | background-image: url('../images/pieces/cardinal/wK.svg');
18 | }
19 | .cg-wrap piece.pawn.black {
20 | background-image: url('../images/pieces/cardinal/bP.svg');
21 | }
22 | .cg-wrap piece.bishop.black {
23 | background-image: url('../images/pieces/cardinal/bB.svg');
24 | }
25 | .cg-wrap piece.knight.black {
26 | background-image: url('../images/pieces/cardinal/bN.svg');
27 | }
28 | .cg-wrap piece.rook.black {
29 | background-image: url('../images/pieces/cardinal/bR.svg');
30 | }
31 | .cg-wrap piece.queen.black {
32 | background-image: url('../images/pieces/cardinal/bQ.svg');
33 | }
34 | .cg-wrap piece.king.black {
35 | background-image: url('../images/pieces/cardinal/bK.svg');
36 | }
37 |
--------------------------------------------------------------------------------
/src/assets/css/pieces/cburnett.css:
--------------------------------------------------------------------------------
1 | .cg-wrap piece.pawn.white {
2 | background-image: url('../images/pieces/cburnett/wP.svg');
3 | }
4 | .cg-wrap piece.bishop.white {
5 | background-image: url('../images/pieces/cburnett/wB.svg');
6 | }
7 | .cg-wrap piece.knight.white {
8 | background-image: url('../images/pieces/cburnett/wN.svg');
9 | }
10 | .cg-wrap piece.rook.white {
11 | background-image: url('../images/pieces/cburnett/wR.svg');
12 | }
13 | .cg-wrap piece.queen.white {
14 | background-image: url('../images/pieces/cburnett/wQ.svg');
15 | }
16 | .cg-wrap piece.king.white {
17 | background-image: url('../images/pieces/cburnett/wK.svg');
18 | }
19 | .cg-wrap piece.pawn.black {
20 | background-image: url('../images/pieces/cburnett/bP.svg');
21 | }
22 | .cg-wrap piece.bishop.black {
23 | background-image: url('../images/pieces/cburnett/bB.svg');
24 | }
25 | .cg-wrap piece.knight.black {
26 | background-image: url('../images/pieces/cburnett/bN.svg');
27 | }
28 | .cg-wrap piece.rook.black {
29 | background-image: url('../images/pieces/cburnett/bR.svg');
30 | }
31 | .cg-wrap piece.queen.black {
32 | background-image: url('../images/pieces/cburnett/bQ.svg');
33 | }
34 | .cg-wrap piece.king.black {
35 | background-image: url('../images/pieces/cburnett/bK.svg');
36 | }
37 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cardinal/bR.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/pieces/pirouetti.css:
--------------------------------------------------------------------------------
1 | .cg-wrap piece.pawn.white {
2 | background-image: url('../images/pieces/pirouetti/wP.svg');
3 | }
4 | .cg-wrap piece.bishop.white {
5 | background-image: url('../images/pieces/pirouetti/wB.svg');
6 | }
7 | .cg-wrap piece.knight.white {
8 | background-image: url('../images/pieces/pirouetti/wN.svg');
9 | }
10 | .cg-wrap piece.rook.white {
11 | background-image: url('../images/pieces/pirouetti/wR.svg');
12 | }
13 | .cg-wrap piece.queen.white {
14 | background-image: url('../images/pieces/pirouetti/wQ.svg');
15 | }
16 | .cg-wrap piece.king.white {
17 | background-image: url('../images/pieces/pirouetti/wK.svg');
18 | }
19 | .cg-wrap piece.pawn.black {
20 | background-image: url('../images/pieces/pirouetti/bP.svg');
21 | }
22 | .cg-wrap piece.bishop.black {
23 | background-image: url('../images/pieces/pirouetti/bB.svg');
24 | }
25 | .cg-wrap piece.knight.black {
26 | background-image: url('../images/pieces/pirouetti/bN.svg');
27 | }
28 | .cg-wrap piece.rook.black {
29 | background-image: url('../images/pieces/pirouetti/bR.svg');
30 | }
31 | .cg-wrap piece.queen.black {
32 | background-image: url('../images/pieces/pirouetti/bQ.svg');
33 | }
34 | .cg-wrap piece.king.black {
35 | background-image: url('../images/pieces/pirouetti/bK.svg');
36 | }
37 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cburnett/wR.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
26 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cardinal/wR.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cburnett/bB.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cburnett/wB.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cardinal/bP.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cburnett/wN.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cburnett/wK.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cardinal/wP.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cburnett/bK.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Free Chess Club",
3 | "short_name": "Free Chess",
4 | "description": "Free Chess Club. Play chess on the Free Internet Chess Server (FICS) using a modern web-based client. No downloads, no hassles—maximum chess guaranteed!",
5 | "start_url": "/play/",
6 | "display": "standalone",
7 | "theme_color": "#000000",
8 | "background_color": "#eeeeee",
9 | "icons": [
10 | {
11 | "src": "/icons/icon-48.webp",
12 | "type": "image/png",
13 | "sizes": "48x48",
14 | "purpose": "any maskable"
15 | },
16 | {
17 | "src": "/icons/icon-72.webp",
18 | "type": "image/png",
19 | "sizes": "72x72",
20 | "purpose": "any maskable"
21 | },
22 | {
23 | "src": "/icons/icon-96.webp",
24 | "type": "image/png",
25 | "sizes": "96x96",
26 | "purpose": "any maskable"
27 | },
28 | {
29 | "src": "/icons/icon-128.webp",
30 | "type": "image/png",
31 | "sizes": "128x128",
32 | "purpose": "any maskable"
33 | },
34 | {
35 | "src": "/icons/icon-192.webp",
36 | "type": "image/png",
37 | "sizes": "192x192",
38 | "purpose": "any maskable"
39 | },
40 | {
41 | "src": "/icons/icon-256.webp",
42 | "type": "image/png",
43 | "sizes": "256x256",
44 | "purpose": "any maskable"
45 | },
46 | {
47 | "src": "/icons/icon-512.webp",
48 | "type": "image/png",
49 | "sizes": "512x512",
50 | "purpose": "any maskable"
51 | }
52 | ]
53 | }
54 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/alpha/bK.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Free Chess Club",
3 | "short_name": "Free Chess",
4 | "description": "Free Chess Club. Play chess on the Free Internet Chess Server (FICS) using a modern web-based client. No downloads, no hassles—maximum chess guaranteed!",
5 | "start_url": "/play/",
6 | "display": "standalone",
7 | "theme_color": "#000000",
8 | "background_color": "#eeeeee",
9 | "icons": [
10 | {
11 | "src": "/icons/icon-48.webp",
12 | "type": "image/png",
13 | "sizes": "48x48",
14 | "purpose": "any maskable"
15 | },
16 | {
17 | "src": "/icons/icon-72.webp",
18 | "type": "image/png",
19 | "sizes": "72x72",
20 | "purpose": "any maskable"
21 | },
22 | {
23 | "src": "/icons/icon-96.webp",
24 | "type": "image/png",
25 | "sizes": "96x96",
26 | "purpose": "any maskable"
27 | },
28 | {
29 | "src": "/icons/icon-128.webp",
30 | "type": "image/png",
31 | "sizes": "128x128",
32 | "purpose": "any maskable"
33 | },
34 | {
35 | "src": "/icons/icon-192.webp",
36 | "type": "image/png",
37 | "sizes": "192x192",
38 | "purpose": "any maskable"
39 | },
40 | {
41 | "src": "/icons/icon-256.webp",
42 | "type": "image/png",
43 | "sizes": "256x256",
44 | "purpose": "any maskable"
45 | },
46 | {
47 | "src": "/icons/icon-512.webp",
48 | "type": "image/png",
49 | "sizes": "512x512",
50 | "purpose": "any maskable"
51 | }
52 | ]
53 | }
54 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/pirouetti/bK.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cburnett/bQ.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
28 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/pirouetti/wK.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/js/settings.ts:
--------------------------------------------------------------------------------
1 | export const settings = {
2 | /** Main settings */
3 |
4 | // toggle game sounds
5 | soundToggle: true,
6 | // toggle for auto-promote to queen
7 | autoPromoteToggle: false,
8 | // toggle for showing Computer opponents in the lobby
9 | lobbyShowComputersToggle: false,
10 | // toggle for showing Rated games in the lobby
11 | lobbyShowUnratedToggle: true,
12 | // toggle for automatically showing new slide-down notifications or notifications in chat channels
13 | notificationsToggle: true,
14 | // toggle for showing highlights/graphics on the board
15 | highlightsToggle: true,
16 | // toggle for showing highlights/graphics on the board
17 | wakelockToggle: true,
18 | // toggle for multi-board mode / single-board mode
19 | multiboardToggle: true,
20 | // toggle for enabling multiple premoves
21 | multiplePremovesToggle: false,
22 | // toggle for enabling smart move
23 | smartmoveToggle: false,
24 | // toggle for remembering user's login and password between sessions
25 | rememberMeToggle: false,
26 | // toggle for showing the eval bar when the engine is running
27 | evalBarToggle: true,
28 | // toggle for showing the best move arrow when the engine is running
29 | bestMoveArrowToggle: true,
30 |
31 | /** Chat settings */
32 |
33 | // toggle for displaying timestamps on messages
34 | timestampToggle: true,
35 | // toggle for creating separate chat tabs instead of displaying messages in the console
36 | chattabsToggle: true,
37 |
38 | /** History settings */
39 |
40 | pieceGlyphsToggle: true,
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/alpha/wB.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/alpha/wQ.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cburnett/bN.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cardinal/wK.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cardinal/bK.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cardinal/wB.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cardinal/bB.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/spatial/bP.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/spatial/wP.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cburnett/bR.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
40 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/merida/wP.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cardinal/wN.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cardinal/bN.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/spatial/bN.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/spatial/wN.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/board/newspaper.svg:
--------------------------------------------------------------------------------
1 |
2 |
26 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cardinal/bQ.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/cardinal/wQ.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/alpha/wN.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/js/service-worker.js:
--------------------------------------------------------------------------------
1 | import { precacheAndRoute, cleanupOutdatedCaches } from 'workbox-precaching';
2 | import { registerRoute } from 'workbox-routing';
3 | import { StaleWhileRevalidate } from 'workbox-strategies';
4 |
5 | // pre-cache external resources
6 | const externals = [
7 | {"url":"https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css", "revision":"1"},
8 | {"url":"https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/fonts/fontawesome-webfont.woff2?v=4.7.0", "revision":"1"},
9 | {"url":"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css", "revision":"1"},
10 | {"url":"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/webfonts/fa-solid-900.woff2", "revision":"1"},
11 | {"url":"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/webfonts/fa-regular-400.woff2", "revision":"1"},
12 | {"url":"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/webfonts/fa-brands-400.woff2", "revision":"1"},
13 | {"url":"https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css", "revision":"1"},
14 | {"url":"https://fonts.googleapis.com/css2?family=Noto+Sans+Math&family=Noto+Sans+Symbols+2&display=swap", "revision":"1"},
15 | {"url":"https://code.jquery.com/jquery-3.7.0.slim.min.js", "revision":"1"},
16 | {"url":"https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js", "revision":"1"},
17 | {"url":"https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js", "revision":"1"},
18 | {"url":"https://cdn.jsdelivr.net/npm/d3@7.8.0/dist/d3.min.js", "revision":"1"},
19 | {"url":"https://fonts.gstatic.com/s/notosanssymbols2/v24/I_uyMoGduATTei9eI8daxVHDyfisHr71-vrgfE71.woff2","revision":"1"},
20 | {"url":"https://fonts.gstatic.com/s/notosansmath/v15/7Aump_cpkSecTWaHRlH2hyV5UEl981w.woff2","revision":"1"},
21 | ];
22 |
23 | const urlParams = new URLSearchParams(self.location.search);
24 | if(urlParams.get('env') === 'app') // Capacitor or Electron app, don't cache static assets
25 | precacheAndRoute(externals);
26 | else
27 | precacheAndRoute([...self.__WB_MANIFEST, ...externals]); // __WB_MANIFEST is injected by inject-manifest.js
28 |
29 | registerRoute(
30 | ({ url }) => url.origin === 'https://cdn.jsdelivr.net',
31 | new StaleWhileRevalidate({ cacheName: 'stalewhile-cache' })
32 | );
33 |
34 | cleanupOutdatedCaches();
35 |
36 | self.addEventListener('install', (event) => {
37 | self.skipWaiting();
38 | });
39 |
40 | self.addEventListener('activate', (event) => {
41 | event.waitUntil(clients.claim());
42 | });
43 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/spatial/wQ.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/spatial/bQ.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/spatial/bK.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/spatial/wK.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/merida/bQ.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ master ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ master ]
20 | schedule:
21 | - cron: '44 23 * * 5'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'javascript' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
37 | # Learn more:
38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
39 |
40 | steps:
41 | - name: Checkout repository
42 | uses: actions/checkout@v2
43 |
44 | # Initializes the CodeQL tools for scanning.
45 | - name: Initialize CodeQL
46 | uses: github/codeql-action/init@v1
47 | with:
48 | languages: ${{ matrix.language }}
49 | # If you wish to specify custom queries, you can do so here or in a config file.
50 | # By default, queries listed here will override any specified in a config file.
51 | # Prefix the list here with "+" to use these queries and those in the config file.
52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
53 |
54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
55 | # If this step fails, then you should remove it and run the build manually (see below)
56 | - name: Autobuild
57 | uses: github/codeql-action/autobuild@v1
58 |
59 | # ℹ️ Command-line programs to run using the OS shell.
60 | # 📚 https://git.io/JvXDl
61 |
62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
63 | # and modify them (or add more) to build your code if your project
64 | # uses a compiled language
65 |
66 | #- run: |
67 | # make bootstrap
68 | # make release
69 |
70 | - name: Perform CodeQL Analysis
71 | uses: github/codeql-action/analyze@v1
72 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/spatial/wR.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/spatial/bR.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/3d.css:
--------------------------------------------------------------------------------
1 | .in3d .cg-wrap {
2 | width: 512px;
3 | height: 464.5px;
4 | }
5 | .in3d .cg-board::before {
6 | position: absolute;
7 | top: -0.730688%;
8 | left: 0;
9 | width: 100%;
10 | height: 103.2%;
11 | content: '';
12 | background-size: cover;
13 | background-image: url('images/board/3d/woodi.1024.png');
14 | }
15 | .in3d .ghost,
16 | .in3d .over {
17 | display: none;
18 | }
19 | .in3d square[data-coord-x]::after {
20 | bottom: calc(-10px - 22%);
21 | }
22 | .in3d piece {
23 | /* original size:
24 | width: 140.625%;
25 | height: 179.6875%; */
26 | /* size on 3D board, with height/width = 90.78571% */
27 | width: 16.741%;
28 | height: 23.563%;
29 | left: -1.85%;
30 | top: -9.1%;
31 | }
32 | .cg-board piece.dragging {
33 | cursor: move;
34 | z-index: 70!important;
35 | }
36 | .in3d .cg-wrap piece.pawn.white {
37 | background-image: url('images/pieces/staunton/basic/White-Pawn.png');
38 | }
39 | .in3d .cg-wrap piece.bishop.white {
40 | background-image: url('images/pieces/staunton/basic/White-Bishop.png');
41 | }
42 | .in3d .cg-wrap.orientation-black div.bishop.white {
43 | background-image: url('images/pieces/staunton/basic/White-Bishop-Flipped.png');
44 | }
45 | .in3d .cg-wrap piece.knight.white {
46 | background-image: url('images/pieces/staunton/basic/White-Knight.png');
47 | }
48 | .in3d .cg-wrap.orientation-black div.knight.white {
49 | background-image: url('images/pieces/staunton/basic/White-Knight-Flipped.png');
50 | }
51 | .in3d .cg-wrap piece.rook.white {
52 | background-image: url('images/pieces/staunton/basic/White-Rook.png');
53 | }
54 | .in3d .cg-wrap piece.queen.white {
55 | background-image: url('images/pieces/staunton/basic/White-Queen.png');
56 | }
57 | .in3d .cg-wrap piece.king.white {
58 | background-image: url('images/pieces/staunton/basic/White-King.png');
59 | }
60 | .in3d .cg-wrap piece.pawn.black {
61 | background-image: url('images/pieces/staunton/basic/Black-Pawn.png');
62 | }
63 | .in3d .cg-wrap piece.bishop.black {
64 | background-image: url('images/pieces/staunton/basic/Black-Bishop.png');
65 | }
66 | .in3d .cg-wrap.orientation-white div.bishop.black {
67 | background-image: url('images/pieces/staunton/basic/Black-Bishop-Flipped.png');
68 | }
69 | .in3d .cg-wrap piece.knight.black {
70 | background-image: url('images/pieces/staunton/basic/Black-Knight.png');
71 | }
72 | .in3d .cg-wrap.orientation-white div.knight.black {
73 | background-image: url('images/pieces/staunton/basic/Black-Knight-Flipped.png');
74 | }
75 | .in3d .cg-wrap piece.rook.black {
76 | background-image: url('images/pieces/staunton/basic/Black-Rook.png');
77 | }
78 | .in3d .cg-wrap piece.queen.black {
79 | background-image: url('images/pieces/staunton/basic/Black-Queen.png');
80 | }
81 | .in3d .cg-wrap piece.king.black {
82 | background-image: url('images/pieces/staunton/basic/Black-King.png');
83 | }
84 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/merida/bN.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/leipzig/wP.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/merida/bB.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/maestro/wR.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/merida/wK.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/maestro/wP.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/spatial/wB.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/spatial/bB.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/merida/wN.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "freechessclub",
3 | "version": "4.1.2",
4 | "license": "MIT",
5 | "description": "Free Chess Club: A modern web interface for FICS.",
6 | "main": "./dist/js/app.js",
7 | "scripts": {
8 | "app": "tsc src/js/app.ts && electron src/js/app.js",
9 | "lint": "eslint -c .eslintrc.js --ext .ts src",
10 | "bundle": "webpack --mode production",
11 | "dev": "webpack --mode development",
12 | "pack": "webpack --config electron.webpack.js && electron-builder --dir",
13 | "dist": "webpack --config electron.webpack.js && electron-builder",
14 | "build": "webpack --config electron.webpack.js && electron-builder -mwl --x64 --arm64 -p always",
15 | "release": "yarn build",
16 | "postinstall": "electron-builder install-app-deps",
17 | "android": "node scripts/copy-app-files.js && npx cap run android",
18 | "ios": "node scripts/copy-app-files.js && npx cap run ios",
19 | "start": "webpack-dev-server --config webpack.config.js"
20 | },
21 | "repository": {
22 | "type": "git",
23 | "url": "https://github.com/freechessclub/freechessclub-app"
24 | },
25 | "author": {
26 | "name": "Free Chess Club Author(s)",
27 | "email": "support@freechess.club"
28 | },
29 | "build": {
30 | "appId": "club.freechess.FreeChessClub",
31 | "productName": "Free Chess Club",
32 | "copyright": "Copyright © 2024 Free Chess Club Author(s)",
33 | "publish": [
34 | "github"
35 | ],
36 | "files": [
37 | "dist/js/**",
38 | "www/**",
39 | "!node_modules/**"
40 | ],
41 | "mac": {
42 | "category": "public.app-category.board-games",
43 | "identity": "Apple Development: tessellate.ai@gmail.com (W893HC69YA)"
44 | },
45 | "linux": {
46 | "target": [
47 | "tar.gz",
48 | "zip"
49 | ],
50 | "category": "Game"
51 | }
52 | },
53 | "dependencies": {
54 | "@capacitor-community/safe-area": "^7.0.0-alpha.1",
55 | "@capacitor/android": "^7.2.0",
56 | "@capacitor/core": "^7.2.0",
57 | "@capacitor/ios": "^7.2.0",
58 | "@capacitor/preferences": "^7.0.1",
59 | "@mliebelt/pgn-parser": "^1.4.15",
60 | "@popperjs/core": "^2.11.6",
61 | "@uriopass/nosleep.js": "^0.12.2",
62 | "autolink-js": "https://github.com/freechessclub/autolink-js",
63 | "bootstrap": "5.2.3",
64 | "builder-util-runtime": "^9.2.10",
65 | "capacitor-secure-storage-plugin": "^0.11.0",
66 | "chess.js": "^0.12.1",
67 | "chessground": "^9.0.4",
68 | "cm-polyglot": "^1.1.0",
69 | "d3": "^7.8.0",
70 | "electron-updater": "6.6.4",
71 | "emoji-mart": "^5.6.0",
72 | "jquery": "^3.7.0",
73 | "js-cookie": "^3.0.1",
74 | "stockfish.js": "^10.0.2",
75 | "virtual-scroller": "^1.13.1"
76 | },
77 | "devDependencies": {
78 | "@capacitor/assets": "^3.0.5",
79 | "@capacitor/cli": "^7.2.0",
80 | "@mliebelt/pgn-types": "^1.0.4",
81 | "@types/bootstrap": "5.2.3",
82 | "@types/jquery": "^3.5.16",
83 | "@types/websocket": "^1.0.1",
84 | "@typescript-eslint/eslint-plugin": "^8.17.0",
85 | "@typescript-eslint/parser": "^8.17.0",
86 | "cheerio": "^1.0.0",
87 | "copy-webpack-plugin": "^13.0.0",
88 | "css-loader": "^6.6.0",
89 | "electron": "^36.3.2",
90 | "electron-builder": "26.0.15",
91 | "eslint": "^8.57.1",
92 | "eslint-plugin-jsdoc": "^50.6.0",
93 | "eslint-plugin-prefer-arrow": "^1.2.3",
94 | "exports-loader": "^3.1.0",
95 | "html-webpack-plugin": "^5.6.3",
96 | "mini-css-extract-plugin": "^2.9.2",
97 | "path-browserify": "^1.0.1",
98 | "style-loader": "^3.3.1",
99 | "sync-request": "^6.1.0",
100 | "ts-loader": "^9.3.1",
101 | "typescript": "^5.8.3",
102 | "webpack": "^5.99.9",
103 | "webpack-cli": "^5.0.2",
104 | "webpack-dev-server": "^5.0.2",
105 | "workbox-build": "^7.3.0",
106 | "workbox-core": "^7.3.0",
107 | "workbox-precaching": "^7.3.0",
108 | "workbox-routing": "^7.3.0",
109 | "workbox-strategies": "^7.3.0"
110 | },
111 | "packageManager": "yarn@4.9.4"
112 | }
113 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/merida/wQ.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/merida/wB.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/merida/bK.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/maestro/bP.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/css/chessground.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Chessground base css properties.
3 | *
4 | * You need to include the css files in themes folder in order to have the
5 | * board and pieces displayed!
6 | */
7 |
8 | .cg-wrap {
9 | box-sizing: content-box;
10 | position: relative;
11 | display: block;
12 | }
13 | .cg-wrap:after {
14 | content: "";
15 | display: block;
16 | padding-bottom: 100%;
17 | }
18 |
19 | cg-container {
20 | position: absolute;
21 | width: 100%;
22 | height: 100%;
23 | display: block;
24 | top: 0;
25 | }
26 |
27 | cg-board {
28 | position: absolute;
29 | top: 0;
30 | left: 0;
31 | width: 100%;
32 | height: 100%;
33 | -webkit-user-select: none;
34 | -moz-user-select: none;
35 | -ms-user-select: none;
36 | user-select: none;
37 | line-height: 0;
38 | background-size: cover;
39 | cursor: pointer;
40 | }
41 | cg-board square {
42 | position: absolute;
43 | top: 0;
44 | left: 0;
45 | width: 12.5%;
46 | height: 12.5%;
47 | pointer-events: none;
48 | }
49 | cg-board square.move-dest {
50 | background: radial-gradient(rgba(20, 85, 30, 0.5) 22%, #208530 0, rgba(0, 0, 0, 0.3) 0, rgba(0, 0, 0, 0) 0);
51 | pointer-events: auto;
52 | }
53 | cg-board square.premove-dest {
54 | background: radial-gradient(rgba(20, 30, 85, 0.5) 22%, #203085 0, rgba(0, 0, 0, 0.3) 0, rgba(0, 0, 0, 0) 0);
55 | }
56 | cg-board square.oc.move-dest {
57 | background: radial-gradient(transparent 0%, transparent 80%, rgba(20, 85, 0, 0.3) 80%);
58 | }
59 | cg-board square.oc.premove-dest {
60 | background: radial-gradient(transparent 0%, transparent 80%, rgba(20, 30, 85, 0.2) 80%);
61 | }
62 | cg-board square.move-dest:hover {
63 | background: rgba(20, 85, 30, 0.3);
64 | }
65 | cg-board square.premove-dest:hover {
66 | background: rgba(20, 30, 85, 0.2);
67 | }
68 | cg-board square.last-move {
69 | will-change: transform;
70 | background-color: rgba(155, 199, 0, 0.41);
71 | }
72 | cg-board square.selected {
73 | background-color: rgba(20, 85, 30, 0.5);
74 | }
75 | cg-board square.check {
76 | background: radial-gradient(ellipse at center, rgba(255, 0, 0, 1) 0%, rgba(231, 0, 0, 1) 25%, rgba(169, 0, 0, 0) 89%, rgba(158, 0, 0, 0) 100%);
77 | }
78 | cg-board square.current-premove {
79 | background-color: rgba(20, 30, 85, 0.5);
80 | }
81 | .cg-wrap piece {
82 | position: absolute;
83 | top: 0;
84 | left: 0;
85 | width: 12.5%;
86 | height: 12.5%;
87 | background-size: cover;
88 | z-index: 2;
89 | will-change: transform;
90 | pointer-events: none;
91 | }
92 | cg-board piece.dragging {
93 | cursor: move;
94 | z-index: 10;
95 | }
96 | cg-board piece.anim {
97 | z-index: 8;
98 | }
99 | cg-board piece.fading {
100 | z-index: 1;
101 | opacity: 0.5;
102 | }
103 | .cg-wrap square.move-dest:hover {
104 | background-color: rgba(20, 85, 30, 0.3);
105 | }
106 | .cg-wrap piece.ghost {
107 | opacity: 0.3;
108 | }
109 | .cg-wrap .cg-shapes, .cg-wrap .cg-custom-svgs {
110 | overflow: hidden;
111 | position: absolute;
112 | top: 0px;
113 | left: 0px;
114 | width: 100%;
115 | height: 100%;
116 | pointer-events: none;
117 | }
118 | .cg-wrap .cg-shapes {
119 | opacity: 0.6;
120 | z-index: 2;
121 | }
122 | .cg-wrap .cg-custom-svgs {
123 | /* over piece.anim = 8, but under piece.dragging = 10 */
124 | z-index: 9;
125 | }
126 | .cg-wrap coords {
127 | position: absolute;
128 | display: flex;
129 | pointer-events: none;
130 | opacity: 0.8;
131 | font-size: 1.2vh;
132 | user-select: none;
133 | }
134 | .cg-wrap coords.ranks {
135 | right: 0;
136 | top: -1.4em;
137 | line-height: 0;
138 | flex-flow: column-reverse;
139 | height: 100%;
140 | width: 0.8em;
141 | }
142 | .cg-wrap coords.ranks.black {
143 | flex-flow: column;
144 | }
145 | .cg-wrap coords.files {
146 | bottom: 0px;
147 | left: 2px;
148 | text-align: left;
149 | flex-flow: row;
150 | width: 100%;
151 | height: 1.4em;
152 | }
153 | .cg-wrap coords.files.black {
154 | flex-flow: row-reverse;
155 | }
156 | .cg-wrap coords.files.coord {
157 | padding-left: 4px;
158 | }
159 | .cg-wrap coords coord {
160 | flex: 1 1 auto;
161 | }
162 | .cg-wrap coords.ranks coord {
163 | transform: translateY(39%);
164 | }
165 | .orientation-white .files coord:nth-child(2n + 1),
166 | .orientation-white .ranks coord:nth-child(2n),
167 | .orientation-black .files coord:nth-child(2n),
168 | .orientation-black .ranks coord:nth-child(2n + 1) {
169 | color: #fff;
170 | }
171 | .orientation-white .files coord:nth-child(2n),
172 | .orientation-white .ranks coord:nth-child(2n + 1),
173 | .orientation-black .files coord:nth-child(2n + 1),
174 | .orientation-black .ranks coord:nth-child(2n) {
175 | color: #000;
176 | }
177 |
--------------------------------------------------------------------------------
/src/assets/css/images/pieces/maestro/bR.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const { exec } = require('child_process');
3 | const path = require('path');
4 | const HtmlWebpackPlugin = require("html-webpack-plugin");
5 | const CopyWebpackPlugin = require("copy-webpack-plugin");
6 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
7 |
8 | module.exports = (env, argv) => {
9 | const isProd = argv.mode === 'production';
10 | const inputDir = 'src';
11 | const outputDir = isProd ? 'www' : 'dev';
12 |
13 | const bundle = {
14 | name: 'bundle',
15 | mode: isProd ? 'production' : 'development',
16 | entry: { application: path.resolve(__dirname, inputDir, 'js/index.ts') },
17 | output: {
18 | path: path.resolve(__dirname, outputDir),
19 | filename: "assets/js/" + (isProd ? "bundle.[contenthash].js" : "bundle.js"),
20 | clean: true,
21 | },
22 | externals: {
23 | $: 'jquery',
24 | d3: 'd3',
25 | '@popperjs/core': 'Popper',
26 | bootstrap: 'Bootstrap'
27 | },
28 | resolve: {
29 | // Add '.ts' and '.tsx' as a resolvable extension.
30 | fallback: { 'crypto': false, 'fs': false, 'path': require.resolve('path-browserify') },
31 | extensions: [".webpack.js", ".web.js", ".ts", ".tsx", ".js"],
32 | alias: { assets: path.resolve(__dirname, inputDir, 'assets') },
33 | },
34 | module: {
35 | rules: [
36 | // all files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'
37 | { test: /\.tsx?$/, use: "ts-loader" },
38 | { test: /\.(woff|woff2|ttf|eot|svg)$/, type: 'asset', generator: { filename: 'assets/img/[name].[hash][ext][query]' } },
39 | { test: /\.m?js/, resolve: { fullySpecified: false } },
40 | { test: /\.wasm$/, type: "asset/resource", generator: { filename: "assets/js/[name][ext]" } },
41 | { test: /\.css$/,
42 | use: isProd
43 | ? [MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { url: false } }]
44 | : ['style-loader', 'css-loader'],
45 | }
46 | ]
47 | },
48 | plugins: [
49 | new webpack.optimize.AggressiveMergingPlugin(),
50 | new HtmlWebpackPlugin({
51 | template: path.resolve(__dirname, inputDir, 'play.html'),
52 | filename: "play.html",
53 | inject: "body",
54 | minify: isProd,
55 | }),
56 | new CopyWebpackPlugin({
57 | patterns: [
58 | {
59 | // copy all static assets
60 | from: path.resolve(__dirname, inputDir),
61 | to: path.resolve(__dirname, outputDir),
62 | globOptions: {
63 | ignore: [
64 | `${inputDir}/play.html`,
65 | `${inputDir}/js/**`,
66 | `${inputDir}/assets/css/application.css`,
67 | `${inputDir}/assets/css/themes/**`
68 | ],
69 | },
70 | }
71 | ],
72 | }),
73 | ...(isProd
74 | ? [
75 | new MiniCssExtractPlugin({
76 | filename: 'assets/css/[name].[contenthash].css',
77 | chunkFilename: 'assets/css/[name].[contenthash].css',
78 | }),
79 | ]
80 | : []),
81 | ],
82 | optimization: {
83 | minimize: isProd,
84 | },
85 | experiments: {
86 | asyncWebAssembly: true,
87 | },
88 | devServer: {
89 | client: {
90 | progress: true,
91 | },
92 | devMiddleware: {
93 | writeToDisk: false,
94 | },
95 | static: {
96 | directory: outputDir,
97 | watch: false,
98 | },
99 | hot: true,
100 | watchFiles: [`${inputDir}/*.html`],
101 | historyApiFallback: {
102 | rewrites: [
103 | { from: /^\/play/, to: '/play.html' },
104 | ],
105 | },
106 | compress: true,
107 | port: 8080,
108 | }
109 | };
110 |
111 | const serviceWorker = {
112 | name: 'service-worker',
113 | dependencies: ['bundle'],
114 | mode: isProd ? 'production' : 'development',
115 | stats: 'errors-warnings',
116 | entry: path.resolve(__dirname, inputDir, 'js/service-worker.js'),
117 | target: 'webworker',
118 | output: {
119 | filename: 'service-worker.js',
120 | path: path.resolve(__dirname, outputDir),
121 | },
122 | plugins: [
123 | {
124 | apply: (compiler) => {
125 | compiler.hooks.done.tap('RunAfterBuildPlugin', () => {
126 | exec(`node "${path.resolve(__dirname, 'scripts/inject-sw-manifest.js')}"`, (err, stdout, stderr) => {
127 | if (stdout) console.log(stdout);
128 | if (stderr) console.error(stderr);
129 | });
130 | });
131 | }
132 | }
133 | ]
134 | };
135 |
136 | return isProd ? [bundle, serviceWorker] : [bundle];
137 | }
138 |
--------------------------------------------------------------------------------