feat(plugins/community/chess): add plugin (#1215) [skip ci]
This commit is contained in:
1
.github/actions/spelling/excludes.txt
vendored
1
.github/actions/spelling/excludes.txt
vendored
@@ -52,3 +52,4 @@ ignore$
|
||||
^\Qsource/templates/terminal/fonts.css\E$
|
||||
^\Qsource/templates/terminal/partials/screenshot.ejs\E$
|
||||
^\Qtests/mocks/api/github/rest/emojis/get.mjs\E$
|
||||
^\Qtests/mocks/api/axios/get/lichess.mjs\E$
|
||||
|
||||
3
.github/actions/spelling/expect.txt
vendored
3
.github/actions/spelling/expect.txt
vendored
@@ -174,6 +174,7 @@ libxml
|
||||
libxmljs
|
||||
libxss
|
||||
libxtst
|
||||
lichess
|
||||
linux
|
||||
lng
|
||||
localhost
|
||||
@@ -236,6 +237,8 @@ params
|
||||
patchnote
|
||||
pdated
|
||||
pened
|
||||
PGN
|
||||
Pgn
|
||||
PGP
|
||||
playcount
|
||||
playlists
|
||||
|
||||
4
.github/actions/spelling/patterns.txt
vendored
4
.github/actions/spelling/patterns.txt
vendored
@@ -90,3 +90,7 @@ place_id: ".*"
|
||||
|
||||
# ignore long runs of a single character:
|
||||
\b([A-Za-z])\g{-1}{3,}\b
|
||||
|
||||
# Chess patterns
|
||||
\brnbqkbnr\b
|
||||
\bRNBQKBNR\b
|
||||
|
||||
BIN
.github/readme/imgs/plugin_chess_lichess_token_0.png
vendored
Normal file
BIN
.github/readme/imgs/plugin_chess_lichess_token_0.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
BIN
.github/readme/imgs/plugin_chess_lichess_token_1.png
vendored
Normal file
BIN
.github/readme/imgs/plugin_chess_lichess_token_1.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
BIN
.github/readme/imgs/plugin_chess_lichess_token_2.png
vendored
Normal file
BIN
.github/readme/imgs/plugin_chess_lichess_token_2.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
2
.github/scripts/files/examples.yml
vendored
2
.github/scripts/files/examples.yml
vendored
@@ -12,6 +12,8 @@ on:
|
||||
required: true
|
||||
METRICS_TOKEN_PERSONAL:
|
||||
required: true
|
||||
CHESS_TOKEN:
|
||||
required: true
|
||||
PAGESPEED_TOKEN:
|
||||
required: true
|
||||
GOOGLE_MAP_TOKEN:
|
||||
|
||||
14
package-lock.json
generated
14
package-lock.json
generated
@@ -19,6 +19,7 @@
|
||||
"@primer/css": "^20.4.3",
|
||||
"@primer/octicons": "^17.5.0",
|
||||
"axios": "^0.27.2",
|
||||
"chess.js": "*",
|
||||
"clipboard": "^2.0.11",
|
||||
"color": "^4.2.3",
|
||||
"compression": "^1.7.4",
|
||||
@@ -57,6 +58,7 @@
|
||||
"libxmljs2": "^0.30.1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"chess.js": "^1.0.0-alpha.0",
|
||||
"gifencoder": "^2.0.1",
|
||||
"libxmljs2": "^0.30.1",
|
||||
"node-chartist": "^1.0.5"
|
||||
@@ -3125,6 +3127,12 @@
|
||||
"entities": "^4.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/chess.js": {
|
||||
"version": "1.0.0-alpha.0",
|
||||
"resolved": "https://registry.npmjs.org/chess.js/-/chess.js-1.0.0-alpha.0.tgz",
|
||||
"integrity": "sha512-nwEDlNEOZR/FaKW1DZLYtjgJrtAlxBW/6Fp4Hk8QXqpCCLrXweOU6/vKfJ/jNHT2gPqasxi0/ZPslcWAAdzozg==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/chownr": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
|
||||
@@ -12435,6 +12443,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"chess.js": {
|
||||
"version": "1.0.0-alpha.0",
|
||||
"resolved": "https://registry.npmjs.org/chess.js/-/chess.js-1.0.0-alpha.0.tgz",
|
||||
"integrity": "sha512-nwEDlNEOZR/FaKW1DZLYtjgJrtAlxBW/6Fp4Hk8QXqpCCLrXweOU6/vKfJ/jNHT2gPqasxi0/ZPslcWAAdzozg==",
|
||||
"optional": true
|
||||
},
|
||||
"chownr": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
"transform": {}
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"chess.js": "^1.0.0-alpha.0",
|
||||
"gifencoder": "^2.0.1",
|
||||
"libxmljs2": "^0.30.1",
|
||||
"node-chartist": "^1.0.5"
|
||||
|
||||
@@ -1043,6 +1043,30 @@
|
||||
},
|
||||
})
|
||||
: null),
|
||||
//Chess
|
||||
...(set.plugins.enabled.chess
|
||||
? ({
|
||||
chess: {
|
||||
platform: options["chess.platform"] || "(chess platform)",
|
||||
meta: {
|
||||
Event: "Casual Correspondence game",
|
||||
Date: faker.date.recent().toISOString().substring(0, 10),
|
||||
White: options["chess.user"],
|
||||
Black: faker.internet.userName(),
|
||||
WhiteElo: faker.datatype.number(3000),
|
||||
BlackElo: faker.datatype.number(3000),
|
||||
},
|
||||
animation: { size: 40, delay: 3, duration: 0.6 },
|
||||
result: { white: faker.datatype.number(3), get black() { return this.white + faker.helpers.arrayElement([-1, +1]) } },
|
||||
moves: [
|
||||
{color: "w", piece: "p", from: "f2", to: "f4", san: "f4", flags: "b"},
|
||||
{color: "b", piece: "p", from: "c7", to: "c5", san: "c5", flags: "b"},
|
||||
{color: "w", piece: "p", from: "e2", to: "e4", san: "e4", flags: "b"},
|
||||
{color: "b", piece: "p", from: "d7", to: "d6", san: "d6", flags: "n"},
|
||||
]
|
||||
},
|
||||
})
|
||||
: null),
|
||||
//Activity
|
||||
...(set.plugins.enabled.activity
|
||||
? ({
|
||||
|
||||
12
source/plugins/community/chess/README.md
Normal file
12
source/plugins/community/chess/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
<!--header-->
|
||||
<!--/header-->
|
||||
|
||||
## ➡️ Available options
|
||||
|
||||
<!--options-->
|
||||
<!--/options-->
|
||||
|
||||
## ℹ️ Examples workflows
|
||||
|
||||
<!--examples-->
|
||||
<!--/examples-->
|
||||
10
source/plugins/community/chess/examples.yml
Normal file
10
source/plugins/community/chess/examples.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
- name: Last chess game from lichess.org
|
||||
uses: lowlighter/metrics@latest
|
||||
with:
|
||||
filename: metrics.plugin.chess.svg
|
||||
token: NOT_NEEDED
|
||||
base: ""
|
||||
plugin_chess: yes
|
||||
plugin_chess_token: ${{ secrets.CHESS_TOKEN }}
|
||||
plugin_chess_platform: lichess.org
|
||||
|
||||
48
source/plugins/community/chess/index.mjs
Normal file
48
source/plugins/community/chess/index.mjs
Normal file
@@ -0,0 +1,48 @@
|
||||
//Imports
|
||||
import { Chess } from "chess.js"
|
||||
|
||||
//Setup
|
||||
export default async function({login, q, imports, data, account}, {enabled = false, token = "", extras = false} = {}) {
|
||||
//Plugin execution
|
||||
try {
|
||||
//Check if plugin is enabled and requirements are met
|
||||
if ((!q.chess) || (!imports.metadata.plugins.chess.enabled(enabled, {extras})))
|
||||
return null
|
||||
|
||||
//Load inputs
|
||||
const {user, platform, animation} = imports.metadata.plugins.chess.inputs({data, account, q})
|
||||
for (const [key, defaulted] of Object.entries({size:40, delay:1, duration:4})) {
|
||||
if (Number.isNaN(Number(animation[key])))
|
||||
animation[key] = defaulted
|
||||
if (animation[key] < 0)
|
||||
animation[key] = defaulted
|
||||
}
|
||||
|
||||
//Fetch PGN
|
||||
console.debug(`metrics/compute/${login}/plugins > chess > fetching last game from ${platform}`)
|
||||
let PGN
|
||||
switch (platform) {
|
||||
case "lichess.org":
|
||||
PGN = (await imports.axios.get(`https://lichess.org/api/games/user/${user}?max=1`, {headers: {Authorization: `Bearer ${token}`}})).data
|
||||
break
|
||||
case "":
|
||||
throw {error: {message: "Unspecified platform"}}
|
||||
default:
|
||||
throw {error: {message: `Unsupported platform "${platform}"`}}
|
||||
}
|
||||
|
||||
//Parse PGN
|
||||
const board = new Chess()
|
||||
board.loadPgn(PGN)
|
||||
const moves = board.history({verbose: true})
|
||||
const meta = board.header()
|
||||
const result = Object.fromEntries(meta.Result.split("-").map((score, i) => [i ? "black" : "white", Number(score)]))
|
||||
|
||||
//Results
|
||||
return {platform, meta, moves, animation, result}
|
||||
}
|
||||
//Handle errors
|
||||
catch (error) {
|
||||
throw imports.format.error(error)
|
||||
}
|
||||
}
|
||||
61
source/plugins/community/chess/metadata.yml
Normal file
61
source/plugins/community/chess/metadata.yml
Normal file
@@ -0,0 +1,61 @@
|
||||
name: ♟️ Chess
|
||||
category: community
|
||||
description: |
|
||||
This plugin displays the last game you played on a supported chess platform.
|
||||
disclaimer: |
|
||||
This plugin is not affiliated, associated, authorized, endorsed by, or in any way officially connected with any of the supported provider.
|
||||
All product and company names are trademarks™ or registered® trademarks of their respective holders.
|
||||
examples:
|
||||
default: https://github.com/lowlighter/metrics/blob/examples/metrics.plugin.chess.svg
|
||||
authors:
|
||||
- lowlighter
|
||||
supports:
|
||||
- user
|
||||
- organization
|
||||
- repository
|
||||
scopes: []
|
||||
inputs:
|
||||
|
||||
plugin_chess:
|
||||
description: |
|
||||
Enable chess plugin
|
||||
type: boolean
|
||||
default: no
|
||||
|
||||
plugin_chess_token:
|
||||
description: |
|
||||
Chess platform token
|
||||
type: token
|
||||
default: ""
|
||||
extras:
|
||||
- metrics.api.chess.any
|
||||
|
||||
plugin_chess_user:
|
||||
description: |
|
||||
AniList login
|
||||
type: string
|
||||
default: .user.login
|
||||
preset: no
|
||||
|
||||
plugin_chess_platform:
|
||||
description: |
|
||||
Chess platform
|
||||
type: string
|
||||
default: ""
|
||||
values:
|
||||
- lichess.org
|
||||
|
||||
plugin_chess_animation:
|
||||
description: |
|
||||
Animation settings
|
||||
|
||||
- `size` is the size of a single chessboard square in pixels (board will be 8 times larger)
|
||||
- `delay` is the delay before starting animation (in seconds)
|
||||
- `duration` is the duration of the animation of a move (in seconds)
|
||||
type: json
|
||||
default: |
|
||||
{
|
||||
"size": 40,
|
||||
"delay": 3,
|
||||
"duration": 0.6
|
||||
}
|
||||
@@ -37,6 +37,7 @@
|
||||
"achievements",
|
||||
"screenshot",
|
||||
"code",
|
||||
"chess",
|
||||
"sponsors",
|
||||
"poopmap",
|
||||
"fortune"
|
||||
|
||||
194
source/templates/classic/partials/chess.ejs
Normal file
194
source/templates/classic/partials/chess.ejs
Normal file
@@ -0,0 +1,194 @@
|
||||
<% if (plugins.chess) { %>
|
||||
<section>
|
||||
<h2 class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.5 3.25c0-.966.784-1.75 1.75-1.75h2.5c.966 0 1.75.784 1.75 1.75v2.5A1.75 1.75 0 015.75 7.5h-2.5A1.75 1.75 0 011.5 5.75v-2.5zM3.25 3a.25.25 0 00-.25.25v2.5c0 .138.112.25.25.25h2.5A.25.25 0 006 5.75v-2.5A.25.25 0 005.75 3h-2.5zM1.5 10.25c0-.966.784-1.75 1.75-1.75h2.5c.966 0 1.75.784 1.75 1.75v2.5a1.75 1.75 0 01-1.75 1.75h-2.5a1.75 1.75 0 01-1.75-1.75v-2.5zM3.25 10a.25.25 0 00-.25.25v2.5c0 .138.112.25.25.25h2.5a.25.25 0 00.25-.25v-2.5a.25.25 0 00-.25-.25h-2.5zM8.5 3.25c0-.966.784-1.75 1.75-1.75h2.5c.966 0 1.75.784 1.75 1.75v2.5a1.75 1.75 0 01-1.75 1.75h-2.5A1.75 1.75 0 018.5 5.75v-2.5zM10.25 3a.25.25 0 00-.25.25v2.5c0 .138.112.25.25.25h2.5a.25.25 0 00.25-.25v-2.5a.25.25 0 00-.25-.25h-2.5zM8.5 10.25c0-.966.784-1.75 1.75-1.75h2.5c.966 0 1.75.784 1.75 1.75v2.5a1.75 1.75 0 01-1.75 1.75h-2.5a1.75 1.75 0 01-1.75-1.75v-2.5zm1.75-.25a.25.25 0 00-.25.25v2.5c0 .138.112.25.25.25h2.5a.25.25 0 00.25-.25v-2.5a.25.25 0 00-.25-.25h-2.5z"></path></svg>
|
||||
Last chess game
|
||||
</h2>
|
||||
<% if (plugins.chess.error) { %>
|
||||
<div class="row">
|
||||
<section>
|
||||
<div class="field error">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2.343 13.657A8 8 0 1113.657 2.343 8 8 0 012.343 13.657zM6.03 4.97a.75.75 0 00-1.06 1.06L6.94 8 4.97 9.97a.75.75 0 101.06 1.06L8 9.06l1.97 1.97a.75.75 0 101.06-1.06L9.06 8l1.97-1.97a.75.75 0 10-1.06-1.06L8 6.94 6.03 4.97z"></path></svg>
|
||||
<%= plugins.chess.error.message %>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<% } else { %>
|
||||
<div class="row largeable-align-start">
|
||||
<section class="largeable-column-fields">
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2.002 2.725a.75.75 0 01.797-.699C8.79 2.42 13.58 7.21 13.974 13.201a.75.75 0 11-1.497.098 10.502 10.502 0 00-9.776-9.776.75.75 0 01-.7-.798zM2 13a1 1 0 112 0 1 1 0 01-2 0zm.84-5.95a.75.75 0 00-.179 1.489c2.509.3 4.5 2.291 4.8 4.8a.75.75 0 101.49-.178A7.003 7.003 0 002.838 7.05z"></path></svg>
|
||||
From <%= plugins.chess.platform %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M10.5 5a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm.061 3.073a4 4 0 10-5.123 0 6.004 6.004 0 00-3.431 5.142.75.75 0 001.498.07 4.5 4.5 0 018.99 0 .75.75 0 101.498-.07 6.005 6.005 0 00-3.432-5.142z"></path></svg>
|
||||
<%= plugins.chess.meta["White"] %> <% if (plugins.chess.meta["WhiteElo"]) { %>(<%= plugins.chess.meta["WhiteElo"] %> ELO)<% } %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<% if (plugins.chess.result.white > plugins.chess.result.black) { %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M3.217 6.962A3.75 3.75 0 010 3.25v-.5C0 1.784.784 1 1.75 1h1.356c.228-.585.796-1 1.462-1h6.864a1.57 1.57 0 011.462 1h1.356c.966 0 1.75.784 1.75 1.75v.5a3.75 3.75 0 01-3.217 3.712 5.014 5.014 0 01-2.771 3.117l.144 1.446c.005.05.03.12.114.204.086.087.217.17.373.227.283.103.618.274.89.568.285.31.467.723.467 1.226v.75h1.25a.75.75 0 110 1.5H2.75a.75.75 0 010-1.5H4v-.75c0-.503.182-.916.468-1.226.27-.294.606-.465.889-.568a1.03 1.03 0 00.373-.227c.084-.085.109-.153.114-.204l.144-1.446a5.014 5.014 0 01-2.77-3.117zM3 2.5H1.75a.25.25 0 00-.25.25v.5c0 .98.626 1.813 1.5 2.122V2.5zm4.457 7.97l-.12 1.204c-.093.925-.858 1.47-1.467 1.691a.764.764 0 00-.3.176c-.037.04-.07.093-.07.21v.75h5v-.75c0-.117-.033-.17-.07-.21a.763.763 0 00-.3-.176c-.609-.221-1.374-.766-1.466-1.69l-.12-1.204a5.052 5.052 0 01-1.087 0zM13 5.373V2.5h1.25a.25.25 0 01.25.25v.5A2.25 2.25 0 0113 5.372zM4.5 1.568c0-.037.03-.068.068-.068h6.864c.037 0 .068.03.068.068V5.5a3.5 3.5 0 11-7 0V1.568z"></path></svg>
|
||||
<% } else { %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 5.5a2.5 2.5 0 100 5 2.5 2.5 0 000-5zM4 8a4 4 0 118 0 4 4 0 01-8 0z"></path></svg>
|
||||
<% } %>
|
||||
<%= plugins.chess.result.white %> victor<%= s(plugins.chess.result.white, "y") %>
|
||||
</div>
|
||||
</section>
|
||||
<section class="largeable-column-fields">
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M4.75 0a.75.75 0 01.75.75V2h5V.75a.75.75 0 011.5 0V2h1.25c.966 0 1.75.784 1.75 1.75v10.5A1.75 1.75 0 0113.25 16H2.75A1.75 1.75 0 011 14.25V3.75C1 2.784 1.784 2 2.75 2H4V.75A.75.75 0 014.75 0zm0 3.5h8.5a.25.25 0 01.25.25V6h-11V3.75a.25.25 0 01.25-.25h2zm-2.25 4v6.75c0 .138.112.25.25.25h10.5a.25.25 0 00.25-.25V7.5h-11z"></path></svg>
|
||||
<%= plugins.chess.meta["Date"] %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M4.243 4.757a3.757 3.757 0 115.851 3.119 6.006 6.006 0 013.9 5.339.75.75 0 01-.715.784H2.721a.75.75 0 01-.714-.784 6.006 6.006 0 013.9-5.34 3.753 3.753 0 01-1.664-3.118z"></path></svg>
|
||||
<%= plugins.chess.meta["Black"] %> <% if (plugins.chess.meta["BlackElo"]) { %>(<%= plugins.chess.meta["BlackElo"] %> ELO)<% } %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<% if (plugins.chess.result.black > plugins.chess.result.white) { %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M3.217 6.962A3.75 3.75 0 010 3.25v-.5C0 1.784.784 1 1.75 1h1.356c.228-.585.796-1 1.462-1h6.864a1.57 1.57 0 011.462 1h1.356c.966 0 1.75.784 1.75 1.75v.5a3.75 3.75 0 01-3.217 3.712 5.014 5.014 0 01-2.771 3.117l.144 1.446c.005.05.03.12.114.204.086.087.217.17.373.227.283.103.618.274.89.568.285.31.467.723.467 1.226v.75h1.25a.75.75 0 110 1.5H2.75a.75.75 0 010-1.5H4v-.75c0-.503.182-.916.468-1.226.27-.294.606-.465.889-.568a1.03 1.03 0 00.373-.227c.084-.085.109-.153.114-.204l.144-1.446a5.014 5.014 0 01-2.77-3.117zM3 2.5H1.75a.25.25 0 00-.25.25v.5c0 .98.626 1.813 1.5 2.122V2.5zm4.457 7.97l-.12 1.204c-.093.925-.858 1.47-1.467 1.691a.764.764 0 00-.3.176c-.037.04-.07.093-.07.21v.75h5v-.75c0-.117-.033-.17-.07-.21a.763.763 0 00-.3-.176c-.609-.221-1.374-.766-1.466-1.69l-.12-1.204a5.052 5.052 0 01-1.087 0zM13 5.373V2.5h1.25a.25.25 0 01.25.25v.5A2.25 2.25 0 0113 5.372zM4.5 1.568c0-.037.03-.068.068-.068h6.864c.037 0 .068.03.068.068V5.5a3.5 3.5 0 11-7 0V1.568z"></path></svg>
|
||||
<% } else { %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8z"></path></svg>
|
||||
<% } %>
|
||||
<%= plugins.chess.result.black %> victor<%= s(plugins.chess.result.black, "y") %>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="chess-board">
|
||||
<% {
|
||||
//Utilities functions
|
||||
const pieces = {
|
||||
w: {p: "♙", r: "♖", n: "♘", b: "♗", q: "♕", k: "♔"},
|
||||
b: {p: "♟︎", r: "♜", n: "♞", b: "♝", q: "♛", k: "♚"},
|
||||
}
|
||||
const init = ["rnbqkbnr", "pppppppp", "", "", "", "", "PPPPPPPP", "RNBQKBNR"]
|
||||
const column = p => ["a", "b", "c", "d", "e", "f", "g", "h"].indexOf(p[0])
|
||||
const row = p => ["8", "7", "6", "5", "4", "3", "2", "1"].indexOf(p[1])
|
||||
const animation = plugins.chess.animation
|
||||
const size = animation.size
|
||||
|
||||
//Empty board
|
||||
for (let i = 0; i < 8; i++) { %>
|
||||
<div class="chess-row">
|
||||
<% for (let j = 0; j < 8; j++) { %>
|
||||
<div class="chess-square <%= (i + j) % 2 ? 'black' : 'white' %>"></div>
|
||||
<% } %>
|
||||
</div>
|
||||
<% }
|
||||
|
||||
//Initial board state
|
||||
for (let i = 0; i < init.length; i++) { for (let j = 0; j < init[i].length; j++) {
|
||||
const color = /[A-Z]/.test(init[i][j]) ? "w" : "b", piece = init[i][j].toLocaleLowerCase() %>
|
||||
<div class="chess-move">
|
||||
<div class="init" style="left: <%= j*size %>px; top: <%= i*size %>px;"><%- pieces[color][piece] %></div>
|
||||
</div>
|
||||
<% }}
|
||||
|
||||
//Draw moves
|
||||
const moves = plugins.chess.moves
|
||||
for (let i = 0; i < moves.length; i++) { const {color, piece, from, to} = moves[i] %>
|
||||
<div class="chess-move chess-move-<%= i %>">
|
||||
<div class="from" style="left: <%= column(from)*size %>px; top: <%= row(from)*size %>px;"><%- pieces[color][piece] %></div>
|
||||
<div class="to" style="left: <%= column(from)*size %>px; top: <%= row(from)*size %>px;"><%- pieces[color][piece] %></div>
|
||||
<style>
|
||||
@keyframes chess-move-<%= i %>-from {
|
||||
100% {
|
||||
opacity: 1;
|
||||
color: transparent;
|
||||
background-color: <%= (row(from)+column(from))%2 ? "#C5A076" : "#ECDAB9" %>;
|
||||
}
|
||||
}
|
||||
.chess-move-<%= i %> .from {
|
||||
animation-name: chess-move-<%= i %>-from;
|
||||
animation-delay: <%= i * animation.duration + animation.delay %>s;
|
||||
}
|
||||
|
||||
@keyframes chess-move-<%= i %>-to {
|
||||
1% {
|
||||
opacity: 1;
|
||||
}
|
||||
99% {
|
||||
background-color: transparent;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
background-color: <%= (row(to)+column(to))%2 ? "#C5A076" : "#ECDAB9" %>;
|
||||
left: <%= column(to)*size %>px;
|
||||
top: <%= row(to)*size %>px;
|
||||
}
|
||||
}
|
||||
.chess-move-<%= i %> .to {
|
||||
animation-name: chess-move-<%= i %>-to;
|
||||
animation-delay: <%= i * animation.duration + animation.delay %>s;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
<% } %>
|
||||
<style>
|
||||
.chess-board {
|
||||
width: <%= 8*size %>px;
|
||||
height: <%= 8*size %>px;
|
||||
position: relative;
|
||||
margin: 6px auto 0;
|
||||
}
|
||||
.chess-square, .chess-move .from, .chess-move .to, .chess-move .init {
|
||||
width: <%= size %>px;
|
||||
height: <%= size %>px;
|
||||
float: left;
|
||||
}
|
||||
.chess-square.white {
|
||||
background-color: #ECDAB9;
|
||||
}
|
||||
.chess-square.black {
|
||||
background-color: #C5A076;
|
||||
}
|
||||
.chess-clock {
|
||||
width: <%= 8*size %>px;
|
||||
height: 4px;
|
||||
margin: auto;
|
||||
background-color: #58A6FF40;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.chess-clock .chess-time {
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
background-color: #58A6FF;
|
||||
animation-fill-mode: forwards;
|
||||
animation-name: chess-clock;
|
||||
animation-delay: <%= animation.delay %>s;
|
||||
animation-duration: <%= moves.length*animation.duration %>s;
|
||||
animation-timing-function: linear;
|
||||
}
|
||||
@keyframes chess-clock {
|
||||
100% {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.chess-move {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.chess-move .from, .chess-move .to, .chess-move .init {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: <%= 0.8*size %>px;
|
||||
animation-fill-mode: forwards;
|
||||
opacity: 0;
|
||||
}
|
||||
.chess-move .init {
|
||||
opacity: 1;
|
||||
}
|
||||
.chess-move .to {
|
||||
animation-duration: <%= animation.duration %>s;
|
||||
}
|
||||
</style>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="chess-clock">
|
||||
<div class="chess-time"></div>
|
||||
</div>
|
||||
<% } %>
|
||||
</section>
|
||||
<% } %>
|
||||
30
tests/mocks/api/axios/get/lichess.mjs
Normal file
30
tests/mocks/api/axios/get/lichess.mjs
Normal file
@@ -0,0 +1,30 @@
|
||||
/**Mocked data */
|
||||
export default function({faker, url, options, login = faker.internet.userName()}) {
|
||||
//Wakatime api
|
||||
if (/^https:..lichess.org.api.games.user.*$/.test(url)) {
|
||||
console.debug(`metrics/compute/mocks > mocking lichess api result > ${url}`)
|
||||
return ({
|
||||
status: 200,
|
||||
data: `
|
||||
[Event "It (cat.17)"]
|
||||
[Site "Wijk aan Zee (Netherlands)"]
|
||||
[Date "1999.??.??"]
|
||||
[Round "?"]
|
||||
[White "Garry Kasparov"]
|
||||
[Black "Veselin Topalov"]
|
||||
[Result "1-0"]
|
||||
|
||||
1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. Be3 Bg7 5. Qd2 c6 6. f3 b5 7. Nge2 Nbd7 8. Bh6
|
||||
Bxh6 9. Qxh6 Bb7 10. a3 e5 11. O-O-O Qe7 12. Kb1 a6 13. Nc1 O-O-O 14. Nb3 exd4
|
||||
15. Rxd4 c5 16. Rd1 Nb6 17. g3 Kb8 18. Na5 Ba8 19. Bh3 d5 20. Qf4+ Ka7 21. Rhe1
|
||||
d4 22. Nd5 Nbxd5 23. exd5 Qd6 24. Rxd4 cxd4 25. Re7+ Kb6 26. Qxd4+ Kxa5 27. b4+
|
||||
Ka4 28. Qc3 Qxd5 29. Ra7 Bb7 30. Rxb7 Qc4 31. Qxf6 Kxa3 32. Qxa6+ Kxb4 33. c3+
|
||||
Kxc3 34. Qa1+ Kd2 35. Qb2+ Kd1 36. Bf1 Rd2 37. Rd7 Rxd7 38. Bxc4 bxc4 39. Qxh8
|
||||
Rd3 40. Qa8 c3 41. Qa4+ Ke1 42. f4 f5 43. Kc1 Rd2 44. Qa7 1-0`.trim()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,5 +11,6 @@
|
||||
"TWITTER_TOKEN":"MOCKED_TOKEN",
|
||||
"GOOGLE_MAP_TOKEN": "MOCKED_TOKEN",
|
||||
"STOCK_TOKEN":"MOCKED_TOKEN",
|
||||
"CHESS_TOKEN":"MOCKED_TOKEN",
|
||||
"POOPMAP_TOKEN":"MOCKED_TOKEN"
|
||||
}
|
||||
Reference in New Issue
Block a user